deepagentsdk 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/elements/index.cjs +5 -0
- package/dist/adapters/elements/index.cjs.map +1 -1
- package/dist/adapters/elements/index.d.cts +1 -1
- package/dist/adapters/elements/index.mjs +5 -0
- package/dist/adapters/elements/index.mjs.map +1 -1
- package/dist/{agent-DuvtniwH.d.cts → agent-64IK97WT.d.cts} +25 -25
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +2 -2
- package/package.json +1 -1
|
@@ -146,6 +146,11 @@ function mapEventToProtocol(event, writer, genId, currentTextId) {
|
|
|
146
146
|
type: "text-start",
|
|
147
147
|
id: textId
|
|
148
148
|
});
|
|
149
|
+
writer.write({
|
|
150
|
+
type: "text-delta",
|
|
151
|
+
id: textId,
|
|
152
|
+
delta: event.text
|
|
153
|
+
});
|
|
149
154
|
return textId;
|
|
150
155
|
}
|
|
151
156
|
writer.write({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/adapters/elements/createElementsRouteHandler.ts","../../../src/adapters/elements/messageConverters.ts"],"sourcesContent":["/**\n * Server-side route handler adapter for AI SDK Elements\n *\n * Creates a Next.js/Express-compatible route handler that runs DeepAgent\n * and returns UI Message Stream compatible responses with full event visibility.\n *\n * This handler streams all DeepAgent event types (26+) including:\n * - Text and tool events (standard protocol)\n * - File system operations\n * - Command execution\n * - Web requests and searches\n * - Subagent lifecycle\n * - State changes (todos, checkpoints)\n *\n * @example\n * ```typescript\n * // app/api/chat/route.ts (Next.js App Router)\n * import { createDeepAgent } from 'deepagentsdk';\n * import { createElementsRouteHandler } from 'deepagentsdk/adapters/elements';\n * import { anthropic } from '@ai-sdk/anthropic';\n *\n * const agent = createDeepAgent({\n * model: anthropic('claude-sonnet-4-20250514'),\n * });\n *\n * export const POST = createElementsRouteHandler({ agent });\n * ```\n *\n * @see https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol\n */\n\nimport {\n createUIMessageStream,\n createUIMessageStreamResponse,\n convertToModelMessages,\n} from \"ai\";\nimport type { DeepAgent } from \"../../agent\";\nimport type { DeepAgentState, DeepAgentEvent } from \"../../types\";\n\n/**\n * Options for creating an Elements route handler\n */\nexport interface CreateElementsRouteHandlerOptions {\n /**\n * The DeepAgent instance to use for handling requests\n */\n agent: DeepAgent;\n\n /**\n * Optional callback before processing a request.\n * Use for authentication, logging, rate limiting, etc.\n *\n * @example\n * ```typescript\n * onRequest: async (req) => {\n * const token = req.headers.get('Authorization');\n * if (!validateToken(token)) {\n * throw new Error('Unauthorized');\n * }\n * }\n * ```\n */\n onRequest?: (req: Request) => Promise<void> | void;\n\n /**\n * Optional initial state to provide to the agent.\n * If not provided, uses empty state { todos: [], files: {} }\n */\n initialState?: DeepAgentState;\n\n /**\n * Optional thread ID for checkpointing.\n * If provided, enables conversation persistence.\n */\n threadId?: string;\n\n /**\n * Optional maximum number of steps for the agent loop.\n */\n maxSteps?: number;\n\n /**\n * Custom ID generator for message IDs.\n * Defaults to crypto.randomUUID if available.\n */\n generateId?: () => string;\n}\n\n/**\n * Creates a route handler that processes chat requests using DeepAgent\n * and streams all 26+ event types in UI Message Stream Protocol format.\n *\n * The returned handler:\n * - Accepts POST requests with { messages: UIMessage[] } body\n * - Runs DeepAgent with the conversation history\n * - Streams responses in UI Message Stream Protocol format\n * - Works with useChat hook from @ai-sdk/react\n * - Provides full visibility into agent behavior (file ops, web requests, subagents, etc.)\n *\n * @param options - Configuration options\n * @returns A request handler function compatible with Next.js/Express\n */\nexport function createElementsRouteHandler(\n options: CreateElementsRouteHandlerOptions\n): (req: Request) => Promise<Response> {\n const {\n agent,\n onRequest,\n initialState = {\n todos: [],\n files: {}\n },\n threadId,\n maxSteps,\n generateId\n } = options;\n\n return async (req: Request): Promise<Response> => {\n // 1. Handle onRequest hook (auth, logging, rate limiting)\n if (onRequest) {\n try {\n await onRequest(req);\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: error instanceof Error ? error.message : 'Request rejected'\n }),\n {\n status: 401,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n }\n\n // 2. Parse request body\n let requestBody;\n try {\n requestBody = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n const { messages } = requestBody;\n if (!messages || !Array.isArray(messages)) {\n return new Response(\n JSON.stringify({ error: 'messages array is required' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n // 3. Convert UI messages to model messages\n const modelMessages = await convertToModelMessages(messages);\n\n // 4. Setup ID generator\n const genId = generateId || (() => crypto.randomUUID());\n\n // 5. Track current text ID for text-start/text-end\n let currentTextId: string | null = null;\n\n // 6. Create UI message stream response\n return createUIMessageStreamResponse({\n stream: createUIMessageStream({\n originalMessages: messages,\n generateId: genId,\n execute: async ({ writer }) => {\n try {\n // Stream all events from DeepAgent\n for await (const event of agent.streamWithEvents({\n messages: modelMessages,\n state: initialState,\n threadId,\n maxSteps\n })) {\n // Update currentTextId from the returned value\n const result = mapEventToProtocol(event, writer, genId, currentTextId);\n if (typeof result === 'string') {\n currentTextId = result;\n } else if (result === null) {\n currentTextId = null;\n }\n }\n\n // Ensure text is properly closed\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n } catch (error) {\n // Close text if error occurs mid-stream\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n throw error;\n }\n },\n onError: (error) => {\n return error instanceof Error ? error.message : 'Unknown error';\n }\n })\n });\n };\n}\n\n/**\n * Maps a DeepAgent event to a UI Message Stream Protocol event.\n *\n * This function handles all 26+ DeepAgent event types, mapping:\n * - Standard protocol events (text, tools, steps, errors)\n * - Custom data events (file operations, web requests, subagents, execution)\n *\n * @param event - The DeepAgent event to map\n * @param writer - The UI message stream writer\n * @param genId - ID generator function\n * @param currentTextId - The current text part ID (for tracking streaming text)\n * @returns The new currentTextId value (string | null)\n *\n * @example\n * ```typescript\n * // Handles text streaming with proper ID tracking\n * let textId: string | null = null;\n * textId = mapEventToProtocol({ type: 'text', text: 'Hello' }, writer, genId, textId);\n * // textId is now the ID of the active text part\n * ```\n */\nexport function mapEventToProtocol(\n event: DeepAgentEvent,\n writer: { write: (chunk: any) => void },\n genId: () => string,\n currentTextId: string | null\n): string | null {\n switch (event.type) {\n // ============================================================================\n // TEXT & FLOW EVENTS (Required for compatibility)\n // ============================================================================\n\n case 'step-start':\n writer.write({ type: 'start-step' });\n return currentTextId;\n\n case 'step-finish':\n writer.write({ type: 'finish-step' });\n return currentTextId;\n\n case 'text':\n // Start text if not already started\n if (!currentTextId) {\n const textId = genId();\n writer.write({\n type: 'text-start',\n id: textId\n });\n return textId;\n }\n writer.write({\n type: 'text-delta',\n id: currentTextId,\n delta: event.text\n });\n return currentTextId;\n\n // ============================================================================\n // TOOL EVENTS (Standard protocol events)\n // ============================================================================\n\n case 'tool-call':\n // End text before tool call\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'tool-input-available',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args\n });\n return null;\n\n case 'tool-result':\n if (event.isError) {\n writer.write({\n type: 'tool-output-error',\n toolCallId: event.toolCallId,\n errorText: String(event.result)\n });\n } else {\n writer.write({\n type: 'tool-output-available',\n toolCallId: event.toolCallId,\n output: event.result\n });\n }\n return currentTextId;\n\n // ============================================================================\n // TODO & PLANNING EVENTS\n // ============================================================================\n\n case 'todos-changed':\n writer.write({\n type: 'data',\n name: 'todos-changed',\n data: { todos: event.todos }\n });\n return currentTextId;\n\n // ============================================================================\n // FILE SYSTEM EVENTS (Custom data events)\n // ============================================================================\n\n case 'file-write-start':\n writer.write({\n type: 'data',\n name: 'file-write-start',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-written':\n writer.write({\n type: 'data',\n name: 'file-written',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-edited':\n writer.write({\n type: 'data',\n name: 'file-edited',\n data: {\n path: event.path,\n occurrences: event.occurrences\n }\n });\n return currentTextId;\n\n case 'file-read':\n writer.write({\n type: 'data',\n name: 'file-read',\n data: {\n path: event.path,\n lines: event.lines\n }\n });\n return currentTextId;\n\n case 'ls':\n writer.write({\n type: 'data',\n name: 'ls',\n data: {\n path: event.path,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'glob':\n writer.write({\n type: 'data',\n name: 'glob',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'grep':\n writer.write({\n type: 'data',\n name: 'grep',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n // ============================================================================\n // EXECUTION EVENTS (Custom data events)\n // ============================================================================\n\n case 'execute-start':\n writer.write({\n type: 'data',\n name: 'execute-start',\n data: {\n command: event.command,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n case 'execute-finish':\n writer.write({\n type: 'data',\n name: 'execute-finish',\n data: {\n command: event.command,\n exitCode: event.exitCode,\n truncated: event.truncated,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n // ============================================================================\n // WEB EVENTS (Custom data events)\n // ============================================================================\n\n case 'web-search-start':\n writer.write({\n type: 'data',\n name: 'web-search-start',\n data: {\n query: event.query\n }\n });\n return currentTextId;\n\n case 'web-search-finish':\n writer.write({\n type: 'data',\n name: 'web-search-finish',\n data: {\n query: event.query,\n resultCount: event.resultCount\n }\n });\n return currentTextId;\n\n case 'http-request-start':\n writer.write({\n type: 'data',\n name: 'http-request-start',\n data: {\n url: event.url,\n method: event.method\n }\n });\n return currentTextId;\n\n case 'http-request-finish':\n writer.write({\n type: 'data',\n name: 'http-request-finish',\n data: {\n url: event.url,\n statusCode: event.statusCode\n }\n });\n return currentTextId;\n\n case 'fetch-url-start':\n writer.write({\n type: 'data',\n name: 'fetch-url-start',\n data: {\n url: event.url\n }\n });\n return currentTextId;\n\n case 'fetch-url-finish':\n writer.write({\n type: 'data',\n name: 'fetch-url-finish',\n data: {\n url: event.url,\n success: event.success\n }\n });\n return currentTextId;\n\n // ============================================================================\n // SUBAGENT EVENTS (Custom data events)\n // ============================================================================\n\n case 'subagent-start':\n writer.write({\n type: 'data',\n name: 'subagent-start',\n data: {\n name: event.name,\n task: event.task\n }\n });\n return currentTextId;\n\n case 'subagent-finish':\n writer.write({\n type: 'data',\n name: 'subagent-finish',\n data: {\n name: event.name,\n result: event.result\n }\n });\n return currentTextId;\n\n case 'subagent-step':\n writer.write({\n type: 'data',\n name: 'subagent-step',\n data: {\n stepIndex: event.stepIndex,\n toolCalls: event.toolCalls\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CHECKPOINT EVENTS (Custom data events)\n // ============================================================================\n\n case 'checkpoint-saved':\n writer.write({\n type: 'data',\n name: 'checkpoint-saved',\n data: {\n threadId: event.threadId,\n step: event.step\n }\n });\n return currentTextId;\n\n case 'checkpoint-loaded':\n writer.write({\n type: 'data',\n name: 'checkpoint-loaded',\n data: {\n threadId: event.threadId,\n step: event.step,\n messagesCount: event.messagesCount\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CONTROL EVENTS\n // ============================================================================\n\n case 'error':\n // End text before error\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'error',\n errorText: event.error.message\n });\n return null;\n\n case 'done':\n // End text before completion\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n // The finish event is auto-emitted by createUIMessageStream\n // We explicitly emit it here for clarity\n writer.write({\n type: 'finish',\n finishReason: 'stop',\n });\n return null;\n\n // Ignore unhandled events (text-segment, user-message, approval events)\n default:\n return currentTextId;\n }\n}\n\n/**\n * Type for the request handler returned by createElementsRouteHandler\n */\nexport type ElementsRouteHandler = (req: Request) => Promise<Response>;\n","/**\n * Message conversion utilities for AI SDK Elements adapter\n *\n * Provides utilities for converting between UI message formats and model message formats.\n * The primary conversion is handled by AI SDK's `convertToModelMessages`, but these\n * utilities provide additional helpers for DeepAgent-specific needs.\n */\n\nimport {\n convertToModelMessages,\n type UIMessage,\n} from \"ai\";\nimport type { ModelMessage } from \"../../types\";\n\n/**\n * Re-export AI SDK's convertToModelMessages for convenience.\n *\n * This function converts UIMessage[] (from useChat) to ModelMessage[]\n * (for agent consumption), handling:\n * - Role mapping (user/assistant)\n * - Tool call/result parts\n * - Text content extraction\n *\n * @example\n * ```typescript\n * import { convertUIMessagesToModelMessages } from 'deepagentsdk/adapters/elements';\n *\n * const modelMessages = await convertUIMessagesToModelMessages(uiMessages);\n * ```\n */\nexport async function convertUIMessagesToModelMessages(\n messages: UIMessage[]\n): Promise<ModelMessage[]> {\n return await convertToModelMessages(messages) as ModelMessage[];\n}\n\n/**\n * Extract the last user message text from a UIMessage array.\n * Useful for extracting the prompt from a conversation.\n *\n * @param messages - Array of UI messages\n * @returns The text content of the last user message, or undefined if none\n */\nexport function extractLastUserMessage(messages: UIMessage[]): string | undefined {\n // Find the last user message\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg && msg.role === \"user\" && msg.parts) {\n // Extract text parts\n const textParts = msg.parts.filter(\n (p): p is { type: \"text\"; text: string } => p.type === \"text\"\n );\n if (textParts.length > 0) {\n return textParts.map(p => p.text).join(\"\");\n }\n }\n }\n return undefined;\n}\n\n/**\n * Check if the messages contain any tool parts.\n * This is a simplified helper that checks for any tool-related parts.\n *\n * @param messages - Array of UI messages\n * @returns True if there are any tool-related parts in the messages\n */\nexport function hasToolParts(messages: UIMessage[]): boolean {\n for (const msg of messages) {\n if (!msg.parts) continue;\n for (const part of msg.parts) {\n // Tool parts have type starting with \"tool-\" or \"dynamic-tool\"\n if (part.type.startsWith(\"tool-\") || part.type === \"dynamic-tool\") {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Count the number of messages by role.\n *\n * @param messages - Array of UI messages\n * @returns Object with counts by role\n */\nexport function countMessagesByRole(\n messages: UIMessage[]\n): { user: number; assistant: number; system: number } {\n let user = 0;\n let assistant = 0;\n let system = 0;\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n user++;\n } else if (msg.role === \"assistant\") {\n assistant++;\n } else if (msg.role === \"system\") {\n system++;\n }\n }\n\n return { user, assistant, system };\n}\n\n/**\n * Extract all text content from a message.\n *\n * @param message - A UI message\n * @returns Combined text from all text parts\n */\nexport function extractTextFromMessage(message: UIMessage): string {\n if (!message.parts) return \"\";\n\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map(p => p.text)\n .join(\"\");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/adapters/elements/createElementsRouteHandler.ts","../../../src/adapters/elements/messageConverters.ts"],"sourcesContent":["/**\n * Server-side route handler adapter for AI SDK Elements\n *\n * Creates a Next.js/Express-compatible route handler that runs DeepAgent\n * and returns UI Message Stream compatible responses with full event visibility.\n *\n * This handler streams all DeepAgent event types (26+) including:\n * - Text and tool events (standard protocol)\n * - File system operations\n * - Command execution\n * - Web requests and searches\n * - Subagent lifecycle\n * - State changes (todos, checkpoints)\n *\n * @example\n * ```typescript\n * // app/api/chat/route.ts (Next.js App Router)\n * import { createDeepAgent } from 'deepagentsdk';\n * import { createElementsRouteHandler } from 'deepagentsdk/adapters/elements';\n * import { anthropic } from '@ai-sdk/anthropic';\n *\n * const agent = createDeepAgent({\n * model: anthropic('claude-sonnet-4-20250514'),\n * });\n *\n * export const POST = createElementsRouteHandler({ agent });\n * ```\n *\n * @see https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol\n */\n\nimport {\n createUIMessageStream,\n createUIMessageStreamResponse,\n convertToModelMessages,\n} from \"ai\";\nimport type { DeepAgent } from \"../../agent\";\nimport type { DeepAgentState, DeepAgentEvent } from \"../../types\";\n\n/**\n * Options for creating an Elements route handler\n */\nexport interface CreateElementsRouteHandlerOptions {\n /**\n * The DeepAgent instance to use for handling requests\n */\n agent: DeepAgent;\n\n /**\n * Optional callback before processing a request.\n * Use for authentication, logging, rate limiting, etc.\n *\n * @example\n * ```typescript\n * onRequest: async (req) => {\n * const token = req.headers.get('Authorization');\n * if (!validateToken(token)) {\n * throw new Error('Unauthorized');\n * }\n * }\n * ```\n */\n onRequest?: (req: Request) => Promise<void> | void;\n\n /**\n * Optional initial state to provide to the agent.\n * If not provided, uses empty state { todos: [], files: {} }\n */\n initialState?: DeepAgentState;\n\n /**\n * Optional thread ID for checkpointing.\n * If provided, enables conversation persistence.\n */\n threadId?: string;\n\n /**\n * Optional maximum number of steps for the agent loop.\n */\n maxSteps?: number;\n\n /**\n * Custom ID generator for message IDs.\n * Defaults to crypto.randomUUID if available.\n */\n generateId?: () => string;\n}\n\n/**\n * Creates a route handler that processes chat requests using DeepAgent\n * and streams all 26+ event types in UI Message Stream Protocol format.\n *\n * The returned handler:\n * - Accepts POST requests with { messages: UIMessage[] } body\n * - Runs DeepAgent with the conversation history\n * - Streams responses in UI Message Stream Protocol format\n * - Works with useChat hook from @ai-sdk/react\n * - Provides full visibility into agent behavior (file ops, web requests, subagents, etc.)\n *\n * @param options - Configuration options\n * @returns A request handler function compatible with Next.js/Express\n */\nexport function createElementsRouteHandler(\n options: CreateElementsRouteHandlerOptions\n): (req: Request) => Promise<Response> {\n const {\n agent,\n onRequest,\n initialState = {\n todos: [],\n files: {}\n },\n threadId,\n maxSteps,\n generateId\n } = options;\n\n return async (req: Request): Promise<Response> => {\n // 1. Handle onRequest hook (auth, logging, rate limiting)\n if (onRequest) {\n try {\n await onRequest(req);\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: error instanceof Error ? error.message : 'Request rejected'\n }),\n {\n status: 401,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n }\n\n // 2. Parse request body\n let requestBody;\n try {\n requestBody = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n const { messages } = requestBody;\n if (!messages || !Array.isArray(messages)) {\n return new Response(\n JSON.stringify({ error: 'messages array is required' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n // 3. Convert UI messages to model messages\n const modelMessages = await convertToModelMessages(messages);\n\n // 4. Setup ID generator\n const genId = generateId || (() => crypto.randomUUID());\n\n // 5. Track current text ID for text-start/text-end\n let currentTextId: string | null = null;\n\n // 6. Create UI message stream response\n return createUIMessageStreamResponse({\n stream: createUIMessageStream({\n originalMessages: messages,\n generateId: genId,\n execute: async ({ writer }) => {\n try {\n // Stream all events from DeepAgent\n for await (const event of agent.streamWithEvents({\n messages: modelMessages,\n state: initialState,\n threadId,\n maxSteps\n })) {\n // Update currentTextId from the returned value\n const result = mapEventToProtocol(event, writer, genId, currentTextId);\n if (typeof result === 'string') {\n currentTextId = result;\n } else if (result === null) {\n currentTextId = null;\n }\n }\n\n // Ensure text is properly closed\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n } catch (error) {\n // Close text if error occurs mid-stream\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n throw error;\n }\n },\n onError: (error) => {\n return error instanceof Error ? error.message : 'Unknown error';\n }\n })\n });\n };\n}\n\n/**\n * Maps a DeepAgent event to a UI Message Stream Protocol event.\n *\n * This function handles all 26+ DeepAgent event types, mapping:\n * - Standard protocol events (text, tools, steps, errors)\n * - Custom data events (file operations, web requests, subagents, execution)\n *\n * @param event - The DeepAgent event to map\n * @param writer - The UI message stream writer\n * @param genId - ID generator function\n * @param currentTextId - The current text part ID (for tracking streaming text)\n * @returns The new currentTextId value (string | null)\n *\n * @example\n * ```typescript\n * // Handles text streaming with proper ID tracking\n * let textId: string | null = null;\n * textId = mapEventToProtocol({ type: 'text', text: 'Hello' }, writer, genId, textId);\n * // textId is now the ID of the active text part\n * ```\n */\nexport function mapEventToProtocol(\n event: DeepAgentEvent,\n writer: { write: (chunk: any) => void },\n genId: () => string,\n currentTextId: string | null\n): string | null {\n switch (event.type) {\n // ============================================================================\n // TEXT & FLOW EVENTS (Required for compatibility)\n // ============================================================================\n\n case 'step-start':\n writer.write({ type: 'start-step' });\n return currentTextId;\n\n case 'step-finish':\n writer.write({ type: 'finish-step' });\n return currentTextId;\n\n case 'text':\n // Start text if not already started\n if (!currentTextId) {\n const textId = genId();\n writer.write({\n type: 'text-start',\n id: textId\n });\n writer.write({\n type: 'text-delta',\n id: textId,\n delta: event.text\n });\n return textId;\n }\n writer.write({\n type: 'text-delta',\n id: currentTextId,\n delta: event.text\n });\n return currentTextId;\n\n // ============================================================================\n // TOOL EVENTS (Standard protocol events)\n // ============================================================================\n\n case 'tool-call':\n // End text before tool call\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'tool-input-available',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args\n });\n return null;\n\n case 'tool-result':\n if (event.isError) {\n writer.write({\n type: 'tool-output-error',\n toolCallId: event.toolCallId,\n errorText: String(event.result)\n });\n } else {\n writer.write({\n type: 'tool-output-available',\n toolCallId: event.toolCallId,\n output: event.result\n });\n }\n return currentTextId;\n\n // ============================================================================\n // TODO & PLANNING EVENTS\n // ============================================================================\n\n case 'todos-changed':\n writer.write({\n type: 'data',\n name: 'todos-changed',\n data: { todos: event.todos }\n });\n return currentTextId;\n\n // ============================================================================\n // FILE SYSTEM EVENTS (Custom data events)\n // ============================================================================\n\n case 'file-write-start':\n writer.write({\n type: 'data',\n name: 'file-write-start',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-written':\n writer.write({\n type: 'data',\n name: 'file-written',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-edited':\n writer.write({\n type: 'data',\n name: 'file-edited',\n data: {\n path: event.path,\n occurrences: event.occurrences\n }\n });\n return currentTextId;\n\n case 'file-read':\n writer.write({\n type: 'data',\n name: 'file-read',\n data: {\n path: event.path,\n lines: event.lines\n }\n });\n return currentTextId;\n\n case 'ls':\n writer.write({\n type: 'data',\n name: 'ls',\n data: {\n path: event.path,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'glob':\n writer.write({\n type: 'data',\n name: 'glob',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'grep':\n writer.write({\n type: 'data',\n name: 'grep',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n // ============================================================================\n // EXECUTION EVENTS (Custom data events)\n // ============================================================================\n\n case 'execute-start':\n writer.write({\n type: 'data',\n name: 'execute-start',\n data: {\n command: event.command,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n case 'execute-finish':\n writer.write({\n type: 'data',\n name: 'execute-finish',\n data: {\n command: event.command,\n exitCode: event.exitCode,\n truncated: event.truncated,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n // ============================================================================\n // WEB EVENTS (Custom data events)\n // ============================================================================\n\n case 'web-search-start':\n writer.write({\n type: 'data',\n name: 'web-search-start',\n data: {\n query: event.query\n }\n });\n return currentTextId;\n\n case 'web-search-finish':\n writer.write({\n type: 'data',\n name: 'web-search-finish',\n data: {\n query: event.query,\n resultCount: event.resultCount\n }\n });\n return currentTextId;\n\n case 'http-request-start':\n writer.write({\n type: 'data',\n name: 'http-request-start',\n data: {\n url: event.url,\n method: event.method\n }\n });\n return currentTextId;\n\n case 'http-request-finish':\n writer.write({\n type: 'data',\n name: 'http-request-finish',\n data: {\n url: event.url,\n statusCode: event.statusCode\n }\n });\n return currentTextId;\n\n case 'fetch-url-start':\n writer.write({\n type: 'data',\n name: 'fetch-url-start',\n data: {\n url: event.url\n }\n });\n return currentTextId;\n\n case 'fetch-url-finish':\n writer.write({\n type: 'data',\n name: 'fetch-url-finish',\n data: {\n url: event.url,\n success: event.success\n }\n });\n return currentTextId;\n\n // ============================================================================\n // SUBAGENT EVENTS (Custom data events)\n // ============================================================================\n\n case 'subagent-start':\n writer.write({\n type: 'data',\n name: 'subagent-start',\n data: {\n name: event.name,\n task: event.task\n }\n });\n return currentTextId;\n\n case 'subagent-finish':\n writer.write({\n type: 'data',\n name: 'subagent-finish',\n data: {\n name: event.name,\n result: event.result\n }\n });\n return currentTextId;\n\n case 'subagent-step':\n writer.write({\n type: 'data',\n name: 'subagent-step',\n data: {\n stepIndex: event.stepIndex,\n toolCalls: event.toolCalls\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CHECKPOINT EVENTS (Custom data events)\n // ============================================================================\n\n case 'checkpoint-saved':\n writer.write({\n type: 'data',\n name: 'checkpoint-saved',\n data: {\n threadId: event.threadId,\n step: event.step\n }\n });\n return currentTextId;\n\n case 'checkpoint-loaded':\n writer.write({\n type: 'data',\n name: 'checkpoint-loaded',\n data: {\n threadId: event.threadId,\n step: event.step,\n messagesCount: event.messagesCount\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CONTROL EVENTS\n // ============================================================================\n\n case 'error':\n // End text before error\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'error',\n errorText: event.error.message\n });\n return null;\n\n case 'done':\n // End text before completion\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n // The finish event is auto-emitted by createUIMessageStream\n // We explicitly emit it here for clarity\n writer.write({\n type: 'finish',\n finishReason: 'stop',\n });\n return null;\n\n // Ignore unhandled events (text-segment, user-message, approval events)\n default:\n return currentTextId;\n }\n}\n\n/**\n * Type for the request handler returned by createElementsRouteHandler\n */\nexport type ElementsRouteHandler = (req: Request) => Promise<Response>;\n","/**\n * Message conversion utilities for AI SDK Elements adapter\n *\n * Provides utilities for converting between UI message formats and model message formats.\n * The primary conversion is handled by AI SDK's `convertToModelMessages`, but these\n * utilities provide additional helpers for DeepAgent-specific needs.\n */\n\nimport {\n convertToModelMessages,\n type UIMessage,\n} from \"ai\";\nimport type { ModelMessage } from \"../../types\";\n\n/**\n * Re-export AI SDK's convertToModelMessages for convenience.\n *\n * This function converts UIMessage[] (from useChat) to ModelMessage[]\n * (for agent consumption), handling:\n * - Role mapping (user/assistant)\n * - Tool call/result parts\n * - Text content extraction\n *\n * @example\n * ```typescript\n * import { convertUIMessagesToModelMessages } from 'deepagentsdk/adapters/elements';\n *\n * const modelMessages = await convertUIMessagesToModelMessages(uiMessages);\n * ```\n */\nexport async function convertUIMessagesToModelMessages(\n messages: UIMessage[]\n): Promise<ModelMessage[]> {\n return await convertToModelMessages(messages) as ModelMessage[];\n}\n\n/**\n * Extract the last user message text from a UIMessage array.\n * Useful for extracting the prompt from a conversation.\n *\n * @param messages - Array of UI messages\n * @returns The text content of the last user message, or undefined if none\n */\nexport function extractLastUserMessage(messages: UIMessage[]): string | undefined {\n // Find the last user message\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg && msg.role === \"user\" && msg.parts) {\n // Extract text parts\n const textParts = msg.parts.filter(\n (p): p is { type: \"text\"; text: string } => p.type === \"text\"\n );\n if (textParts.length > 0) {\n return textParts.map(p => p.text).join(\"\");\n }\n }\n }\n return undefined;\n}\n\n/**\n * Check if the messages contain any tool parts.\n * This is a simplified helper that checks for any tool-related parts.\n *\n * @param messages - Array of UI messages\n * @returns True if there are any tool-related parts in the messages\n */\nexport function hasToolParts(messages: UIMessage[]): boolean {\n for (const msg of messages) {\n if (!msg.parts) continue;\n for (const part of msg.parts) {\n // Tool parts have type starting with \"tool-\" or \"dynamic-tool\"\n if (part.type.startsWith(\"tool-\") || part.type === \"dynamic-tool\") {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Count the number of messages by role.\n *\n * @param messages - Array of UI messages\n * @returns Object with counts by role\n */\nexport function countMessagesByRole(\n messages: UIMessage[]\n): { user: number; assistant: number; system: number } {\n let user = 0;\n let assistant = 0;\n let system = 0;\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n user++;\n } else if (msg.role === \"assistant\") {\n assistant++;\n } else if (msg.role === \"system\") {\n system++;\n }\n }\n\n return { user, assistant, system };\n}\n\n/**\n * Extract all text content from a message.\n *\n * @param message - A UI message\n * @returns Combined text from all text parts\n */\nexport function extractTextFromMessage(message: UIMessage): string {\n if (!message.parts) return \"\";\n\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map(p => p.text)\n .join(\"\");\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as DeepAgentEvent, r as ModelMessage$1, t as DeepAgent, yt as DeepAgentState } from "../../agent-
|
|
1
|
+
import { p as DeepAgentEvent, r as ModelMessage$1, t as DeepAgent, yt as DeepAgentState } from "../../agent-64IK97WT.cjs";
|
|
2
2
|
import { UIMessage, UIMessage as UIMessage$1, UIMessagePart } from "ai";
|
|
3
3
|
|
|
4
4
|
//#region src/adapters/elements/createElementsRouteHandler.d.ts
|
|
@@ -145,6 +145,11 @@ function mapEventToProtocol(event, writer, genId, currentTextId) {
|
|
|
145
145
|
type: "text-start",
|
|
146
146
|
id: textId
|
|
147
147
|
});
|
|
148
|
+
writer.write({
|
|
149
|
+
type: "text-delta",
|
|
150
|
+
id: textId,
|
|
151
|
+
delta: event.text
|
|
152
|
+
});
|
|
148
153
|
return textId;
|
|
149
154
|
}
|
|
150
155
|
writer.write({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/elements/createElementsRouteHandler.ts","../../../src/adapters/elements/messageConverters.ts"],"sourcesContent":["/**\n * Server-side route handler adapter for AI SDK Elements\n *\n * Creates a Next.js/Express-compatible route handler that runs DeepAgent\n * and returns UI Message Stream compatible responses with full event visibility.\n *\n * This handler streams all DeepAgent event types (26+) including:\n * - Text and tool events (standard protocol)\n * - File system operations\n * - Command execution\n * - Web requests and searches\n * - Subagent lifecycle\n * - State changes (todos, checkpoints)\n *\n * @example\n * ```typescript\n * // app/api/chat/route.ts (Next.js App Router)\n * import { createDeepAgent } from 'deepagentsdk';\n * import { createElementsRouteHandler } from 'deepagentsdk/adapters/elements';\n * import { anthropic } from '@ai-sdk/anthropic';\n *\n * const agent = createDeepAgent({\n * model: anthropic('claude-sonnet-4-20250514'),\n * });\n *\n * export const POST = createElementsRouteHandler({ agent });\n * ```\n *\n * @see https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol\n */\n\nimport {\n createUIMessageStream,\n createUIMessageStreamResponse,\n convertToModelMessages,\n} from \"ai\";\nimport type { DeepAgent } from \"../../agent\";\nimport type { DeepAgentState, DeepAgentEvent } from \"../../types\";\n\n/**\n * Options for creating an Elements route handler\n */\nexport interface CreateElementsRouteHandlerOptions {\n /**\n * The DeepAgent instance to use for handling requests\n */\n agent: DeepAgent;\n\n /**\n * Optional callback before processing a request.\n * Use for authentication, logging, rate limiting, etc.\n *\n * @example\n * ```typescript\n * onRequest: async (req) => {\n * const token = req.headers.get('Authorization');\n * if (!validateToken(token)) {\n * throw new Error('Unauthorized');\n * }\n * }\n * ```\n */\n onRequest?: (req: Request) => Promise<void> | void;\n\n /**\n * Optional initial state to provide to the agent.\n * If not provided, uses empty state { todos: [], files: {} }\n */\n initialState?: DeepAgentState;\n\n /**\n * Optional thread ID for checkpointing.\n * If provided, enables conversation persistence.\n */\n threadId?: string;\n\n /**\n * Optional maximum number of steps for the agent loop.\n */\n maxSteps?: number;\n\n /**\n * Custom ID generator for message IDs.\n * Defaults to crypto.randomUUID if available.\n */\n generateId?: () => string;\n}\n\n/**\n * Creates a route handler that processes chat requests using DeepAgent\n * and streams all 26+ event types in UI Message Stream Protocol format.\n *\n * The returned handler:\n * - Accepts POST requests with { messages: UIMessage[] } body\n * - Runs DeepAgent with the conversation history\n * - Streams responses in UI Message Stream Protocol format\n * - Works with useChat hook from @ai-sdk/react\n * - Provides full visibility into agent behavior (file ops, web requests, subagents, etc.)\n *\n * @param options - Configuration options\n * @returns A request handler function compatible with Next.js/Express\n */\nexport function createElementsRouteHandler(\n options: CreateElementsRouteHandlerOptions\n): (req: Request) => Promise<Response> {\n const {\n agent,\n onRequest,\n initialState = {\n todos: [],\n files: {}\n },\n threadId,\n maxSteps,\n generateId\n } = options;\n\n return async (req: Request): Promise<Response> => {\n // 1. Handle onRequest hook (auth, logging, rate limiting)\n if (onRequest) {\n try {\n await onRequest(req);\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: error instanceof Error ? error.message : 'Request rejected'\n }),\n {\n status: 401,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n }\n\n // 2. Parse request body\n let requestBody;\n try {\n requestBody = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n const { messages } = requestBody;\n if (!messages || !Array.isArray(messages)) {\n return new Response(\n JSON.stringify({ error: 'messages array is required' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n // 3. Convert UI messages to model messages\n const modelMessages = await convertToModelMessages(messages);\n\n // 4. Setup ID generator\n const genId = generateId || (() => crypto.randomUUID());\n\n // 5. Track current text ID for text-start/text-end\n let currentTextId: string | null = null;\n\n // 6. Create UI message stream response\n return createUIMessageStreamResponse({\n stream: createUIMessageStream({\n originalMessages: messages,\n generateId: genId,\n execute: async ({ writer }) => {\n try {\n // Stream all events from DeepAgent\n for await (const event of agent.streamWithEvents({\n messages: modelMessages,\n state: initialState,\n threadId,\n maxSteps\n })) {\n // Update currentTextId from the returned value\n const result = mapEventToProtocol(event, writer, genId, currentTextId);\n if (typeof result === 'string') {\n currentTextId = result;\n } else if (result === null) {\n currentTextId = null;\n }\n }\n\n // Ensure text is properly closed\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n } catch (error) {\n // Close text if error occurs mid-stream\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n throw error;\n }\n },\n onError: (error) => {\n return error instanceof Error ? error.message : 'Unknown error';\n }\n })\n });\n };\n}\n\n/**\n * Maps a DeepAgent event to a UI Message Stream Protocol event.\n *\n * This function handles all 26+ DeepAgent event types, mapping:\n * - Standard protocol events (text, tools, steps, errors)\n * - Custom data events (file operations, web requests, subagents, execution)\n *\n * @param event - The DeepAgent event to map\n * @param writer - The UI message stream writer\n * @param genId - ID generator function\n * @param currentTextId - The current text part ID (for tracking streaming text)\n * @returns The new currentTextId value (string | null)\n *\n * @example\n * ```typescript\n * // Handles text streaming with proper ID tracking\n * let textId: string | null = null;\n * textId = mapEventToProtocol({ type: 'text', text: 'Hello' }, writer, genId, textId);\n * // textId is now the ID of the active text part\n * ```\n */\nexport function mapEventToProtocol(\n event: DeepAgentEvent,\n writer: { write: (chunk: any) => void },\n genId: () => string,\n currentTextId: string | null\n): string | null {\n switch (event.type) {\n // ============================================================================\n // TEXT & FLOW EVENTS (Required for compatibility)\n // ============================================================================\n\n case 'step-start':\n writer.write({ type: 'start-step' });\n return currentTextId;\n\n case 'step-finish':\n writer.write({ type: 'finish-step' });\n return currentTextId;\n\n case 'text':\n // Start text if not already started\n if (!currentTextId) {\n const textId = genId();\n writer.write({\n type: 'text-start',\n id: textId\n });\n return textId;\n }\n writer.write({\n type: 'text-delta',\n id: currentTextId,\n delta: event.text\n });\n return currentTextId;\n\n // ============================================================================\n // TOOL EVENTS (Standard protocol events)\n // ============================================================================\n\n case 'tool-call':\n // End text before tool call\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'tool-input-available',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args\n });\n return null;\n\n case 'tool-result':\n if (event.isError) {\n writer.write({\n type: 'tool-output-error',\n toolCallId: event.toolCallId,\n errorText: String(event.result)\n });\n } else {\n writer.write({\n type: 'tool-output-available',\n toolCallId: event.toolCallId,\n output: event.result\n });\n }\n return currentTextId;\n\n // ============================================================================\n // TODO & PLANNING EVENTS\n // ============================================================================\n\n case 'todos-changed':\n writer.write({\n type: 'data',\n name: 'todos-changed',\n data: { todos: event.todos }\n });\n return currentTextId;\n\n // ============================================================================\n // FILE SYSTEM EVENTS (Custom data events)\n // ============================================================================\n\n case 'file-write-start':\n writer.write({\n type: 'data',\n name: 'file-write-start',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-written':\n writer.write({\n type: 'data',\n name: 'file-written',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-edited':\n writer.write({\n type: 'data',\n name: 'file-edited',\n data: {\n path: event.path,\n occurrences: event.occurrences\n }\n });\n return currentTextId;\n\n case 'file-read':\n writer.write({\n type: 'data',\n name: 'file-read',\n data: {\n path: event.path,\n lines: event.lines\n }\n });\n return currentTextId;\n\n case 'ls':\n writer.write({\n type: 'data',\n name: 'ls',\n data: {\n path: event.path,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'glob':\n writer.write({\n type: 'data',\n name: 'glob',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'grep':\n writer.write({\n type: 'data',\n name: 'grep',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n // ============================================================================\n // EXECUTION EVENTS (Custom data events)\n // ============================================================================\n\n case 'execute-start':\n writer.write({\n type: 'data',\n name: 'execute-start',\n data: {\n command: event.command,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n case 'execute-finish':\n writer.write({\n type: 'data',\n name: 'execute-finish',\n data: {\n command: event.command,\n exitCode: event.exitCode,\n truncated: event.truncated,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n // ============================================================================\n // WEB EVENTS (Custom data events)\n // ============================================================================\n\n case 'web-search-start':\n writer.write({\n type: 'data',\n name: 'web-search-start',\n data: {\n query: event.query\n }\n });\n return currentTextId;\n\n case 'web-search-finish':\n writer.write({\n type: 'data',\n name: 'web-search-finish',\n data: {\n query: event.query,\n resultCount: event.resultCount\n }\n });\n return currentTextId;\n\n case 'http-request-start':\n writer.write({\n type: 'data',\n name: 'http-request-start',\n data: {\n url: event.url,\n method: event.method\n }\n });\n return currentTextId;\n\n case 'http-request-finish':\n writer.write({\n type: 'data',\n name: 'http-request-finish',\n data: {\n url: event.url,\n statusCode: event.statusCode\n }\n });\n return currentTextId;\n\n case 'fetch-url-start':\n writer.write({\n type: 'data',\n name: 'fetch-url-start',\n data: {\n url: event.url\n }\n });\n return currentTextId;\n\n case 'fetch-url-finish':\n writer.write({\n type: 'data',\n name: 'fetch-url-finish',\n data: {\n url: event.url,\n success: event.success\n }\n });\n return currentTextId;\n\n // ============================================================================\n // SUBAGENT EVENTS (Custom data events)\n // ============================================================================\n\n case 'subagent-start':\n writer.write({\n type: 'data',\n name: 'subagent-start',\n data: {\n name: event.name,\n task: event.task\n }\n });\n return currentTextId;\n\n case 'subagent-finish':\n writer.write({\n type: 'data',\n name: 'subagent-finish',\n data: {\n name: event.name,\n result: event.result\n }\n });\n return currentTextId;\n\n case 'subagent-step':\n writer.write({\n type: 'data',\n name: 'subagent-step',\n data: {\n stepIndex: event.stepIndex,\n toolCalls: event.toolCalls\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CHECKPOINT EVENTS (Custom data events)\n // ============================================================================\n\n case 'checkpoint-saved':\n writer.write({\n type: 'data',\n name: 'checkpoint-saved',\n data: {\n threadId: event.threadId,\n step: event.step\n }\n });\n return currentTextId;\n\n case 'checkpoint-loaded':\n writer.write({\n type: 'data',\n name: 'checkpoint-loaded',\n data: {\n threadId: event.threadId,\n step: event.step,\n messagesCount: event.messagesCount\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CONTROL EVENTS\n // ============================================================================\n\n case 'error':\n // End text before error\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'error',\n errorText: event.error.message\n });\n return null;\n\n case 'done':\n // End text before completion\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n // The finish event is auto-emitted by createUIMessageStream\n // We explicitly emit it here for clarity\n writer.write({\n type: 'finish',\n finishReason: 'stop',\n });\n return null;\n\n // Ignore unhandled events (text-segment, user-message, approval events)\n default:\n return currentTextId;\n }\n}\n\n/**\n * Type for the request handler returned by createElementsRouteHandler\n */\nexport type ElementsRouteHandler = (req: Request) => Promise<Response>;\n","/**\n * Message conversion utilities for AI SDK Elements adapter\n *\n * Provides utilities for converting between UI message formats and model message formats.\n * The primary conversion is handled by AI SDK's `convertToModelMessages`, but these\n * utilities provide additional helpers for DeepAgent-specific needs.\n */\n\nimport {\n convertToModelMessages,\n type UIMessage,\n} from \"ai\";\nimport type { ModelMessage } from \"../../types\";\n\n/**\n * Re-export AI SDK's convertToModelMessages for convenience.\n *\n * This function converts UIMessage[] (from useChat) to ModelMessage[]\n * (for agent consumption), handling:\n * - Role mapping (user/assistant)\n * - Tool call/result parts\n * - Text content extraction\n *\n * @example\n * ```typescript\n * import { convertUIMessagesToModelMessages } from 'deepagentsdk/adapters/elements';\n *\n * const modelMessages = await convertUIMessagesToModelMessages(uiMessages);\n * ```\n */\nexport async function convertUIMessagesToModelMessages(\n messages: UIMessage[]\n): Promise<ModelMessage[]> {\n return await convertToModelMessages(messages) as ModelMessage[];\n}\n\n/**\n * Extract the last user message text from a UIMessage array.\n * Useful for extracting the prompt from a conversation.\n *\n * @param messages - Array of UI messages\n * @returns The text content of the last user message, or undefined if none\n */\nexport function extractLastUserMessage(messages: UIMessage[]): string | undefined {\n // Find the last user message\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg && msg.role === \"user\" && msg.parts) {\n // Extract text parts\n const textParts = msg.parts.filter(\n (p): p is { type: \"text\"; text: string } => p.type === \"text\"\n );\n if (textParts.length > 0) {\n return textParts.map(p => p.text).join(\"\");\n }\n }\n }\n return undefined;\n}\n\n/**\n * Check if the messages contain any tool parts.\n * This is a simplified helper that checks for any tool-related parts.\n *\n * @param messages - Array of UI messages\n * @returns True if there are any tool-related parts in the messages\n */\nexport function hasToolParts(messages: UIMessage[]): boolean {\n for (const msg of messages) {\n if (!msg.parts) continue;\n for (const part of msg.parts) {\n // Tool parts have type starting with \"tool-\" or \"dynamic-tool\"\n if (part.type.startsWith(\"tool-\") || part.type === \"dynamic-tool\") {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Count the number of messages by role.\n *\n * @param messages - Array of UI messages\n * @returns Object with counts by role\n */\nexport function countMessagesByRole(\n messages: UIMessage[]\n): { user: number; assistant: number; system: number } {\n let user = 0;\n let assistant = 0;\n let system = 0;\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n user++;\n } else if (msg.role === \"assistant\") {\n assistant++;\n } else if (msg.role === \"system\") {\n system++;\n }\n }\n\n return { user, assistant, system };\n}\n\n/**\n * Extract all text content from a message.\n *\n * @param message - A UI message\n * @returns Combined text from all text parts\n */\nexport function extractTextFromMessage(message: UIMessage): string {\n if (!message.parts) return \"\";\n\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map(p => p.text)\n .join(\"\");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/adapters/elements/createElementsRouteHandler.ts","../../../src/adapters/elements/messageConverters.ts"],"sourcesContent":["/**\n * Server-side route handler adapter for AI SDK Elements\n *\n * Creates a Next.js/Express-compatible route handler that runs DeepAgent\n * and returns UI Message Stream compatible responses with full event visibility.\n *\n * This handler streams all DeepAgent event types (26+) including:\n * - Text and tool events (standard protocol)\n * - File system operations\n * - Command execution\n * - Web requests and searches\n * - Subagent lifecycle\n * - State changes (todos, checkpoints)\n *\n * @example\n * ```typescript\n * // app/api/chat/route.ts (Next.js App Router)\n * import { createDeepAgent } from 'deepagentsdk';\n * import { createElementsRouteHandler } from 'deepagentsdk/adapters/elements';\n * import { anthropic } from '@ai-sdk/anthropic';\n *\n * const agent = createDeepAgent({\n * model: anthropic('claude-sonnet-4-20250514'),\n * });\n *\n * export const POST = createElementsRouteHandler({ agent });\n * ```\n *\n * @see https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol\n */\n\nimport {\n createUIMessageStream,\n createUIMessageStreamResponse,\n convertToModelMessages,\n} from \"ai\";\nimport type { DeepAgent } from \"../../agent\";\nimport type { DeepAgentState, DeepAgentEvent } from \"../../types\";\n\n/**\n * Options for creating an Elements route handler\n */\nexport interface CreateElementsRouteHandlerOptions {\n /**\n * The DeepAgent instance to use for handling requests\n */\n agent: DeepAgent;\n\n /**\n * Optional callback before processing a request.\n * Use for authentication, logging, rate limiting, etc.\n *\n * @example\n * ```typescript\n * onRequest: async (req) => {\n * const token = req.headers.get('Authorization');\n * if (!validateToken(token)) {\n * throw new Error('Unauthorized');\n * }\n * }\n * ```\n */\n onRequest?: (req: Request) => Promise<void> | void;\n\n /**\n * Optional initial state to provide to the agent.\n * If not provided, uses empty state { todos: [], files: {} }\n */\n initialState?: DeepAgentState;\n\n /**\n * Optional thread ID for checkpointing.\n * If provided, enables conversation persistence.\n */\n threadId?: string;\n\n /**\n * Optional maximum number of steps for the agent loop.\n */\n maxSteps?: number;\n\n /**\n * Custom ID generator for message IDs.\n * Defaults to crypto.randomUUID if available.\n */\n generateId?: () => string;\n}\n\n/**\n * Creates a route handler that processes chat requests using DeepAgent\n * and streams all 26+ event types in UI Message Stream Protocol format.\n *\n * The returned handler:\n * - Accepts POST requests with { messages: UIMessage[] } body\n * - Runs DeepAgent with the conversation history\n * - Streams responses in UI Message Stream Protocol format\n * - Works with useChat hook from @ai-sdk/react\n * - Provides full visibility into agent behavior (file ops, web requests, subagents, etc.)\n *\n * @param options - Configuration options\n * @returns A request handler function compatible with Next.js/Express\n */\nexport function createElementsRouteHandler(\n options: CreateElementsRouteHandlerOptions\n): (req: Request) => Promise<Response> {\n const {\n agent,\n onRequest,\n initialState = {\n todos: [],\n files: {}\n },\n threadId,\n maxSteps,\n generateId\n } = options;\n\n return async (req: Request): Promise<Response> => {\n // 1. Handle onRequest hook (auth, logging, rate limiting)\n if (onRequest) {\n try {\n await onRequest(req);\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: error instanceof Error ? error.message : 'Request rejected'\n }),\n {\n status: 401,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n }\n\n // 2. Parse request body\n let requestBody;\n try {\n requestBody = await req.json();\n } catch {\n return new Response(\n JSON.stringify({ error: 'Invalid JSON body' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n const { messages } = requestBody;\n if (!messages || !Array.isArray(messages)) {\n return new Response(\n JSON.stringify({ error: 'messages array is required' }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n // 3. Convert UI messages to model messages\n const modelMessages = await convertToModelMessages(messages);\n\n // 4. Setup ID generator\n const genId = generateId || (() => crypto.randomUUID());\n\n // 5. Track current text ID for text-start/text-end\n let currentTextId: string | null = null;\n\n // 6. Create UI message stream response\n return createUIMessageStreamResponse({\n stream: createUIMessageStream({\n originalMessages: messages,\n generateId: genId,\n execute: async ({ writer }) => {\n try {\n // Stream all events from DeepAgent\n for await (const event of agent.streamWithEvents({\n messages: modelMessages,\n state: initialState,\n threadId,\n maxSteps\n })) {\n // Update currentTextId from the returned value\n const result = mapEventToProtocol(event, writer, genId, currentTextId);\n if (typeof result === 'string') {\n currentTextId = result;\n } else if (result === null) {\n currentTextId = null;\n }\n }\n\n // Ensure text is properly closed\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n } catch (error) {\n // Close text if error occurs mid-stream\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n }\n throw error;\n }\n },\n onError: (error) => {\n return error instanceof Error ? error.message : 'Unknown error';\n }\n })\n });\n };\n}\n\n/**\n * Maps a DeepAgent event to a UI Message Stream Protocol event.\n *\n * This function handles all 26+ DeepAgent event types, mapping:\n * - Standard protocol events (text, tools, steps, errors)\n * - Custom data events (file operations, web requests, subagents, execution)\n *\n * @param event - The DeepAgent event to map\n * @param writer - The UI message stream writer\n * @param genId - ID generator function\n * @param currentTextId - The current text part ID (for tracking streaming text)\n * @returns The new currentTextId value (string | null)\n *\n * @example\n * ```typescript\n * // Handles text streaming with proper ID tracking\n * let textId: string | null = null;\n * textId = mapEventToProtocol({ type: 'text', text: 'Hello' }, writer, genId, textId);\n * // textId is now the ID of the active text part\n * ```\n */\nexport function mapEventToProtocol(\n event: DeepAgentEvent,\n writer: { write: (chunk: any) => void },\n genId: () => string,\n currentTextId: string | null\n): string | null {\n switch (event.type) {\n // ============================================================================\n // TEXT & FLOW EVENTS (Required for compatibility)\n // ============================================================================\n\n case 'step-start':\n writer.write({ type: 'start-step' });\n return currentTextId;\n\n case 'step-finish':\n writer.write({ type: 'finish-step' });\n return currentTextId;\n\n case 'text':\n // Start text if not already started\n if (!currentTextId) {\n const textId = genId();\n writer.write({\n type: 'text-start',\n id: textId\n });\n writer.write({\n type: 'text-delta',\n id: textId,\n delta: event.text\n });\n return textId;\n }\n writer.write({\n type: 'text-delta',\n id: currentTextId,\n delta: event.text\n });\n return currentTextId;\n\n // ============================================================================\n // TOOL EVENTS (Standard protocol events)\n // ============================================================================\n\n case 'tool-call':\n // End text before tool call\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'tool-input-available',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args\n });\n return null;\n\n case 'tool-result':\n if (event.isError) {\n writer.write({\n type: 'tool-output-error',\n toolCallId: event.toolCallId,\n errorText: String(event.result)\n });\n } else {\n writer.write({\n type: 'tool-output-available',\n toolCallId: event.toolCallId,\n output: event.result\n });\n }\n return currentTextId;\n\n // ============================================================================\n // TODO & PLANNING EVENTS\n // ============================================================================\n\n case 'todos-changed':\n writer.write({\n type: 'data',\n name: 'todos-changed',\n data: { todos: event.todos }\n });\n return currentTextId;\n\n // ============================================================================\n // FILE SYSTEM EVENTS (Custom data events)\n // ============================================================================\n\n case 'file-write-start':\n writer.write({\n type: 'data',\n name: 'file-write-start',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-written':\n writer.write({\n type: 'data',\n name: 'file-written',\n data: {\n path: event.path,\n content: event.content\n }\n });\n return currentTextId;\n\n case 'file-edited':\n writer.write({\n type: 'data',\n name: 'file-edited',\n data: {\n path: event.path,\n occurrences: event.occurrences\n }\n });\n return currentTextId;\n\n case 'file-read':\n writer.write({\n type: 'data',\n name: 'file-read',\n data: {\n path: event.path,\n lines: event.lines\n }\n });\n return currentTextId;\n\n case 'ls':\n writer.write({\n type: 'data',\n name: 'ls',\n data: {\n path: event.path,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'glob':\n writer.write({\n type: 'data',\n name: 'glob',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n case 'grep':\n writer.write({\n type: 'data',\n name: 'grep',\n data: {\n pattern: event.pattern,\n count: event.count\n }\n });\n return currentTextId;\n\n // ============================================================================\n // EXECUTION EVENTS (Custom data events)\n // ============================================================================\n\n case 'execute-start':\n writer.write({\n type: 'data',\n name: 'execute-start',\n data: {\n command: event.command,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n case 'execute-finish':\n writer.write({\n type: 'data',\n name: 'execute-finish',\n data: {\n command: event.command,\n exitCode: event.exitCode,\n truncated: event.truncated,\n sandboxId: event.sandboxId\n }\n });\n return currentTextId;\n\n // ============================================================================\n // WEB EVENTS (Custom data events)\n // ============================================================================\n\n case 'web-search-start':\n writer.write({\n type: 'data',\n name: 'web-search-start',\n data: {\n query: event.query\n }\n });\n return currentTextId;\n\n case 'web-search-finish':\n writer.write({\n type: 'data',\n name: 'web-search-finish',\n data: {\n query: event.query,\n resultCount: event.resultCount\n }\n });\n return currentTextId;\n\n case 'http-request-start':\n writer.write({\n type: 'data',\n name: 'http-request-start',\n data: {\n url: event.url,\n method: event.method\n }\n });\n return currentTextId;\n\n case 'http-request-finish':\n writer.write({\n type: 'data',\n name: 'http-request-finish',\n data: {\n url: event.url,\n statusCode: event.statusCode\n }\n });\n return currentTextId;\n\n case 'fetch-url-start':\n writer.write({\n type: 'data',\n name: 'fetch-url-start',\n data: {\n url: event.url\n }\n });\n return currentTextId;\n\n case 'fetch-url-finish':\n writer.write({\n type: 'data',\n name: 'fetch-url-finish',\n data: {\n url: event.url,\n success: event.success\n }\n });\n return currentTextId;\n\n // ============================================================================\n // SUBAGENT EVENTS (Custom data events)\n // ============================================================================\n\n case 'subagent-start':\n writer.write({\n type: 'data',\n name: 'subagent-start',\n data: {\n name: event.name,\n task: event.task\n }\n });\n return currentTextId;\n\n case 'subagent-finish':\n writer.write({\n type: 'data',\n name: 'subagent-finish',\n data: {\n name: event.name,\n result: event.result\n }\n });\n return currentTextId;\n\n case 'subagent-step':\n writer.write({\n type: 'data',\n name: 'subagent-step',\n data: {\n stepIndex: event.stepIndex,\n toolCalls: event.toolCalls\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CHECKPOINT EVENTS (Custom data events)\n // ============================================================================\n\n case 'checkpoint-saved':\n writer.write({\n type: 'data',\n name: 'checkpoint-saved',\n data: {\n threadId: event.threadId,\n step: event.step\n }\n });\n return currentTextId;\n\n case 'checkpoint-loaded':\n writer.write({\n type: 'data',\n name: 'checkpoint-loaded',\n data: {\n threadId: event.threadId,\n step: event.step,\n messagesCount: event.messagesCount\n }\n });\n return currentTextId;\n\n // ============================================================================\n // CONTROL EVENTS\n // ============================================================================\n\n case 'error':\n // End text before error\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n writer.write({\n type: 'error',\n errorText: event.error.message\n });\n return null;\n\n case 'done':\n // End text before completion\n if (currentTextId) {\n writer.write({\n type: 'text-end',\n id: currentTextId\n });\n currentTextId = null;\n }\n // The finish event is auto-emitted by createUIMessageStream\n // We explicitly emit it here for clarity\n writer.write({\n type: 'finish',\n finishReason: 'stop',\n });\n return null;\n\n // Ignore unhandled events (text-segment, user-message, approval events)\n default:\n return currentTextId;\n }\n}\n\n/**\n * Type for the request handler returned by createElementsRouteHandler\n */\nexport type ElementsRouteHandler = (req: Request) => Promise<Response>;\n","/**\n * Message conversion utilities for AI SDK Elements adapter\n *\n * Provides utilities for converting between UI message formats and model message formats.\n * The primary conversion is handled by AI SDK's `convertToModelMessages`, but these\n * utilities provide additional helpers for DeepAgent-specific needs.\n */\n\nimport {\n convertToModelMessages,\n type UIMessage,\n} from \"ai\";\nimport type { ModelMessage } from \"../../types\";\n\n/**\n * Re-export AI SDK's convertToModelMessages for convenience.\n *\n * This function converts UIMessage[] (from useChat) to ModelMessage[]\n * (for agent consumption), handling:\n * - Role mapping (user/assistant)\n * - Tool call/result parts\n * - Text content extraction\n *\n * @example\n * ```typescript\n * import { convertUIMessagesToModelMessages } from 'deepagentsdk/adapters/elements';\n *\n * const modelMessages = await convertUIMessagesToModelMessages(uiMessages);\n * ```\n */\nexport async function convertUIMessagesToModelMessages(\n messages: UIMessage[]\n): Promise<ModelMessage[]> {\n return await convertToModelMessages(messages) as ModelMessage[];\n}\n\n/**\n * Extract the last user message text from a UIMessage array.\n * Useful for extracting the prompt from a conversation.\n *\n * @param messages - Array of UI messages\n * @returns The text content of the last user message, or undefined if none\n */\nexport function extractLastUserMessage(messages: UIMessage[]): string | undefined {\n // Find the last user message\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg && msg.role === \"user\" && msg.parts) {\n // Extract text parts\n const textParts = msg.parts.filter(\n (p): p is { type: \"text\"; text: string } => p.type === \"text\"\n );\n if (textParts.length > 0) {\n return textParts.map(p => p.text).join(\"\");\n }\n }\n }\n return undefined;\n}\n\n/**\n * Check if the messages contain any tool parts.\n * This is a simplified helper that checks for any tool-related parts.\n *\n * @param messages - Array of UI messages\n * @returns True if there are any tool-related parts in the messages\n */\nexport function hasToolParts(messages: UIMessage[]): boolean {\n for (const msg of messages) {\n if (!msg.parts) continue;\n for (const part of msg.parts) {\n // Tool parts have type starting with \"tool-\" or \"dynamic-tool\"\n if (part.type.startsWith(\"tool-\") || part.type === \"dynamic-tool\") {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Count the number of messages by role.\n *\n * @param messages - Array of UI messages\n * @returns Object with counts by role\n */\nexport function countMessagesByRole(\n messages: UIMessage[]\n): { user: number; assistant: number; system: number } {\n let user = 0;\n let assistant = 0;\n let system = 0;\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n user++;\n } else if (msg.role === \"assistant\") {\n assistant++;\n } else if (msg.role === \"system\") {\n system++;\n }\n }\n\n return { user, assistant, system };\n}\n\n/**\n * Extract all text content from a message.\n *\n * @param message - A UI message\n * @returns Combined text from all text parts\n */\nexport function extractTextFromMessage(message: UIMessage): string {\n if (!message.parts) return \"\";\n\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map(p => p.text)\n .join(\"\");\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as ai2 from "ai";
|
|
2
2
|
import { LanguageModel, LanguageModel as LanguageModel$2, LanguageModelMiddleware, ModelMessage, ModelMessage as ModelMessage$1, StopCondition, ToolLoopAgent, ToolLoopAgentSettings, ToolSet } from "ai";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
@@ -366,7 +366,7 @@ declare function createWebSearchTool(state: DeepAgentState, options: {
|
|
|
366
366
|
onEvent?: EventCallback;
|
|
367
367
|
toolResultEvictionLimit?: number;
|
|
368
368
|
tavilyApiKey: string;
|
|
369
|
-
}):
|
|
369
|
+
}): ai2.Tool<{
|
|
370
370
|
query: string;
|
|
371
371
|
max_results: number;
|
|
372
372
|
topic: "general" | "news" | "finance";
|
|
@@ -380,7 +380,7 @@ declare function createHttpRequestTool(state: DeepAgentState, options: {
|
|
|
380
380
|
onEvent?: EventCallback;
|
|
381
381
|
toolResultEvictionLimit?: number;
|
|
382
382
|
defaultTimeout: number;
|
|
383
|
-
}):
|
|
383
|
+
}): ai2.Tool<{
|
|
384
384
|
timeout: number;
|
|
385
385
|
url: string;
|
|
386
386
|
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
@@ -396,7 +396,7 @@ declare function createFetchUrlTool(state: DeepAgentState, options: {
|
|
|
396
396
|
onEvent?: EventCallback;
|
|
397
397
|
toolResultEvictionLimit?: number;
|
|
398
398
|
defaultTimeout: number;
|
|
399
|
-
}):
|
|
399
|
+
}): ai2.Tool<{
|
|
400
400
|
timeout: number;
|
|
401
401
|
url: string;
|
|
402
402
|
extract_article: boolean;
|
|
@@ -433,13 +433,13 @@ declare const fetch_url: typeof createFetchUrlTool;
|
|
|
433
433
|
/**
|
|
434
434
|
* Create the ls tool.
|
|
435
435
|
*/
|
|
436
|
-
declare function createLsTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback):
|
|
436
|
+
declare function createLsTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback): ai2.Tool<{
|
|
437
437
|
path: string;
|
|
438
438
|
}, string>;
|
|
439
439
|
/**
|
|
440
440
|
* Create the read_file tool.
|
|
441
441
|
*/
|
|
442
|
-
declare function createReadFileTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, evictionLimit?: number, onEvent?: EventCallback):
|
|
442
|
+
declare function createReadFileTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, evictionLimit?: number, onEvent?: EventCallback): ai2.Tool<{
|
|
443
443
|
file_path: string;
|
|
444
444
|
offset: number;
|
|
445
445
|
limit: number;
|
|
@@ -447,14 +447,14 @@ declare function createReadFileTool(state: DeepAgentState, backend: BackendProto
|
|
|
447
447
|
/**
|
|
448
448
|
* Create the write_file tool.
|
|
449
449
|
*/
|
|
450
|
-
declare function createWriteFileTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback):
|
|
450
|
+
declare function createWriteFileTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback): ai2.Tool<{
|
|
451
451
|
content: string;
|
|
452
452
|
file_path: string;
|
|
453
453
|
}, string>;
|
|
454
454
|
/**
|
|
455
455
|
* Create the edit_file tool.
|
|
456
456
|
*/
|
|
457
|
-
declare function createEditFileTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback):
|
|
457
|
+
declare function createEditFileTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback): ai2.Tool<{
|
|
458
458
|
file_path: string;
|
|
459
459
|
old_string: string;
|
|
460
460
|
new_string: string;
|
|
@@ -463,14 +463,14 @@ declare function createEditFileTool(state: DeepAgentState, backend: BackendProto
|
|
|
463
463
|
/**
|
|
464
464
|
* Create the glob tool.
|
|
465
465
|
*/
|
|
466
|
-
declare function createGlobTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback):
|
|
466
|
+
declare function createGlobTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, onEvent?: EventCallback): ai2.Tool<{
|
|
467
467
|
path: string;
|
|
468
468
|
pattern: string;
|
|
469
469
|
}, string>;
|
|
470
470
|
/**
|
|
471
471
|
* Create the grep tool.
|
|
472
472
|
*/
|
|
473
|
-
declare function createGrepTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, evictionLimit?: number, onEvent?: EventCallback):
|
|
473
|
+
declare function createGrepTool(state: DeepAgentState, backend: BackendProtocol | BackendFactory, evictionLimit?: number, onEvent?: EventCallback): ai2.Tool<{
|
|
474
474
|
path: string;
|
|
475
475
|
pattern: string;
|
|
476
476
|
glob?: string | null | undefined;
|
|
@@ -493,29 +493,29 @@ interface CreateFilesystemToolsOptions {
|
|
|
493
493
|
* @param onEvent - Optional callback for emitting events (deprecated, use options)
|
|
494
494
|
*/
|
|
495
495
|
declare function createFilesystemTools(state: DeepAgentState, backendOrOptions?: BackendProtocol | BackendFactory | CreateFilesystemToolsOptions, onEvent?: EventCallback): {
|
|
496
|
-
ls:
|
|
496
|
+
ls: ai2.Tool<{
|
|
497
497
|
path: string;
|
|
498
498
|
}, string>;
|
|
499
|
-
read_file:
|
|
499
|
+
read_file: ai2.Tool<{
|
|
500
500
|
file_path: string;
|
|
501
501
|
offset: number;
|
|
502
502
|
limit: number;
|
|
503
503
|
}, string>;
|
|
504
|
-
write_file:
|
|
504
|
+
write_file: ai2.Tool<{
|
|
505
505
|
content: string;
|
|
506
506
|
file_path: string;
|
|
507
507
|
}, string>;
|
|
508
|
-
edit_file:
|
|
508
|
+
edit_file: ai2.Tool<{
|
|
509
509
|
file_path: string;
|
|
510
510
|
old_string: string;
|
|
511
511
|
new_string: string;
|
|
512
512
|
replace_all: boolean;
|
|
513
513
|
}, string>;
|
|
514
|
-
glob:
|
|
514
|
+
glob: ai2.Tool<{
|
|
515
515
|
path: string;
|
|
516
516
|
pattern: string;
|
|
517
517
|
}, string>;
|
|
518
|
-
grep:
|
|
518
|
+
grep: ai2.Tool<{
|
|
519
519
|
path: string;
|
|
520
520
|
pattern: string;
|
|
521
521
|
glob?: string | null | undefined;
|
|
@@ -538,7 +538,7 @@ declare const grep: typeof createGrepTool;
|
|
|
538
538
|
* @param state - The shared agent state
|
|
539
539
|
* @param onEvent - Optional callback for emitting events
|
|
540
540
|
*/
|
|
541
|
-
declare function createTodosTool(state: DeepAgentState, onEvent?: EventCallback):
|
|
541
|
+
declare function createTodosTool(state: DeepAgentState, onEvent?: EventCallback): ai2.Tool<{
|
|
542
542
|
todos: {
|
|
543
543
|
status: "pending" | "in_progress" | "completed" | "cancelled";
|
|
544
544
|
id: string;
|
|
@@ -599,7 +599,7 @@ interface CreateExecuteToolOptions {
|
|
|
599
599
|
* });
|
|
600
600
|
* ```
|
|
601
601
|
*/
|
|
602
|
-
declare function createExecuteTool(options: CreateExecuteToolOptions):
|
|
602
|
+
declare function createExecuteTool(options: CreateExecuteToolOptions): ai2.Tool<{
|
|
603
603
|
command: string;
|
|
604
604
|
}, string>;
|
|
605
605
|
/**
|
|
@@ -617,7 +617,7 @@ declare function createExecuteTool(options: CreateExecuteToolOptions): ai15.Tool
|
|
|
617
617
|
* };
|
|
618
618
|
* ```
|
|
619
619
|
*/
|
|
620
|
-
declare function createExecuteToolFromBackend(backend: SandboxBackendProtocol):
|
|
620
|
+
declare function createExecuteToolFromBackend(backend: SandboxBackendProtocol): ai2.Tool<{
|
|
621
621
|
command: string;
|
|
622
622
|
}, string>;
|
|
623
623
|
/**
|
|
@@ -751,7 +751,7 @@ interface PrepareStepArgs {
|
|
|
751
751
|
stepNumber: number;
|
|
752
752
|
steps: unknown[];
|
|
753
753
|
model: LanguageModel$2;
|
|
754
|
-
messages:
|
|
754
|
+
messages: ai2.ModelMessage[];
|
|
755
755
|
experimental_context?: unknown;
|
|
756
756
|
}
|
|
757
757
|
/**
|
|
@@ -824,7 +824,7 @@ interface SummarizationConfig {
|
|
|
824
824
|
/** Whether summarization is enabled */
|
|
825
825
|
enabled: boolean;
|
|
826
826
|
/** Optional model to use for summarization (defaults to agent model) */
|
|
827
|
-
model?:
|
|
827
|
+
model?: ai2.LanguageModel;
|
|
828
828
|
/** Token count threshold at which to trigger summarization */
|
|
829
829
|
tokenThreshold: number;
|
|
830
830
|
/** Number of recent messages to keep intact (not summarized) */
|
|
@@ -1334,7 +1334,7 @@ declare class DeepAgent {
|
|
|
1334
1334
|
generate(options: {
|
|
1335
1335
|
prompt: string;
|
|
1336
1336
|
maxSteps?: number;
|
|
1337
|
-
}): Promise<
|
|
1337
|
+
}): Promise<ai2.GenerateTextResult<{}, never> & {
|
|
1338
1338
|
state: DeepAgentState;
|
|
1339
1339
|
}>;
|
|
1340
1340
|
/**
|
|
@@ -1343,7 +1343,7 @@ declare class DeepAgent {
|
|
|
1343
1343
|
stream(options: {
|
|
1344
1344
|
prompt: string;
|
|
1345
1345
|
maxSteps?: number;
|
|
1346
|
-
}): Promise<
|
|
1346
|
+
}): Promise<ai2.StreamTextResult<{}, never> & {
|
|
1347
1347
|
state: DeepAgentState;
|
|
1348
1348
|
}>;
|
|
1349
1349
|
/**
|
|
@@ -1353,7 +1353,7 @@ declare class DeepAgent {
|
|
|
1353
1353
|
prompt: string;
|
|
1354
1354
|
state: DeepAgentState;
|
|
1355
1355
|
maxSteps?: number;
|
|
1356
|
-
}): Promise<
|
|
1356
|
+
}): Promise<ai2.GenerateTextResult<{}, never> & {
|
|
1357
1357
|
state: DeepAgentState;
|
|
1358
1358
|
}>;
|
|
1359
1359
|
/**
|
|
@@ -1607,4 +1607,4 @@ declare class DeepAgent {
|
|
|
1607
1607
|
declare function createDeepAgent(params: CreateDeepAgentParams): DeepAgent;
|
|
1608
1608
|
//#endregion
|
|
1609
1609
|
export { createLsTool as $, TextEvent as A, isSandboxBackend as At, DynamicApprovalConfig as B, FileWrittenEvent as C, FileDownloadResponse as Ct, StepStartEvent as D, GrepMatch as Dt, StepFinishEvent as E, FileUploadResponse as Et, WebSearchStartEvent as F, ResumeDecision as Ft, createExecuteToolFromBackend as G, SubAgent as H, AgentMemoryOptions as I, ResumeOptions as It, write_todos as J, execute as K, CreateDeepAgentParams as L, ToolCallEvent as M, Checkpoint as Mt, ToolResultEvent as N, CheckpointSaverOptions as Nt, SubagentFinishEvent as O, SandboxBackendProtocol as Ot, WebSearchFinishEvent as P, InterruptData as Pt, createGrepTool as Q, SummarizationConfig as R, FileWriteStartEvent as S, FileData as St, HttpRequestStartEvent as T, FileOperationError as Tt, CreateExecuteToolOptions as U, InterruptOnConfig as V, createExecuteTool as W, createFilesystemTools as X, createEditFileTool as Y, createGlobTool as Z, ExecuteFinishEvent as _, BackendFactory as _t, eventHasStructuredOutput as a, ls as at, FetchUrlStartEvent as b, EditResult as bt, hasStructuredOutput as c, CreateWebToolsOptions as ct, CheckpointLoadedEvent as d, createWebSearchTool as dt, createReadFileTool as et, CheckpointSavedEvent as f, createWebTools as ft, EventCallback as g, web_search as gt, ErrorEvent as h, http_request as ht, StructuredAgentResult as i, grep as it, TodosChangedEvent as j, BaseCheckpointSaver as jt, SubagentStartEvent as k, WriteResult as kt, ApprovalRequestedEvent as l, createFetchUrlTool as lt, DoneEvent as m, htmlToMarkdown as mt, createDeepAgent as n, edit_file as nt, getEventOutput as o, read_file as ot, DeepAgentEvent as p, fetch_url as pt, createTodosTool as q, ModelMessage$1 as r, glob as rt, getStructuredOutput as s, write_file as st, DeepAgent as t, createWriteFileTool as tt, ApprovalResponseEvent as u, createHttpRequestTool as ut, ExecuteStartEvent as v, BackendProtocol as vt, HttpRequestFinishEvent as w, FileInfo as wt, FileEditedEvent as x, ExecuteResponse as xt, FetchUrlFinishEvent as y, DeepAgentState as yt, TodoItem as z };
|
|
1610
|
-
//# sourceMappingURL=agent-
|
|
1610
|
+
//# sourceMappingURL=agent-64IK97WT.d.cts.map
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as createLsTool, A as TextEvent, At as isSandboxBackend, B as DynamicApprovalConfig, C as FileWrittenEvent, Ct as FileDownloadResponse, D as StepStartEvent, Dt as GrepMatch, E as StepFinishEvent, Et as FileUploadResponse, F as WebSearchStartEvent, Ft as ResumeDecision, G as createExecuteToolFromBackend, H as SubAgent, I as AgentMemoryOptions, It as ResumeOptions, J as write_todos, K as execute, L as CreateDeepAgentParams, M as ToolCallEvent, Mt as Checkpoint, N as ToolResultEvent, Nt as CheckpointSaverOptions, O as SubagentFinishEvent, Ot as SandboxBackendProtocol, P as WebSearchFinishEvent, Pt as InterruptData, Q as createGrepTool, R as SummarizationConfig, S as FileWriteStartEvent, St as FileData, T as HttpRequestStartEvent, Tt as FileOperationError, U as CreateExecuteToolOptions, V as InterruptOnConfig, W as createExecuteTool, X as createFilesystemTools, Y as createEditFileTool, Z as createGlobTool, _ as ExecuteFinishEvent, _t as BackendFactory, a as eventHasStructuredOutput, at as ls, b as FetchUrlStartEvent, bt as EditResult, c as hasStructuredOutput, ct as CreateWebToolsOptions, d as CheckpointLoadedEvent, dt as createWebSearchTool, et as createReadFileTool, f as CheckpointSavedEvent, ft as createWebTools, g as EventCallback, gt as web_search, h as ErrorEvent, ht as http_request, i as StructuredAgentResult, it as grep, j as TodosChangedEvent, jt as BaseCheckpointSaver, k as SubagentStartEvent, kt as WriteResult, l as ApprovalRequestedEvent, lt as createFetchUrlTool, m as DoneEvent, mt as htmlToMarkdown, n as createDeepAgent, nt as edit_file, o as getEventOutput, ot as read_file, p as DeepAgentEvent, pt as fetch_url, q as createTodosTool, r as ModelMessage$1, rt as glob, s as getStructuredOutput, st as write_file, t as DeepAgent, tt as createWriteFileTool, u as ApprovalResponseEvent, ut as createHttpRequestTool, v as ExecuteStartEvent, vt as BackendProtocol, w as HttpRequestFinishEvent, wt as FileInfo, x as FileEditedEvent, xt as ExecuteResponse, y as FetchUrlFinishEvent, yt as DeepAgentState, z as TodoItem } from "./agent-
|
|
1
|
+
import { $ as createLsTool, A as TextEvent, At as isSandboxBackend, B as DynamicApprovalConfig, C as FileWrittenEvent, Ct as FileDownloadResponse, D as StepStartEvent, Dt as GrepMatch, E as StepFinishEvent, Et as FileUploadResponse, F as WebSearchStartEvent, Ft as ResumeDecision, G as createExecuteToolFromBackend, H as SubAgent, I as AgentMemoryOptions, It as ResumeOptions, J as write_todos, K as execute, L as CreateDeepAgentParams, M as ToolCallEvent, Mt as Checkpoint, N as ToolResultEvent, Nt as CheckpointSaverOptions, O as SubagentFinishEvent, Ot as SandboxBackendProtocol, P as WebSearchFinishEvent, Pt as InterruptData, Q as createGrepTool, R as SummarizationConfig, S as FileWriteStartEvent, St as FileData, T as HttpRequestStartEvent, Tt as FileOperationError, U as CreateExecuteToolOptions, V as InterruptOnConfig, W as createExecuteTool, X as createFilesystemTools, Y as createEditFileTool, Z as createGlobTool, _ as ExecuteFinishEvent, _t as BackendFactory, a as eventHasStructuredOutput, at as ls, b as FetchUrlStartEvent, bt as EditResult, c as hasStructuredOutput, ct as CreateWebToolsOptions, d as CheckpointLoadedEvent, dt as createWebSearchTool, et as createReadFileTool, f as CheckpointSavedEvent, ft as createWebTools, g as EventCallback, gt as web_search, h as ErrorEvent, ht as http_request, i as StructuredAgentResult, it as grep, j as TodosChangedEvent, jt as BaseCheckpointSaver, k as SubagentStartEvent, kt as WriteResult, l as ApprovalRequestedEvent, lt as createFetchUrlTool, m as DoneEvent, mt as htmlToMarkdown, n as createDeepAgent, nt as edit_file, o as getEventOutput, ot as read_file, p as DeepAgentEvent, pt as fetch_url, q as createTodosTool, r as ModelMessage$1, rt as glob, s as getStructuredOutput, st as write_file, t as DeepAgent, tt as createWriteFileTool, u as ApprovalResponseEvent, ut as createHttpRequestTool, v as ExecuteStartEvent, vt as BackendProtocol, w as HttpRequestFinishEvent, wt as FileInfo, x as FileEditedEvent, xt as ExecuteResponse, y as FetchUrlFinishEvent, yt as DeepAgentState, z as TodoItem } from "./agent-64IK97WT.cjs";
|
|
2
2
|
import * as ai18 from "ai";
|
|
3
3
|
import { LanguageModel, LanguageModelMiddleware, LanguageModelMiddleware as LanguageModelMiddleware$1, ModelMessage, ToolLoopAgent, ToolSet, hasToolCall, stepCountIs, wrapLanguageModel } from "ai";
|
|
4
4
|
import { Sandbox } from "e2b";
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $ as createLsTool, A as TextEvent, At as isSandboxBackend, B as DynamicApprovalConfig, C as FileWrittenEvent, Ct as FileDownloadResponse, D as StepStartEvent, Dt as GrepMatch, E as StepFinishEvent, Et as FileUploadResponse, F as WebSearchStartEvent, Ft as ResumeDecision, G as createExecuteToolFromBackend, H as SubAgent, I as AgentMemoryOptions, It as ResumeOptions, J as write_todos, K as execute, L as CreateDeepAgentParams, M as ToolCallEvent, Mt as Checkpoint, N as ToolResultEvent, Nt as CheckpointSaverOptions, O as SubagentFinishEvent, Ot as SandboxBackendProtocol, P as WebSearchFinishEvent, Pt as InterruptData, Q as createGrepTool, R as SummarizationConfig, S as FileWriteStartEvent, St as FileData, T as HttpRequestStartEvent, Tt as FileOperationError, U as CreateExecuteToolOptions, V as InterruptOnConfig, W as createExecuteTool, X as createFilesystemTools, Y as createEditFileTool, Z as createGlobTool, _ as ExecuteFinishEvent, _t as BackendFactory, a as eventHasStructuredOutput, at as ls, b as FetchUrlStartEvent, bt as EditResult, c as hasStructuredOutput, ct as CreateWebToolsOptions, d as CheckpointLoadedEvent, dt as createWebSearchTool, et as createReadFileTool, f as CheckpointSavedEvent, ft as createWebTools, g as EventCallback, gt as web_search, h as ErrorEvent, ht as http_request, i as StructuredAgentResult, it as grep, j as TodosChangedEvent, jt as BaseCheckpointSaver, k as SubagentStartEvent, kt as WriteResult, l as ApprovalRequestedEvent, lt as createFetchUrlTool, m as DoneEvent, mt as htmlToMarkdown, n as createDeepAgent, nt as edit_file, o as getEventOutput, ot as read_file, p as DeepAgentEvent, pt as fetch_url, q as createTodosTool, r as ModelMessage$1, rt as glob, s as getStructuredOutput, st as write_file, t as DeepAgent, tt as createWriteFileTool, u as ApprovalResponseEvent, ut as createHttpRequestTool, v as ExecuteStartEvent, vt as BackendProtocol, w as HttpRequestFinishEvent, wt as FileInfo, x as FileEditedEvent, xt as ExecuteResponse, y as FetchUrlFinishEvent, yt as DeepAgentState, z as TodoItem } from "./agent-BwmAQJhR.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as ai20 from "ai";
|
|
3
3
|
import { LanguageModel, LanguageModelMiddleware, LanguageModelMiddleware as LanguageModelMiddleware$1, ModelMessage, ToolLoopAgent, ToolSet, hasToolCall, stepCountIs, wrapLanguageModel } from "ai";
|
|
4
4
|
import { ModalClient, Sandbox } from "modal";
|
|
5
5
|
import { Sandbox as Sandbox$1 } from "e2b";
|
|
@@ -1034,7 +1034,7 @@ interface CreateSubagentToolOptions {
|
|
|
1034
1034
|
/**
|
|
1035
1035
|
* Create the task tool for spawning subagents using ToolLoopAgent.
|
|
1036
1036
|
*/
|
|
1037
|
-
declare function createSubagentTool(state: DeepAgentState, options: CreateSubagentToolOptions):
|
|
1037
|
+
declare function createSubagentTool(state: DeepAgentState, options: CreateSubagentToolOptions): ai20.Tool<{
|
|
1038
1038
|
description: string;
|
|
1039
1039
|
subagent_type: string;
|
|
1040
1040
|
}, string>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepagentsdk",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Deep Agent implementation using Vercel AI SDK - build controllable AI agents with planning, filesystem, and subagent capabilities",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|