@cloudbase/agent-adapter-claude-agent-sdk 1.0.1-alpha.8 → 1.0.1-alpha.9
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 +26 -0
- package/dist/index.d.mts +2 -5
- package/dist/index.d.ts +2 -5
- package/dist/index.js +53 -58
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -58
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
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
|
-
|
|
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
|
-
|
|
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 === "
|
|
461
|
+
if (streamEvent.type === "content_block_start") {
|
|
462
|
+
const { type } = streamEvent.content_block;
|
|
483
463
|
this.activeMessageId = this.generateMessageId();
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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 === "
|
|
508
|
-
if (
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACaA,IAAAA,iBAA0B;AAC1B,sBAA8B;AAC9B,IAAAC,2BAAsB;AAEtB,kBAAuC;;;ACHhC,IAAM,mBAAN,MAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBrB,gBAAgB,cAAqC;AAC1D,UAAM,QAAkB,CAAC;AAEzB,eAAW,OAAO,cAAc;AAC9B,cAAQ,IAAI,MAAM;AAAA,QAChB,KAAK;AAEH,cAAI,IAAI,SAAS;AACf,kBAAM,KAAK;AAAA,EAAa,IAAI,OAAO;AAAA,CAAI;AAAA,UACzC;AACA;AAAA,QAEF,KAAK;AAEH,cAAI,IAAI,SAAS;AACf,kBAAM,KAAK,GAAG,IAAI,OAAO;AAAA,CAAI;AAAA,UAC/B;AACA;AAAA,QAEF,KAAK;AAEH,cAAI,IAAI,SAAS;AACf,kBAAM,KAAK;AAAA,EAAgB,IAAI,OAAO;AAAA,CAAI;AAAA,UAC5C;AAGA;AAAA,QAEF,KAAK;AAGH,cAAI,IAAI,cAAc,IAAI,SAAS;AACjC,kBAAM,KAAK,iBAAiB,IAAI,UAAU;AAAA,EAAM,IAAI,OAAO;AAAA,CAAI;AAAA,UACjE;AACA;AAAA,QAEF;AAEE,kBAAQ;AAAA,YACN,4CAA6C,IAAY,IAAI;AAAA,UAC/D;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,sBAAsB,cAAqC;AAChE,UAAM,iBAAiB,aACpB,OAAO,CAAC,QAAQ,IAAI,SAAS,YAAY,IAAI,OAAO,EACpD,IAAI,CAAC,QAAQ,IAAI,OAAO;AAE3B,WAAO,eAAe,KAAK,MAAM;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,uBAAuB,cAAqC;AAEjE,UAAM,kBAAkB,CAAC,GAAG,YAAY;AACxC,aAAS,IAAI,gBAAgB,SAAS,GAAG,KAAK,GAAG,KAAK;AACpD,UAAI,gBAAgB,CAAC,EAAE,SAAS,QAAQ;AACtC,wBAAgB,OAAO,GAAG,CAAC;AAC3B;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,gBAAgB,eAAe;AAAA,EAC7C;AACF;;;AC5GA,8BAAyC;AACzC,gBAAkB;AAQX,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASf,gBAAgB,MAAc,OAAmB,gBAAyB,OAAY;AAC3F,UAAM,WAAW,MAAM,IAAI,eAAa,KAAK,iBAAiB,WAAW,aAAa,CAAC;AAEvF,eAAO,4CAAmB;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBO,8BACL,MACA,OACA,gBAAyB,MACpB;AACL,UAAM,WAAW,MAAM,IAAI,CAAAC,UAAQ,KAAK,2BAA2BA,OAAM,aAAa,CAAC;AAEvF,eAAO,4CAAmB;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,iBAAiB,WAAqB,eAAwB,OAAY;AAChF,UAAM,WAAW,UAAU,YAAY;AACvC,UAAM,WAAW,SAAS,QAAQ;AAClC,UAAM,kBAAkB,SAAS,eAAe,gBAAgB,QAAQ;AAGxE,QAAI,WAAgB,CAAC;AAErB,QAAI,SAAS,QAAQ;AACnB,YAAM,SAAS,SAAS;AACxB,UAAI,OAAO,QAAQ,OAAO,OAAO,KAAK,UAAU,YAAY;AAC1D,mBAAW,OAAO,KAAK,MAAM;AAAA,MAC/B,WAAW,OAAO,QAAQ,OAAO,KAAK,OAAO;AAC3C,mBAAW,OAAO,KAAK;AAAA,MACzB,OAAO;AACL,gBAAQ,KAAK,sBAAsB,QAAQ,gDAAgD;AAAA,MAC7F;AAAA,IACF;AAEA,WAAO,KAAK,cAAc,UAAU,iBAAiB,UAAU,YAAY;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,2BACN,SAKA,eAAwB,OACnB;AAEL,UAAM,WAAW,KAAK,qBAAqB,QAAQ,UAAU;AAE7D,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ,eAAe,SAAS,QAAQ,IAAI;AAAA,MAC5C;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,cACN,MACA,aACA,UACA,eAAwB,OACnB;AACL,eAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,MAAW,UAAmB;AACnC,gBAAQ,IAAI,6BAA6B,IAAI,mBAAmB,YAAY,IAAI,EAAE,KAAK,CAAC;AAExF,YAAI,cAAc;AAGhB,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK,UAAU;AAAA,kBACnB,iBAAiB;AAAA;AAAA,kBACjB,MAAM;AAAA,kBACN;AAAA,kBACA,SAAS;AAAA,gBACX,CAAC;AAAA,cACH;AAAA,YACF;AAAA,YACA,SAAS;AAAA,UACX;AAAA,QACF;AAIA,gBAAQ,KAAK,kCAAkC,IAAI,yCAAyC;AAC5F,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK,UAAU;AAAA,gBACnB,MAAM;AAAA,gBACN;AAAA,gBACA,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,qBAAqB,YAAsB;AACjD,QAAI,CAAC,cAAc,OAAO,eAAe,UAAU;AACjD,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,WAAgB,CAAC;AAGvB,QAAI,WAAW,SAAS,YAAY,WAAW,YAAY;AACzD,YAAM,WAAW,MAAM,QAAQ,WAAW,QAAQ,IAAI,WAAW,WAAW,CAAC;AAE7E,iBAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,WAAW,UAAU,GAAG;AACrE,cAAM,aAAa,SAAS,SAAS,GAAG;AACxC,iBAAS,GAAG,IAAI,KAAK,wBAAwB,YAAmB,UAAU;AAAA,MAC5E;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAAwB,QAAa,YAA0B;AACrE,QAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,aAAO,aAAa,YAAE,IAAI,IAAI,YAAE,IAAI,EAAE,SAAS;AAAA,IACjD;AAEA,QAAI;AAEJ,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,kBAAU,YAAE,OAAO;AACnB,YAAI,OAAO,YAAa,WAAU,QAAQ,SAAS,OAAO,WAAW;AACrE,YAAI,MAAM,QAAQ,OAAO,IAAI,GAAG;AAC9B,oBAAU,YAAE,KAAK,OAAO,IAA6B;AAAA,QACvD;AACA;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,kBAAU,OAAO,SAAS,YAAY,YAAE,OAAO,EAAE,IAAI,IAAI,YAAE,OAAO;AAClE,YAAI,OAAO,YAAa,WAAU,QAAQ,SAAS,OAAO,WAAW;AACrE,YAAI,OAAO,YAAY,OAAW,WAAU,QAAQ,IAAI,OAAO,OAAO;AACtE,YAAI,OAAO,YAAY,OAAW,WAAU,QAAQ,IAAI,OAAO,OAAO;AACtE;AAAA,MAEF,KAAK;AACH,kBAAU,YAAE,QAAQ;AACpB,YAAI,OAAO,YAAa,WAAU,QAAQ,SAAS,OAAO,WAAW;AACrE;AAAA,MAEF,KAAK;AACH,YAAI,OAAO,OAAO;AAChB,gBAAM,WAAW,KAAK,wBAAwB,OAAO,OAAO,IAAI;AAChE,oBAAU,YAAE,MAAM,QAAQ;AAAA,QAC5B,OAAO;AACL,oBAAU,YAAE,MAAM,YAAE,IAAI,CAAC;AAAA,QAC3B;AACA,YAAI,OAAO,YAAa,WAAU,QAAQ,SAAS,OAAO,WAAW;AACrE;AAAA,MAEF,KAAK;AACH,YAAI,OAAO,YAAY;AACrB,gBAAM,cAAc,KAAK,qBAAqB,MAAM;AACpD,oBAAU,YAAE,OAAO,WAAW;AAAA,QAChC,OAAO;AACL,oBAAU,YAAE,OAAO,YAAE,OAAO,GAAG,YAAE,IAAI,CAAC;AAAA,QACxC;AACA,YAAI,OAAO,YAAa,WAAU,QAAQ,SAAS,OAAO,WAAW;AACrE;AAAA,MAEF;AACE,kBAAU,YAAE,IAAI;AAChB,YAAI,OAAO,YAAa,WAAU,QAAQ,SAAS,OAAO,WAAW;AAAA,IACzE;AAEA,WAAO,aAAa,UAAU,QAAQ,SAAS;AAAA,EACjD;AAEF;;;AC9PA,oBAA0B;AAcnB,IAAM,mBAAN,MAAuB;AAAA;AAAA;AAAA;AAAA;AAAA,EAS5B,YAAY,mBAA4B,OAAO;AAP/C,SAAQ,iBAAyB;AAQ/B,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBO,iBACL,YACA,UACA,OACa;AACb,UAAM,SAAsB,CAAC;AAE7B,YAAQ,WAAW,MAAM;AAAA,MACvB,KAAK;AACH,eAAO,KAAK,GAAG,KAAK,uBAAuB,YAAmC,UAAU,KAAK,CAAC;AAC9F;AAAA,MAEF,KAAK;AACH,eAAO,KAAK,GAAG,KAAK,8BAA8B,YAA0C,UAAU,KAAK,CAAC;AAC5G;AAAA,MAEF,KAAK;AACH,eAAO,KAAK,GAAG,KAAK,oBAAoB,YAAgC,UAAU,KAAK,CAAC;AACxF;AAAA,MAEF,KAAK;AAEH,eAAO,KAAK,GAAG,KAAK,kBAAkB,YAAmB,UAAU,KAAK,CAAC;AACzE;AAAA,MAEF,KAAK;AAEH;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AAEH;AAAA,MAEF;AACE,gBAAQ,KAAK,+CAAgD,WAAmB,IAAI,EAAE;AAAA,IAC1F;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,uBACN,YACA,UACA,OACa;AACb,UAAM,SAAsB,CAAC;AAC7B,UAAM,UAAU,WAAW;AAI3B,QAAI,KAAK,kBAAkB;AACzB,cAAQ,IAAI,gHAAsG;AAGlH,iBAAW,WAAW,QAAQ,SAAS;AACrC,YAAI,QAAQ,SAAS,YAAY;AAE/B,gBAAM,gBAAgB,KAAK,gBAAgB,QAAQ,IAAI;AAEvD,iBAAO,KAAK;AAAA,YACV,MAAM,wBAAU;AAAA,YAChB,YAAY,QAAQ;AAAA,YACpB,cAAc;AAAA,UAChB,CAAuB;AAEvB,gBAAM,WAAW,KAAK,UAAU,QAAQ,SAAS,CAAC,CAAC;AACnD,iBAAO,KAAK;AAAA,YACV,MAAM,wBAAU;AAAA,YAChB,YAAY,QAAQ;AAAA,YACpB,OAAO;AAAA,UACT,CAAsB;AAEtB,iBAAO,KAAK;AAAA,YACV,MAAM,wBAAU;AAAA,YAChB,YAAY,QAAQ;AAAA,UACtB,CAAqB;AAAA,QACvB;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAMA,QAAI,KAAK,iBAAiB;AACxB,cAAQ,IAAI,+CAA+C,KAAK,eAAe;AAC/E,aAAO,KAAK;AAAA,QACV,MAAM,wBAAU;AAAA,QAChB,WAAW,KAAK;AAAA,MAClB,CAAwB;AAAA,IAC1B;AAGA,SAAK,kBAAkB,KAAK,kBAAkB;AAC9C,SAAK,iBAAiB;AACtB,YAAQ,IAAI,4CAA4C,KAAK,eAAe;AAE5E,WAAO,KAAK;AAAA,MACV,MAAM,wBAAU;AAAA,MAChB,WAAW,KAAK;AAAA,MAChB,MAAM;AAAA,IACR,CAA0B;AAG1B,eAAW,WAAW,QAAQ,SAAS;AACrC,UAAI,QAAQ,SAAS,QAAQ;AAC3B,aAAK,kBAAkB,QAAQ;AAC/B,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,WAAW,KAAK;AAAA,UAChB,OAAO,QAAQ;AAAA,QACjB,CAA4B;AAAA,MAC9B,WAAW,QAAQ,SAAS,YAAY;AAItC,cAAM,gBAAgB,KAAK,gBAAgB,QAAQ,IAAI;AAGvD,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,YAAY,QAAQ;AAAA,UACpB,cAAc;AAAA,QAChB,CAAuB;AAGvB,cAAM,WAAW,KAAK,UAAU,QAAQ,SAAS,CAAC,CAAC;AACnD,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,YAAY,QAAQ;AAAA,UACpB,OAAO;AAAA,QACT,CAAsB;AAGtB,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,YAAY,QAAQ;AAAA,QACtB,CAAqB;AAAA,MACvB;AAAA,IACF;AAGA,WAAO,KAAK;AAAA,MACV,MAAM,wBAAU;AAAA,MAChB,WAAW,KAAK;AAAA,IAClB,CAAwB;AAGxB,SAAK,kBAAkB;AACvB,SAAK,iBAAiB;AAEtB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,8BACN,YACA,UACA,OACa;AACb,UAAM,SAAsB,CAAC;AAC7B,UAAM,cAAc,WAAW;AAG/B,QAAI,YAAY,SAAS,iBAAiB;AACxC,WAAK,kBAAkB,KAAK,kBAAkB;AAC9C,aAAO,KAAK;AAAA,QACV,MAAM,wBAAU;AAAA,QAChB,WAAW,KAAK;AAAA,QAChB,MAAM;AAAA,MACR,CAA0B;AAAA,IAC5B,WAAW,YAAY,SAAS,uBAAuB;AAErD,UAAI,CAAC,KAAK,iBAAiB;AACzB,aAAK,kBAAkB,KAAK,kBAAkB;AAC9C,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,WAAW,KAAK;AAAA,UAChB,MAAM;AAAA,QACR,CAA0B;AAAA,MAC5B;AAGA,UAAI,YAAY,MAAM,SAAS,cAAc;AAC3C,cAAM,YAAY,YAAY,MAAM;AACpC,aAAK,kBAAkB;AACvB,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,WAAW,KAAK;AAAA,UAChB,OAAO;AAAA,QACT,CAA4B;AAAA,MAC9B;AAAA,IACF,WAAW,YAAY,SAAS,iBAAiB;AAE/C,UAAI,YAAY,MAAM,aAAa;AAEjC,YAAI,KAAK,iBAAiB;AACxB,iBAAO,KAAK;AAAA,YACV,MAAM,wBAAU;AAAA,YAChB,WAAW,KAAK;AAAA,UAClB,CAAwB;AACxB,eAAK,kBAAkB;AACvB,eAAK,iBAAiB;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBACN,YACA,UACA,OACa;AACb,UAAM,SAAsB,CAAC;AAC7B,UAAM,UAAU,WAAW;AAE3B,QAAI,CAAC,WAAW,CAAC,QAAQ,WAAW,CAAC,MAAM,QAAQ,QAAQ,OAAO,GAAG;AACnE,aAAO;AAAA,IACT;AAGA,eAAW,WAAW,QAAQ,SAAS;AACrC,UAAI,QAAQ,SAAS,eAAe;AAElC,YAAI,gBAAgB;AACpB,YAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,0BAAgB,QAAQ;AAAA,QAC1B,WAAW,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAEzC,0BAAgB,QAAQ,QACrB,IAAI,CAAC,UAAe;AACnB,gBAAI,MAAM,SAAS,QAAQ;AACzB,qBAAO,MAAM;AAAA,YACf;AACA,mBAAO;AAAA,UACT,CAAC,EACA,KAAK,EAAE;AAAA,QACZ;AAGA,cAAM,eAAe,KAAK,mBAAmB,aAAa;AAE1D,YAAI,cAAc;AAChB,kBAAQ,IAAI,iDAAiD,QAAQ,WAAW,8BAA8B;AAG9G;AAAA,QACF;AAGA,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,YAAY,QAAQ;AAAA,UACpB,SAAS;AAAA,QACX,CAAwB;AAAA,MAE1B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBACN,SACA,UACA,OACa;AACb,UAAM,SAAsB,CAAC;AAO7B,QAAI,QAAQ,sBAAsB,QAAQ,mBAAmB,SAAS,GAAG;AACvE,iBAAW,UAAU,QAAQ,oBAAoB;AAC/C,gBAAQ,KAAK,kDAAkD,OAAO,SAAS,kBAAkB,OAAO,WAAW,EAAE;AAErH,eAAO,KAAK;AAAA,UACV,MAAM,wBAAU;AAAA,UAChB,SAAS,+BAA+B,OAAO,SAAS;AAAA,UACxD,UAAU;AAAA,QACZ,CAAQ;AAAA,MACV;AAAA,IACF;AAGA,QAAI,QAAQ,YAAY,WAAW;AACjC,cAAQ,IAAI,oDAAoD,QAAQ,MAAM,YAAY,QAAQ,SAAS,YAAY,QAAQ,cAAc,EAAE;AAAA,IACjJ,OAAO;AAEL,YAAM,WAAW,iBAAiB,QAAQ,OAAO;AACjD,cAAQ,MAAM,sBAAsB,QAAQ,aAAa,QAAQ,QAAQ,KAAK,IAAI,CAAC,EAAE;AACrF,aAAO,KAAK;AAAA,QACV,MAAM,wBAAU;AAAA,QAChB,SAAS;AAAA,QACT,UAAU;AAAA,MACZ,CAAQ;AAAA,IACV;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,wBAAqC;AAC1C,QAAI,KAAK,iBAAiB;AACxB,YAAM,QAA6B;AAAA,QACjC,MAAM,wBAAU;AAAA,QAChB,WAAW,KAAK;AAAA,MAClB;AAEA,WAAK,kBAAkB;AACvB,WAAK,iBAAiB;AAEtB,aAAO,CAAC,KAAK;AAAA,IACf;AACA,WAAO,CAAC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,QAAc;AACnB,SAAK,kBAAkB;AACvB,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAA4B;AAClC,WAAO,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAA6B;AACnC,WAAO,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBQ,gBAAgB,UAA0B;AAEhD,UAAM,aAAa;AACnB,UAAM,QAAQ,SAAS,MAAM,UAAU;AAEvC,QAAI,OAAO;AACT,YAAM,YAAY,MAAM,CAAC;AACzB,cAAQ,IAAI,0CAA0C,QAAQ,OAAO,SAAS,EAAE;AAChF,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,mBAAmB,eAAgC;AACzD,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,aAAa;AAEvC,aAAO,OAAO,oBAAoB;AAAA,IACpC,SAAS,OAAO;AAEd,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC/cO,IAAM,eAAN,MAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASjB,YACL,YACA,UACA,OAC8B;AAC9B,WAAO;AAAA;AAAA,MAEL,YAAY,KAAK,qBAAqB,UAAU;AAAA;AAAA,MAGhD,aAAa,KAAK,sBAAsB,UAAU;AAAA;AAAA,MAGlD,cAAc,KAAK,uBAAuB,YAAY,UAAU,KAAK;AAAA,MACrE,YAAY,KAAK,qBAAqB,YAAY,UAAU,KAAK;AAAA;AAAA,MAGjE,cAAc,KAAK,uBAAuB,UAAU;AAAA;AAAA,MAGpD,kBAAkB,KAAK,2BAA2B,UAAU;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBAAqB,YAAiD;AAC5E,WAAO,OAAO,UAAe;AAG3B,UAAI,MAAM,aAAa,MAAM,UAAU;AACrC,gBAAQ,IAAI,gCAAgC,MAAM,QAAQ,KAAK,MAAM,SAAS,GAAG;AAAA,MACnF;AAGA,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,sBAAsB,YAAiD;AAC7E,WAAO,OAAO,UAAe;AAK3B,UAAI,MAAM,aAAa,MAAM,UAAU;AACrC,gBAAQ,IAAI,iCAAiC,MAAM,QAAQ,KAAK,MAAM,SAAS,GAAG;AAAA,MACpF;AAEA,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBACN,YACA,UACA,OACc;AACd,WAAO,OAAO,UAAe;AAI3B,cAAQ,IAAI,mCAAmC,QAAQ,EAAE;AAEzD,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBACN,YACA,UACA,OACc;AACd,WAAO,OAAO,UAAe;AAI3B,cAAQ,IAAI,iCAAiC,QAAQ,EAAE;AAEvD,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,YAAiD;AAC9E,WAAO,OAAO,UAAe;AAI3B,UAAI,MAAM,SAAS;AACjB,gBAAQ,IAAI,yBAAyB,MAAM,OAAO,EAAE;AAAA,MACtD;AAEA,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,2BAA2B,YAAiD;AAClF,WAAO,OAAO,UAAe;AAI3B,UAAI,MAAM,QAAQ;AAChB,gBAAQ,IAAI,yCAAyC,MAAM,MAAM,EAAE;AAAA,MACrE;AAEA,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AAAA,EACF;AACF;;;AJpHO,IAAM,eAAN,MAAM,qBAAoB,8BAAc;AAAA,EAgB7C,YAAY,QAA8B;AACxC,UAAM,MAAM;AAfd,SAAQ,aAAoB,CAAC;AAgB3B,SAAK,SAAS;AAGd,SAAK,mBAAmB,IAAI,iBAAiB;AAC7C,SAAK,aAAa,IAAI,WAAW;AACjC,SAAK,eAAe,IAAI,aAAa;AAAA,EAIvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,IAAI,OAA6C;AACtD,WAAO,IAAI,uBAAsB,CAAC,eAAe;AAE/C,UAAI,MAAM,gBAAgB,QAAQ;AAChC,aAAK,QAAQ,YAAY,KAAK,EAAE,MAAM,CAAC,UAAU;AAE/C,kBAAQ,MAAM,gBAAgB,KAAK;AAAA,QACrC,CAAC;AAAA,MACH,OAAO;AACL,aAAK,KAAK,YAAY,KAAK,EAAE,MAAM,CAAC,UAAU;AAE5C,kBAAQ,MAAM,aAAa,KAAK;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,KACZ,YACA,OACe;AACf,UAAM,EAAE,UAAU,OAAO,UAAU,OAAO,WAAW,IAAI;AAGzD,SAAK,oBAAoB;AAGzB,eAAW,KAAK;AAAA,MACd,MAAM,yBAAU;AAAA,MAChB;AAAA,MACA;AAAA,IACF,CAAoB;AAEpB,QAAI;AAEF,YAAM,SAAS,KAAK,iBAAiB,gBAAgB,QAAQ;AAG7D,YAAM,aAAkC;AAAA,QACtC,GAAI,KAAK,OAAO,cAAc,CAAC;AAAA,QAC/B,GAAI,KAAK,OAAO,eAAe,cAAc,CAAC;AAAA,MAChD;AAIA,UAAI,cAAc,WAAW,SAAS,GAAG;AAEvC,cAAM,cAAc,WAAW,IAAI,CAAAC,WAAS;AAAA,UAC1C,MAAMA,MAAK;AAAA,UACX,aAAaA,MAAK;AAAA,UAClB,YAAY,OAAOA,MAAK,eAAe,WACnC,KAAK,MAAMA,MAAK,UAAU,IAC1BA,MAAK;AAAA,QACX,EAAE;AAKF,cAAM,gBAAgB,KAAK,WAAW;AAAA,UACpC;AAAA,UACA;AAAA,QACF;AAGA,mBAAW,OAAO,IAAI;AAAA,MACxB;AAIA,UAAI,KAAK,OAAO,UAAU,CAAC,QAAQ,IAAI,mBAAmB;AACxD,gBAAQ,IAAI,oBAAoB,KAAK,OAAO;AAAA,MAC9C;AAEA,YAAM,UAAqC;AAAA,QACzC,OAAO,KAAK,OAAO,SAAS;AAAA,QAC5B,uBAAuB,KAAK,OAAO;AAAA,QACnC,YAAY,OAAO,KAAK,UAAU,EAAE,SAAS,IAAI,aAAa;AAAA,QAC9D,gBAAgB,KAAK,OAAO;AAAA,QAC5B,YAAY,KAAK,OAAO;AAAA,QACxB,iCAAiC,KAAK,OAAO;AAAA,QAC7C,wBAAwB,KAAK,OAAO,2BAA2B;AAAA;AAAA,QAC/D,OAAO,KAAK,aAAa,YAAY,YAAY,UAAU,KAAK;AAAA,QAChE,GAAG,KAAK,OAAO;AAAA,MACjB;AAGA,YAAM,iBAAiB,aAAY,aAAa,IAAI,QAAQ;AAC5D,UAAI,gBAAgB;AAClB,gBAAQ,IAAI,mCAAmC,cAAc,gBAAgB,QAAQ,EAAE;AACvF,gBAAQ,SAAS;AAAA,MACnB;AAGA,YAAM,iBAAa,gCAAM;AAAA,QACvB;AAAA,QACA;AAAA,MACF,CAAC;AAGD,WAAK,eAAe;AAIpB,YAAM,mBAAmB,QAAQ,2BAA2B;AAC5D,cAAQ,IAAI,oCAAoC,gBAAgB;AAChE,YAAM,mBAAmB,IAAI,iBAAiB,gBAAgB;AAG9D,uBAAiB,cAAc,YAAY;AAEzC,YAAI,WAAW,SAAS,UAAU;AAChC,gBAAM,YAAY;AAClB,cAAI,UAAU,YAAY,UAAU,UAAU,YAAY;AACxD,oBAAQ,IAAI,sCAAsC,UAAU,UAAU,gBAAgB,QAAQ,EAAE;AAChG,yBAAY,aAAa,IAAI,UAAU,UAAU,UAAU;AAAA,UAC7D;AAAA,QACF;AAIA,cAAM,SAAS,iBAAiB,iBAAiB,YAAY,UAAU,KAAK;AAG5E,mBAAW,SAAS,QAAQ;AAC1B,qBAAW,KAAK,KAAK;AAAA,QACvB;AAGA,cAAM,cAAc,iBAAiB,sBAAsB;AAE3D,mBAAW,SAAS,aAAa;AAC/B,qBAAW,KAAK,KAAK;AAAA,QACvB;AAGA,cAAM,oBAAoB,KAAK,gBAAgB,UAAU;AACzD,YAAI,mBAAmB;AACrB,kBAAQ,IAAI,qCAAqC,iBAAiB;AAGlE,qBAAW,KAAK;AAAA,YACd,MAAM,yBAAU;AAAA,YAChB;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT,WAAW;AAAA,UACb,CAAqB;AAIrB,qBAAW,SAAS;AACpB;AAAA,QACF;AAAA,MACF;AAMA,iBAAW,KAAK;AAAA,QACd,MAAM,yBAAU;AAAA,QAChB;AAAA,QACA;AAAA,MACF,CAAqB;AAErB,iBAAW,SAAS;AAAA,IACtB,SAAS,OAAO;AAEd,iBAAW,KAAK;AAAA,QACd,MAAM,yBAAU;AAAA,QAChB;AAAA,QACA;AAAA,QACA,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,MAAM,iBAAiB,QAAQ,MAAM,OAAO;AAAA,MAC9C,CAAkB;AAKlB,iBAAW,SAAS;AAAA,IACtB,UAAE;AAAA,IAIF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,kBAA4D;AACjE,QAAI,KAAK,mBAAmB;AAC1B,aAAO,CAAC,UAAqB;AAC3B,aAAK,kBAAmB,KAAK,KAAK;AAAA,MACpC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAgB,YAIf;AAEP,QAAI,WAAW,SAAS,QAAQ;AAC9B,YAAM,UAAW,WAAmB;AAEpC,UAAI,CAAC,WAAW,CAAC,QAAQ,WAAW,CAAC,MAAM,QAAQ,QAAQ,OAAO,GAAG;AACnE,eAAO;AAAA,MACT;AAEA,iBAAW,WAAW,QAAQ,SAAS;AACrC,YAAI,QAAQ,SAAS,eAAe;AAElC,cAAI,gBAAgB;AACpB,cAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,4BAAgB,QAAQ;AAAA,UAC1B,WAAW,MAAM,QAAQ,QAAQ,OAAO,GAAG;AACzC,4BAAgB,QAAQ,QACrB,IAAI,CAAC,UAAe;AACnB,kBAAI,MAAM,SAAS,QAAQ;AACzB,uBAAO,MAAM;AAAA,cACf;AACA,qBAAO;AAAA,YACT,CAAC,EACA,KAAK,EAAE;AAAA,UACZ;AAGA,cAAI;AACF,kBAAM,SAAS,KAAK,MAAM,aAAa;AACvC,oBAAQ,IAAI,wCAAwC,MAAM;AAC1D,kBAAM,EAAE,YAAY,IAAI;AACxB,gBAAI,OAAO,kBAAkB,MAAM;AACjC,qBAAO;AAAA,gBACL,IAAI;AAAA,gBACJ,QAAQ,OAAO,UAAU;AAAA;AAAA,gBAEzB,SAAS;AAAA,cACX;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,QACZ,YACA,OACe;AACf,UAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,UAAM,gBAAgB,MAAM,gBAAgB,QAAQ;AAEpD,SAAK,oBAAoB;AAGzB,YAAQ,IAAI,wCAAwC,aAAa;AAEjE,QAAI;AAEF,YAAM,YAAY,aAAY,aAAa,IAAI,QAAQ;AACvD,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,mCAAmC,QAAQ,yDAAyD;AAAA,MACtH;AAEA,cAAQ,IAAI,mCAAmC,SAAS,EAAE;AAG1D,YAAM,eAAe,KAAK,kBAAkB,aAAa;AAGzD,YAAM,aAAkC;AAAA,QACtC,GAAI,KAAK,OAAO,cAAc,CAAC;AAAA,QAC/B,GAAI,KAAK,OAAO,eAAe,cAAc,CAAC;AAAA,MAChD;AAGA,YAAM,UAAqC;AAAA,QACzC,OAAO,KAAK,OAAO,SAAS;AAAA,QAC5B,YAAY,OAAO,KAAK,UAAU,EAAE,SAAS,IAAI,aAAa;AAAA,QAC9D,wBAAwB,KAAK,OAAO,2BAA2B;AAAA,QAC/D,OAAO,KAAK,aAAa,YAAY,YAAY,UAAU,KAAK;AAAA;AAAA,QAEhE,QAAQ;AAAA,QACR,gBAAgB,KAAK,OAAO;AAAA,QAC5B,YAAY,KAAK,OAAO;AAAA,QACxB,iCAAiC,KAAK,OAAO;AAAA,QAC7C,GAAG,KAAK,OAAO;AAAA,MACjB;AAGA,YAAM,iBAAa,gCAAM;AAAA,QACvB,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AAED,WAAK,eAAe;AAEpB,iBAAW,KAAK;AAAA,QACd,MAAM,yBAAU;AAAA,QAChB;AAAA,QACA;AAAA,MACF,CAAoB;AAEpB,YAAM,mBAAmB,QAAQ,2BAA2B;AAC5D,YAAM,mBAAmB,IAAI,iBAAiB,gBAAgB;AAG9D,uBAAiB,cAAc,YAAY;AAGzC,cAAM,SAAS,iBAAiB,iBAAiB,YAAY,UAAU,KAAK;AAC5E,mBAAW,SAAS,QAAQ;AAC1B,qBAAW,KAAK,KAAK;AAAA,QACvB;AAIA,cAAM,oBAAoB,KAAK,gBAAgB,UAAU;AACzD,YAAI,mBAAmB;AACrB,kBAAQ,IAAI,+CAA+C,iBAAiB;AAG5E,qBAAW,KAAK;AAAA,YACd,MAAM,yBAAU;AAAA,YAChB;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT,WAAW;AAAA,UACb,CAAqB;AAGrB,qBAAW,SAAS;AACpB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,iBAAiB,sBAAsB;AAC3D,iBAAW,SAAS,aAAa;AAC/B,mBAAW,KAAK,KAAK;AAAA,MACvB;AAEA,iBAAW,KAAK;AAAA,QACd,MAAM,yBAAU;AAAA,QAChB;AAAA,QACA;AAAA,MACF,CAAqB;AAErB,iBAAW,SAAS;AAAA,IAEtB,SAAS,OAAO;AACd,iBAAW,KAAK;AAAA,QACd,MAAM,yBAAU;AAAA,QAChB;AAAA,QACA;AAAA,QACA,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,MAAM;AAAA,MACR,CAAkB;AAKlB,iBAAW,SAAS;AAAA,IACtB,UAAE;AAAA,IAIF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,SAAsB;AAE9C,QAAI,QAAQ,OAAO;AACjB,YAAM,eAAe,QAAQ,MAAM,OAAO,CAAC,MAAW,EAAE,WAAW,SAAS;AAC5E,YAAM,gBAAgB,QAAQ,MAAM,OAAO,CAAC,MAAW,EAAE,WAAW,UAAU;AAE9E,UAAI,SAAS;AAEb,UAAI,cAAc,SAAS,GAAG;AAC5B,kBAAU,sCAAsC,cAAc,IAAI,CAAC,MAAW,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;AAAA,MACzG;AAEA,gBAAU,2CAA2C,aAAa,IAAI,CAAC,MAAW,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;AAC3G,gBAAU;AAEV,aAAO;AAAA,IACT;AAGA,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKO,aAAa,UAAwB;AAC1C,iBAAY,aAAa,OAAO,QAAQ;AACxC,YAAQ,IAAI,6CAA6C,QAAQ,EAAE;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,oBAAyC;AACrD,WAAO,aAAY;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKO,WAAmB;AACxB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKO,YAAoB;AACzB,UAAM,MAAM,KAAK,OAAO,UAAU,QAAQ,IAAI,qBAAqB;AACnE,WAAO,MAAM,GAAG,IAAI,UAAU,GAAG,CAAC,CAAC,QAAQ;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKO,qBAA6B;AAClC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKO,wBAAiC;AACtC,WAAO,KAAK,OAAO,uBAAuB;AAAA,EAC5C;AACF;AAAA;AAAA;AA9ea,aASG,eAAoC,oBAAI,IAAI;AATrD,IAAM,cAAN;","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
|
-
|
|
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
|
-
|
|
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 === "
|
|
431
|
+
if (streamEvent.type === "content_block_start") {
|
|
432
|
+
const { type } = streamEvent.content_block;
|
|
453
433
|
this.activeMessageId = this.generateMessageId();
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
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 === "
|
|
478
|
-
if (
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
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,
|
package/dist/index.mjs.map
CHANGED
|
@@ -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": "1.0.1-alpha.
|
|
3
|
+
"version": "1.0.1-alpha.9",
|
|
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-
|
|
41
|
-
"@cloudbase/agent-
|
|
40
|
+
"@cloudbase/agent-tools": "1.0.1-alpha.9",
|
|
41
|
+
"@cloudbase/agent-agents": "1.0.1-alpha.9"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"zod": "^3.25.0 || ^4.0.0",
|
|
45
|
-
"@cloudbase/agent-agents": "1.0.1-alpha.
|
|
45
|
+
"@cloudbase/agent-agents": "1.0.1-alpha.9"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"test": "echo \"Error: no test specified\" && exit 1",
|