@cloudbase/agent-adapter-claude-agent-sdk 0.0.8 → 0.0.11

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @cloudbase/agent-adapter-claude-agent-sdk
2
2
 
3
+ ## 1.0.1-alpha.5
4
+
5
+ ### Patch Changes
6
+
7
+ - alpha release 0.1.2-alpha.1
8
+ - Update all public packages to version 0.1.2-alpha.1
9
+ - Trigger automated alpha release workflow
10
+ - Includes latest features and improvements
11
+
12
+ - Updated dependencies
13
+ - @cloudbase/agent-tools@1.0.1-alpha.5
14
+ - @cloudbase/agent-agents@1.0.1-alpha.5
15
+
3
16
  ## 1.0.1-alpha.4
4
17
 
5
18
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -205,14 +205,6 @@ declare class MessageConverter {
205
205
  * ```
206
206
  */
207
207
  convertToPrompt(aguiMessages: Message[]): string;
208
- /**
209
- * Extract the latest user message from AG-UI messages
210
- * Useful when you only need the current user input
211
- *
212
- * @param aguiMessages - Array of AG-UI messages
213
- * @returns Latest user message content or empty string
214
- */
215
- extractLatestUserMessage(aguiMessages: Message[]): string;
216
208
  /**
217
209
  * Extract system messages and combine them
218
210
  * Useful for setting up Claude's context
@@ -396,20 +388,6 @@ declare class EventTransformer {
396
388
  * Generate unique tool call ID
397
389
  */
398
390
  private generateToolCallId;
399
- /**
400
- * Detect interrupt marker in tool result
401
- *
402
- * Checks if a tool result contains the __interrupt__ marker used for
403
- * human-in-the-loop workflows. Returns interrupt details if found.
404
- *
405
- * @param resultContent - Tool result content string
406
- * @returns Interrupt object if found, undefined otherwise
407
- */
408
- detectInterrupt(resultContent: string): {
409
- id: string;
410
- reason: string;
411
- payload: any;
412
- } | undefined;
413
391
  /**
414
392
  * Remove MCP namespace prefix from tool name
415
393
  *
package/dist/index.d.ts CHANGED
@@ -205,14 +205,6 @@ declare class MessageConverter {
205
205
  * ```
206
206
  */
207
207
  convertToPrompt(aguiMessages: Message[]): string;
208
- /**
209
- * Extract the latest user message from AG-UI messages
210
- * Useful when you only need the current user input
211
- *
212
- * @param aguiMessages - Array of AG-UI messages
213
- * @returns Latest user message content or empty string
214
- */
215
- extractLatestUserMessage(aguiMessages: Message[]): string;
216
208
  /**
217
209
  * Extract system messages and combine them
218
210
  * Useful for setting up Claude's context
@@ -396,20 +388,6 @@ declare class EventTransformer {
396
388
  * Generate unique tool call ID
397
389
  */
398
390
  private generateToolCallId;
399
- /**
400
- * Detect interrupt marker in tool result
401
- *
402
- * Checks if a tool result contains the __interrupt__ marker used for
403
- * human-in-the-loop workflows. Returns interrupt details if found.
404
- *
405
- * @param resultContent - Tool result content string
406
- * @returns Interrupt object if found, undefined otherwise
407
- */
408
- detectInterrupt(resultContent: string): {
409
- id: string;
410
- reason: string;
411
- payload: any;
412
- } | undefined;
413
391
  /**
414
392
  * Remove MCP namespace prefix from tool name
415
393
  *
package/dist/index.js CHANGED
@@ -94,27 +94,6 @@ ${msg.content}
94
94
  }
95
95
  return lines.join("\n");
96
96
  }
97
- /**
98
- * Extract the latest user message from AG-UI messages
99
- * Useful when you only need the current user input
100
- *
101
- * @param aguiMessages - Array of AG-UI messages
102
- * @returns Latest user message content or empty string
103
- */
104
- extractLatestUserMessage(aguiMessages) {
105
- for (let i = aguiMessages.length - 1; i >= 0; i--) {
106
- const msg = aguiMessages[i];
107
- if (msg.role === "user" && msg.content) {
108
- if (typeof msg.content === "string") {
109
- return msg.content;
110
- } else {
111
- const content = msg.content.filter((m) => m.type === "text").map((m) => m.text).join("");
112
- if (content) return content;
113
- }
114
- }
115
- }
116
- return "";
117
- }
118
97
  /**
119
98
  * Extract system messages and combine them
120
99
  * Useful for setting up Claude's context
@@ -643,31 +622,6 @@ var EventTransformer = class {
643
622
  generateToolCallId() {
644
623
  return `tool_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
645
624
  }
646
- /**
647
- * Detect interrupt marker in tool result
648
- *
649
- * Checks if a tool result contains the __interrupt__ marker used for
650
- * human-in-the-loop workflows. Returns interrupt details if found.
651
- *
652
- * @param resultContent - Tool result content string
653
- * @returns Interrupt object if found, undefined otherwise
654
- */
655
- detectInterrupt(resultContent) {
656
- try {
657
- const parsed = JSON.parse(resultContent);
658
- if (parsed.__interrupt__ === true) {
659
- return {
660
- // 🔑 Generate unique ID for this interrupt
661
- id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
662
- reason: parsed.reason || "Agent requested interrupt",
663
- // 🔑 Payload contains the full interrupt data (including type, steps, etc.)
664
- payload: parsed
665
- };
666
- }
667
- } catch (error) {
668
- }
669
- return void 0;
670
- }
671
625
  /**
672
626
  * Remove MCP namespace prefix from tool name
673
627
  *
@@ -991,10 +945,11 @@ var _ClaudeAgent = class _ClaudeAgent extends import_abstract.AbstractAgent {
991
945
  }
992
946
  try {
993
947
  const parsed = JSON.parse(resultContent);
948
+ console.log("[ClaudeAgent] Parsed interrupt data:", parsed);
949
+ const { interruptId } = parsed;
994
950
  if (parsed.__interrupt__ === true) {
995
951
  return {
996
- // 🔑 Generate unique ID for this interrupt
997
- id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
952
+ id: interruptId,
998
953
  reason: parsed.reason || "Agent requested interrupt",
999
954
  // 🔑 Payload contains the full interrupt data (including type, steps, etc.)
1000
955
  payload: parsed
@@ -1056,6 +1011,19 @@ var _ClaudeAgent = class _ClaudeAgent extends import_abstract.AbstractAgent {
1056
1011
  for (const event of events) {
1057
1012
  subscriber.next(event);
1058
1013
  }
1014
+ const interruptDetected = this.detectInterrupt(sdkMessage);
1015
+ if (interruptDetected) {
1016
+ console.log("[ClaudeAgent] Interrupt detected in resume:", interruptDetected);
1017
+ subscriber.next({
1018
+ type: import_client2.EventType.RUN_FINISHED,
1019
+ threadId,
1020
+ runId,
1021
+ outcome: "interrupt",
1022
+ interrupt: interruptDetected
1023
+ });
1024
+ subscriber.complete();
1025
+ return;
1026
+ }
1059
1027
  }
1060
1028
  const finalEvents = eventTransformer.completeActiveMessage();
1061
1029
  for (const event of finalEvents) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/message-converter.ts","../src/tool-bridge.ts","../src/event-transformer.ts","../src/hooks-manager.ts"],"sourcesContent":["/**\n * Claude Agent SDK integration for AG-Kit\n * \n * This module provides integration between Anthropic's Claude Agent SDK\n * and AG-Kit's unified agent interface.\n * \n * @example\n * ```typescript\n * import { ClaudeAgent } from \"@cloudbase/agent-agents/claude-agent\";\n * \n * const agent = new ClaudeAgent({\n * name: \"my-claude-agent\",\n * model: \"claude-3-5-sonnet-20241022\",\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * enableBuiltInTools: true,\n * });\n * ```\n * \n * @module claude-agent\n */\n\n// Core agent class\nexport { ClaudeAgent } from \"./agent\";\n\n// Type definitions\nexport type { ClaudeAgentSDKConfig } from \"./types\";\n\n// Utility modules (for advanced usage)\nexport { MessageConverter } from \"./message-converter\";\nexport { ToolBridge } from \"./tool-bridge\";\nexport { EventTransformer } from \"./event-transformer\";\nexport { HooksManager } from \"./hooks-manager\";\n\n// Re-export useful Claude SDK types\nexport type {\n ClaudeSDKOptions,\n SDKMessage,\n SDKAssistantMessage,\n SDKUserMessage,\n SDKResultMessage,\n SDKPartialAssistantMessage,\n Query,\n} from \"./types\";\n\n","/**\n * Claude Agent SDK integration for AG-Kit\n * Main agent class that bridges Claude Agent SDK with AG-Kit\n * @module claude-sdk/agent\n */\n\nimport type {\n RunAgentInput,\n BaseEvent,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport { AbstractAgent } from \"@cloudbase/agent-agents/abstract\";\nimport { query } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { Query, SDKMessage, SDKSystemMessage, SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Observable, Subscriber } from \"rxjs\";\n\nimport type { ClaudeAgentSDKConfig, ClaudeSDKOptions } from \"./types\";\nimport { MessageConverter } from \"./message-converter\";\nimport { ToolBridge } from \"./tool-bridge\";\nimport { EventTransformer } from \"./event-transformer\";\nimport { HooksManager } from \"./hooks-manager\";\n\n/**\n * Claude Agent SDK adapter for AG-Kit\n * \n * Integrates Anthropic's Claude Agent SDK with AG-Kit's unified agent interface.\n * Provides seamless integration with AG-UI components while leveraging Claude's\n * built-in tools, MCP support, hooks system, and permission management.\n * \n * @example\n * ```typescript\n * const agent = new ClaudeAgentSDK({\n * name: \"my-claude-agent\",\n * model: \"\",\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * enableBuiltInTools: true,\n * permissionMode: \"ask\",\n * });\n * ```\n */\nexport class ClaudeAgent extends AbstractAgent {\n private config: ClaudeAgentSDKConfig;\n private mcpServers: any[] = [];\n private messageConverter: MessageConverter;\n private toolBridge: ToolBridge;\n private hooksManager: HooksManager;\n\n // 🔑 Session management for HITL\n // Use static storage to persist across agent instance recreations\n public static sessionStore: Map<string, string> = new Map(); // threadId → session_id\n private currentQuery?: Query;\n\n // 🔑 Event emitter for tool intermediate messages\n // Allows MCP tools to emit events during execution\n private currentSubscriber?: Subscriber<BaseEvent>;\n\n constructor(config: ClaudeAgentSDKConfig) {\n super(config);\n console.log('ClaudeAgent constructor called');\n this.config = config;\n\n // Initialize utility modules\n this.messageConverter = new MessageConverter();\n this.toolBridge = new ToolBridge();\n this.hooksManager = new HooksManager();\n\n // Note: Tools are provided at runtime via RunAgentInput, not in config\n // MCP servers from tools will be created dynamically during run()\n }\n\n /**\n * Run the Claude agent with given input\n * \n * @param input - AG-UI RunAgentInput\n * @returns Observable stream of AG-UI BaseEvents\n */\n public run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n // 🔑 Check if this is a resume request\n if (input.forwardedProps?.resume) {\n this._resume(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('resume error', error);\n });\n } else {\n this._run(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('run error', error);\n });\n }\n });\n }\n\n /**\n * Internal run implementation\n * Handles the full agent execution lifecycle\n */\n private async _run(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { messages, runId, threadId, tools: inputTools } = input;\n\n // 🔑 Store subscriber for tool intermediate events\n this.currentSubscriber = subscriber;\n // console.log('_run********* subscriber', this.currentSubscriber)\n\n // Emit RUN_STARTED event\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n try {\n // Convert AG-UI messages to Claude prompt\n const prompt = this.messageConverter.convertToPrompt(messages);\n\n // Prepare MCP servers\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Convert runtime tools to MCP server if provided\n // inputTools are AG-UI tools with JSON Schema: { name, description, parameters }\n if (inputTools && inputTools.length > 0) {\n // Prepare tools for conversion\n const toolsForMcp = inputTools.map(tool => ({\n name: tool.name,\n description: tool.description,\n parameters: typeof tool.parameters === 'string'\n ? JSON.parse(tool.parameters)\n : tool.parameters,\n }));\n\n // Create MCP server from AG-UI tools (JSON Schema)\n // Use short server name to avoid long MCP prefixes in tool names\n // MCP will prefix tools as: mcp__agkit__<tool-name>\n const runtimeServer = this.toolBridge.createMcpServerFromJsonSchema(\n \"agkit\",\n toolsForMcp\n );\n\n // Add to MCP servers dict\n mcpServers[\"agkit\"] = runtimeServer;\n }\n\n // Ensure API key is set in environment\n // Claude Agent SDK reads from ANTHROPIC_API_KEY environment variable\n if (this.config.apiKey && !process.env.ANTHROPIC_API_KEY) {\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n }\n console.log('[ClaudeAgent] includePartialMessages:', this.config.includePartialMessages);\n // console.log('[ClaudeAgent] claudeOptions:', this.config.claudeOptions);\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n additionalDirectories: this.config.additionalDirectories,\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n includePartialMessages: this.config.includePartialMessages !== false, // Default true for streaming\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n ...this.config.claudeOptions,\n };\n\n // 🔑 Check if there's a saved session ID for this thread (for session continuity)\n const savedSessionId = ClaudeAgent.sessionStore.get(threadId);\n if (savedSessionId) {\n console.log(`[ClaudeAgent] Resuming session: ${savedSessionId} for thread: ${threadId}`);\n options.resume = savedSessionId;\n }\n\n // Create Claude Agent SDK query\n const agentQuery = query({\n prompt,\n options,\n });\n\n // console.log('options', JSON.stringify(options, null, 2));\n\n // Store query reference for potential interrupt\n this.currentQuery = agentQuery;\n\n // Create event transformer\n // Pass streaming flag to avoid duplicate text messages\n const streamingEnabled = options.includePartialMessages === true;\n console.log('[ClaudeAgent] Streaming enabled:', streamingEnabled);\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Process SDKMessages\n for await (const sdkMessage of agentQuery) {\n console.log(\"sdkMessage\", JSON.stringify(sdkMessage, null, 2));\n console.log('[ClaudeAgent] SDKMessage type:', sdkMessage.type);\n\n // 🔑 Capture session ID from init message\n if (sdkMessage.type === 'system') {\n const systemMsg = sdkMessage as SDKSystemMessage;\n if (systemMsg.subtype === 'init' && systemMsg.session_id) {\n console.log(`[ClaudeAgent] Captured session ID: ${systemMsg.session_id} for thread: ${threadId}`);\n ClaudeAgent.sessionStore.set(threadId, systemMsg.session_id);\n }\n }\n\n // Transform SDKMessage to AG-UI events FIRST\n // This ensures TOOL_CALL_RESULT is sent before interrupt detection\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n\n // Emit all events\n for (const event of events) {\n subscriber.next(event);\n }\n\n // 🔑 Detect interrupt from tool results AFTER emitting events\n const interruptDetected = this.detectInterrupt(sdkMessage);\n if (interruptDetected) {\n console.log(\"[ClaudeAgent] Interrupt detected:\", interruptDetected);\n\n // Emit RUN_FINISHED with interrupt\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n outcome: \"interrupt\",\n interrupt: interruptDetected,\n } as RunFinishedEvent);\n\n // 🔑 Complete the observable - no need to wait for resume\n // The next request will be a separate HTTP call with forwardedProps.resume\n subscriber.complete();\n return;\n }\n }\n\n // Complete any active message\n console.log('[ClaudeAgent] Calling completeActiveMessage...');\n const finalEvents = eventTransformer.completeActiveMessage();\n // console.log('[ClaudeAgent] Final events:', finalEvents.map(e => e.type));\n\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n // Note: Usage statistics are included in SDKResultMessage\n // which is already processed by EventTransformer\n\n // Emit RUN_FINISHED event\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n } catch (error) {\n // Emit RUN_ERROR event\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // 🔑 Clear subscriber reference\n // this.currentSubscriber = undefined;\n // console.log('run finally ********* subscriber', this.currentSubscriber)\n }\n }\n\n /**\n * Get event emitter for MCP tools\n * Allows tools to emit intermediate events during execution\n * \n * @returns Event emitter function or undefined if no active run\n */\n public getEventEmitter(): ((event: BaseEvent) => void) | undefined {\n if (this.currentSubscriber) {\n return (event: BaseEvent) => {\n this.currentSubscriber!.next(event);\n };\n }\n return undefined;\n }\n\n /**\n * 🔑 Detect interrupt from SDKMessage\n * Checks if tool result contains __interrupt__ marker\n */\n private detectInterrupt(sdkMessage: SDKMessage): {\n id: string;\n reason: string;\n payload: any;\n } | null {\n // 🔑 Check user message for tool_result with __interrupt__\n if (sdkMessage.type === \"user\") {\n const message = (sdkMessage as any).message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return null;\n }\n\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // Try to parse as JSON and check for __interrupt__\n try {\n const parsed = JSON.parse(resultContent);\n if (parsed.__interrupt__ === true) {\n return {\n // 🔑 Generate unique ID for this interrupt\n id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n reason: parsed.reason || \"Agent requested interrupt\",\n // 🔑 Payload contains the full interrupt data (including type, steps, etc.)\n payload: parsed,\n };\n }\n } catch {\n // Not JSON or doesn't contain interrupt marker\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * 🔑 Resume execution after interrupt\n * Uses saved session ID to continue conversation\n */\n private async _resume(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { runId, threadId } = input;\n const resumePayload = input.forwardedProps?.resume?.payload;\n\n this.currentSubscriber = subscriber;\n // console.log('_resume ********* subscriber', this.currentSubscriber)\n\n console.log('[ClaudeAgent] Resuming with payload:', resumePayload);\n\n try {\n // 🔑 Get saved session ID from static storage\n const sessionId = ClaudeAgent.sessionStore.get(threadId);\n if (!sessionId) {\n throw new Error(`No session ID found for thread: ${threadId}. Make sure the initial request completed successfully.`);\n }\n\n console.log(`[ClaudeAgent] Resuming session: ${sessionId}`);\n\n // 🔑 Build resume prompt from user's modified data\n const resumePrompt = this.buildResumePrompt(resumePayload);\n\n // Prepare MCP servers (same as initial run)\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n includePartialMessages: this.config.includePartialMessages !== false,\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n // 🔑 Use session ID to resume (SDK auto-loads history)\n resume: sessionId,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n ...this.config.claudeOptions,\n };\n\n // Create new query (SDK will restore full context)\n const agentQuery = query({\n prompt: resumePrompt,\n options,\n });\n\n this.currentQuery = agentQuery;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n const streamingEnabled = options.includePartialMessages === true;\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Continue processing messages\n for await (const sdkMessage of agentQuery) {\n // console.log(\"sdkMessage (resumed)\", JSON.stringify(sdkMessage, null, 2));\n\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n for (const event of events) {\n subscriber.next(event);\n }\n }\n\n const finalEvents = eventTransformer.completeActiveMessage();\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n\n } catch (error) {\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: \"RESUME_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // this.currentSubscriber = undefined;\n // console.log('_resume finally ********* subscriber', this.currentSubscriber)\n\n }\n }\n\n /**\n * Build resume prompt from user's modified data\n */\n private buildResumePrompt(payload: any): string {\n // If payload contains steps, construct a descriptive prompt\n if (payload.steps) {\n const enabledSteps = payload.steps.filter((s: any) => s.status === 'enabled');\n const disabledSteps = payload.steps.filter((s: any) => s.status === 'disabled');\n\n let prompt = \"The user has reviewed the steps. \";\n\n if (disabledSteps.length > 0) {\n prompt += `They disabled the following steps: ${disabledSteps.map((s: any) => s.description).join(', ')}. `;\n }\n\n prompt += `Please continue with the enabled steps: ${enabledSteps.map((s: any) => s.description).join(', ')}. `;\n prompt += \"Provide a creative but short description (3 sentences max) of how you will perform the task.\";\n\n return prompt;\n }\n\n // Default: use payload as JSON\n return JSON.stringify(payload);\n }\n\n /**\n * Clear session for a thread\n */\n public clearSession(threadId: string): void {\n ClaudeAgent.sessionStore.delete(threadId);\n console.log(`[ClaudeAgent] Cleared session for thread: ${threadId}`);\n }\n\n /**\n * 🔑 Get all active sessions (for debugging)\n */\n public static getActiveSessions(): Map<string, string> {\n return ClaudeAgent.sessionStore;\n }\n\n /**\n * Get the configured model name\n */\n public getModel(): string {\n return this.config.model || \"\";\n }\n\n /**\n * Get the configured API key (masked for security)\n */\n public getApiKey(): string {\n const key = this.config.apiKey || process.env.ANTHROPIC_API_KEY || \"\";\n return key ? `${key.substring(0, 8)}...` : \"not configured\";\n }\n\n /**\n * Get MCP servers count\n */\n public getMcpServersCount(): number {\n return this.mcpServers.length;\n }\n\n /**\n * Check if built-in tools are enabled\n */\n public isBuiltInToolsEnabled(): boolean {\n return this.config.enableBuiltInTools !== false; // Default true\n }\n}\n\n","/**\n * Message format converter for Claude Agent SDK\n * Converts AG-UI messages to Claude Agent SDK prompt format\n * @module claude-sdk/message-converter\n */\n\nimport type { Message as AGUIMessage } from \"@ag-ui/client\";\n\n/**\n * Converts AG-UI messages to Claude Agent SDK prompt format\n *\n * Claude Agent SDK uses a simple prompt string or streaming messages.\n * This converter formats AG-UI message history into a structured prompt.\n */\nexport class MessageConverter {\n /**\n * Convert AG-UI messages to a structured prompt string\n *\n * Formats conversation history with role markers for clarity.\n * Claude Agent SDK will parse this and maintain context.\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted prompt string\n *\n * @example\n * ```typescript\n * const converter = new MessageConverter();\n * const prompt = converter.convertToPrompt([\n * { role: \"system\", content: \"You are a helpful assistant\" },\n * { role: \"user\", content: \"Hello!\" },\n * ]);\n * // Returns: \"[System]\\nYou are a helpful assistant\\n\\n[User]\\nHello!\\n\"\n * ```\n */\n public convertToPrompt(aguiMessages: AGUIMessage[]): string {\n const lines: string[] = [];\n\n for (const msg of aguiMessages) {\n switch (msg.role) {\n case \"system\":\n // System messages provide context\n if (msg.content) {\n lines.push(`[System]\\n${msg.content}\\n`);\n }\n break;\n\n case \"user\":\n // User messages are the main input\n if (msg.content) {\n lines.push(`${msg.content}\\n`);\n }\n break;\n\n case \"assistant\":\n // Assistant messages show previous responses\n if (msg.content) {\n lines.push(`[Assistant]\\n${msg.content}\\n`);\n }\n // Tool calls are handled automatically by Claude via MCP\n // We don't need to explicitly format them in the prompt\n break;\n\n case \"tool\":\n // Tool results provide context for Claude\n // Format them clearly so Claude understands the tool output\n if (msg.toolCallId && msg.content) {\n lines.push(`[Tool Result: ${msg.toolCallId}]\\n${msg.content}\\n`);\n }\n break;\n\n default:\n // Skip unknown message types\n console.warn(\n `[MessageConverter] Unknown message role: ${(msg as any).role}`\n );\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Extract the latest user message from AG-UI messages\n * Useful when you only need the current user input\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Latest user message content or empty string\n */\n public extractLatestUserMessage(aguiMessages: AGUIMessage[]): string {\n // Find the last user message\n for (let i = aguiMessages.length - 1; i >= 0; i--) {\n const msg = aguiMessages[i];\n if (msg.role === \"user\" && msg.content) {\n if (typeof msg.content === \"string\") {\n return msg.content;\n } else {\n const content = msg.content\n .filter((m) => m.type === \"text\")\n .map((m) => m.text)\n .join(\"\");\n\n if (content) return content;\n }\n }\n }\n return \"\";\n }\n\n /**\n * Extract system messages and combine them\n * Useful for setting up Claude's context\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Combined system message content\n */\n public extractSystemMessages(aguiMessages: AGUIMessage[]): string {\n const systemMessages = aguiMessages\n .filter((msg) => msg.role === \"system\" && msg.content)\n .map((msg) => msg.content);\n\n return systemMessages.join(\"\\n\\n\");\n }\n\n /**\n * Get conversation history excluding the latest user message\n * Useful for providing context without duplicating current input\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted conversation history\n */\n public getConversationHistory(aguiMessages: AGUIMessage[]): string {\n // Remove the last user message (current input)\n const historyMessages = [...aguiMessages];\n for (let i = historyMessages.length - 1; i >= 0; i--) {\n if (historyMessages[i].role === \"user\") {\n historyMessages.splice(i, 1);\n break;\n }\n }\n\n return this.convertToPrompt(historyMessages);\n }\n}\n","/**\n * Tool bridge for converting AG-Kit tools to MCP servers\n * Handles Zod schema extraction and MCP server creation\n * @module claude-sdk/tool-bridge\n */\n\nimport type { BaseTool } from \"@cloudbase/agent-tools\";\nimport { createSdkMcpServer, tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod/v3\";\n\n/**\n * Bridges AG-Kit tools to Claude Agent SDK via MCP servers\n * \n * Supports both BaseTool (Zod schema) and AG-UI tools (JSON Schema)\n * and creates MCP tools that Claude SDK can use directly.\n */\nexport class ToolBridge {\n /**\n * Create an MCP server from AG-Kit BaseTool instances\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-Kit BaseTool instances\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n */\n public createMcpServer(name: string, tools: BaseTool[], isClientTools: boolean = false): any {\n const mcpTools = tools.map(agkitTool => this.convertToMcpTool(agkitTool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Create an MCP server from AG-UI tool definitions (JSON Schema format)\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-UI tool definitions with JSON Schema\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n * \n * @example\n * ```typescript\n * const bridge = new ToolBridge();\n * const server = bridge.createMcpServerFromJsonSchema(\"my-tools\", [\n * {\n * name: \"get_weather\",\n * description: \"Get weather\",\n * parameters: { type: \"object\", properties: { location: { type: \"string\" } } }\n * }\n * ], true); // true = client-side tools\n * ```\n */\n public createMcpServerFromJsonSchema(\n name: string,\n tools: Array<{ name: string; description: string; parameters: any }>,\n isClientTools: boolean = true // 🔑 Default true: inputTools are usually client tools\n ): any {\n const mcpTools = tools.map(tool => this.convertJsonSchemaToolToMcp(tool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Convert a single AG-Kit BaseTool to MCP tool definition\n * \n * @param agkitTool - AG-Kit BaseTool instance\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertToMcpTool(agkitTool: BaseTool, isClientTool: boolean = false): any {\n const metadata = agkitTool.getMetadata();\n const toolName = metadata.name || \"unnamed_tool\";\n const toolDescription = metadata.description || `AG-Kit tool: ${toolName}`;\n\n // Extract Zod schema shape from BaseTool\n let zodShape: any = {};\n\n if (metadata.schema) {\n const schema = metadata.schema as any;\n if (schema._def && typeof schema._def.shape === 'function') {\n zodShape = schema._def.shape();\n } else if (schema._def && schema._def.shape) {\n zodShape = schema._def.shape;\n } else {\n console.warn(`[ToolBridge] Tool \"${toolName}\" schema is not a ZodObject, using empty shape`);\n }\n }\n\n return this.createMcpTool(toolName, toolDescription, zodShape, isClientTool);\n }\n\n /**\n * Convert a JSON Schema tool to MCP tool definition\n * \n * @param toolDef - Tool definition with JSON Schema parameters\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertJsonSchemaToolToMcp(\n toolDef: {\n name: string;\n description: string;\n parameters: any;\n },\n isClientTool: boolean = false\n ): any {\n // Convert JSON Schema to Zod shape\n const zodShape = this.jsonSchemaToZodShape(toolDef.parameters);\n\n return this.createMcpTool(\n toolDef.name,\n toolDef.description || `Tool: ${toolDef.name}`,\n zodShape,\n isClientTool\n );\n }\n\n /**\n * Create an MCP tool with common logic\n * \n * @param name - Tool name\n * @param description - Tool description\n * @param zodShape - Zod schema for parameters\n * @param isClientTool - Whether this is a client-side tool\n */\n private createMcpTool(\n name: string,\n description: string,\n zodShape: any,\n isClientTool: boolean = false\n ): any {\n return tool(\n name,\n description,\n zodShape,\n async (args: any, extra: unknown) => {\n console.log(`[ToolBridge] Tool called: ${name}, isClientTool: ${isClientTool}`, { args });\n\n if (isClientTool) {\n // 🔑 Client-side tool: Return special marker for frontend execution\n // The EventTransformer will detect this and NOT send tool-result event\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n __client_tool__: true, // ← Special marker\n tool: name,\n args,\n message: \"Waiting for client-side execution\",\n }),\n },\n ],\n isError: false,\n };\n }\n\n // Server-side tool: Should have custom implementation\n // This is a fallback that should not be reached\n console.warn(`[ToolBridge] Server-side tool \"${name}\" called but no implementation provided`);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n tool: name,\n args,\n message: \"Tool executed on backend (placeholder)\",\n }),\n },\n ],\n isError: false,\n };\n }\n );\n }\n\n /**\n * Convert JSON Schema to Zod shape (ZodRawShape)\n * \n * @param jsonSchema - JSON Schema object\n * @returns Zod shape object\n */\n private jsonSchemaToZodShape(jsonSchema: any): any {\n if (!jsonSchema || typeof jsonSchema !== \"object\") {\n return {};\n }\n\n const zodShape: any = {};\n\n // Handle object schema with properties\n if (jsonSchema.type === \"object\" && jsonSchema.properties) {\n const required = Array.isArray(jsonSchema.required) ? jsonSchema.required : [];\n\n for (const [key, propSchema] of Object.entries(jsonSchema.properties)) {\n const isRequired = required.includes(key);\n zodShape[key] = this.jsonSchemaPropertyToZod(propSchema as any, isRequired);\n }\n }\n\n return zodShape;\n }\n\n /**\n * Convert a single JSON Schema property to Zod type\n */\n private jsonSchemaPropertyToZod(schema: any, isRequired: boolean): any {\n if (!schema || typeof schema !== \"object\") {\n return isRequired ? z.any() : z.any().optional();\n }\n\n let zodType: any;\n\n switch (schema.type) {\n case \"string\":\n zodType = z.string();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (Array.isArray(schema.enum)) {\n zodType = z.enum(schema.enum as [string, ...string[]]);\n }\n break;\n\n case \"number\":\n case \"integer\":\n zodType = schema.type === \"integer\" ? z.number().int() : z.number();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (schema.minimum !== undefined) zodType = zodType.min(schema.minimum);\n if (schema.maximum !== undefined) zodType = zodType.max(schema.maximum);\n break;\n\n case \"boolean\":\n zodType = z.boolean();\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"array\":\n if (schema.items) {\n const itemType = this.jsonSchemaPropertyToZod(schema.items, true);\n zodType = z.array(itemType);\n } else {\n zodType = z.array(z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"object\":\n if (schema.properties) {\n const nestedShape = this.jsonSchemaToZodShape(schema);\n zodType = z.object(nestedShape);\n } else {\n zodType = z.record(z.string(), z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n default:\n zodType = z.any();\n if (schema.description) zodType = zodType.describe(schema.description);\n }\n\n return isRequired ? zodType : zodType.optional();\n }\n\n}\n\n","/**\n * Event transformer for Claude Agent SDK\n * Converts SDKMessage to AG-UI BaseEvent\n * @module claude-sdk/event-transformer\n */\n\nimport type {\n BaseEvent,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type {\n SDKMessage,\n SDKAssistantMessage,\n SDKPartialAssistantMessage,\n SDKResultMessage,\n SDKPermissionDenial,\n} from \"./types\";\n\n/**\n * Transforms Claude Agent SDK messages to AG-UI events\n * \n * Handles streaming messages, tool calls, and error states.\n */\nexport class EventTransformer {\n private activeMessageId?: string;\n private messageContent: string = \"\";\n private streamingEnabled: boolean;\n\n /**\n * @param streamingEnabled - Whether streaming mode is enabled (includePartialMessages)\n * When true, assistant messages will skip text content to avoid duplicates\n */\n constructor(streamingEnabled: boolean = false) {\n this.streamingEnabled = streamingEnabled;\n }\n\n /**\n * Transform a single SDKMessage to AG-UI BaseEvent(s)\n * \n * One SDKMessage may produce multiple AG-UI events.\n * For example, an assistant message with tool calls produces:\n * - TEXT_MESSAGE_START\n * - TEXT_MESSAGE_CONTENT\n * - TOOL_CALL_START (for each tool)\n * - TOOL_CALL_ARGS (for each tool)\n * - TOOL_CALL_END (for each tool)\n * - TEXT_MESSAGE_END\n * \n * @param sdkMessage - Claude SDK message\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Array of AG-UI events\n */\n public transformMessage(\n sdkMessage: SDKMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n switch (sdkMessage.type) {\n case \"assistant\":\n events.push(...this.handleAssistantMessage(sdkMessage as SDKAssistantMessage, threadId, runId));\n break;\n\n case \"stream_event\":\n events.push(...this.handlePartialAssistantMessage(sdkMessage as SDKPartialAssistantMessage, threadId, runId));\n break;\n\n case \"result\":\n events.push(...this.handleResultMessage(sdkMessage as SDKResultMessage, threadId, runId));\n break;\n\n case \"user\":\n // Handle tool_result messages from user\n events.push(...this.handleUserMessage(sdkMessage as any, threadId, runId));\n break;\n\n case \"system\":\n // System messages are input/context, don't emit events\n break;\n\n case \"tool_progress\":\n case \"auth_status\":\n // Progress and status messages, can be ignored for now\n break;\n\n default:\n console.warn(`[EventTransformer] Unknown SDKMessage type: ${(sdkMessage as any).type}`);\n }\n\n // console.log(\"events\", JSON.stringify(events, null, 2));\n return events;\n }\n\n /**\n * Handle complete assistant message\n * Emits full message with any tool calls\n * \n * When streaming is enabled (includePartialMessages: true), this method will:\n * - Skip text content (already sent via stream_event messages) \n * - Only process tool_use content (tools are not streamed)\n */\n private handleAssistantMessage(\n sdkMessage: SDKAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message; // Extract the actual API message\n\n // 🔑 When streaming is enabled, skip text content to avoid duplicates\n // Text content is already sent via stream_event messages\n if (this.streamingEnabled) {\n console.log('[EventTransformer] ⚠️ Streaming enabled: skipping assistant message text content to avoid duplicates');\n\n // Only process tool calls (they're not streamed)\n for (const content of message.content) {\n if (content.type === \"tool_use\") {\n // Process tool calls normally\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n return events;\n }\n\n // Non-streaming mode: process everything normally\n // console.log('[EventTransformer] Non-streaming mode: processing full assistant message');\n\n // If there's an active message, end it first\n if (this.activeMessageId) {\n console.log('[EventTransformer] Ending previous message:', this.activeMessageId);\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n }\n\n // Start new message\n this.activeMessageId = this.generateMessageId();\n this.messageContent = \"\";\n console.log('[EventTransformer] Starting new message:', this.activeMessageId);\n\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n\n // Add text content if present\n for (const content of message.content) {\n console.log(\"content\", JSON.stringify(content, null, 2));\n if (content.type === \"text\") {\n this.messageContent += content.text;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: content.text,\n } as TextMessageContentEvent);\n } else if (content.type === \"tool_use\") {\n // Remove MCP prefix for cleaner tool names\n // Claude Agent SDK adds MCP namespace: \"mcp__server-name__tool-name\"\n // We want frontend to see: \"tool-name\"\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n // TOOL_CALL_START\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n // TOOL_CALL_ARGS\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n // TOOL_CALL_END\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n // End message and clear active message ID\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n\n // Clear activeMessageId since message is complete\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return events;\n }\n\n /**\n * Handle streaming partial assistant message\n * Emits incremental content deltas\n */\n private handlePartialAssistantMessage(\n sdkMessage: SDKPartialAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const streamEvent = sdkMessage.event; // Extract the actual stream event\n\n // Handle different stream event types\n if (streamEvent.type === \"message_start\") {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n } else if (streamEvent.type === \"content_block_delta\") {\n // If no active message, start one (edge case)\n if (!this.activeMessageId) {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n }\n\n // Handle text delta\n if (streamEvent.delta.type === \"text_delta\") {\n const textDelta = streamEvent.delta.text;\n this.messageContent += textDelta;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: textDelta,\n } as TextMessageContentEvent);\n }\n } else if (streamEvent.type === \"message_delta\") {\n // Message end or stop reason\n if (streamEvent.delta.stop_reason) {\n // Can emit TEXT_MESSAGE_END here if needed\n if (this.activeMessageId) {\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n }\n }\n\n return events;\n }\n\n /**\n * Handle user message (mainly for tool_result)\n * Claude SDK sends tool results as user messages with tool_result content\n */\n private handleUserMessage(\n sdkMessage: any,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return events;\n }\n\n // Process tool_result content blocks\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n // content.content is an array of content blocks\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // 🔑 Check if this is a client-side tool marker\n const isClientTool = this.isClientToolMarker(resultContent);\n\n if (isClientTool) {\n console.log(`[EventTransformer] Client-side tool detected: ${content.tool_use_id}, skipping tool-result event`);\n // ⚠️ DO NOT emit TOOL_CALL_RESULT event for client tools\n // The client will execute the tool and send the result back\n continue;\n }\n\n // Emit TOOL_CALL_RESULT event for server-side tools\n events.push({\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: content.tool_use_id,\n content: resultContent,\n } as ToolCallResultEvent);\n\n console.log(`[EventTransformer] Tool result for ${content.tool_use_id}: ${resultContent}`);\n }\n }\n\n return events;\n }\n\n /**\n * Handle result message (final query result)\n * This represents the end of the query execution\n */\n private handleResultMessage(\n message: SDKResultMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n // SDKResultMessage represents the final result of the entire query\n // It doesn't directly map to TOOL_CALL_RESULT\n // Instead, we can emit it as metadata or ignore it\n\n // If there are permission denials, we can log them\n if (message.permission_denials && message.permission_denials.length > 0) {\n for (const denial of message.permission_denials) {\n console.warn(`[EventTransformer] Permission denied for tool: ${denial.tool_name}, tool_use_id: ${denial.tool_use_id}`);\n // Optionally emit as error events\n events.push({\n type: EventType.RUN_ERROR,\n message: `Permission denied for tool: ${denial.tool_name}`,\n rawEvent: denial,\n } as any);\n }\n }\n\n // Handle success or error result\n if (message.subtype === 'success') {\n console.log(`[EventTransformer] Query completed successfully: ${message.result}, turns: ${message.num_turns}, cost: $${message.total_cost_usd}`);\n } else {\n // Error subtypes: error_during_execution, error_max_turns, error_max_budget_usd\n const errorMsg = `Query failed: ${message.subtype}`;\n console.error(`[EventTransformer] ${errorMsg}, errors: ${message.errors?.join(', ')}`);\n events.push({\n type: EventType.RUN_ERROR,\n message: errorMsg,\n rawEvent: message,\n } as any);\n }\n\n return events;\n }\n\n /**\n * Complete any active message\n * Call this when streaming ends to ensure TEXT_MESSAGE_END is emitted\n */\n public completeActiveMessage(): BaseEvent[] {\n if (this.activeMessageId) {\n const event: TextMessageEndEvent = {\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n };\n\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return [event];\n }\n return [];\n }\n\n /**\n * Reset transformer state\n * Call this between runs to ensure clean state\n */\n public reset(): void {\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n\n /**\n * Generate unique message ID\n */\n private generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Generate unique tool call ID\n */\n private generateToolCallId(): string {\n return `tool_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Detect interrupt marker in tool result\n * \n * Checks if a tool result contains the __interrupt__ marker used for\n * human-in-the-loop workflows. Returns interrupt details if found.\n * \n * @param resultContent - Tool result content string\n * @returns Interrupt object if found, undefined otherwise\n */\n public detectInterrupt(resultContent: string):\n | { id: string; reason: string; payload: any }\n | undefined {\n try {\n const parsed = JSON.parse(resultContent);\n if (parsed.__interrupt__ === true) {\n return {\n // 🔑 Generate unique ID for this interrupt\n id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n reason: parsed.reason || \"Agent requested interrupt\",\n // 🔑 Payload contains the full interrupt data (including type, steps, etc.)\n payload: parsed,\n };\n }\n } catch (error) {\n // Not JSON or doesn't contain interrupt marker\n }\n return undefined;\n }\n\n /**\n * Remove MCP namespace prefix from tool name\n * \n * Claude Agent SDK adds MCP server namespace to tool names:\n * \"mcp__server-name__tool-name\" -> \"tool-name\"\n * \n * This ensures tool names match what the frontend expects and maintains\n * consistency with other AG-Kit agent implementations (LangChain, LangGraph).\n * \n * @param toolName - Tool name potentially with MCP prefix\n * @returns Clean tool name without prefix\n * \n * @example\n * removeMcpPrefix(\"mcp__agkit__change-background-color\") // \"change-background-color\"\n * removeMcpPrefix(\"change-background-color\") // \"change-background-color\"\n */\n private removeMcpPrefix(toolName: string): string {\n // Match pattern: mcp__<server-name>__<tool-name>\n const mcpPattern = /^mcp__[^_]+__(.+)$/;\n const match = toolName.match(mcpPattern);\n\n if (match) {\n const cleanName = match[1];\n console.log(`[EventTransformer] Removed MCP prefix: ${toolName} -> ${cleanName}`);\n return cleanName;\n }\n\n // No MCP prefix found, return original name\n return toolName;\n }\n\n /**\n * Check if tool result content contains client-side tool marker\n * \n * Client-side tools return a special marker indicating they need to be\n * executed on the frontend. We detect this marker to avoid sending\n * tool-result events prematurely.\n * \n * @param resultContent - Tool result content string\n * @returns true if this is a client-side tool marker\n */\n private isClientToolMarker(resultContent: string): boolean {\n try {\n const parsed = JSON.parse(resultContent);\n // 🔑 Check for __client_tool__ marker\n return parsed.__client_tool__ === true;\n } catch (error) {\n // Not JSON or doesn't contain marker\n return false;\n }\n }\n}\n\n","/**\n * Hooks manager for Claude Agent SDK\n * Creates hooks for monitoring and controlling Claude agent behavior\n * @module claude-sdk/hooks-manager\n */\n\nimport type { Subscriber } from \"rxjs\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { HookCallback } from \"./types\";\n\n/**\n * Manages Claude Agent SDK hooks for AG-UI event emission\n * \n * Hooks allow us to intercept Claude's behavior and emit corresponding AG-UI events.\n * This bridges Claude's lifecycle events to AG-Kit's event system.\n */\nexport class HooksManager {\n /**\n * Create hooks configuration for Claude Agent SDK\n * \n * @param subscriber - RxJS subscriber to emit AG-UI events\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Hooks configuration object\n */\n public createHooks(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): Record<string, HookCallback> {\n return {\n // Pre-tool use hook - called before tool execution\n preToolUse: this.createPreToolUseHook(subscriber),\n\n // Post-tool use hook - called after tool execution\n postToolUse: this.createPostToolUseHook(subscriber),\n\n // Session lifecycle hooks\n sessionStart: this.createSessionStartHook(subscriber, threadId, runId),\n sessionEnd: this.createSessionEndHook(subscriber, threadId, runId),\n\n // Notification hook - for system notifications\n notification: this.createNotificationHook(subscriber),\n\n // User prompt submit hook - when user submits input\n userPromptSubmit: this.createUserPromptSubmitHook(subscriber),\n };\n }\n\n /**\n * Create pre-tool use hook\n * Used for logging and permission checks before tool execution\n * \n * NOTE: We do NOT emit TOOL_CALL_START here to avoid duplicate events.\n * The EventTransformer will emit all tool call events when processing SDKAssistantMessage.\n */\n private createPreToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Log tool use for debugging/monitoring\n // The actual TOOL_CALL_START event will be emitted by EventTransformer\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Pre-tool use: ${input.toolName} (${input.toolUseId})`);\n }\n\n // Return continue signal to allow tool execution\n return { continue: true };\n };\n }\n\n /**\n * Create post-tool use hook\n * Called after tool execution completes\n */\n private createPostToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Tool result will be emitted via SDKResultMessage\n // This hook can be used for logging or side effects\n\n // Log tool execution completion\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Tool executed: ${input.toolName} (${input.toolUseId})`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create session start hook\n * Called when agent session begins\n */\n private createSessionStartHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session started - RUN_STARTED already emitted in main run method\n // This hook can be used for additional initialization\n\n console.log(`[HooksManager] Session started: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create session end hook\n * Called when agent session ends\n */\n private createSessionEndHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session ended - RUN_FINISHED will be emitted after query completes\n // This hook can be used for cleanup\n\n console.log(`[HooksManager] Session ended: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create notification hook\n * Handles system notifications from Claude\n */\n private createNotificationHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Emit notification as console log\n // Could be extended to emit custom AG-UI notification events\n\n if (input.message) {\n console.log(`[Claude Notification] ${input.message}`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create user prompt submit hook\n * Called when user submits a prompt\n */\n private createUserPromptSubmitHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // User prompt submitted\n // This is mainly for logging as the input is already processed\n\n if (input.prompt) {\n console.log(`[HooksManager] User prompt submitted: ${input.prompt}`);\n }\n\n return { continue: true };\n };\n }\n}\n\n"],"mappings":"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","names":["import_client","import_claude_agent_sdk","tool","tool"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/message-converter.ts","../src/tool-bridge.ts","../src/event-transformer.ts","../src/hooks-manager.ts"],"sourcesContent":["/**\n * Claude Agent SDK integration for AG-Kit\n * \n * This module provides integration between Anthropic's Claude Agent SDK\n * and AG-Kit's unified agent interface.\n * \n * @example\n * ```typescript\n * import { ClaudeAgent } from \"@cloudbase/agent-agents/claude-agent\";\n * \n * const agent = new ClaudeAgent({\n * name: \"my-claude-agent\",\n * model: \"claude-3-5-sonnet-20241022\",\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * enableBuiltInTools: true,\n * });\n * ```\n * \n * @module claude-agent\n */\n\n// Core agent class\nexport { ClaudeAgent } from \"./agent\";\n\n// Type definitions\nexport type { ClaudeAgentSDKConfig } from \"./types\";\n\n// Utility modules (for advanced usage)\nexport { MessageConverter } from \"./message-converter\";\nexport { ToolBridge } from \"./tool-bridge\";\nexport { EventTransformer } from \"./event-transformer\";\nexport { HooksManager } from \"./hooks-manager\";\n\n// Re-export useful Claude SDK types\nexport type {\n ClaudeSDKOptions,\n SDKMessage,\n SDKAssistantMessage,\n SDKUserMessage,\n SDKResultMessage,\n SDKPartialAssistantMessage,\n Query,\n} from \"./types\";\n\n","/**\n * Claude Agent SDK integration for AG-Kit\n * Main agent class that bridges Claude Agent SDK with AG-Kit\n * @module claude-sdk/agent\n */\n\nimport type {\n RunAgentInput,\n BaseEvent,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport { AbstractAgent } from \"@cloudbase/agent-agents/abstract\";\nimport { query } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { Query, SDKMessage, SDKSystemMessage, SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Observable, Subscriber } from \"rxjs\";\n\nimport type { ClaudeAgentSDKConfig, ClaudeSDKOptions } from \"./types\";\nimport { MessageConverter } from \"./message-converter\";\nimport { ToolBridge } from \"./tool-bridge\";\nimport { EventTransformer } from \"./event-transformer\";\nimport { HooksManager } from \"./hooks-manager\";\n\n/**\n * Claude Agent SDK adapter for AG-Kit\n * \n * Integrates Anthropic's Claude Agent SDK with AG-Kit's unified agent interface.\n * Provides seamless integration with AG-UI components while leveraging Claude's\n * built-in tools, MCP support, hooks system, and permission management.\n * \n * @example\n * ```typescript\n * const agent = new ClaudeAgentSDK({\n * name: \"my-claude-agent\",\n * model: \"\",\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * enableBuiltInTools: true,\n * permissionMode: \"ask\",\n * });\n * ```\n */\nexport class ClaudeAgent extends AbstractAgent {\n private config: ClaudeAgentSDKConfig;\n private mcpServers: any[] = [];\n private messageConverter: MessageConverter;\n private toolBridge: ToolBridge;\n private hooksManager: HooksManager;\n\n // 🔑 Session management for HITL\n // Use static storage to persist across agent instance recreations\n public static sessionStore: Map<string, string> = new Map(); // threadId → session_id\n private currentQuery?: Query;\n\n // 🔑 Event emitter for tool intermediate messages\n // Allows MCP tools to emit events during execution\n private currentSubscriber?: Subscriber<BaseEvent>;\n\n constructor(config: ClaudeAgentSDKConfig) {\n super(config);\n console.log('ClaudeAgent constructor called');\n this.config = config;\n\n // Initialize utility modules\n this.messageConverter = new MessageConverter();\n this.toolBridge = new ToolBridge();\n this.hooksManager = new HooksManager();\n\n // Note: Tools are provided at runtime via RunAgentInput, not in config\n // MCP servers from tools will be created dynamically during run()\n }\n\n /**\n * Run the Claude agent with given input\n * \n * @param input - AG-UI RunAgentInput\n * @returns Observable stream of AG-UI BaseEvents\n */\n public run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n // 🔑 Check if this is a resume request\n if (input.forwardedProps?.resume) {\n this._resume(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('resume error', error);\n });\n } else {\n this._run(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('run error', error);\n });\n }\n });\n }\n\n /**\n * Internal run implementation\n * Handles the full agent execution lifecycle\n */\n private async _run(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { messages, runId, threadId, tools: inputTools } = input;\n\n // 🔑 Store subscriber for tool intermediate events\n this.currentSubscriber = subscriber;\n // console.log('_run********* subscriber', this.currentSubscriber)\n\n // Emit RUN_STARTED event\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n try {\n // Convert AG-UI messages to Claude prompt\n const prompt = this.messageConverter.convertToPrompt(messages);\n\n // Prepare MCP servers\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Convert runtime tools to MCP server if provided\n // inputTools are AG-UI tools with JSON Schema: { name, description, parameters }\n if (inputTools && inputTools.length > 0) {\n // Prepare tools for conversion\n const toolsForMcp = inputTools.map(tool => ({\n name: tool.name,\n description: tool.description,\n parameters: typeof tool.parameters === 'string'\n ? JSON.parse(tool.parameters)\n : tool.parameters,\n }));\n\n // Create MCP server from AG-UI tools (JSON Schema)\n // Use short server name to avoid long MCP prefixes in tool names\n // MCP will prefix tools as: mcp__agkit__<tool-name>\n const runtimeServer = this.toolBridge.createMcpServerFromJsonSchema(\n \"agkit\",\n toolsForMcp\n );\n\n // Add to MCP servers dict\n mcpServers[\"agkit\"] = runtimeServer;\n }\n\n // Ensure API key is set in environment\n // Claude Agent SDK reads from ANTHROPIC_API_KEY environment variable\n if (this.config.apiKey && !process.env.ANTHROPIC_API_KEY) {\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n }\n console.log('[ClaudeAgent] includePartialMessages:', this.config.includePartialMessages);\n // console.log('[ClaudeAgent] claudeOptions:', this.config.claudeOptions);\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n additionalDirectories: this.config.additionalDirectories,\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n includePartialMessages: this.config.includePartialMessages !== false, // Default true for streaming\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n ...this.config.claudeOptions,\n };\n\n // 🔑 Check if there's a saved session ID for this thread (for session continuity)\n const savedSessionId = ClaudeAgent.sessionStore.get(threadId);\n if (savedSessionId) {\n console.log(`[ClaudeAgent] Resuming session: ${savedSessionId} for thread: ${threadId}`);\n options.resume = savedSessionId;\n }\n\n // Create Claude Agent SDK query\n const agentQuery = query({\n prompt,\n options,\n });\n\n // console.log('options', JSON.stringify(options, null, 2));\n\n // Store query reference for potential interrupt\n this.currentQuery = agentQuery;\n\n // Create event transformer\n // Pass streaming flag to avoid duplicate text messages\n const streamingEnabled = options.includePartialMessages === true;\n console.log('[ClaudeAgent] Streaming enabled:', streamingEnabled);\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Process SDKMessages\n for await (const sdkMessage of agentQuery) {\n console.log(\"sdkMessage\", JSON.stringify(sdkMessage, null, 2));\n console.log('[ClaudeAgent] SDKMessage type:', sdkMessage.type);\n\n // 🔑 Capture session ID from init message\n if (sdkMessage.type === 'system') {\n const systemMsg = sdkMessage as SDKSystemMessage;\n if (systemMsg.subtype === 'init' && systemMsg.session_id) {\n console.log(`[ClaudeAgent] Captured session ID: ${systemMsg.session_id} for thread: ${threadId}`);\n ClaudeAgent.sessionStore.set(threadId, systemMsg.session_id);\n }\n }\n\n // Transform SDKMessage to AG-UI events FIRST\n // This ensures TOOL_CALL_RESULT is sent before interrupt detection\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n\n // Emit all events\n for (const event of events) {\n subscriber.next(event);\n }\n\n // 🔑 Detect interrupt from tool results AFTER emitting events\n const interruptDetected = this.detectInterrupt(sdkMessage);\n if (interruptDetected) {\n console.log(\"[ClaudeAgent] Interrupt detected:\", interruptDetected);\n\n // Emit RUN_FINISHED with interrupt\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n outcome: \"interrupt\",\n interrupt: interruptDetected,\n } as RunFinishedEvent);\n\n // 🔑 Complete the observable - no need to wait for resume\n // The next request will be a separate HTTP call with forwardedProps.resume\n subscriber.complete();\n return;\n }\n }\n\n // Complete any active message\n console.log('[ClaudeAgent] Calling completeActiveMessage...');\n const finalEvents = eventTransformer.completeActiveMessage();\n // console.log('[ClaudeAgent] Final events:', finalEvents.map(e => e.type));\n\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n // Note: Usage statistics are included in SDKResultMessage\n // which is already processed by EventTransformer\n\n // Emit RUN_FINISHED event\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n } catch (error) {\n // Emit RUN_ERROR event\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // 🔑 Clear subscriber reference\n // this.currentSubscriber = undefined;\n // console.log('run finally ********* subscriber', this.currentSubscriber)\n }\n }\n\n /**\n * Get event emitter for MCP tools\n * Allows tools to emit intermediate events during execution\n * \n * @returns Event emitter function or undefined if no active run\n */\n public getEventEmitter(): ((event: BaseEvent) => void) | undefined {\n if (this.currentSubscriber) {\n return (event: BaseEvent) => {\n this.currentSubscriber!.next(event);\n };\n }\n return undefined;\n }\n\n /**\n * 🔑 Detect interrupt from SDKMessage\n * Checks if tool result contains __interrupt__ marker\n */\n private detectInterrupt(sdkMessage: SDKMessage): {\n id: string;\n reason: string;\n payload: any;\n } | null {\n // 🔑 Check user message for tool_result with __interrupt__\n if (sdkMessage.type === \"user\") {\n const message = (sdkMessage as any).message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return null;\n }\n\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // Try to parse as JSON and check for __interrupt__\n try {\n const parsed = JSON.parse(resultContent);\n console.log('[ClaudeAgent] Parsed interrupt data:', parsed);\n const { interruptId } = parsed\n if (parsed.__interrupt__ === true) {\n return {\n id: interruptId,\n reason: parsed.reason || \"Agent requested interrupt\",\n // 🔑 Payload contains the full interrupt data (including type, steps, etc.)\n payload: parsed,\n };\n }\n } catch {\n // Not JSON or doesn't contain interrupt marker\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * 🔑 Resume execution after interrupt\n * Uses saved session ID to continue conversation\n */\n private async _resume(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { runId, threadId } = input;\n const resumePayload = input.forwardedProps?.resume?.payload;\n\n this.currentSubscriber = subscriber;\n // console.log('_resume ********* subscriber', this.currentSubscriber)\n\n console.log('[ClaudeAgent] Resuming with payload:', resumePayload);\n\n try {\n // 🔑 Get saved session ID from static storage\n const sessionId = ClaudeAgent.sessionStore.get(threadId);\n if (!sessionId) {\n throw new Error(`No session ID found for thread: ${threadId}. Make sure the initial request completed successfully.`);\n }\n\n console.log(`[ClaudeAgent] Resuming session: ${sessionId}`);\n\n // 🔑 Build resume prompt from user's modified data\n const resumePrompt = this.buildResumePrompt(resumePayload);\n\n // Prepare MCP servers (same as initial run)\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n includePartialMessages: this.config.includePartialMessages !== false,\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n // 🔑 Use session ID to resume (SDK auto-loads history)\n resume: sessionId,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n ...this.config.claudeOptions,\n };\n\n // Create new query (SDK will restore full context)\n const agentQuery = query({\n prompt: resumePrompt,\n options,\n });\n\n this.currentQuery = agentQuery;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n const streamingEnabled = options.includePartialMessages === true;\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Continue processing messages\n for await (const sdkMessage of agentQuery) {\n // console.log(\"sdkMessage (resumed)\", JSON.stringify(sdkMessage, null, 2));\n\n // Transform SDKMessage to AG-UI events FIRST\n // This ensures TOOL_CALL_RESULT is sent before interrupt detection\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n for (const event of events) {\n subscriber.next(event);\n }\n\n // 🔑 Detect interrupt from tool results AFTER emitting events\n // Resume 场景下也可能触发新的中断(例如模型调用了另一个需要确认的工具)\n const interruptDetected = this.detectInterrupt(sdkMessage);\n if (interruptDetected) {\n console.log(\"[ClaudeAgent] Interrupt detected in resume:\", interruptDetected);\n\n // Emit RUN_FINISHED with interrupt\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n outcome: \"interrupt\",\n interrupt: interruptDetected,\n } as RunFinishedEvent);\n\n // 🔑 Complete the observable\n subscriber.complete();\n return;\n }\n }\n\n const finalEvents = eventTransformer.completeActiveMessage();\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n\n } catch (error) {\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: \"RESUME_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // this.currentSubscriber = undefined;\n // console.log('_resume finally ********* subscriber', this.currentSubscriber)\n\n }\n }\n\n /**\n * Build resume prompt from user's modified data\n */\n private buildResumePrompt(payload: any): string {\n // If payload contains steps, construct a descriptive prompt\n if (payload.steps) {\n const enabledSteps = payload.steps.filter((s: any) => s.status === 'enabled');\n const disabledSteps = payload.steps.filter((s: any) => s.status === 'disabled');\n\n let prompt = \"The user has reviewed the steps. \";\n\n if (disabledSteps.length > 0) {\n prompt += `They disabled the following steps: ${disabledSteps.map((s: any) => s.description).join(', ')}. `;\n }\n\n prompt += `Please continue with the enabled steps: ${enabledSteps.map((s: any) => s.description).join(', ')}. `;\n prompt += \"Provide a creative but short description (3 sentences max) of how you will perform the task.\";\n\n return prompt;\n }\n\n // Default: use payload as JSON\n return JSON.stringify(payload);\n }\n\n /**\n * Clear session for a thread\n */\n public clearSession(threadId: string): void {\n ClaudeAgent.sessionStore.delete(threadId);\n console.log(`[ClaudeAgent] Cleared session for thread: ${threadId}`);\n }\n\n /**\n * 🔑 Get all active sessions (for debugging)\n */\n public static getActiveSessions(): Map<string, string> {\n return ClaudeAgent.sessionStore;\n }\n\n /**\n * Get the configured model name\n */\n public getModel(): string {\n return this.config.model || \"\";\n }\n\n /**\n * Get the configured API key (masked for security)\n */\n public getApiKey(): string {\n const key = this.config.apiKey || process.env.ANTHROPIC_API_KEY || \"\";\n return key ? `${key.substring(0, 8)}...` : \"not configured\";\n }\n\n /**\n * Get MCP servers count\n */\n public getMcpServersCount(): number {\n return this.mcpServers.length;\n }\n\n /**\n * Check if built-in tools are enabled\n */\n public isBuiltInToolsEnabled(): boolean {\n return this.config.enableBuiltInTools !== false; // Default true\n }\n}\n\n","/**\n * Message format converter for Claude Agent SDK\n * Converts AG-UI messages to Claude Agent SDK prompt format\n * @module claude-sdk/message-converter\n */\n\nimport type { Message as AGUIMessage } from \"@ag-ui/client\";\n\n/**\n * Converts AG-UI messages to Claude Agent SDK prompt format\n *\n * Claude Agent SDK uses a simple prompt string or streaming messages.\n * This converter formats AG-UI message history into a structured prompt.\n */\nexport class MessageConverter {\n /**\n * Convert AG-UI messages to a structured prompt string\n *\n * Formats conversation history with role markers for clarity.\n * Claude Agent SDK will parse this and maintain context.\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted prompt string\n *\n * @example\n * ```typescript\n * const converter = new MessageConverter();\n * const prompt = converter.convertToPrompt([\n * { role: \"system\", content: \"You are a helpful assistant\" },\n * { role: \"user\", content: \"Hello!\" },\n * ]);\n * // Returns: \"[System]\\nYou are a helpful assistant\\n\\n[User]\\nHello!\\n\"\n * ```\n */\n public convertToPrompt(aguiMessages: AGUIMessage[]): string {\n const lines: string[] = [];\n\n for (const msg of aguiMessages) {\n switch (msg.role) {\n case \"system\":\n // System messages provide context\n if (msg.content) {\n lines.push(`[System]\\n${msg.content}\\n`);\n }\n break;\n\n case \"user\":\n // User messages are the main input\n if (msg.content) {\n lines.push(`${msg.content}\\n`);\n }\n break;\n\n case \"assistant\":\n // Assistant messages show previous responses\n if (msg.content) {\n lines.push(`[Assistant]\\n${msg.content}\\n`);\n }\n // Tool calls are handled automatically by Claude via MCP\n // We don't need to explicitly format them in the prompt\n break;\n\n case \"tool\":\n // Tool results provide context for Claude\n // Format them clearly so Claude understands the tool output\n if (msg.toolCallId && msg.content) {\n lines.push(`[Tool Result: ${msg.toolCallId}]\\n${msg.content}\\n`);\n }\n break;\n\n default:\n // Skip unknown message types\n console.warn(\n `[MessageConverter] Unknown message role: ${(msg as any).role}`\n );\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Extract system messages and combine them\n * Useful for setting up Claude's context\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Combined system message content\n */\n public extractSystemMessages(aguiMessages: AGUIMessage[]): string {\n const systemMessages = aguiMessages\n .filter((msg) => msg.role === \"system\" && msg.content)\n .map((msg) => msg.content);\n\n return systemMessages.join(\"\\n\\n\");\n }\n\n /**\n * Get conversation history excluding the latest user message\n * Useful for providing context without duplicating current input\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted conversation history\n */\n public getConversationHistory(aguiMessages: AGUIMessage[]): string {\n // Remove the last user message (current input)\n const historyMessages = [...aguiMessages];\n for (let i = historyMessages.length - 1; i >= 0; i--) {\n if (historyMessages[i].role === \"user\") {\n historyMessages.splice(i, 1);\n break;\n }\n }\n\n return this.convertToPrompt(historyMessages);\n }\n}\n","/**\n * Tool bridge for converting AG-Kit tools to MCP servers\n * Handles Zod schema extraction and MCP server creation\n * @module claude-sdk/tool-bridge\n */\n\nimport type { BaseTool } from \"@cloudbase/agent-tools\";\nimport { createSdkMcpServer, tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod/v3\";\n\n/**\n * Bridges AG-Kit tools to Claude Agent SDK via MCP servers\n * \n * Supports both BaseTool (Zod schema) and AG-UI tools (JSON Schema)\n * and creates MCP tools that Claude SDK can use directly.\n */\nexport class ToolBridge {\n /**\n * Create an MCP server from AG-Kit BaseTool instances\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-Kit BaseTool instances\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n */\n public createMcpServer(name: string, tools: BaseTool[], isClientTools: boolean = false): any {\n const mcpTools = tools.map(agkitTool => this.convertToMcpTool(agkitTool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Create an MCP server from AG-UI tool definitions (JSON Schema format)\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-UI tool definitions with JSON Schema\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n * \n * @example\n * ```typescript\n * const bridge = new ToolBridge();\n * const server = bridge.createMcpServerFromJsonSchema(\"my-tools\", [\n * {\n * name: \"get_weather\",\n * description: \"Get weather\",\n * parameters: { type: \"object\", properties: { location: { type: \"string\" } } }\n * }\n * ], true); // true = client-side tools\n * ```\n */\n public createMcpServerFromJsonSchema(\n name: string,\n tools: Array<{ name: string; description: string; parameters: any }>,\n isClientTools: boolean = true // 🔑 Default true: inputTools are usually client tools\n ): any {\n const mcpTools = tools.map(tool => this.convertJsonSchemaToolToMcp(tool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Convert a single AG-Kit BaseTool to MCP tool definition\n * \n * @param agkitTool - AG-Kit BaseTool instance\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertToMcpTool(agkitTool: BaseTool, isClientTool: boolean = false): any {\n const metadata = agkitTool.getMetadata();\n const toolName = metadata.name || \"unnamed_tool\";\n const toolDescription = metadata.description || `AG-Kit tool: ${toolName}`;\n\n // Extract Zod schema shape from BaseTool\n let zodShape: any = {};\n\n if (metadata.schema) {\n const schema = metadata.schema as any;\n if (schema._def && typeof schema._def.shape === 'function') {\n zodShape = schema._def.shape();\n } else if (schema._def && schema._def.shape) {\n zodShape = schema._def.shape;\n } else {\n console.warn(`[ToolBridge] Tool \"${toolName}\" schema is not a ZodObject, using empty shape`);\n }\n }\n\n return this.createMcpTool(toolName, toolDescription, zodShape, isClientTool);\n }\n\n /**\n * Convert a JSON Schema tool to MCP tool definition\n * \n * @param toolDef - Tool definition with JSON Schema parameters\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertJsonSchemaToolToMcp(\n toolDef: {\n name: string;\n description: string;\n parameters: any;\n },\n isClientTool: boolean = false\n ): any {\n // Convert JSON Schema to Zod shape\n const zodShape = this.jsonSchemaToZodShape(toolDef.parameters);\n\n return this.createMcpTool(\n toolDef.name,\n toolDef.description || `Tool: ${toolDef.name}`,\n zodShape,\n isClientTool\n );\n }\n\n /**\n * Create an MCP tool with common logic\n * \n * @param name - Tool name\n * @param description - Tool description\n * @param zodShape - Zod schema for parameters\n * @param isClientTool - Whether this is a client-side tool\n */\n private createMcpTool(\n name: string,\n description: string,\n zodShape: any,\n isClientTool: boolean = false\n ): any {\n return tool(\n name,\n description,\n zodShape,\n async (args: any, extra: unknown) => {\n console.log(`[ToolBridge] Tool called: ${name}, isClientTool: ${isClientTool}`, { args });\n\n if (isClientTool) {\n // 🔑 Client-side tool: Return special marker for frontend execution\n // The EventTransformer will detect this and NOT send tool-result event\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n __client_tool__: true, // ← Special marker\n tool: name,\n args,\n message: \"Waiting for client-side execution\",\n }),\n },\n ],\n isError: false,\n };\n }\n\n // Server-side tool: Should have custom implementation\n // This is a fallback that should not be reached\n console.warn(`[ToolBridge] Server-side tool \"${name}\" called but no implementation provided`);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n tool: name,\n args,\n message: \"Tool executed on backend (placeholder)\",\n }),\n },\n ],\n isError: false,\n };\n }\n );\n }\n\n /**\n * Convert JSON Schema to Zod shape (ZodRawShape)\n * \n * @param jsonSchema - JSON Schema object\n * @returns Zod shape object\n */\n private jsonSchemaToZodShape(jsonSchema: any): any {\n if (!jsonSchema || typeof jsonSchema !== \"object\") {\n return {};\n }\n\n const zodShape: any = {};\n\n // Handle object schema with properties\n if (jsonSchema.type === \"object\" && jsonSchema.properties) {\n const required = Array.isArray(jsonSchema.required) ? jsonSchema.required : [];\n\n for (const [key, propSchema] of Object.entries(jsonSchema.properties)) {\n const isRequired = required.includes(key);\n zodShape[key] = this.jsonSchemaPropertyToZod(propSchema as any, isRequired);\n }\n }\n\n return zodShape;\n }\n\n /**\n * Convert a single JSON Schema property to Zod type\n */\n private jsonSchemaPropertyToZod(schema: any, isRequired: boolean): any {\n if (!schema || typeof schema !== \"object\") {\n return isRequired ? z.any() : z.any().optional();\n }\n\n let zodType: any;\n\n switch (schema.type) {\n case \"string\":\n zodType = z.string();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (Array.isArray(schema.enum)) {\n zodType = z.enum(schema.enum as [string, ...string[]]);\n }\n break;\n\n case \"number\":\n case \"integer\":\n zodType = schema.type === \"integer\" ? z.number().int() : z.number();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (schema.minimum !== undefined) zodType = zodType.min(schema.minimum);\n if (schema.maximum !== undefined) zodType = zodType.max(schema.maximum);\n break;\n\n case \"boolean\":\n zodType = z.boolean();\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"array\":\n if (schema.items) {\n const itemType = this.jsonSchemaPropertyToZod(schema.items, true);\n zodType = z.array(itemType);\n } else {\n zodType = z.array(z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"object\":\n if (schema.properties) {\n const nestedShape = this.jsonSchemaToZodShape(schema);\n zodType = z.object(nestedShape);\n } else {\n zodType = z.record(z.string(), z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n default:\n zodType = z.any();\n if (schema.description) zodType = zodType.describe(schema.description);\n }\n\n return isRequired ? zodType : zodType.optional();\n }\n\n}\n\n","/**\n * Event transformer for Claude Agent SDK\n * Converts SDKMessage to AG-UI BaseEvent\n * @module claude-sdk/event-transformer\n */\n\nimport type {\n BaseEvent,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type {\n SDKMessage,\n SDKAssistantMessage,\n SDKPartialAssistantMessage,\n SDKResultMessage,\n SDKPermissionDenial,\n} from \"./types\";\n\n/**\n * Transforms Claude Agent SDK messages to AG-UI events\n * \n * Handles streaming messages, tool calls, and error states.\n */\nexport class EventTransformer {\n private activeMessageId?: string;\n private messageContent: string = \"\";\n private streamingEnabled: boolean;\n\n /**\n * @param streamingEnabled - Whether streaming mode is enabled (includePartialMessages)\n * When true, assistant messages will skip text content to avoid duplicates\n */\n constructor(streamingEnabled: boolean = false) {\n this.streamingEnabled = streamingEnabled;\n }\n\n /**\n * Transform a single SDKMessage to AG-UI BaseEvent(s)\n * \n * One SDKMessage may produce multiple AG-UI events.\n * For example, an assistant message with tool calls produces:\n * - TEXT_MESSAGE_START\n * - TEXT_MESSAGE_CONTENT\n * - TOOL_CALL_START (for each tool)\n * - TOOL_CALL_ARGS (for each tool)\n * - TOOL_CALL_END (for each tool)\n * - TEXT_MESSAGE_END\n * \n * @param sdkMessage - Claude SDK message\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Array of AG-UI events\n */\n public transformMessage(\n sdkMessage: SDKMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n switch (sdkMessage.type) {\n case \"assistant\":\n events.push(...this.handleAssistantMessage(sdkMessage as SDKAssistantMessage, threadId, runId));\n break;\n\n case \"stream_event\":\n events.push(...this.handlePartialAssistantMessage(sdkMessage as SDKPartialAssistantMessage, threadId, runId));\n break;\n\n case \"result\":\n events.push(...this.handleResultMessage(sdkMessage as SDKResultMessage, threadId, runId));\n break;\n\n case \"user\":\n // Handle tool_result messages from user\n events.push(...this.handleUserMessage(sdkMessage as any, threadId, runId));\n break;\n\n case \"system\":\n // System messages are input/context, don't emit events\n break;\n\n case \"tool_progress\":\n case \"auth_status\":\n // Progress and status messages, can be ignored for now\n break;\n\n default:\n console.warn(`[EventTransformer] Unknown SDKMessage type: ${(sdkMessage as any).type}`);\n }\n\n // console.log(\"events\", JSON.stringify(events, null, 2));\n return events;\n }\n\n /**\n * Handle complete assistant message\n * Emits full message with any tool calls\n * \n * When streaming is enabled (includePartialMessages: true), this method will:\n * - Skip text content (already sent via stream_event messages) \n * - Only process tool_use content (tools are not streamed)\n */\n private handleAssistantMessage(\n sdkMessage: SDKAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message; // Extract the actual API message\n\n // 🔑 When streaming is enabled, skip text content to avoid duplicates\n // Text content is already sent via stream_event messages\n if (this.streamingEnabled) {\n console.log('[EventTransformer] ⚠️ Streaming enabled: skipping assistant message text content to avoid duplicates');\n\n // Only process tool calls (they're not streamed)\n for (const content of message.content) {\n if (content.type === \"tool_use\") {\n // Process tool calls normally\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n return events;\n }\n\n // Non-streaming mode: process everything normally\n // console.log('[EventTransformer] Non-streaming mode: processing full assistant message');\n\n // If there's an active message, end it first\n if (this.activeMessageId) {\n console.log('[EventTransformer] Ending previous message:', this.activeMessageId);\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n }\n\n // Start new message\n this.activeMessageId = this.generateMessageId();\n this.messageContent = \"\";\n console.log('[EventTransformer] Starting new message:', this.activeMessageId);\n\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n\n // Add text content if present\n for (const content of message.content) {\n console.log(\"content\", JSON.stringify(content, null, 2));\n if (content.type === \"text\") {\n this.messageContent += content.text;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: content.text,\n } as TextMessageContentEvent);\n } else if (content.type === \"tool_use\") {\n // Remove MCP prefix for cleaner tool names\n // Claude Agent SDK adds MCP namespace: \"mcp__server-name__tool-name\"\n // We want frontend to see: \"tool-name\"\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n // TOOL_CALL_START\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n // TOOL_CALL_ARGS\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n // TOOL_CALL_END\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n // End message and clear active message ID\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n\n // Clear activeMessageId since message is complete\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return events;\n }\n\n /**\n * Handle streaming partial assistant message\n * Emits incremental content deltas\n */\n private handlePartialAssistantMessage(\n sdkMessage: SDKPartialAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const streamEvent = sdkMessage.event; // Extract the actual stream event\n\n // Handle different stream event types\n if (streamEvent.type === \"message_start\") {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n } else if (streamEvent.type === \"content_block_delta\") {\n // If no active message, start one (edge case)\n if (!this.activeMessageId) {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n }\n\n // Handle text delta\n if (streamEvent.delta.type === \"text_delta\") {\n const textDelta = streamEvent.delta.text;\n this.messageContent += textDelta;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: textDelta,\n } as TextMessageContentEvent);\n }\n } else if (streamEvent.type === \"message_delta\") {\n // Message end or stop reason\n if (streamEvent.delta.stop_reason) {\n // Can emit TEXT_MESSAGE_END here if needed\n if (this.activeMessageId) {\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n }\n }\n\n return events;\n }\n\n /**\n * Handle user message (mainly for tool_result)\n * Claude SDK sends tool results as user messages with tool_result content\n */\n private handleUserMessage(\n sdkMessage: any,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return events;\n }\n\n // Process tool_result content blocks\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n // content.content is an array of content blocks\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // 🔑 Check if this is a client-side tool marker\n const isClientTool = this.isClientToolMarker(resultContent);\n\n if (isClientTool) {\n console.log(`[EventTransformer] Client-side tool detected: ${content.tool_use_id}, skipping tool-result event`);\n // ⚠️ DO NOT emit TOOL_CALL_RESULT event for client tools\n // The client will execute the tool and send the result back\n continue;\n }\n\n // Emit TOOL_CALL_RESULT event for server-side tools\n events.push({\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: content.tool_use_id,\n content: resultContent,\n } as ToolCallResultEvent);\n\n console.log(`[EventTransformer] Tool result for ${content.tool_use_id}: ${resultContent}`);\n }\n }\n\n return events;\n }\n\n /**\n * Handle result message (final query result)\n * This represents the end of the query execution\n */\n private handleResultMessage(\n message: SDKResultMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n // SDKResultMessage represents the final result of the entire query\n // It doesn't directly map to TOOL_CALL_RESULT\n // Instead, we can emit it as metadata or ignore it\n\n // If there are permission denials, we can log them\n if (message.permission_denials && message.permission_denials.length > 0) {\n for (const denial of message.permission_denials) {\n console.warn(`[EventTransformer] Permission denied for tool: ${denial.tool_name}, tool_use_id: ${denial.tool_use_id}`);\n // Optionally emit as error events\n events.push({\n type: EventType.RUN_ERROR,\n message: `Permission denied for tool: ${denial.tool_name}`,\n rawEvent: denial,\n } as any);\n }\n }\n\n // Handle success or error result\n if (message.subtype === 'success') {\n console.log(`[EventTransformer] Query completed successfully: ${message.result}, turns: ${message.num_turns}, cost: $${message.total_cost_usd}`);\n } else {\n // Error subtypes: error_during_execution, error_max_turns, error_max_budget_usd\n const errorMsg = `Query failed: ${message.subtype}`;\n console.error(`[EventTransformer] ${errorMsg}, errors: ${message.errors?.join(', ')}`);\n events.push({\n type: EventType.RUN_ERROR,\n message: errorMsg,\n rawEvent: message,\n } as any);\n }\n\n return events;\n }\n\n /**\n * Complete any active message\n * Call this when streaming ends to ensure TEXT_MESSAGE_END is emitted\n */\n public completeActiveMessage(): BaseEvent[] {\n if (this.activeMessageId) {\n const event: TextMessageEndEvent = {\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n };\n\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return [event];\n }\n return [];\n }\n\n /**\n * Reset transformer state\n * Call this between runs to ensure clean state\n */\n public reset(): void {\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n\n /**\n * Generate unique message ID\n */\n private generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Generate unique tool call ID\n */\n private generateToolCallId(): string {\n return `tool_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Remove MCP namespace prefix from tool name\n * \n * Claude Agent SDK adds MCP server namespace to tool names:\n * \"mcp__server-name__tool-name\" -> \"tool-name\"\n * \n * This ensures tool names match what the frontend expects and maintains\n * consistency with other AG-Kit agent implementations (LangChain, LangGraph).\n * \n * @param toolName - Tool name potentially with MCP prefix\n * @returns Clean tool name without prefix\n * \n * @example\n * removeMcpPrefix(\"mcp__agkit__change-background-color\") // \"change-background-color\"\n * removeMcpPrefix(\"change-background-color\") // \"change-background-color\"\n */\n private removeMcpPrefix(toolName: string): string {\n // Match pattern: mcp__<server-name>__<tool-name>\n const mcpPattern = /^mcp__[^_]+__(.+)$/;\n const match = toolName.match(mcpPattern);\n\n if (match) {\n const cleanName = match[1];\n console.log(`[EventTransformer] Removed MCP prefix: ${toolName} -> ${cleanName}`);\n return cleanName;\n }\n\n // No MCP prefix found, return original name\n return toolName;\n }\n\n /**\n * Check if tool result content contains client-side tool marker\n * \n * Client-side tools return a special marker indicating they need to be\n * executed on the frontend. We detect this marker to avoid sending\n * tool-result events prematurely.\n * \n * @param resultContent - Tool result content string\n * @returns true if this is a client-side tool marker\n */\n private isClientToolMarker(resultContent: string): boolean {\n try {\n const parsed = JSON.parse(resultContent);\n // 🔑 Check for __client_tool__ marker\n return parsed.__client_tool__ === true;\n } catch (error) {\n // Not JSON or doesn't contain marker\n return false;\n }\n }\n}\n\n","/**\n * Hooks manager for Claude Agent SDK\n * Creates hooks for monitoring and controlling Claude agent behavior\n * @module claude-sdk/hooks-manager\n */\n\nimport type { Subscriber } from \"rxjs\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { HookCallback } from \"./types\";\n\n/**\n * Manages Claude Agent SDK hooks for AG-UI event emission\n * \n * Hooks allow us to intercept Claude's behavior and emit corresponding AG-UI events.\n * This bridges Claude's lifecycle events to AG-Kit's event system.\n */\nexport class HooksManager {\n /**\n * Create hooks configuration for Claude Agent SDK\n * \n * @param subscriber - RxJS subscriber to emit AG-UI events\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Hooks configuration object\n */\n public createHooks(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): Record<string, HookCallback> {\n return {\n // Pre-tool use hook - called before tool execution\n preToolUse: this.createPreToolUseHook(subscriber),\n\n // Post-tool use hook - called after tool execution\n postToolUse: this.createPostToolUseHook(subscriber),\n\n // Session lifecycle hooks\n sessionStart: this.createSessionStartHook(subscriber, threadId, runId),\n sessionEnd: this.createSessionEndHook(subscriber, threadId, runId),\n\n // Notification hook - for system notifications\n notification: this.createNotificationHook(subscriber),\n\n // User prompt submit hook - when user submits input\n userPromptSubmit: this.createUserPromptSubmitHook(subscriber),\n };\n }\n\n /**\n * Create pre-tool use hook\n * Used for logging and permission checks before tool execution\n * \n * NOTE: We do NOT emit TOOL_CALL_START here to avoid duplicate events.\n * The EventTransformer will emit all tool call events when processing SDKAssistantMessage.\n */\n private createPreToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Log tool use for debugging/monitoring\n // The actual TOOL_CALL_START event will be emitted by EventTransformer\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Pre-tool use: ${input.toolName} (${input.toolUseId})`);\n }\n\n // Return continue signal to allow tool execution\n return { continue: true };\n };\n }\n\n /**\n * Create post-tool use hook\n * Called after tool execution completes\n */\n private createPostToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Tool result will be emitted via SDKResultMessage\n // This hook can be used for logging or side effects\n\n // Log tool execution completion\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Tool executed: ${input.toolName} (${input.toolUseId})`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create session start hook\n * Called when agent session begins\n */\n private createSessionStartHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session started - RUN_STARTED already emitted in main run method\n // This hook can be used for additional initialization\n\n console.log(`[HooksManager] Session started: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create session end hook\n * Called when agent session ends\n */\n private createSessionEndHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session ended - RUN_FINISHED will be emitted after query completes\n // This hook can be used for cleanup\n\n console.log(`[HooksManager] Session ended: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create notification hook\n * Handles system notifications from Claude\n */\n private createNotificationHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Emit notification as console log\n // Could be extended to emit custom AG-UI notification events\n\n if (input.message) {\n console.log(`[Claude Notification] ${input.message}`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create user prompt submit hook\n * Called when user submits a prompt\n */\n private createUserPromptSubmitHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // User prompt submitted\n // This is mainly for logging as the input is already processed\n\n if (input.prompt) {\n console.log(`[HooksManager] User prompt submitted: ${input.prompt}`);\n }\n\n return { continue: true };\n };\n }\n}\n\n"],"mappings":"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","names":["import_client","import_claude_agent_sdk","tool","tool"]}
package/dist/index.mjs CHANGED
@@ -64,27 +64,6 @@ ${msg.content}
64
64
  }
