@cloudbase/agent-adapter-claude-agent-sdk 0.0.13 → 0.0.15

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,31 @@
1
1
  # @cloudbase/agent-adapter-claude-agent-sdk
2
2
 
3
+ ## 1.0.1-alpha.8
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.8
14
+ - @cloudbase/agent-agents@1.0.1-alpha.8
15
+
16
+ ## 1.0.1-alpha.7
17
+
18
+ ### Patch Changes
19
+
20
+ - alpha release 0.1.2-alpha.1
21
+ - Update all public packages to version 0.1.2-alpha.1
22
+ - Trigger automated alpha release workflow
23
+ - Includes latest features and improvements
24
+
25
+ - Updated dependencies
26
+ - @cloudbase/agent-tools@1.0.1-alpha.7
27
+ - @cloudbase/agent-agents@1.0.1-alpha.7
28
+
3
29
  ## 1.0.1-alpha.6
4
30
 
5
31
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -321,6 +321,7 @@ declare class ToolBridge {
321
321
  */
322
322
  declare class EventTransformer {
323
323
  private activeMessageId?;
324
+ private activeToolCallId?;
324
325
  private messageContent;
325
326
  private streamingEnabled;
326
327
  /**
@@ -375,11 +376,6 @@ declare class EventTransformer {
375
376
  * Call this when streaming ends to ensure TEXT_MESSAGE_END is emitted
376
377
  */
377
378
  completeActiveMessage(): BaseEvent[];
378
- /**
379
- * Reset transformer state
380
- * Call this between runs to ensure clean state
381
- */
382
- reset(): void;
383
379
  /**
384
380
  * Generate unique message ID
385
381
  */
@@ -416,6 +412,7 @@ declare class EventTransformer {
416
412
  * @returns true if this is a client-side tool marker
417
413
  */
418
414
  private isClientToolMarker;
415
+ private isInterruptMarker;
419
416
  }
420
417
 
421
418
  /**
package/dist/index.d.ts CHANGED
@@ -321,6 +321,7 @@ declare class ToolBridge {
321
321
  */
322
322
  declare class EventTransformer {
323
323
  private activeMessageId?;
324
+ private activeToolCallId?;
324
325
  private messageContent;
325
326
  private streamingEnabled;
326
327
  /**
@@ -375,11 +376,6 @@ declare class EventTransformer {
375
376
  * Call this when streaming ends to ensure TEXT_MESSAGE_END is emitted
376
377
  */
377
378
  completeActiveMessage(): BaseEvent[];
378
- /**
379
- * Reset transformer state
380
- * Call this between runs to ensure clean state
381
- */
382
- reset(): void;
383
379
  /**
384
380
  * Generate unique message ID
385
381
  */
@@ -416,6 +412,7 @@ declare class EventTransformer {
416
412
  * @returns true if this is a client-side tool marker
417
413
  */
418
414
  private isClientToolMarker;
415
+ private isInterruptMarker;
419
416
  }
420
417
 
421
418
  /**
package/dist/index.js CHANGED
@@ -366,7 +366,9 @@ var EventTransformer = class {
366
366
  const events = [];
367
367
  switch (sdkMessage.type) {
368
368
  case "assistant":
369
- events.push(...this.handleAssistantMessage(sdkMessage, threadId, runId));
369
+ if (!this.streamingEnabled) {
370
+ events.push(...this.handleAssistantMessage(sdkMessage, threadId, runId));
371
+ }
370
372
  break;
371
373
  case "stream_event":
372
374
  events.push(...this.handlePartialAssistantMessage(sdkMessage, threadId, runId));
@@ -398,30 +400,7 @@ var EventTransformer = class {
398
400
  handleAssistantMessage(sdkMessage, threadId, runId) {
399
401
  const events = [];
400
402
  const message = sdkMessage.message;
401
- if (this.streamingEnabled) {
402
- console.log("[EventTransformer] \u26A0\uFE0F Streaming enabled: skipping assistant message text content to avoid duplicates");
403
- for (const content of message.content) {
404
- if (content.type === "tool_use") {
405
- const cleanToolName = this.removeMcpPrefix(content.name);
406
- events.push({
407
- type: import_client.EventType.TOOL_CALL_START,
408
- toolCallId: content.id,
409
- toolCallName: cleanToolName
410
- });
411
- const argsJson = JSON.stringify(content.input || {});
412
- events.push({
413
- type: import_client.EventType.TOOL_CALL_ARGS,
414
- toolCallId: content.id,
415
- delta: argsJson
416
- });
417
- events.push({
418
- type: import_client.EventType.TOOL_CALL_END,
419
- toolCallId: content.id
420
- });
421
- }
422
- }
423
- return events;
424
- }
403
+ console.log("[EventTransformer] Non-streaming mode: processing full assistant message");
425
404
  if (this.activeMessageId) {
426
405
  console.log("[EventTransformer] Ending previous message:", this.activeMessageId);
427
406
  events.push({
@@ -479,13 +458,24 @@ var EventTransformer = class {
479
458
  handlePartialAssistantMessage(sdkMessage, threadId, runId) {
480
459
  const events = [];
481
460
  const streamEvent = sdkMessage.event;
482
- if (streamEvent.type === "message_start") {
461
+ if (streamEvent.type === "content_block_start") {
462
+ const { type } = streamEvent.content_block;
483
463
  this.activeMessageId = this.generateMessageId();
484
- events.push({
485
- type: import_client.EventType.TEXT_MESSAGE_START,
486
- messageId: this.activeMessageId,
487
- role: "assistant"
488
- });
464
+ if (type === "text") {
465
+ events.push({
466
+ type: import_client.EventType.TEXT_MESSAGE_START,
467
+ messageId: this.activeMessageId,
468
+ role: "assistant"
469
+ });
470
+ } else if (type === "tool_use") {
471
+ const cleanToolName = this.removeMcpPrefix(streamEvent.content_block.name);
472
+ this.activeToolCallId = streamEvent.content_block.id;
473
+ events.push({
474
+ type: import_client.EventType.TOOL_CALL_START,
475
+ toolCallId: streamEvent.content_block.id,
476
+ toolCallName: cleanToolName
477
+ });
478
+ }
489
479
  } else if (streamEvent.type === "content_block_delta") {
490
480
  if (!this.activeMessageId) {
491
481
  this.activeMessageId = this.generateMessageId();
@@ -503,17 +493,28 @@ var EventTransformer = class {
503
493
  messageId: this.activeMessageId,
504
494
  delta: textDelta
505
495
  });
496
+ } else if (streamEvent.delta.type === "input_json_delta") {
497
+ const toolUseDelta = streamEvent.delta.partial_json;
498
+ events.push({
499
+ type: import_client.EventType.TOOL_CALL_ARGS,
500
+ toolCallId: this.activeToolCallId,
501
+ delta: toolUseDelta
502
+ });
506
503
  }
507
- } else if (streamEvent.type === "message_delta") {
508
- if (streamEvent.delta.stop_reason) {
509
- if (this.activeMessageId) {
510
- events.push({
511
- type: import_client.EventType.TEXT_MESSAGE_END,
512
- messageId: this.activeMessageId
513
- });
514
- this.activeMessageId = void 0;
515
- this.messageContent = "";
516
- }
504
+ } else if (streamEvent.type === "content_block_stop") {
505
+ if (this.activeToolCallId) {
506
+ events.push({
507
+ type: import_client.EventType.TOOL_CALL_END,
508
+ toolCallId: this.activeToolCallId
509
+ });
510
+ this.activeToolCallId = void 0;
511
+ } else if (this.activeMessageId) {
512
+ events.push({
513
+ type: import_client.EventType.TEXT_MESSAGE_END,
514
+ messageId: this.activeMessageId
515
+ });
516
+ this.activeMessageId = void 0;
517
+ this.messageContent = "";
517
518
  }
518
519
  }
519
520
  return events;
@@ -546,10 +547,12 @@ var EventTransformer = class {
546
547
  console.log(`[EventTransformer] Client-side tool detected: ${content.tool_use_id}, skipping tool-result event`);
547
548
  continue;
548
549
  }
550
+ const isInterrupt = this.isInterruptMarker(resultContent);
549
551
  events.push({
550
552
  type: import_client.EventType.TOOL_CALL_RESULT,
551
553
  toolCallId: content.tool_use_id,
552
- content: resultContent
554
+ content: resultContent,
555
+ rawEvent: isInterrupt ? "interrupt" : void 0
553
556
  });
554
557
  }
555
558
  }
@@ -600,14 +603,6 @@ var EventTransformer = class {
600
603
  }
601
604
  return [];
602
605
  }
603
- /**
604
- * Reset transformer state
605
- * Call this between runs to ensure clean state
606
- */
607
- reset() {
608
- this.activeMessageId = void 0;
609
- this.messageContent = "";
610
- }
611
606
  /**
612
607
  * Generate unique message ID
613
608
  */
@@ -664,6 +659,14 @@ var EventTransformer = class {
664
659
  return false;
665
660
  }
666
661
  }
662
+ isInterruptMarker(resultContent) {
663
+ try {
664
+ const parsed = JSON.parse(resultContent);
665
+ return parsed.__interrupt__ === true;
666
+ } catch (error) {
667
+ return false;
668
+ }
669
+ }
667
670
  };
668
671
 
669
672
  // src/hooks-manager.ts
@@ -863,10 +866,6 @@ var _ClaudeAgent = class _ClaudeAgent extends import_abstract.AbstractAgent {
863
866
  for (const event of events) {
864
867
  subscriber.next(event);
865
868
  }
866
- const finalEvents = eventTransformer.completeActiveMessage();
867
- for (const event of finalEvents) {
868
- subscriber.next(event);
869
- }
870
869
  const interruptDetected = this.detectInterrupt(sdkMessage);
871
870
  if (interruptDetected) {
872
871
  console.log("[ClaudeAgent] Interrupt detected:", interruptDetected);
@@ -1018,10 +1017,6 @@ var _ClaudeAgent = class _ClaudeAgent extends import_abstract.AbstractAgent {
1018
1017
  return;
1019
1018
  }
1020
1019
  }
1021
- const finalEvents = eventTransformer.completeActiveMessage();
1022
- for (const event of finalEvents) {
1023
- subscriber.next(event);
1024
- }
1025
1020
  subscriber.next({
1026
1021
  type: import_client2.EventType.RUN_FINISHED,
1027
1022
  threadId,
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 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\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 // 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 // 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 // 🔑 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 // Complete any active message\n const finalEvents = eventTransformer.completeActiveMessage();\n\n for (const event of finalEvents) {\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 // 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 // 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 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 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 }\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"]}
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 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\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 // 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 // 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 // 🔑 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 // // Complete any active message\n // const finalEvents = eventTransformer.completeActiveMessage();\n\n // for (const event of finalEvents) {\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 // 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 // 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 activeToolCallId?: 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 if (!this.streamingEnabled) {\n events.push(...this.handleAssistantMessage(sdkMessage as SDKAssistantMessage, threadId, runId));\n }\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 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 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 // Handle different stream event types\n if (streamEvent.type === \"content_block_start\") {\n const { type } = streamEvent.content_block;\n this.activeMessageId = this.generateMessageId();\n if (type === \"text\") {\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n } else if (type === \"tool_use\") {\n const cleanToolName = this.removeMcpPrefix(streamEvent.content_block.name);\n this.activeToolCallId = streamEvent.content_block.id;\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: streamEvent.content_block.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n }\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 } else if (streamEvent.delta.type === \"input_json_delta\") {\n const toolUseDelta = streamEvent.delta.partial_json;\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: this.activeToolCallId,\n delta: toolUseDelta,\n } as ToolCallArgsEvent);\n }\n } else if (streamEvent.type === \"content_block_stop\") {\n if (this.activeToolCallId) {\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: this.activeToolCallId,\n } as ToolCallEndEvent);\n this.activeToolCallId = undefined;\n } else 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 // 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 const isInterrupt = this.isInterruptMarker(resultContent);\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 rawEvent: isInterrupt ? \"interrupt\" : undefined,\n } as ToolCallResultEvent);\n\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 * 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 private isInterruptMarker(resultContent: string): boolean {\n try {\n const parsed = JSON.parse(resultContent);\n return parsed.__interrupt__ === true;\n } catch (error) {\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
@@ -336,7 +336,9 @@ var EventTransformer = class {
336
336
  const events = [];
337
337
  switch (sdkMessage.type) {
338
338
  case "assistant":
339
- events.push(...this.handleAssistantMessage(sdkMessage, threadId, runId));
339
+ if (!this.streamingEnabled) {
340
+ events.push(...this.handleAssistantMessage(sdkMessage, threadId, runId));
341
+ }
340
342
  break;
341
343
  case "stream_event":
342
344
  events.push(...this.handlePartialAssistantMessage(sdkMessage, threadId, runId));
@@ -368,30 +370,7 @@ var EventTransformer = class {
368
370
  handleAssistantMessage(sdkMessage, threadId, runId) {
369
371
  const events = [];
370
372
  const message = sdkMessage.message;
371
- if (this.streamingEnabled) {
372
- console.log("[EventTransformer] \u26A0\uFE0F Streaming enabled: skipping assistant message text content to avoid duplicates");
373
- for (const content of message.content) {
374
- if (content.type === "tool_use") {
375
- const cleanToolName = this.removeMcpPrefix(content.name);
376
- events.push({
377
- type: EventType.TOOL_CALL_START,
378
- toolCallId: content.id,
379
- toolCallName: cleanToolName
380
- });
381
- const argsJson = JSON.stringify(content.input || {});
382
- events.push({
383
- type: EventType.TOOL_CALL_ARGS,
384
- toolCallId: content.id,
385
- delta: argsJson
386
- });
387
- events.push({
388
- type: EventType.TOOL_CALL_END,
389
- toolCallId: content.id
390
- });
391
- }
392
- }
393
- return events;
394
- }
373
+ console.log("[EventTransformer] Non-streaming mode: processing full assistant message");
395
374
  if (this.activeMessageId) {
396
375
  console.log("[EventTransformer] Ending previous message:", this.activeMessageId);
397
376
  events.push({
@@ -449,13 +428,24 @@ var EventTransformer = class {
449
428
  handlePartialAssistantMessage(sdkMessage, threadId, runId) {
450
429
  const events = [];
451
430
  const streamEvent = sdkMessage.event;
452
- if (streamEvent.type === "message_start") {
431
+ if (streamEvent.type === "content_block_start") {
432
+ const { type } = streamEvent.content_block;
453
433
  this.activeMessageId = this.generateMessageId();
454
- events.push({
455
- type: EventType.TEXT_MESSAGE_START,
456
- messageId: this.activeMessageId,
457
- role: "assistant"
458
- });
434
+ if (type === "text") {
435
+ events.push({
436
+ type: EventType.TEXT_MESSAGE_START,
437
+ messageId: this.activeMessageId,
438
+ role: "assistant"
439
+ });
440
+ } else if (type === "tool_use") {
441
+ const cleanToolName = this.removeMcpPrefix(streamEvent.content_block.name);
442
+ this.activeToolCallId = streamEvent.content_block.id;
443
+ events.push({
444
+ type: EventType.TOOL_CALL_START,
445
+ toolCallId: streamEvent.content_block.id,
446
+ toolCallName: cleanToolName
447
+ });
448
+ }
459
449
  } else if (streamEvent.type === "content_block_delta") {
460
450
  if (!this.activeMessageId) {
461
451
  this.activeMessageId = this.generateMessageId();
@@ -473,17 +463,28 @@ var EventTransformer = class {
473
463
  messageId: this.activeMessageId,
474
464
  delta: textDelta
475
465
  });
466
+ } else if (streamEvent.delta.type === "input_json_delta") {
467
+ const toolUseDelta = streamEvent.delta.partial_json;
468
+ events.push({
469
+ type: EventType.TOOL_CALL_ARGS,
470
+ toolCallId: this.activeToolCallId,
471
+ delta: toolUseDelta
472
+ });
476
473
  }
477
- } else if (streamEvent.type === "message_delta") {
478
- if (streamEvent.delta.stop_reason) {
479
- if (this.activeMessageId) {
480
- events.push({
481
- type: EventType.TEXT_MESSAGE_END,
482
- messageId: this.activeMessageId
483
- });
484
- this.activeMessageId = void 0;
485
- this.messageContent = "";
486
- }
474
+ } else if (streamEvent.type === "content_block_stop") {
475
+ if (this.activeToolCallId) {
476
+ events.push({
477
+ type: EventType.TOOL_CALL_END,
478
+ toolCallId: this.activeToolCallId
479
+ });
480
+ this.activeToolCallId = void 0;
481
+ } else if (this.activeMessageId) {
482
+ events.push({
483
+ type: EventType.TEXT_MESSAGE_END,
484
+ messageId: this.activeMessageId
485
+ });
486
+ this.activeMessageId = void 0;
487
+ this.messageContent = "";
487
488
  }
488
489
  }
489
490
  return events;
@@ -516,10 +517,12 @@ var EventTransformer = class {
516
517
  console.log(`[EventTransformer] Client-side tool detected: ${content.tool_use_id}, skipping tool-result event`);
517
518
  continue;
518
519
  }
520
+ const isInterrupt = this.isInterruptMarker(resultContent);
519
521
  events.push({
520
522
  type: EventType.TOOL_CALL_RESULT,
521
523
  toolCallId: content.tool_use_id,
522
- content: resultContent
524
+ content: resultContent,
525
+ rawEvent: isInterrupt ? "interrupt" : void 0
523
526
  });
524
527
  }
525
528
  }
@@ -570,14 +573,6 @@ var EventTransformer = class {
570
573
  }
571
574
  return [];
572
575
  }
573
- /**
574
- * Reset transformer state
575
- * Call this between runs to ensure clean state
576
- */
577
- reset() {
578
- this.activeMessageId = void 0;
579
- this.messageContent = "";
580
- }
581
576
  /**
582
577
  * Generate unique message ID
583
578
  */
@@ -634,6 +629,14 @@ var EventTransformer = class {
634
629
  return false;
635
630
  }
636
631
  }
632
+ isInterruptMarker(resultContent) {
633
+ try {
634
+ const parsed = JSON.parse(resultContent);
635
+ return parsed.__interrupt__ === true;
636
+ } catch (error) {
637
+ return false;
638
+ }
639
+ }
637
640
  };
638
641
 
639
642
  // src/hooks-manager.ts
@@ -833,10 +836,6 @@ var _ClaudeAgent = class _ClaudeAgent extends AbstractAgent {
833
836
  for (const event of events) {
834
837
  subscriber.next(event);
835
838
  }
836
- const finalEvents = eventTransformer.completeActiveMessage();
837
- for (const event of finalEvents) {
838
- subscriber.next(event);
839
- }
840
839
  const interruptDetected = this.detectInterrupt(sdkMessage);
841
840
  if (interruptDetected) {
842
841
  console.log("[ClaudeAgent] Interrupt detected:", interruptDetected);
@@ -988,10 +987,6 @@ var _ClaudeAgent = class _ClaudeAgent extends AbstractAgent {
988
987
  return;
989
988
  }
990
989
  }
991
- const finalEvents = eventTransformer.completeActiveMessage();
992
- for (const event of finalEvents) {
993
- subscriber.next(event);
994
- }
995
990
  subscriber.next({
996
991
  type: EventType2.RUN_FINISHED,
997
992
  threadId,
@@ -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 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\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 // 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 // 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 // 🔑 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 // Complete any active message\n const finalEvents = eventTransformer.completeActiveMessage();\n\n for (const event of finalEvents) {\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 // 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 // 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 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 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 }\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"]}
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 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\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 // 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 // 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 // 🔑 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 // // Complete any active message\n // const finalEvents = eventTransformer.completeActiveMessage();\n\n // for (const event of finalEvents) {\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 // 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 // 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 activeToolCallId?: 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 if (!this.streamingEnabled) {\n events.push(...this.handleAssistantMessage(sdkMessage as SDKAssistantMessage, threadId, runId));\n }\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 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 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 // Handle different stream event types\n if (streamEvent.type === \"content_block_start\") {\n const { type } = streamEvent.content_block;\n this.activeMessageId = this.generateMessageId();\n if (type === \"text\") {\n events.push({\n type: EventType.TEXT_MESSAGE_START,\n messageId: this.activeMessageId,\n role: \"assistant\",\n } as TextMessageStartEvent);\n } else if (type === \"tool_use\") {\n const cleanToolName = this.removeMcpPrefix(streamEvent.content_block.name);\n this.activeToolCallId = streamEvent.content_block.id;\n events.push({\n type: EventType.TOOL_CALL_START,\n toolCallId: streamEvent.content_block.id,\n toolCallName: cleanToolName,\n } as ToolCallStartEvent);\n }\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 } else if (streamEvent.delta.type === \"input_json_delta\") {\n const toolUseDelta = streamEvent.delta.partial_json;\n events.push({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: this.activeToolCallId,\n delta: toolUseDelta,\n } as ToolCallArgsEvent);\n }\n } else if (streamEvent.type === \"content_block_stop\") {\n if (this.activeToolCallId) {\n events.push({\n type: EventType.TOOL_CALL_END,\n toolCallId: this.activeToolCallId,\n } as ToolCallEndEvent);\n this.activeToolCallId = undefined;\n } else 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 // 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 const isInterrupt = this.isInterruptMarker(resultContent);\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 rawEvent: isInterrupt ? \"interrupt\" : undefined,\n } as ToolCallResultEvent);\n\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 * 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 private isInterruptMarker(resultContent: string): boolean {\n try {\n const parsed = JSON.parse(resultContent);\n return parsed.__interrupt__ === true;\n } catch (error) {\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.13",
3
+ "version": "0.0.15",
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-agents": "0.0.13",
41
- "@cloudbase/agent-tools": "0.0.13"
40
+ "@cloudbase/agent-agents": "0.0.15",
41
+ "@cloudbase/agent-tools": "0.0.15"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "zod": "^3.25.0 || ^4.0.0",
45
- "@cloudbase/agent-agents": "0.0.13"
45
+ "@cloudbase/agent-agents": "0.0.15"
46
46
  },
47
47
  "scripts": {
48
48
  "test": "echo \"Error: no test specified\" && exit 1",