AgentProvider
Interface for implementing custom AI agent providers. Agent providers handle sending prompts to AI services and streaming responses.
Properties
send
(context: AgentContext<T>, signal: AbortSignal) => AsyncIterable<string>
required
Send a prompt to the agent and receive streaming response. Must return an async iterable that yields status message strings.
context - The agent context with content, prompt, and options
signal - AbortSignal for cancellation support
resume
(sessionId: string, signal: AbortSignal, storage: AgentSessionStorage) => AsyncIterable<string>
Resume a previously started session. Only required if supportsResume is true.
sessionId - ID of the session to resume
signal - AbortSignal for cancellation
storage - Storage interface for retrieving session data
abort
(sessionId: string) => Promise<void>
Abort a running session. Called when user cancels an active agent operation.
Whether this provider supports resuming sessions after page reload.
Whether this provider supports follow-up prompts in the same session.
Custom text for the dismiss button in the agent UI. Defaults to “Dismiss”.
Check if the agent service is available. Called before showing agent UI.
Get a custom completion message to show when agent finishes successfully.
Undo the last agent action. Only required if canUndo returns true.
Whether undo is currently available. Checked to show/hide undo button.
Redo a previously undone action. Only required if canRedo returns true.
Whether redo is currently available. Checked to show/hide redo button.
AgentContext
Context object passed to agent providers containing the prompt and selected content.
Properties
Array of content strings from selected elements. Each string represents the code/content of one grabbed element.
The user’s prompt/instruction for the agent.
Custom options for the agent provider. Type parameter T allows providers to specify their own options interface.
Unique session identifier. Useful for tracking and resuming sessions.
AgentSession
Represents an active or completed agent session with its state and metadata.
Properties
Unique session identifier.
The agent context (content, prompt, options) for this session.
The most recent status message from the agent.
Whether the agent is currently streaming responses.
Whether the session UI is fading out (dismissing).
Timestamp (ms) when the session was created.
Timestamp (ms) of the last update to this session.
position
{ x: number; y: number }
required
Screen position where the agent UI should appear.
Visual bounds of selected elements for highlighting.
HTML tag name of the primary selected element.
React component name of the primary selected element.
Error message if the session failed.
AgentSessionStorage
Storage interface for persisting agent session data. Used for session resumption.
Properties
getItem
(key: string) => string | null
required
Retrieve a stored value by key. Returns null if not found.
setItem
(key: string, value: string) => void
required
Store a value with the given key. Overwrites existing value.
removeItem
(key: string) => void
required
Remove a stored value by key.
AgentOptions
Configuration options for agent integration.
Properties
The agent provider instance to use for this operation.
storage
AgentSessionStorage | null
Storage implementation for session persistence. Pass null to disable.
Function that returns custom options to pass to the provider.
onStart
(session: AgentSession, elements: Element[]) => void
Called when an agent session starts.
onStatus
(status: string, session: AgentSession) => void
Called when agent sends a status update.
onComplete
(session: AgentSession, elements: Element[]) => AgentCompleteResult | void | Promise<AgentCompleteResult | void>
Called when agent completes successfully. Can return an error to show.
onError
(error: Error, session: AgentSession) => void
Called when agent encounters an error.
onResume
(session: AgentSession) => void
Called when a session is resumed.
onAbort
(session: AgentSession, elements: Element[]) => void
Called when user aborts a session.
onUndo
(session: AgentSession, elements: Element[]) => void
Called when user triggers undo.
onDismiss
(session: AgentSession, elements: Element[]) => void
Called when user dismisses the session UI.
Usage
Basic Agent Provider
import { AgentProvider, AgentContext } from 'react-grab';
const myAgent: AgentProvider = {
async *send(context, signal) {
yield 'Connecting to AI service...';
const response = await fetch('/api/agent', {
method: 'POST',
body: JSON.stringify({
prompt: context.prompt,
content: context.content
}),
signal
});
yield 'Processing request...';
const result = await response.json();
yield 'Applying changes...';
// Apply the changes
await applyChanges(result);
yield 'Complete!';
},
checkConnection: async () => {
try {
await fetch('/api/health');
return true;
} catch {
return false;
}
}
};
Agent with Custom Options
interface MyAgentOptions {
model: string;
temperature: number;
}
const configurableAgent: AgentProvider<MyAgentOptions> = {
async *send(context, signal) {
const { model, temperature } = context.options || {};
yield `Using model: ${model}...`;
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({
model,
temperature,
prompt: context.prompt,
content: context.content
}),
signal
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (reader) {
const { done, value } = await reader.read();
if (done) break;
yield decoder.decode(value);
}
},
supportsFollowUp: true,
dismissButtonText: 'Done'
};
Using Agent in Action
import { ContextMenuAction } from 'react-grab';
const refactorAction: ContextMenuAction = {
id: 'refactor',
label: 'Refactor with AI',
onAction: async (context) => {
context.enterPromptMode?.({
provider: myAgent,
getOptions: () => ({
model: 'gpt-4',
temperature: 0.7
}),
onComplete: (session, elements) => {
console.log('Refactoring complete!');
},
onError: (error) => {
console.error('Failed:', error);
}
});
}
};
Agent with Session Storage
const persistentAgent: AgentProvider = {
async *send(context, signal) {
// Implementation...
yield 'Processing...';
},
async *resume(sessionId, signal, storage) {
const savedState = storage.getItem(`session-${sessionId}`);
if (!savedState) {
throw new Error('Session not found');
}
yield 'Resuming session...';
const state = JSON.parse(savedState);
// Continue from saved state
yield 'Resumed!';
},
supportsResume: true
};
// Use with storage
const action: ContextMenuAction = {
id: 'ai-assist',
label: 'AI Assist',
onAction: (context) => {
context.enterPromptMode?.({
provider: persistentAgent,
storage: localStorage, // Use browser localStorage
onStart: (session) => {
localStorage.setItem(
`session-${session.id}`,
JSON.stringify(session.context)
);
}
});
}
};
Type Definitions
export interface AgentProvider<T = any> {
send: (context: AgentContext<T>, signal: AbortSignal) => AsyncIterable<string>;
resume?: (sessionId: string, signal: AbortSignal, storage: AgentSessionStorage) => AsyncIterable<string>;
abort?: (sessionId: string) => Promise<void>;
supportsResume?: boolean;
supportsFollowUp?: boolean;
dismissButtonText?: string;
checkConnection?: () => Promise<boolean>;
getCompletionMessage?: () => string | undefined;
undo?: () => Promise<void>;
canUndo?: () => boolean;
redo?: () => Promise<void>;
canRedo?: () => boolean;
}
export interface AgentContext<T = unknown> {
content: string[];
prompt: string;
options?: T;
sessionId?: string;
}
export interface AgentSession {
id: string;
context: AgentContext;
lastStatus: string;
isStreaming: boolean;
isFading?: boolean;
createdAt: number;
lastUpdatedAt: number;
position: { x: number; y: number };
selectionBounds: OverlayBounds[];
tagName?: string;
componentName?: string;
error?: string;
}
export interface AgentSessionStorage {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
removeItem(key: string): void;
}
export interface AgentOptions<T = any> {
provider?: AgentProvider<T>;
storage?: AgentSessionStorage | null;
getOptions?: () => T;
onStart?: (session: AgentSession, elements: Element[]) => void;
onStatus?: (status: string, session: AgentSession) => void;
onComplete?: (session: AgentSession, elements: Element[]) => AgentCompleteResult | void | Promise<AgentCompleteResult | void>;
onError?: (error: Error, session: AgentSession) => void;
onResume?: (session: AgentSession) => void;
onAbort?: (session: AgentSession, elements: Element[]) => void;
onUndo?: (session: AgentSession, elements: Element[]) => void;
onDismiss?: (session: AgentSession, elements: Element[]) => void;
}
See Also
- Actions - Use actions to trigger agent operations
- Plugin - Register agents via plugins