65
65
  return lines.join("\n");
66
66
  }
67
- /**
68
- * Extract the latest user message from AG-UI messages
69
- * Useful when you only need the current user input
70
- *
71
- * @param aguiMessages - Array of AG-UI messages
72
- * @returns Latest user message content or empty string
73
- */
74
- extractLatestUserMessage(aguiMessages) {
75
- for (let i = aguiMessages.length - 1; i >= 0; i--) {
76
- const msg = aguiMessages[i];
77
- if (msg.role === "user" && msg.content) {
78
- if (typeof msg.content === "string") {
79
- return msg.content;
80
- } else {
81
- const content = msg.content.filter((m) => m.type === "text").map((m) => m.text).join("");
82
- if (content) return content;
83
- }
84
- }
85
- }
86
- return "";
87
- }
88
67
  /**
89
68
  * Extract system messages and combine them
90
69
  * Useful for setting up Claude's context
@@ -613,31 +592,6 @@ var EventTransformer = class {
613
592
  generateToolCallId() {
614
593
  return `tool_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
615
594
  }
616
- /**
617
- * Detect interrupt marker in tool result
618
- *
619
- * Checks if a tool result contains the __interrupt__ marker used for
620
- * human-in-the-loop workflows. Returns interrupt details if found.
621
- *
622
- * @param resultContent - Tool result content string
623
- * @returns Interrupt object if found, undefined otherwise
624
- */
625
- detectInterrupt(resultContent) {
626
- try {
627
- const parsed = JSON.parse(resultContent);
628
- if (parsed.__interrupt__ === true) {
629
- return {
630
- // 🔑 Generate unique ID for this interrupt
631
- id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
632
- reason: parsed.reason || "Agent requested interrupt",
633
- // 🔑 Payload contains the full interrupt data (including type, steps, etc.)
634
- payload: parsed
635
- };
636
- }
637
- } catch (error) {
638
- }
639
- return void 0;
640
- }
641
595
  /**
642
596
  * Remove MCP namespace prefix from tool name
643
597
  *
@@ -961,10 +915,11 @@ var _ClaudeAgent = class _ClaudeAgent extends AbstractAgent {
961
915
  }
962
916
  try {
963
917
  const parsed = JSON.parse(resultContent);
918
+ console.log("[ClaudeAgent] Parsed interrupt data:", parsed);
919
+ const { interruptId } = parsed;
964
920
  if (parsed.__interrupt__ === true) {
965
921
  return {
966
- // 🔑 Generate unique ID for this interrupt
967
- id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
922
+ id: interruptId,
968
923
  reason: parsed.reason || "Agent requested interrupt",
969
924
  // 🔑 Payload contains the full interrupt data (including type, steps, etc.)
970
925
  payload: parsed
@@ -1026,6 +981,19 @@ var _ClaudeAgent = class _ClaudeAgent extends AbstractAgent {
1026
981
  for (const event of events) {
1027
982
  subscriber.next(event);
1028
983
  }
984
+ const interruptDetected = this.detectInterrupt(sdkMessage);
985
+ if (interruptDetected) {
986
+ console.log("[ClaudeAgent] Interrupt detected in resume:", interruptDetected);
987
+ subscriber.next({
988
+ type: EventType2.RUN_FINISHED,
989
+ threadId,
990
+ runId,
991
+ outcome: "interrupt",
992
+ interrupt: interruptDetected
993
+ });
994
+ subscriber.complete();
995
+ return;
996
+ }
1029
997
  }
1030
998
  const finalEvents = eventTransformer.completeActiveMessage();
1031
999
  for (const event of finalEvents) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent.ts","../src/message-converter.ts","../src/tool-bridge.ts","../src/event-transformer.ts","../src/hooks-manager.ts"],"sourcesContent":["/**\n * Claude Agent SDK integration for AG-Kit\n * Main agent class that bridges Claude Agent SDK with AG-Kit\n * @module claude-sdk/agent\n */\n\nimport type {\n RunAgentInput,\n BaseEvent,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport { AbstractAgent } from \"@cloudbase/agent-agents/abstract\";\nimport { query } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { Query, SDKMessage, SDKSystemMessage, SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Observable, Subscriber } from \"rxjs\";\n\nimport type { ClaudeAgentSDKConfig, ClaudeSDKOptions } from \"./types\";\nimport { MessageConverter } from \"./message-converter\";\nimport { ToolBridge } from \"./tool-bridge\";\nimport { EventTransformer } from \"./event-transformer\";\nimport { HooksManager } from \"./hooks-manager\";\n\n/**\n * Claude Agent SDK adapter for AG-Kit\n * \n * Integrates Anthropic's Claude Agent SDK with AG-Kit's unified agent interface.\n * Provides seamless integration with AG-UI components while leveraging Claude's\n * built-in tools, MCP support, hooks system, and permission management.\n * \n * @example\n * ```typescript\n * const agent = new ClaudeAgentSDK({\n * name: \"my-claude-agent\",\n * model: \"\",\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * enableBuiltInTools: true,\n * permissionMode: \"ask\",\n * });\n * ```\n */\nexport class ClaudeAgent extends AbstractAgent {\n private config: ClaudeAgentSDKConfig;\n private mcpServers: any[] = [];\n private messageConverter: MessageConverter;\n private toolBridge: ToolBridge;\n private hooksManager: HooksManager;\n\n // 🔑 Session management for HITL\n // Use static storage to persist across agent instance recreations\n public static sessionStore: Map<string, string> = new Map(); // threadId → session_id\n private currentQuery?: Query;\n\n // 🔑 Event emitter for tool intermediate messages\n // Allows MCP tools to emit events during execution\n private currentSubscriber?: Subscriber<BaseEvent>;\n\n constructor(config: ClaudeAgentSDKConfig) {\n super(config);\n console.log('ClaudeAgent constructor called');\n this.config = config;\n\n // Initialize utility modules\n this.messageConverter = new MessageConverter();\n this.toolBridge = new ToolBridge();\n this.hooksManager = new HooksManager();\n\n // Note: Tools are provided at runtime via RunAgentInput, not in config\n // MCP servers from tools will be created dynamically during run()\n }\n\n /**\n * Run the Claude agent with given input\n * \n * @param input - AG-UI RunAgentInput\n * @returns Observable stream of AG-UI BaseEvents\n */\n public run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n // 🔑 Check if this is a resume request\n if (input.forwardedProps?.resume) {\n this._resume(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('resume error', error);\n });\n } else {\n this._run(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('run error', error);\n });\n }\n });\n }\n\n /**\n * Internal run implementation\n * Handles the full agent execution lifecycle\n */\n private async _run(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { messages, runId, threadId, tools: inputTools } = input;\n\n // 🔑 Store subscriber for tool intermediate events\n this.currentSubscriber = subscriber;\n // console.log('_run********* subscriber', this.currentSubscriber)\n\n // Emit RUN_STARTED event\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n try {\n // Convert AG-UI messages to Claude prompt\n const prompt = this.messageConverter.convertToPrompt(messages);\n\n // Prepare MCP servers\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Convert runtime tools to MCP server if provided\n // inputTools are AG-UI tools with JSON Schema: { name, description, parameters }\n if (inputTools && inputTools.length > 0) {\n // Prepare tools for conversion\n const toolsForMcp = inputTools.map(tool => ({\n name: tool.name,\n description: tool.description,\n parameters: typeof tool.parameters === 'string'\n ? JSON.parse(tool.parameters)\n : tool.parameters,\n }));\n\n // Create MCP server from AG-UI tools (JSON Schema)\n // Use short server name to avoid long MCP prefixes in tool names\n // MCP will prefix tools as: mcp__agkit__<tool-name>\n const runtimeServer = this.toolBridge.createMcpServerFromJsonSchema(\n \"agkit\",\n toolsForMcp\n );\n\n // Add to MCP servers dict\n mcpServers[\"agkit\"] = runtimeServer;\n }\n\n // Ensure API key is set in environment\n // Claude Agent SDK reads from ANTHROPIC_API_KEY environment variable\n if (this.config.apiKey && !process.env.ANTHROPIC_API_KEY) {\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n }\n console.log('[ClaudeAgent] includePartialMessages:', this.config.includePartialMessages);\n // console.log('[ClaudeAgent] claudeOptions:', this.config.claudeOptions);\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n additionalDirectories: this.config.additionalDirectories,\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n includePartialMessages: this.config.includePartialMessages !== false, // Default true for streaming\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n ...this.config.claudeOptions,\n };\n\n // 🔑 Check if there's a saved session ID for this thread (for session continuity)\n const savedSessionId = ClaudeAgent.sessionStore.get(threadId);\n if (savedSessionId) {\n console.log(`[ClaudeAgent] Resuming session: ${savedSessionId} for thread: ${threadId}`);\n options.resume = savedSessionId;\n }\n\n // Create Claude Agent SDK query\n const agentQuery = query({\n prompt,\n options,\n });\n\n // console.log('options', JSON.stringify(options, null, 2));\n\n // Store query reference for potential interrupt\n this.currentQuery = agentQuery;\n\n // Create event transformer\n // Pass streaming flag to avoid duplicate text messages\n const streamingEnabled = options.includePartialMessages === true;\n console.log('[ClaudeAgent] Streaming enabled:', streamingEnabled);\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Process SDKMessages\n for await (const sdkMessage of agentQuery) {\n console.log(\"sdkMessage\", JSON.stringify(sdkMessage, null, 2));\n console.log('[ClaudeAgent] SDKMessage type:', sdkMessage.type);\n\n // 🔑 Capture session ID from init message\n if (sdkMessage.type === 'system') {\n const systemMsg = sdkMessage as SDKSystemMessage;\n if (systemMsg.subtype === 'init' && systemMsg.session_id) {\n console.log(`[ClaudeAgent] Captured session ID: ${systemMsg.session_id} for thread: ${threadId}`);\n ClaudeAgent.sessionStore.set(threadId, systemMsg.session_id);\n }\n }\n\n // Transform SDKMessage to AG-UI events FIRST\n // This ensures TOOL_CALL_RESULT is sent before interrupt detection\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n\n // Emit all events\n for (const event of events) {\n subscriber.next(event);\n }\n\n // 🔑 Detect interrupt from tool results AFTER emitting events\n const interruptDetected = this.detectInterrupt(sdkMessage);\n if (interruptDetected) {\n console.log(\"[ClaudeAgent] Interrupt detected:\", interruptDetected);\n\n // Emit RUN_FINISHED with interrupt\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n outcome: \"interrupt\",\n interrupt: interruptDetected,\n } as RunFinishedEvent);\n\n // 🔑 Complete the observable - no need to wait for resume\n // The next request will be a separate HTTP call with forwardedProps.resume\n subscriber.complete();\n return;\n }\n }\n\n // Complete any active message\n console.log('[ClaudeAgent] Calling completeActiveMessage...');\n const finalEvents = eventTransformer.completeActiveMessage();\n // console.log('[ClaudeAgent] Final events:', finalEvents.map(e => e.type));\n\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n // Note: Usage statistics are included in SDKResultMessage\n // which is already processed by EventTransformer\n\n // Emit RUN_FINISHED event\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n } catch (error) {\n // Emit RUN_ERROR event\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // 🔑 Clear subscriber reference\n // this.currentSubscriber = undefined;\n // console.log('run finally ********* subscriber', this.currentSubscriber)\n }\n }\n\n /**\n * Get event emitter for MCP tools\n * Allows tools to emit intermediate events during execution\n * \n * @returns Event emitter function or undefined if no active run\n */\n public getEventEmitter(): ((event: BaseEvent) => void) | undefined {\n if (this.currentSubscriber) {\n return (event: BaseEvent) => {\n this.currentSubscriber!.next(event);\n };\n }\n return undefined;\n }\n\n /**\n * 🔑 Detect interrupt from SDKMessage\n * Checks if tool result contains __interrupt__ marker\n */\n private detectInterrupt(sdkMessage: SDKMessage): {\n id: string;\n reason: string;\n payload: any;\n } | null {\n // 🔑 Check user message for tool_result with __interrupt__\n if (sdkMessage.type === \"user\") {\n const message = (sdkMessage as any).message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return null;\n }\n\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // Try to parse as JSON and check for __interrupt__\n try {\n const parsed = JSON.parse(resultContent);\n if (parsed.__interrupt__ === true) {\n return {\n // 🔑 Generate unique ID for this interrupt\n id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n reason: parsed.reason || \"Agent requested interrupt\",\n // 🔑 Payload contains the full interrupt data (including type, steps, etc.)\n payload: parsed,\n };\n }\n } catch {\n // Not JSON or doesn't contain interrupt marker\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * 🔑 Resume execution after interrupt\n * Uses saved session ID to continue conversation\n */\n private async _resume(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { runId, threadId } = input;\n const resumePayload = input.forwardedProps?.resume?.payload;\n\n this.currentSubscriber = subscriber;\n // console.log('_resume ********* subscriber', this.currentSubscriber)\n\n console.log('[ClaudeAgent] Resuming with payload:', resumePayload);\n\n try {\n // 🔑 Get saved session ID from static storage\n const sessionId = ClaudeAgent.sessionStore.get(threadId);\n if (!sessionId) {\n throw new Error(`No session ID found for thread: ${threadId}. Make sure the initial request completed successfully.`);\n }\n\n console.log(`[ClaudeAgent] Resuming session: ${sessionId}`);\n\n // 🔑 Build resume prompt from user's modified data\n const resumePrompt = this.buildResumePrompt(resumePayload);\n\n // Prepare MCP servers (same as initial run)\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n includePartialMessages: this.config.includePartialMessages !== false,\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n // 🔑 Use session ID to resume (SDK auto-loads history)\n resume: sessionId,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n ...this.config.claudeOptions,\n };\n\n // Create new query (SDK will restore full context)\n const agentQuery = query({\n prompt: resumePrompt,\n options,\n });\n\n this.currentQuery = agentQuery;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n const streamingEnabled = options.includePartialMessages === true;\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Continue processing messages\n for await (const sdkMessage of agentQuery) {\n // console.log(\"sdkMessage (resumed)\", JSON.stringify(sdkMessage, null, 2));\n\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n for (const event of events) {\n subscriber.next(event);\n }\n }\n\n const finalEvents = eventTransformer.completeActiveMessage();\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n\n } catch (error) {\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: \"RESUME_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // this.currentSubscriber = undefined;\n // console.log('_resume finally ********* subscriber', this.currentSubscriber)\n\n }\n }\n\n /**\n * Build resume prompt from user's modified data\n */\n private buildResumePrompt(payload: any): string {\n // If payload contains steps, construct a descriptive prompt\n if (payload.steps) {\n const enabledSteps = payload.steps.filter((s: any) => s.status === 'enabled');\n const disabledSteps = payload.steps.filter((s: any) => s.status === 'disabled');\n\n let prompt = \"The user has reviewed the steps. \";\n\n if (disabledSteps.length > 0) {\n prompt += `They disabled the following steps: ${disabledSteps.map((s: any) => s.description).join(', ')}. `;\n }\n\n prompt += `Please continue with the enabled steps: ${enabledSteps.map((s: any) => s.description).join(', ')}. `;\n prompt += \"Provide a creative but short description (3 sentences max) of how you will perform the task.\";\n\n return prompt;\n }\n\n // Default: use payload as JSON\n return JSON.stringify(payload);\n }\n\n /**\n * Clear session for a thread\n */\n public clearSession(threadId: string): void {\n ClaudeAgent.sessionStore.delete(threadId);\n console.log(`[ClaudeAgent] Cleared session for thread: ${threadId}`);\n }\n\n /**\n * 🔑 Get all active sessions (for debugging)\n */\n public static getActiveSessions(): Map<string, string> {\n return ClaudeAgent.sessionStore;\n }\n\n /**\n * Get the configured model name\n */\n public getModel(): string {\n return this.config.model || \"\";\n }\n\n /**\n * Get the configured API key (masked for security)\n */\n public getApiKey(): string {\n const key = this.config.apiKey || process.env.ANTHROPIC_API_KEY || \"\";\n return key ? `${key.substring(0, 8)}...` : \"not configured\";\n }\n\n /**\n * Get MCP servers count\n */\n public getMcpServersCount(): number {\n return this.mcpServers.length;\n }\n\n /**\n * Check if built-in tools are enabled\n */\n public isBuiltInToolsEnabled(): boolean {\n return this.config.enableBuiltInTools !== false; // Default true\n }\n}\n\n","/**\n * Message format converter for Claude Agent SDK\n * Converts AG-UI messages to Claude Agent SDK prompt format\n * @module claude-sdk/message-converter\n */\n\nimport type { Message as AGUIMessage } from \"@ag-ui/client\";\n\n/**\n * Converts AG-UI messages to Claude Agent SDK prompt format\n *\n * Claude Agent SDK uses a simple prompt string or streaming messages.\n * This converter formats AG-UI message history into a structured prompt.\n */\nexport class MessageConverter {\n /**\n * Convert AG-UI messages to a structured prompt string\n *\n * Formats conversation history with role markers for clarity.\n * Claude Agent SDK will parse this and maintain context.\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted prompt string\n *\n * @example\n * ```typescript\n * const converter = new MessageConverter();\n * const prompt = converter.convertToPrompt([\n * { role: \"system\", content: \"You are a helpful assistant\" },\n * { role: \"user\", content: \"Hello!\" },\n * ]);\n * // Returns: \"[System]\\nYou are a helpful assistant\\n\\n[User]\\nHello!\\n\"\n * ```\n */\n public convertToPrompt(aguiMessages: AGUIMessage[]): string {\n const lines: string[] = [];\n\n for (const msg of aguiMessages) {\n switch (msg.role) {\n case \"system\":\n // System messages provide context\n if (msg.content) {\n lines.push(`[System]\\n${msg.content}\\n`);\n }\n break;\n\n case \"user\":\n // User messages are the main input\n if (msg.content) {\n lines.push(`${msg.content}\\n`);\n }\n break;\n\n case \"assistant\":\n // Assistant messages show previous responses\n if (msg.content) {\n lines.push(`[Assistant]\\n${msg.content}\\n`);\n }\n // Tool calls are handled automatically by Claude via MCP\n // We don't need to explicitly format them in the prompt\n break;\n\n case \"tool\":\n // Tool results provide context for Claude\n // Format them clearly so Claude understands the tool output\n if (msg.toolCallId && msg.content) {\n lines.push(`[Tool Result: ${msg.toolCallId}]\\n${msg.content}\\n`);\n }\n break;\n\n default:\n // Skip unknown message types\n console.warn(\n `[MessageConverter] Unknown message role: ${(msg as any).role}`\n );\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Extract the latest user message from AG-UI messages\n * Useful when you only need the current user input\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Latest user message content or empty string\n */\n public extractLatestUserMessage(aguiMessages: AGUIMessage[]): string {\n // Find the last user message\n for (let i = aguiMessages.length - 1; i >= 0; i--) {\n const msg = aguiMessages[i];\n if (msg.role === \"user\" && msg.content) {\n if (typeof msg.content === \"string\") {\n return msg.content;\n } else {\n const content = msg.content\n .filter((m) => m.type === \"text\")\n .map((m) => m.text)\n .join(\"\");\n\n if (content) return content;\n }\n }\n }\n return \"\";\n }\n\n /**\n * Extract system messages and combine them\n * Useful for setting up Claude's context\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Combined system message content\n */\n public extractSystemMessages(aguiMessages: AGUIMessage[]): string {\n const systemMessages = aguiMessages\n .filter((msg) => msg.role === \"system\" && msg.content)\n .map((msg) => msg.content);\n\n return systemMessages.join(\"\\n\\n\");\n }\n\n /**\n * Get conversation history excluding the latest user message\n * Useful for providing context without duplicating current input\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted conversation history\n */\n public getConversationHistory(aguiMessages: AGUIMessage[]): string {\n // Remove the last user message (current input)\n const historyMessages = [...aguiMessages];\n for (let i = historyMessages.length - 1; i >= 0; i--) {\n if (historyMessages[i].role === \"user\") {\n historyMessages.splice(i, 1);\n break;\n }\n }\n\n return this.convertToPrompt(historyMessages);\n }\n}\n","/**\n * Tool bridge for converting AG-Kit tools to MCP servers\n * Handles Zod schema extraction and MCP server creation\n * @module claude-sdk/tool-bridge\n */\n\nimport type { BaseTool } from \"@cloudbase/agent-tools\";\nimport { createSdkMcpServer, tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod/v3\";\n\n/**\n * Bridges AG-Kit tools to Claude Agent SDK via MCP servers\n * \n * Supports both BaseTool (Zod schema) and AG-UI tools (JSON Schema)\n * and creates MCP tools that Claude SDK can use directly.\n */\nexport class ToolBridge {\n /**\n * Create an MCP server from AG-Kit BaseTool instances\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-Kit BaseTool instances\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n */\n public createMcpServer(name: string, tools: BaseTool[], isClientTools: boolean = false): any {\n const mcpTools = tools.map(agkitTool => this.convertToMcpTool(agkitTool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Create an MCP server from AG-UI tool definitions (JSON Schema format)\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-UI tool definitions with JSON Schema\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n * \n * @example\n * ```typescript\n * const bridge = new ToolBridge();\n * const server = bridge.createMcpServerFromJsonSchema(\"my-tools\", [\n * {\n * name: \"get_weather\",\n * description: \"Get weather\",\n * parameters: { type: \"object\", properties: { location: { type: \"string\" } } }\n * }\n * ], true); // true = client-side tools\n * ```\n */\n public createMcpServerFromJsonSchema(\n name: string,\n tools: Array<{ name: string; description: string; parameters: any }>,\n isClientTools: boolean = true // 🔑 Default true: inputTools are usually client tools\n ): any {\n const mcpTools = tools.map(tool => this.convertJsonSchemaToolToMcp(tool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Convert a single AG-Kit BaseTool to MCP tool definition\n * \n * @param agkitTool - AG-Kit BaseTool instance\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertToMcpTool(agkitTool: BaseTool, isClientTool: boolean = false): any {\n const metadata = agkitTool.getMetadata();\n const toolName = metadata.name || \"unnamed_tool\";\n const toolDescription = metadata.description || `AG-Kit tool: ${toolName}`;\n\n // Extract Zod schema shape from BaseTool\n let zodShape: any = {};\n\n if (metadata.schema) {\n const schema = metadata.schema as any;\n if (schema._def && typeof schema._def.shape === 'function') {\n zodShape = schema._def.shape();\n } else if (schema._def && schema._def.shape) {\n zodShape = schema._def.shape;\n } else {\n console.warn(`[ToolBridge] Tool \"${toolName}\" schema is not a ZodObject, using empty shape`);\n }\n }\n\n return this.createMcpTool(toolName, toolDescription, zodShape, isClientTool);\n }\n\n /**\n * Convert a JSON Schema tool to MCP tool definition\n * \n * @param toolDef - Tool definition with JSON Schema parameters\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertJsonSchemaToolToMcp(\n toolDef: {\n name: string;\n description: string;\n parameters: any;\n },\n isClientTool: boolean = false\n ): any {\n // Convert JSON Schema to Zod shape\n const zodShape = this.jsonSchemaToZodShape(toolDef.parameters);\n\n return this.createMcpTool(\n toolDef.name,\n toolDef.description || `Tool: ${toolDef.name}`,\n zodShape,\n isClientTool\n );\n }\n\n /**\n * Create an MCP tool with common logic\n * \n * @param name - Tool name\n * @param description - Tool description\n * @param zodShape - Zod schema for parameters\n * @param isClientTool - Whether this is a client-side tool\n */\n private createMcpTool(\n name: string,\n description: string,\n zodShape: any,\n isClientTool: boolean = false\n ): any {\n return tool(\n name,\n description,\n zodShape,\n async (args: any, extra: unknown) => {\n console.log(`[ToolBridge] Tool called: ${name}, isClientTool: ${isClientTool}`, { args });\n\n if (isClientTool) {\n // 🔑 Client-side tool: Return special marker for frontend execution\n // The EventTransformer will detect this and NOT send tool-result event\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n __client_tool__: true, // ← Special marker\n tool: name,\n args,\n message: \"Waiting for client-side execution\",\n }),\n },\n ],\n isError: false,\n };\n }\n\n // Server-side tool: Should have custom implementation\n // This is a fallback that should not be reached\n console.warn(`[ToolBridge] Server-side tool \"${name}\" called but no implementation provided`);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n tool: name,\n args,\n message: \"Tool executed on backend (placeholder)\",\n }),\n },\n ],\n isError: false,\n };\n }\n );\n }\n\n /**\n * Convert JSON Schema to Zod shape (ZodRawShape)\n * \n * @param jsonSchema - JSON Schema object\n * @returns Zod shape object\n */\n private jsonSchemaToZodShape(jsonSchema: any): any {\n if (!jsonSchema || typeof jsonSchema !== \"object\") {\n return {};\n }\n\n const zodShape: any = {};\n\n // Handle object schema with properties\n if (jsonSchema.type === \"object\" && jsonSchema.properties) {\n const required = Array.isArray(jsonSchema.required) ? jsonSchema.required : [];\n\n for (const [key, propSchema] of Object.entries(jsonSchema.properties)) {\n const isRequired = required.includes(key);\n zodShape[key] = this.jsonSchemaPropertyToZod(propSchema as any, isRequired);\n }\n }\n\n return zodShape;\n }\n\n /**\n * Convert a single JSON Schema property to Zod type\n */\n private jsonSchemaPropertyToZod(schema: any, isRequired: boolean): any {\n if (!schema || typeof schema !== \"object\") {\n return isRequired ? z.any() : z.any().optional();\n }\n\n let zodType: any;\n\n switch (schema.type) {\n case \"string\":\n zodType = z.string();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (Array.isArray(schema.enum)) {\n zodType = z.enum(schema.enum as [string, ...string[]]);\n }\n break;\n\n case \"number\":\n case \"integer\":\n zodType = schema.type === \"integer\" ? z.number().int() : z.number();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (schema.minimum !== undefined) zodType = zodType.min(schema.minimum);\n if (schema.maximum !== undefined) zodType = zodType.max(schema.maximum);\n break;\n\n case \"boolean\":\n zodType = z.boolean();\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"array\":\n if (schema.items) {\n const itemType = this.jsonSchemaPropertyToZod(schema.items, true);\n zodType = z.array(itemType);\n } else {\n zodType = z.array(z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"object\":\n if (schema.properties) {\n const nestedShape = this.jsonSchemaToZodShape(schema);\n zodType = z.object(nestedShape);\n } else {\n zodType = z.record(z.string(), z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n default:\n zodType = z.any();\n if (schema.description) zodType = zodType.describe(schema.description);\n }\n\n return isRequired ? zodType : zodType.optional();\n }\n\n}\n\n","/**\n * Event transformer for Claude Agent SDK\n * Converts SDKMessage to AG-UI BaseEvent\n * @module claude-sdk/event-transformer\n */\n\nimport type {\n BaseEvent,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type {\n SDKMessage,\n SDKAssistantMessage,\n SDKPartialAssistantMessage,\n SDKResultMessage,\n SDKPermissionDenial,\n} from \"./types\";\n\n/**\n * Transforms Claude Agent SDK messages to AG-UI events\n * \n * Handles streaming messages, tool calls, and error states.\n */\nexport class EventTransformer {\n private activeMessageId?: string;\n private messageContent: string = \"\";\n private streamingEnabled: boolean;\n\n /**\n * @param streamingEnabled - Whether streaming mode is enabled (includePartialMessages)\n * When true, assistant messages will skip text content to avoid duplicates\n */\n constructor(streamingEnabled: boolean = false) {\n this.streamingEnabled = streamingEnabled;\n }\n\n /**\n * Transform a single SDKMessage to AG-UI BaseEvent(s)\n * \n * One SDKMessage may produce multiple AG-UI events.\n * For example, an assistant message with tool calls produces:\n * - TEXT_MESSAGE_START\n * - TEXT_MESSAGE_CONTENT\n * - TOOL_CALL_START (for each tool)\n * - TOOL_CALL_ARGS (for each tool)\n * - TOOL_CALL_END (for each tool)\n * - TEXT_MESSAGE_END\n * \n * @param sdkMessage - Claude SDK message\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Array of AG-UI events\n */\n public transformMessage(\n sdkMessage: SDKMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n switch (sdkMessage.type) {\n case \"assistant\":\n events.push(...this.handleAssistantMessage(sdkMessage as SDKAssistantMessage, threadId, runId));\n break;\n\n case \"stream_event\":\n events.push(...this.handlePartialAssistantMessage(sdkMessage as SDKPartialAssistantMessage, threadId, runId));\n break;\n\n case \"result\":\n events.push(...this.handleResultMessage(sdkMessage as SDKResultMessage, threadId, runId));\n break;\n\n case \"user\":\n // Handle tool_result messages from user\n events.push(...this.handleUserMessage(sdkMessage as any, threadId, runId));\n break;\n\n case \"system\":\n // System messages are input/context, don't emit events\n break;\n\n case \"tool_progress\":\n case \"auth_status\":\n // Progress and status messages, can be ignored for now\n break;\n\n default:\n console.warn(`[EventTransformer] Unknown SDKMessage type: ${(sdkMessage as any).type}`);\n }\n\n // console.log(\"events\", JSON.stringify(events, null, 2));\n return events;\n }\n\n /**\n * Handle complete assistant message\n * Emits full message with any tool calls\n * \n * When streaming is enabled (includePartialMessages: true), this method will:\n * - Skip text content (already sent via stream_event messages) \n * - Only process tool_use content (tools are not streamed)\n */\n private handleAssistantMessage(\n sdkMessage: SDKAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message; // Extract the actual API message\n\n // 🔑 When streaming is enabled, skip text content to avoid duplicates\n // Text content is already sent via stream_event messages\n if (this.streamingEnabled) {\n console.log('[EventTransformer] ⚠️ Streaming enabled: skipping assistant message text content to avoid duplicates');\n\n // Only process tool calls (they're not streamed)\n for (const content of message.content) {\n if (content.type === \"tool_use\") {\n // Process tool calls normally\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n return events;\n }\n\n // Non-streaming mode: process everything normally\n // console.log('[EventTransformer] Non-streaming mode: processing full assistant message');\n\n // If there's an active message, end it first\n if (this.activeMessageId) {\n console.log('[EventTransformer] Ending previous message:', this.activeMessageId);\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n }\n\n // Start new message\n this.activeMessageId = this.generateMessageId();\n this.messageContent = \"\";\n console.log('[EventTransformer] Starting new message:', this.activeMessageId);\n\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n\n // Add text content if present\n for (const content of message.content) {\n console.log(\"content\", JSON.stringify(content, null, 2));\n if (content.type === \"text\") {\n this.messageContent += content.text;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: content.text,\n } as TextMessageContentEvent);\n } else if (content.type === \"tool_use\") {\n // Remove MCP prefix for cleaner tool names\n // Claude Agent SDK adds MCP namespace: \"mcp__server-name__tool-name\"\n // We want frontend to see: \"tool-name\"\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n // TOOL_CALL_START\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n // TOOL_CALL_ARGS\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n // TOOL_CALL_END\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n // End message and clear active message ID\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n\n // Clear activeMessageId since message is complete\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return events;\n }\n\n /**\n * Handle streaming partial assistant message\n * Emits incremental content deltas\n */\n private handlePartialAssistantMessage(\n sdkMessage: SDKPartialAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const streamEvent = sdkMessage.event; // Extract the actual stream event\n\n // Handle different stream event types\n if (streamEvent.type === \"message_start\") {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n } else if (streamEvent.type === \"content_block_delta\") {\n // If no active message, start one (edge case)\n if (!this.activeMessageId) {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n }\n\n // Handle text delta\n if (streamEvent.delta.type === \"text_delta\") {\n const textDelta = streamEvent.delta.text;\n this.messageContent += textDelta;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: textDelta,\n } as TextMessageContentEvent);\n }\n } else if (streamEvent.type === \"message_delta\") {\n // Message end or stop reason\n if (streamEvent.delta.stop_reason) {\n // Can emit TEXT_MESSAGE_END here if needed\n if (this.activeMessageId) {\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n }\n }\n\n return events;\n }\n\n /**\n * Handle user message (mainly for tool_result)\n * Claude SDK sends tool results as user messages with tool_result content\n */\n private handleUserMessage(\n sdkMessage: any,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return events;\n }\n\n // Process tool_result content blocks\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n // content.content is an array of content blocks\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // 🔑 Check if this is a client-side tool marker\n const isClientTool = this.isClientToolMarker(resultContent);\n\n if (isClientTool) {\n console.log(`[EventTransformer] Client-side tool detected: ${content.tool_use_id}, skipping tool-result event`);\n // ⚠️ DO NOT emit TOOL_CALL_RESULT event for client tools\n // The client will execute the tool and send the result back\n continue;\n }\n\n // Emit TOOL_CALL_RESULT event for server-side tools\n events.push({\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: content.tool_use_id,\n content: resultContent,\n } as ToolCallResultEvent);\n\n console.log(`[EventTransformer] Tool result for ${content.tool_use_id}: ${resultContent}`);\n }\n }\n\n return events;\n }\n\n /**\n * Handle result message (final query result)\n * This represents the end of the query execution\n */\n private handleResultMessage(\n message: SDKResultMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n // SDKResultMessage represents the final result of the entire query\n // It doesn't directly map to TOOL_CALL_RESULT\n // Instead, we can emit it as metadata or ignore it\n\n // If there are permission denials, we can log them\n if (message.permission_denials && message.permission_denials.length > 0) {\n for (const denial of message.permission_denials) {\n console.warn(`[EventTransformer] Permission denied for tool: ${denial.tool_name}, tool_use_id: ${denial.tool_use_id}`);\n // Optionally emit as error events\n events.push({\n type: EventType.RUN_ERROR,\n message: `Permission denied for tool: ${denial.tool_name}`,\n rawEvent: denial,\n } as any);\n }\n }\n\n // Handle success or error result\n if (message.subtype === 'success') {\n console.log(`[EventTransformer] Query completed successfully: ${message.result}, turns: ${message.num_turns}, cost: $${message.total_cost_usd}`);\n } else {\n // Error subtypes: error_during_execution, error_max_turns, error_max_budget_usd\n const errorMsg = `Query failed: ${message.subtype}`;\n console.error(`[EventTransformer] ${errorMsg}, errors: ${message.errors?.join(', ')}`);\n events.push({\n type: EventType.RUN_ERROR,\n message: errorMsg,\n rawEvent: message,\n } as any);\n }\n\n return events;\n }\n\n /**\n * Complete any active message\n * Call this when streaming ends to ensure TEXT_MESSAGE_END is emitted\n */\n public completeActiveMessage(): BaseEvent[] {\n if (this.activeMessageId) {\n const event: TextMessageEndEvent = {\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n };\n\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return [event];\n }\n return [];\n }\n\n /**\n * Reset transformer state\n * Call this between runs to ensure clean state\n */\n public reset(): void {\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n\n /**\n * Generate unique message ID\n */\n private generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Generate unique tool call ID\n */\n private generateToolCallId(): string {\n return `tool_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Detect interrupt marker in tool result\n * \n * Checks if a tool result contains the __interrupt__ marker used for\n * human-in-the-loop workflows. Returns interrupt details if found.\n * \n * @param resultContent - Tool result content string\n * @returns Interrupt object if found, undefined otherwise\n */\n public detectInterrupt(resultContent: string):\n | { id: string; reason: string; payload: any }\n | undefined {\n try {\n const parsed = JSON.parse(resultContent);\n if (parsed.__interrupt__ === true) {\n return {\n // 🔑 Generate unique ID for this interrupt\n id: `interrupt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n reason: parsed.reason || \"Agent requested interrupt\",\n // 🔑 Payload contains the full interrupt data (including type, steps, etc.)\n payload: parsed,\n };\n }\n } catch (error) {\n // Not JSON or doesn't contain interrupt marker\n }\n return undefined;\n }\n\n /**\n * Remove MCP namespace prefix from tool name\n * \n * Claude Agent SDK adds MCP server namespace to tool names:\n * \"mcp__server-name__tool-name\" -> \"tool-name\"\n * \n * This ensures tool names match what the frontend expects and maintains\n * consistency with other AG-Kit agent implementations (LangChain, LangGraph).\n * \n * @param toolName - Tool name potentially with MCP prefix\n * @returns Clean tool name without prefix\n * \n * @example\n * removeMcpPrefix(\"mcp__agkit__change-background-color\") // \"change-background-color\"\n * removeMcpPrefix(\"change-background-color\") // \"change-background-color\"\n */\n private removeMcpPrefix(toolName: string): string {\n // Match pattern: mcp__<server-name>__<tool-name>\n const mcpPattern = /^mcp__[^_]+__(.+)$/;\n const match = toolName.match(mcpPattern);\n\n if (match) {\n const cleanName = match[1];\n console.log(`[EventTransformer] Removed MCP prefix: ${toolName} -> ${cleanName}`);\n return cleanName;\n }\n\n // No MCP prefix found, return original name\n return toolName;\n }\n\n /**\n * Check if tool result content contains client-side tool marker\n * \n * Client-side tools return a special marker indicating they need to be\n * executed on the frontend. We detect this marker to avoid sending\n * tool-result events prematurely.\n * \n * @param resultContent - Tool result content string\n * @returns true if this is a client-side tool marker\n */\n private isClientToolMarker(resultContent: string): boolean {\n try {\n const parsed = JSON.parse(resultContent);\n // 🔑 Check for __client_tool__ marker\n return parsed.__client_tool__ === true;\n } catch (error) {\n // Not JSON or doesn't contain marker\n return false;\n }\n }\n}\n\n","/**\n * Hooks manager for Claude Agent SDK\n * Creates hooks for monitoring and controlling Claude agent behavior\n * @module claude-sdk/hooks-manager\n */\n\nimport type { Subscriber } from \"rxjs\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { HookCallback } from \"./types\";\n\n/**\n * Manages Claude Agent SDK hooks for AG-UI event emission\n * \n * Hooks allow us to intercept Claude's behavior and emit corresponding AG-UI events.\n * This bridges Claude's lifecycle events to AG-Kit's event system.\n */\nexport class HooksManager {\n /**\n * Create hooks configuration for Claude Agent SDK\n * \n * @param subscriber - RxJS subscriber to emit AG-UI events\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Hooks configuration object\n */\n public createHooks(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): Record<string, HookCallback> {\n return {\n // Pre-tool use hook - called before tool execution\n preToolUse: this.createPreToolUseHook(subscriber),\n\n // Post-tool use hook - called after tool execution\n postToolUse: this.createPostToolUseHook(subscriber),\n\n // Session lifecycle hooks\n sessionStart: this.createSessionStartHook(subscriber, threadId, runId),\n sessionEnd: this.createSessionEndHook(subscriber, threadId, runId),\n\n // Notification hook - for system notifications\n notification: this.createNotificationHook(subscriber),\n\n // User prompt submit hook - when user submits input\n userPromptSubmit: this.createUserPromptSubmitHook(subscriber),\n };\n }\n\n /**\n * Create pre-tool use hook\n * Used for logging and permission checks before tool execution\n * \n * NOTE: We do NOT emit TOOL_CALL_START here to avoid duplicate events.\n * The EventTransformer will emit all tool call events when processing SDKAssistantMessage.\n */\n private createPreToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Log tool use for debugging/monitoring\n // The actual TOOL_CALL_START event will be emitted by EventTransformer\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Pre-tool use: ${input.toolName} (${input.toolUseId})`);\n }\n\n // Return continue signal to allow tool execution\n return { continue: true };\n };\n }\n\n /**\n * Create post-tool use hook\n * Called after tool execution completes\n */\n private createPostToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Tool result will be emitted via SDKResultMessage\n // This hook can be used for logging or side effects\n\n // Log tool execution completion\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Tool executed: ${input.toolName} (${input.toolUseId})`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create session start hook\n * Called when agent session begins\n */\n private createSessionStartHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session started - RUN_STARTED already emitted in main run method\n // This hook can be used for additional initialization\n\n console.log(`[HooksManager] Session started: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create session end hook\n * Called when agent session ends\n */\n private createSessionEndHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session ended - RUN_FINISHED will be emitted after query completes\n // This hook can be used for cleanup\n\n console.log(`[HooksManager] Session ended: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create notification hook\n * Handles system notifications from Claude\n */\n private createNotificationHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Emit notification as console log\n // Could be extended to emit custom AG-UI notification events\n\n if (input.message) {\n console.log(`[Claude Notification] ${input.message}`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create user prompt submit hook\n * Called when user submits a prompt\n */\n private createUserPromptSubmitHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // User prompt submitted\n // This is mainly for logging as the input is already processed\n\n if (input.prompt) {\n console.log(`[HooksManager] User prompt submitted: ${input.prompt}`);\n }\n\n return { continue: true };\n };\n }\n}\n\n"],"mappings":"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","names":["EventType","tool","EventType","tool"]}
1
+ {"version":3,"sources":["../src/agent.ts","../src/message-converter.ts","../src/tool-bridge.ts","../src/event-transformer.ts","../src/hooks-manager.ts"],"sourcesContent":["/**\n * Claude Agent SDK integration for AG-Kit\n * Main agent class that bridges Claude Agent SDK with AG-Kit\n * @module claude-sdk/agent\n */\n\nimport type {\n RunAgentInput,\n BaseEvent,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport { AbstractAgent } from \"@cloudbase/agent-agents/abstract\";\nimport { query } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { Query, SDKMessage, SDKSystemMessage, SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Observable, Subscriber } from \"rxjs\";\n\nimport type { ClaudeAgentSDKConfig, ClaudeSDKOptions } from \"./types\";\nimport { MessageConverter } from \"./message-converter\";\nimport { ToolBridge } from \"./tool-bridge\";\nimport { EventTransformer } from \"./event-transformer\";\nimport { HooksManager } from \"./hooks-manager\";\n\n/**\n * Claude Agent SDK adapter for AG-Kit\n * \n * Integrates Anthropic's Claude Agent SDK with AG-Kit's unified agent interface.\n * Provides seamless integration with AG-UI components while leveraging Claude's\n * built-in tools, MCP support, hooks system, and permission management.\n * \n * @example\n * ```typescript\n * const agent = new ClaudeAgentSDK({\n * name: \"my-claude-agent\",\n * model: \"\",\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * enableBuiltInTools: true,\n * permissionMode: \"ask\",\n * });\n * ```\n */\nexport class ClaudeAgent extends AbstractAgent {\n private config: ClaudeAgentSDKConfig;\n private mcpServers: any[] = [];\n private messageConverter: MessageConverter;\n private toolBridge: ToolBridge;\n private hooksManager: HooksManager;\n\n // 🔑 Session management for HITL\n // Use static storage to persist across agent instance recreations\n public static sessionStore: Map<string, string> = new Map(); // threadId → session_id\n private currentQuery?: Query;\n\n // 🔑 Event emitter for tool intermediate messages\n // Allows MCP tools to emit events during execution\n private currentSubscriber?: Subscriber<BaseEvent>;\n\n constructor(config: ClaudeAgentSDKConfig) {\n super(config);\n console.log('ClaudeAgent constructor called');\n this.config = config;\n\n // Initialize utility modules\n this.messageConverter = new MessageConverter();\n this.toolBridge = new ToolBridge();\n this.hooksManager = new HooksManager();\n\n // Note: Tools are provided at runtime via RunAgentInput, not in config\n // MCP servers from tools will be created dynamically during run()\n }\n\n /**\n * Run the Claude agent with given input\n * \n * @param input - AG-UI RunAgentInput\n * @returns Observable stream of AG-UI BaseEvents\n */\n public run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n // 🔑 Check if this is a resume request\n if (input.forwardedProps?.resume) {\n this._resume(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('resume error', error);\n });\n } else {\n this._run(subscriber, input).catch((error) => {\n // subscriber.error(error);\n console.error('run error', error);\n });\n }\n });\n }\n\n /**\n * Internal run implementation\n * Handles the full agent execution lifecycle\n */\n private async _run(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { messages, runId, threadId, tools: inputTools } = input;\n\n // 🔑 Store subscriber for tool intermediate events\n this.currentSubscriber = subscriber;\n // console.log('_run********* subscriber', this.currentSubscriber)\n\n // Emit RUN_STARTED event\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n try {\n // Convert AG-UI messages to Claude prompt\n const prompt = this.messageConverter.convertToPrompt(messages);\n\n // Prepare MCP servers\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Convert runtime tools to MCP server if provided\n // inputTools are AG-UI tools with JSON Schema: { name, description, parameters }\n if (inputTools && inputTools.length > 0) {\n // Prepare tools for conversion\n const toolsForMcp = inputTools.map(tool => ({\n name: tool.name,\n description: tool.description,\n parameters: typeof tool.parameters === 'string'\n ? JSON.parse(tool.parameters)\n : tool.parameters,\n }));\n\n // Create MCP server from AG-UI tools (JSON Schema)\n // Use short server name to avoid long MCP prefixes in tool names\n // MCP will prefix tools as: mcp__agkit__<tool-name>\n const runtimeServer = this.toolBridge.createMcpServerFromJsonSchema(\n \"agkit\",\n toolsForMcp\n );\n\n // Add to MCP servers dict\n mcpServers[\"agkit\"] = runtimeServer;\n }\n\n // Ensure API key is set in environment\n // Claude Agent SDK reads from ANTHROPIC_API_KEY environment variable\n if (this.config.apiKey && !process.env.ANTHROPIC_API_KEY) {\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n }\n console.log('[ClaudeAgent] includePartialMessages:', this.config.includePartialMessages);\n // console.log('[ClaudeAgent] claudeOptions:', this.config.claudeOptions);\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n additionalDirectories: this.config.additionalDirectories,\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n includePartialMessages: this.config.includePartialMessages !== false, // Default true for streaming\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n ...this.config.claudeOptions,\n };\n\n // 🔑 Check if there's a saved session ID for this thread (for session continuity)\n const savedSessionId = ClaudeAgent.sessionStore.get(threadId);\n if (savedSessionId) {\n console.log(`[ClaudeAgent] Resuming session: ${savedSessionId} for thread: ${threadId}`);\n options.resume = savedSessionId;\n }\n\n // Create Claude Agent SDK query\n const agentQuery = query({\n prompt,\n options,\n });\n\n // console.log('options', JSON.stringify(options, null, 2));\n\n // Store query reference for potential interrupt\n this.currentQuery = agentQuery;\n\n // Create event transformer\n // Pass streaming flag to avoid duplicate text messages\n const streamingEnabled = options.includePartialMessages === true;\n console.log('[ClaudeAgent] Streaming enabled:', streamingEnabled);\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Process SDKMessages\n for await (const sdkMessage of agentQuery) {\n console.log(\"sdkMessage\", JSON.stringify(sdkMessage, null, 2));\n console.log('[ClaudeAgent] SDKMessage type:', sdkMessage.type);\n\n // 🔑 Capture session ID from init message\n if (sdkMessage.type === 'system') {\n const systemMsg = sdkMessage as SDKSystemMessage;\n if (systemMsg.subtype === 'init' && systemMsg.session_id) {\n console.log(`[ClaudeAgent] Captured session ID: ${systemMsg.session_id} for thread: ${threadId}`);\n ClaudeAgent.sessionStore.set(threadId, systemMsg.session_id);\n }\n }\n\n // Transform SDKMessage to AG-UI events FIRST\n // This ensures TOOL_CALL_RESULT is sent before interrupt detection\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n\n // Emit all events\n for (const event of events) {\n subscriber.next(event);\n }\n\n // 🔑 Detect interrupt from tool results AFTER emitting events\n const interruptDetected = this.detectInterrupt(sdkMessage);\n if (interruptDetected) {\n console.log(\"[ClaudeAgent] Interrupt detected:\", interruptDetected);\n\n // Emit RUN_FINISHED with interrupt\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n outcome: \"interrupt\",\n interrupt: interruptDetected,\n } as RunFinishedEvent);\n\n // 🔑 Complete the observable - no need to wait for resume\n // The next request will be a separate HTTP call with forwardedProps.resume\n subscriber.complete();\n return;\n }\n }\n\n // Complete any active message\n console.log('[ClaudeAgent] Calling completeActiveMessage...');\n const finalEvents = eventTransformer.completeActiveMessage();\n // console.log('[ClaudeAgent] Final events:', finalEvents.map(e => e.type));\n\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n // Note: Usage statistics are included in SDKResultMessage\n // which is already processed by EventTransformer\n\n // Emit RUN_FINISHED event\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n } catch (error) {\n // Emit RUN_ERROR event\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: error instanceof Error ? error.name : \"UNKNOWN_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // 🔑 Clear subscriber reference\n // this.currentSubscriber = undefined;\n // console.log('run finally ********* subscriber', this.currentSubscriber)\n }\n }\n\n /**\n * Get event emitter for MCP tools\n * Allows tools to emit intermediate events during execution\n * \n * @returns Event emitter function or undefined if no active run\n */\n public getEventEmitter(): ((event: BaseEvent) => void) | undefined {\n if (this.currentSubscriber) {\n return (event: BaseEvent) => {\n this.currentSubscriber!.next(event);\n };\n }\n return undefined;\n }\n\n /**\n * 🔑 Detect interrupt from SDKMessage\n * Checks if tool result contains __interrupt__ marker\n */\n private detectInterrupt(sdkMessage: SDKMessage): {\n id: string;\n reason: string;\n payload: any;\n } | null {\n // 🔑 Check user message for tool_result with __interrupt__\n if (sdkMessage.type === \"user\") {\n const message = (sdkMessage as any).message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return null;\n }\n\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // Try to parse as JSON and check for __interrupt__\n try {\n const parsed = JSON.parse(resultContent);\n console.log('[ClaudeAgent] Parsed interrupt data:', parsed);\n const { interruptId } = parsed\n if (parsed.__interrupt__ === true) {\n return {\n id: interruptId,\n reason: parsed.reason || \"Agent requested interrupt\",\n // 🔑 Payload contains the full interrupt data (including type, steps, etc.)\n payload: parsed,\n };\n }\n } catch {\n // Not JSON or doesn't contain interrupt marker\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * 🔑 Resume execution after interrupt\n * Uses saved session ID to continue conversation\n */\n private async _resume(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n const { runId, threadId } = input;\n const resumePayload = input.forwardedProps?.resume?.payload;\n\n this.currentSubscriber = subscriber;\n // console.log('_resume ********* subscriber', this.currentSubscriber)\n\n console.log('[ClaudeAgent] Resuming with payload:', resumePayload);\n\n try {\n // 🔑 Get saved session ID from static storage\n const sessionId = ClaudeAgent.sessionStore.get(threadId);\n if (!sessionId) {\n throw new Error(`No session ID found for thread: ${threadId}. Make sure the initial request completed successfully.`);\n }\n\n console.log(`[ClaudeAgent] Resuming session: ${sessionId}`);\n\n // 🔑 Build resume prompt from user's modified data\n const resumePrompt = this.buildResumePrompt(resumePayload);\n\n // Prepare MCP servers (same as initial run)\n const mcpServers: Record<string, any> = {\n ...(this.config.mcpServers || {}),\n ...(this.config.claudeOptions?.mcpServers || {}),\n };\n\n // Create Claude Agent SDK options\n const options: Partial<ClaudeSDKOptions> = {\n model: this.config.model || \"\",\n mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,\n includePartialMessages: this.config.includePartialMessages !== false,\n hooks: this.hooksManager.createHooks(subscriber, threadId, runId),\n // 🔑 Use session ID to resume (SDK auto-loads history)\n resume: sessionId,\n permissionMode: this.config.permissionMode,\n canUseTool: this.config.canUseTool,\n allowDangerouslySkipPermissions: this.config.allowDangerouslySkipPermissions,\n ...this.config.claudeOptions,\n };\n\n // Create new query (SDK will restore full context)\n const agentQuery = query({\n prompt: resumePrompt,\n options,\n });\n\n this.currentQuery = agentQuery;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n const streamingEnabled = options.includePartialMessages === true;\n const eventTransformer = new EventTransformer(streamingEnabled);\n\n // Continue processing messages\n for await (const sdkMessage of agentQuery) {\n // console.log(\"sdkMessage (resumed)\", JSON.stringify(sdkMessage, null, 2));\n\n // Transform SDKMessage to AG-UI events FIRST\n // This ensures TOOL_CALL_RESULT is sent before interrupt detection\n const events = eventTransformer.transformMessage(sdkMessage, threadId, runId);\n for (const event of events) {\n subscriber.next(event);\n }\n\n // 🔑 Detect interrupt from tool results AFTER emitting events\n // Resume 场景下也可能触发新的中断(例如模型调用了另一个需要确认的工具)\n const interruptDetected = this.detectInterrupt(sdkMessage);\n if (interruptDetected) {\n console.log(\"[ClaudeAgent] Interrupt detected in resume:\", interruptDetected);\n\n // Emit RUN_FINISHED with interrupt\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n outcome: \"interrupt\",\n interrupt: interruptDetected,\n } as RunFinishedEvent);\n\n // 🔑 Complete the observable\n subscriber.complete();\n return;\n }\n }\n\n const finalEvents = eventTransformer.completeActiveMessage();\n for (const event of finalEvents) {\n subscriber.next(event);\n }\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n\n subscriber.complete();\n\n } catch (error) {\n subscriber.next({\n type: EventType.RUN_ERROR,\n threadId,\n runId,\n message: error instanceof Error ? error.message : String(error),\n code: \"RESUME_ERROR\",\n } as RunErrorEvent);\n\n // 🔧 正常完成 Observable 流(与 RUN_FINISHED 保持一致)\n // 错误已通过 RUN_ERROR 事件通知,不需要 subscriber.error()\n // 这样所有结束方式都是正常完成流,只是最后的事件类型不同\n subscriber.complete();\n } finally {\n // this.currentSubscriber = undefined;\n // console.log('_resume finally ********* subscriber', this.currentSubscriber)\n\n }\n }\n\n /**\n * Build resume prompt from user's modified data\n */\n private buildResumePrompt(payload: any): string {\n // If payload contains steps, construct a descriptive prompt\n if (payload.steps) {\n const enabledSteps = payload.steps.filter((s: any) => s.status === 'enabled');\n const disabledSteps = payload.steps.filter((s: any) => s.status === 'disabled');\n\n let prompt = \"The user has reviewed the steps. \";\n\n if (disabledSteps.length > 0) {\n prompt += `They disabled the following steps: ${disabledSteps.map((s: any) => s.description).join(', ')}. `;\n }\n\n prompt += `Please continue with the enabled steps: ${enabledSteps.map((s: any) => s.description).join(', ')}. `;\n prompt += \"Provide a creative but short description (3 sentences max) of how you will perform the task.\";\n\n return prompt;\n }\n\n // Default: use payload as JSON\n return JSON.stringify(payload);\n }\n\n /**\n * Clear session for a thread\n */\n public clearSession(threadId: string): void {\n ClaudeAgent.sessionStore.delete(threadId);\n console.log(`[ClaudeAgent] Cleared session for thread: ${threadId}`);\n }\n\n /**\n * 🔑 Get all active sessions (for debugging)\n */\n public static getActiveSessions(): Map<string, string> {\n return ClaudeAgent.sessionStore;\n }\n\n /**\n * Get the configured model name\n */\n public getModel(): string {\n return this.config.model || \"\";\n }\n\n /**\n * Get the configured API key (masked for security)\n */\n public getApiKey(): string {\n const key = this.config.apiKey || process.env.ANTHROPIC_API_KEY || \"\";\n return key ? `${key.substring(0, 8)}...` : \"not configured\";\n }\n\n /**\n * Get MCP servers count\n */\n public getMcpServersCount(): number {\n return this.mcpServers.length;\n }\n\n /**\n * Check if built-in tools are enabled\n */\n public isBuiltInToolsEnabled(): boolean {\n return this.config.enableBuiltInTools !== false; // Default true\n }\n}\n\n","/**\n * Message format converter for Claude Agent SDK\n * Converts AG-UI messages to Claude Agent SDK prompt format\n * @module claude-sdk/message-converter\n */\n\nimport type { Message as AGUIMessage } from \"@ag-ui/client\";\n\n/**\n * Converts AG-UI messages to Claude Agent SDK prompt format\n *\n * Claude Agent SDK uses a simple prompt string or streaming messages.\n * This converter formats AG-UI message history into a structured prompt.\n */\nexport class MessageConverter {\n /**\n * Convert AG-UI messages to a structured prompt string\n *\n * Formats conversation history with role markers for clarity.\n * Claude Agent SDK will parse this and maintain context.\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted prompt string\n *\n * @example\n * ```typescript\n * const converter = new MessageConverter();\n * const prompt = converter.convertToPrompt([\n * { role: \"system\", content: \"You are a helpful assistant\" },\n * { role: \"user\", content: \"Hello!\" },\n * ]);\n * // Returns: \"[System]\\nYou are a helpful assistant\\n\\n[User]\\nHello!\\n\"\n * ```\n */\n public convertToPrompt(aguiMessages: AGUIMessage[]): string {\n const lines: string[] = [];\n\n for (const msg of aguiMessages) {\n switch (msg.role) {\n case \"system\":\n // System messages provide context\n if (msg.content) {\n lines.push(`[System]\\n${msg.content}\\n`);\n }\n break;\n\n case \"user\":\n // User messages are the main input\n if (msg.content) {\n lines.push(`${msg.content}\\n`);\n }\n break;\n\n case \"assistant\":\n // Assistant messages show previous responses\n if (msg.content) {\n lines.push(`[Assistant]\\n${msg.content}\\n`);\n }\n // Tool calls are handled automatically by Claude via MCP\n // We don't need to explicitly format them in the prompt\n break;\n\n case \"tool\":\n // Tool results provide context for Claude\n // Format them clearly so Claude understands the tool output\n if (msg.toolCallId && msg.content) {\n lines.push(`[Tool Result: ${msg.toolCallId}]\\n${msg.content}\\n`);\n }\n break;\n\n default:\n // Skip unknown message types\n console.warn(\n `[MessageConverter] Unknown message role: ${(msg as any).role}`\n );\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Extract system messages and combine them\n * Useful for setting up Claude's context\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Combined system message content\n */\n public extractSystemMessages(aguiMessages: AGUIMessage[]): string {\n const systemMessages = aguiMessages\n .filter((msg) => msg.role === \"system\" && msg.content)\n .map((msg) => msg.content);\n\n return systemMessages.join(\"\\n\\n\");\n }\n\n /**\n * Get conversation history excluding the latest user message\n * Useful for providing context without duplicating current input\n *\n * @param aguiMessages - Array of AG-UI messages\n * @returns Formatted conversation history\n */\n public getConversationHistory(aguiMessages: AGUIMessage[]): string {\n // Remove the last user message (current input)\n const historyMessages = [...aguiMessages];\n for (let i = historyMessages.length - 1; i >= 0; i--) {\n if (historyMessages[i].role === \"user\") {\n historyMessages.splice(i, 1);\n break;\n }\n }\n\n return this.convertToPrompt(historyMessages);\n }\n}\n","/**\n * Tool bridge for converting AG-Kit tools to MCP servers\n * Handles Zod schema extraction and MCP server creation\n * @module claude-sdk/tool-bridge\n */\n\nimport type { BaseTool } from \"@cloudbase/agent-tools\";\nimport { createSdkMcpServer, tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod/v3\";\n\n/**\n * Bridges AG-Kit tools to Claude Agent SDK via MCP servers\n * \n * Supports both BaseTool (Zod schema) and AG-UI tools (JSON Schema)\n * and creates MCP tools that Claude SDK can use directly.\n */\nexport class ToolBridge {\n /**\n * Create an MCP server from AG-Kit BaseTool instances\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-Kit BaseTool instances\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n */\n public createMcpServer(name: string, tools: BaseTool[], isClientTools: boolean = false): any {\n const mcpTools = tools.map(agkitTool => this.convertToMcpTool(agkitTool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Create an MCP server from AG-UI tool definitions (JSON Schema format)\n * \n * @param name - Name for the MCP server\n * @param tools - Array of AG-UI tool definitions with JSON Schema\n * @param isClientTools - Whether these are client-side tools (executed on frontend)\n * @returns MCP server configuration\n * \n * @example\n * ```typescript\n * const bridge = new ToolBridge();\n * const server = bridge.createMcpServerFromJsonSchema(\"my-tools\", [\n * {\n * name: \"get_weather\",\n * description: \"Get weather\",\n * parameters: { type: \"object\", properties: { location: { type: \"string\" } } }\n * }\n * ], true); // true = client-side tools\n * ```\n */\n public createMcpServerFromJsonSchema(\n name: string,\n tools: Array<{ name: string; description: string; parameters: any }>,\n isClientTools: boolean = true // 🔑 Default true: inputTools are usually client tools\n ): any {\n const mcpTools = tools.map(tool => this.convertJsonSchemaToolToMcp(tool, isClientTools));\n\n return createSdkMcpServer({\n name,\n version: \"1.0.0\",\n tools: mcpTools,\n });\n }\n\n /**\n * Convert a single AG-Kit BaseTool to MCP tool definition\n * \n * @param agkitTool - AG-Kit BaseTool instance\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertToMcpTool(agkitTool: BaseTool, isClientTool: boolean = false): any {\n const metadata = agkitTool.getMetadata();\n const toolName = metadata.name || \"unnamed_tool\";\n const toolDescription = metadata.description || `AG-Kit tool: ${toolName}`;\n\n // Extract Zod schema shape from BaseTool\n let zodShape: any = {};\n\n if (metadata.schema) {\n const schema = metadata.schema as any;\n if (schema._def && typeof schema._def.shape === 'function') {\n zodShape = schema._def.shape();\n } else if (schema._def && schema._def.shape) {\n zodShape = schema._def.shape;\n } else {\n console.warn(`[ToolBridge] Tool \"${toolName}\" schema is not a ZodObject, using empty shape`);\n }\n }\n\n return this.createMcpTool(toolName, toolDescription, zodShape, isClientTool);\n }\n\n /**\n * Convert a JSON Schema tool to MCP tool definition\n * \n * @param toolDef - Tool definition with JSON Schema parameters\n * @param isClientTool - Whether this is a client-side tool\n * @returns MCP tool created with tool() function\n */\n private convertJsonSchemaToolToMcp(\n toolDef: {\n name: string;\n description: string;\n parameters: any;\n },\n isClientTool: boolean = false\n ): any {\n // Convert JSON Schema to Zod shape\n const zodShape = this.jsonSchemaToZodShape(toolDef.parameters);\n\n return this.createMcpTool(\n toolDef.name,\n toolDef.description || `Tool: ${toolDef.name}`,\n zodShape,\n isClientTool\n );\n }\n\n /**\n * Create an MCP tool with common logic\n * \n * @param name - Tool name\n * @param description - Tool description\n * @param zodShape - Zod schema for parameters\n * @param isClientTool - Whether this is a client-side tool\n */\n private createMcpTool(\n name: string,\n description: string,\n zodShape: any,\n isClientTool: boolean = false\n ): any {\n return tool(\n name,\n description,\n zodShape,\n async (args: any, extra: unknown) => {\n console.log(`[ToolBridge] Tool called: ${name}, isClientTool: ${isClientTool}`, { args });\n\n if (isClientTool) {\n // 🔑 Client-side tool: Return special marker for frontend execution\n // The EventTransformer will detect this and NOT send tool-result event\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n __client_tool__: true, // ← Special marker\n tool: name,\n args,\n message: \"Waiting for client-side execution\",\n }),\n },\n ],\n isError: false,\n };\n }\n\n // Server-side tool: Should have custom implementation\n // This is a fallback that should not be reached\n console.warn(`[ToolBridge] Server-side tool \"${name}\" called but no implementation provided`);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n tool: name,\n args,\n message: \"Tool executed on backend (placeholder)\",\n }),\n },\n ],\n isError: false,\n };\n }\n );\n }\n\n /**\n * Convert JSON Schema to Zod shape (ZodRawShape)\n * \n * @param jsonSchema - JSON Schema object\n * @returns Zod shape object\n */\n private jsonSchemaToZodShape(jsonSchema: any): any {\n if (!jsonSchema || typeof jsonSchema !== \"object\") {\n return {};\n }\n\n const zodShape: any = {};\n\n // Handle object schema with properties\n if (jsonSchema.type === \"object\" && jsonSchema.properties) {\n const required = Array.isArray(jsonSchema.required) ? jsonSchema.required : [];\n\n for (const [key, propSchema] of Object.entries(jsonSchema.properties)) {\n const isRequired = required.includes(key);\n zodShape[key] = this.jsonSchemaPropertyToZod(propSchema as any, isRequired);\n }\n }\n\n return zodShape;\n }\n\n /**\n * Convert a single JSON Schema property to Zod type\n */\n private jsonSchemaPropertyToZod(schema: any, isRequired: boolean): any {\n if (!schema || typeof schema !== \"object\") {\n return isRequired ? z.any() : z.any().optional();\n }\n\n let zodType: any;\n\n switch (schema.type) {\n case \"string\":\n zodType = z.string();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (Array.isArray(schema.enum)) {\n zodType = z.enum(schema.enum as [string, ...string[]]);\n }\n break;\n\n case \"number\":\n case \"integer\":\n zodType = schema.type === \"integer\" ? z.number().int() : z.number();\n if (schema.description) zodType = zodType.describe(schema.description);\n if (schema.minimum !== undefined) zodType = zodType.min(schema.minimum);\n if (schema.maximum !== undefined) zodType = zodType.max(schema.maximum);\n break;\n\n case \"boolean\":\n zodType = z.boolean();\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"array\":\n if (schema.items) {\n const itemType = this.jsonSchemaPropertyToZod(schema.items, true);\n zodType = z.array(itemType);\n } else {\n zodType = z.array(z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n case \"object\":\n if (schema.properties) {\n const nestedShape = this.jsonSchemaToZodShape(schema);\n zodType = z.object(nestedShape);\n } else {\n zodType = z.record(z.string(), z.any());\n }\n if (schema.description) zodType = zodType.describe(schema.description);\n break;\n\n default:\n zodType = z.any();\n if (schema.description) zodType = zodType.describe(schema.description);\n }\n\n return isRequired ? zodType : zodType.optional();\n }\n\n}\n\n","/**\n * Event transformer for Claude Agent SDK\n * Converts SDKMessage to AG-UI BaseEvent\n * @module claude-sdk/event-transformer\n */\n\nimport type {\n BaseEvent,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type {\n SDKMessage,\n SDKAssistantMessage,\n SDKPartialAssistantMessage,\n SDKResultMessage,\n SDKPermissionDenial,\n} from \"./types\";\n\n/**\n * Transforms Claude Agent SDK messages to AG-UI events\n * \n * Handles streaming messages, tool calls, and error states.\n */\nexport class EventTransformer {\n private activeMessageId?: string;\n private messageContent: string = \"\";\n private streamingEnabled: boolean;\n\n /**\n * @param streamingEnabled - Whether streaming mode is enabled (includePartialMessages)\n * When true, assistant messages will skip text content to avoid duplicates\n */\n constructor(streamingEnabled: boolean = false) {\n this.streamingEnabled = streamingEnabled;\n }\n\n /**\n * Transform a single SDKMessage to AG-UI BaseEvent(s)\n * \n * One SDKMessage may produce multiple AG-UI events.\n * For example, an assistant message with tool calls produces:\n * - TEXT_MESSAGE_START\n * - TEXT_MESSAGE_CONTENT\n * - TOOL_CALL_START (for each tool)\n * - TOOL_CALL_ARGS (for each tool)\n * - TOOL_CALL_END (for each tool)\n * - TEXT_MESSAGE_END\n * \n * @param sdkMessage - Claude SDK message\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Array of AG-UI events\n */\n public transformMessage(\n sdkMessage: SDKMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n switch (sdkMessage.type) {\n case \"assistant\":\n events.push(...this.handleAssistantMessage(sdkMessage as SDKAssistantMessage, threadId, runId));\n break;\n\n case \"stream_event\":\n events.push(...this.handlePartialAssistantMessage(sdkMessage as SDKPartialAssistantMessage, threadId, runId));\n break;\n\n case \"result\":\n events.push(...this.handleResultMessage(sdkMessage as SDKResultMessage, threadId, runId));\n break;\n\n case \"user\":\n // Handle tool_result messages from user\n events.push(...this.handleUserMessage(sdkMessage as any, threadId, runId));\n break;\n\n case \"system\":\n // System messages are input/context, don't emit events\n break;\n\n case \"tool_progress\":\n case \"auth_status\":\n // Progress and status messages, can be ignored for now\n break;\n\n default:\n console.warn(`[EventTransformer] Unknown SDKMessage type: ${(sdkMessage as any).type}`);\n }\n\n // console.log(\"events\", JSON.stringify(events, null, 2));\n return events;\n }\n\n /**\n * Handle complete assistant message\n * Emits full message with any tool calls\n * \n * When streaming is enabled (includePartialMessages: true), this method will:\n * - Skip text content (already sent via stream_event messages) \n * - Only process tool_use content (tools are not streamed)\n */\n private handleAssistantMessage(\n sdkMessage: SDKAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message; // Extract the actual API message\n\n // 🔑 When streaming is enabled, skip text content to avoid duplicates\n // Text content is already sent via stream_event messages\n if (this.streamingEnabled) {\n console.log('[EventTransformer] ⚠️ Streaming enabled: skipping assistant message text content to avoid duplicates');\n\n // Only process tool calls (they're not streamed)\n for (const content of message.content) {\n if (content.type === \"tool_use\") {\n // Process tool calls normally\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n return events;\n }\n\n // Non-streaming mode: process everything normally\n // console.log('[EventTransformer] Non-streaming mode: processing full assistant message');\n\n // If there's an active message, end it first\n if (this.activeMessageId) {\n console.log('[EventTransformer] Ending previous message:', this.activeMessageId);\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n }\n\n // Start new message\n this.activeMessageId = this.generateMessageId();\n this.messageContent = \"\";\n console.log('[EventTransformer] Starting new message:', this.activeMessageId);\n\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n\n // Add text content if present\n for (const content of message.content) {\n console.log(\"content\", JSON.stringify(content, null, 2));\n if (content.type === \"text\") {\n this.messageContent += content.text;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: content.text,\n } as TextMessageContentEvent);\n } else if (content.type === \"tool_use\") {\n // Remove MCP prefix for cleaner tool names\n // Claude Agent SDK adds MCP namespace: \"mcp__server-name__tool-name\"\n // We want frontend to see: \"tool-name\"\n const cleanToolName = this.removeMcpPrefix(content.name);\n\n // TOOL_CALL_START\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: content.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n\n // TOOL_CALL_ARGS\n const argsJson = JSON.stringify(content.input || {});\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: content.id,\n delta: argsJson,\n } as ToolCallArgsEvent);\n\n // TOOL_CALL_END\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: content.id,\n } as ToolCallEndEvent);\n }\n }\n\n // End message and clear active message ID\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n\n // Clear activeMessageId since message is complete\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return events;\n }\n\n /**\n * Handle streaming partial assistant message\n * Emits incremental content deltas\n */\n private handlePartialAssistantMessage(\n sdkMessage: SDKPartialAssistantMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const streamEvent = sdkMessage.event; // Extract the actual stream event\n\n // Handle different stream event types\n if (streamEvent.type === \"message_start\") {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n } else if (streamEvent.type === \"content_block_delta\") {\n // If no active message, start one (edge case)\n if (!this.activeMessageId) {\n this.activeMessageId = this.generateMessageId();\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n }\n\n // Handle text delta\n if (streamEvent.delta.type === \"text_delta\") {\n const textDelta = streamEvent.delta.text;\n this.messageContent += textDelta;\n events.push({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: this.activeMessageId,\n delta: textDelta,\n } as TextMessageContentEvent);\n }\n } else if (streamEvent.type === \"message_delta\") {\n // Message end or stop reason\n if (streamEvent.delta.stop_reason) {\n // Can emit TEXT_MESSAGE_END here if needed\n if (this.activeMessageId) {\n events.push({\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n } as TextMessageEndEvent);\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n }\n }\n\n return events;\n }\n\n /**\n * Handle user message (mainly for tool_result)\n * Claude SDK sends tool results as user messages with tool_result content\n */\n private handleUserMessage(\n sdkMessage: any,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n const message = sdkMessage.message;\n\n if (!message || !message.content || !Array.isArray(message.content)) {\n return events;\n }\n\n // Process tool_result content blocks\n for (const content of message.content) {\n if (content.type === \"tool_result\") {\n // Extract tool result content\n let resultContent = \"\";\n if (typeof content.content === \"string\") {\n resultContent = content.content;\n } else if (Array.isArray(content.content)) {\n // content.content is an array of content blocks\n resultContent = content.content\n .map((block: any) => {\n if (block.type === \"text\") {\n return block.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n\n // 🔑 Check if this is a client-side tool marker\n const isClientTool = this.isClientToolMarker(resultContent);\n\n if (isClientTool) {\n console.log(`[EventTransformer] Client-side tool detected: ${content.tool_use_id}, skipping tool-result event`);\n // ⚠️ DO NOT emit TOOL_CALL_RESULT event for client tools\n // The client will execute the tool and send the result back\n continue;\n }\n\n // Emit TOOL_CALL_RESULT event for server-side tools\n events.push({\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: content.tool_use_id,\n content: resultContent,\n } as ToolCallResultEvent);\n\n console.log(`[EventTransformer] Tool result for ${content.tool_use_id}: ${resultContent}`);\n }\n }\n\n return events;\n }\n\n /**\n * Handle result message (final query result)\n * This represents the end of the query execution\n */\n private handleResultMessage(\n message: SDKResultMessage,\n threadId: string,\n runId: string\n ): BaseEvent[] {\n const events: BaseEvent[] = [];\n\n // SDKResultMessage represents the final result of the entire query\n // It doesn't directly map to TOOL_CALL_RESULT\n // Instead, we can emit it as metadata or ignore it\n\n // If there are permission denials, we can log them\n if (message.permission_denials && message.permission_denials.length > 0) {\n for (const denial of message.permission_denials) {\n console.warn(`[EventTransformer] Permission denied for tool: ${denial.tool_name}, tool_use_id: ${denial.tool_use_id}`);\n // Optionally emit as error events\n events.push({\n type: EventType.RUN_ERROR,\n message: `Permission denied for tool: ${denial.tool_name}`,\n rawEvent: denial,\n } as any);\n }\n }\n\n // Handle success or error result\n if (message.subtype === 'success') {\n console.log(`[EventTransformer] Query completed successfully: ${message.result}, turns: ${message.num_turns}, cost: $${message.total_cost_usd}`);\n } else {\n // Error subtypes: error_during_execution, error_max_turns, error_max_budget_usd\n const errorMsg = `Query failed: ${message.subtype}`;\n console.error(`[EventTransformer] ${errorMsg}, errors: ${message.errors?.join(', ')}`);\n events.push({\n type: EventType.RUN_ERROR,\n message: errorMsg,\n rawEvent: message,\n } as any);\n }\n\n return events;\n }\n\n /**\n * Complete any active message\n * Call this when streaming ends to ensure TEXT_MESSAGE_END is emitted\n */\n public completeActiveMessage(): BaseEvent[] {\n if (this.activeMessageId) {\n const event: TextMessageEndEvent = {\n type: EventType.TEXT_MESSAGE_END,\n messageId: this.activeMessageId,\n };\n\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n\n return [event];\n }\n return [];\n }\n\n /**\n * Reset transformer state\n * Call this between runs to ensure clean state\n */\n public reset(): void {\n this.activeMessageId = undefined;\n this.messageContent = \"\";\n }\n\n /**\n * Generate unique message ID\n */\n private generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Generate unique tool call ID\n */\n private generateToolCallId(): string {\n return `tool_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n }\n\n /**\n * Remove MCP namespace prefix from tool name\n * \n * Claude Agent SDK adds MCP server namespace to tool names:\n * \"mcp__server-name__tool-name\" -> \"tool-name\"\n * \n * This ensures tool names match what the frontend expects and maintains\n * consistency with other AG-Kit agent implementations (LangChain, LangGraph).\n * \n * @param toolName - Tool name potentially with MCP prefix\n * @returns Clean tool name without prefix\n * \n * @example\n * removeMcpPrefix(\"mcp__agkit__change-background-color\") // \"change-background-color\"\n * removeMcpPrefix(\"change-background-color\") // \"change-background-color\"\n */\n private removeMcpPrefix(toolName: string): string {\n // Match pattern: mcp__<server-name>__<tool-name>\n const mcpPattern = /^mcp__[^_]+__(.+)$/;\n const match = toolName.match(mcpPattern);\n\n if (match) {\n const cleanName = match[1];\n console.log(`[EventTransformer] Removed MCP prefix: ${toolName} -> ${cleanName}`);\n return cleanName;\n }\n\n // No MCP prefix found, return original name\n return toolName;\n }\n\n /**\n * Check if tool result content contains client-side tool marker\n * \n * Client-side tools return a special marker indicating they need to be\n * executed on the frontend. We detect this marker to avoid sending\n * tool-result events prematurely.\n * \n * @param resultContent - Tool result content string\n * @returns true if this is a client-side tool marker\n */\n private isClientToolMarker(resultContent: string): boolean {\n try {\n const parsed = JSON.parse(resultContent);\n // 🔑 Check for __client_tool__ marker\n return parsed.__client_tool__ === true;\n } catch (error) {\n // Not JSON or doesn't contain marker\n return false;\n }\n }\n}\n\n","/**\n * Hooks manager for Claude Agent SDK\n * Creates hooks for monitoring and controlling Claude agent behavior\n * @module claude-sdk/hooks-manager\n */\n\nimport type { Subscriber } from \"rxjs\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { HookCallback } from \"./types\";\n\n/**\n * Manages Claude Agent SDK hooks for AG-UI event emission\n * \n * Hooks allow us to intercept Claude's behavior and emit corresponding AG-UI events.\n * This bridges Claude's lifecycle events to AG-Kit's event system.\n */\nexport class HooksManager {\n /**\n * Create hooks configuration for Claude Agent SDK\n * \n * @param subscriber - RxJS subscriber to emit AG-UI events\n * @param threadId - Conversation thread ID\n * @param runId - Current run ID\n * @returns Hooks configuration object\n */\n public createHooks(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): Record<string, HookCallback> {\n return {\n // Pre-tool use hook - called before tool execution\n preToolUse: this.createPreToolUseHook(subscriber),\n\n // Post-tool use hook - called after tool execution\n postToolUse: this.createPostToolUseHook(subscriber),\n\n // Session lifecycle hooks\n sessionStart: this.createSessionStartHook(subscriber, threadId, runId),\n sessionEnd: this.createSessionEndHook(subscriber, threadId, runId),\n\n // Notification hook - for system notifications\n notification: this.createNotificationHook(subscriber),\n\n // User prompt submit hook - when user submits input\n userPromptSubmit: this.createUserPromptSubmitHook(subscriber),\n };\n }\n\n /**\n * Create pre-tool use hook\n * Used for logging and permission checks before tool execution\n * \n * NOTE: We do NOT emit TOOL_CALL_START here to avoid duplicate events.\n * The EventTransformer will emit all tool call events when processing SDKAssistantMessage.\n */\n private createPreToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Log tool use for debugging/monitoring\n // The actual TOOL_CALL_START event will be emitted by EventTransformer\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Pre-tool use: ${input.toolName} (${input.toolUseId})`);\n }\n\n // Return continue signal to allow tool execution\n return { continue: true };\n };\n }\n\n /**\n * Create post-tool use hook\n * Called after tool execution completes\n */\n private createPostToolUseHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Tool result will be emitted via SDKResultMessage\n // This hook can be used for logging or side effects\n\n // Log tool execution completion\n if (input.toolUseId && input.toolName) {\n console.log(`[HooksManager] Tool executed: ${input.toolName} (${input.toolUseId})`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create session start hook\n * Called when agent session begins\n */\n private createSessionStartHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session started - RUN_STARTED already emitted in main run method\n // This hook can be used for additional initialization\n\n console.log(`[HooksManager] Session started: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create session end hook\n * Called when agent session ends\n */\n private createSessionEndHook(\n subscriber: Subscriber<BaseEvent>,\n threadId: string,\n runId: string\n ): HookCallback {\n return async (input: any) => {\n // Session ended - RUN_FINISHED will be emitted after query completes\n // This hook can be used for cleanup\n\n console.log(`[HooksManager] Session ended: ${threadId}`);\n\n return { continue: true };\n };\n }\n\n /**\n * Create notification hook\n * Handles system notifications from Claude\n */\n private createNotificationHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // Emit notification as console log\n // Could be extended to emit custom AG-UI notification events\n\n if (input.message) {\n console.log(`[Claude Notification] ${input.message}`);\n }\n\n return { continue: true };\n };\n }\n\n /**\n * Create user prompt submit hook\n * Called when user submits a prompt\n */\n private createUserPromptSubmitHook(subscriber: Subscriber<BaseEvent>): HookCallback {\n return async (input: any) => {\n // User prompt submitted\n // This is mainly for logging as the input is already processed\n\n if (input.prompt) {\n console.log(`[HooksManager] User prompt submitted: ${input.prompt}`);\n }\n\n return { continue: true };\n };\n }\n}\n\n"],"mappings":"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","names":["EventType","tool","EventType","tool"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/agent-adapter-claude-agent-sdk",
3
- "version": "0.0.8",
3
+ "version": "0.0.11",
4
4
  "description": "Claude Agent SDK adapter for AG-Kit agents",
5
5
  "files": [
6
6
  "dist/",
@@ -37,12 +37,12 @@
37
37
  "@anthropic-ai/claude-agent-sdk": "0.1.47",
38
38
  "@anthropic-ai/sdk": "^0.65.0",
39
39
  "rxjs": "^7.8.1",
40
- "@cloudbase/agent-tools": "0.0.8",
41
- "@cloudbase/agent-agents": "0.0.8"
40
+ "@cloudbase/agent-tools": "0.0.11",
41
+ "@cloudbase/agent-agents": "0.0.11"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "zod": "^3.25.0 || ^4.0.0",
45
- "@cloudbase/agent-agents": "0.0.8"
45
+ "@cloudbase/agent-agents": "0.0.11"
46
46
  },
47
47
  "scripts": {
48
48
  "test": "echo \"Error: no test specified\" && exit 1",