{"version":3,"sources":["../src/adapter.ts","../src/config.ts","../src/utils.ts","../src/handlers.ts"],"sourcesContent":["/**\n * Claude Agent SDK adapter for AG-UI protocol.\n */\n\nimport { Observable, Subscriber } from \"rxjs\";\nimport { AbstractAgent, EventType, randomUUID } from \"@ag-ui/client\";\nimport type { BaseEvent, RunAgentInput, Message } from \"@ag-ui/core\";\n\nimport { createSdkMcpServer, query } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n  Query,\n  Options,\n  SDKResultMessage,\n  SDKPartialAssistantMessage,\n  SDKAssistantMessage,\n  SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { BetaToolUseBlock } from \"@anthropic-ai/sdk/resources/beta/messages/messages\";\n\nimport type { ClaudeAgentAdapterConfig, ProcessedEvent } from \"./types\";\nimport {\n  ALLOWED_FORWARDED_PROPS,\n  STATE_MANAGEMENT_TOOL_NAME,\n  STATE_MANAGEMENT_TOOL_FULL_NAME,\n  AG_UI_MCP_SERVER_NAME,\n} from \"./config\";\nimport {\n  processMessages,\n  buildStateContextAddendum,\n  extractToolNames,\n  stripMcpPrefix,\n  convertAguiToolToClaudeSdk,\n  createStateManagementTool,\n  applyForwardedProps,\n  hasState,\n  buildAguiAssistantMessage,\n  buildAguiToolMessage,\n  isStateManagementTool,\n} from \"./utils\";\nimport { handleToolUseBlock } from \"./handlers\";\n\n/**\n * AG-UI adapter for the Anthropic Claude Agent SDK.\n *\n * Manages the SDK query lifecycle internally via per-request `query()` calls\n * with session resume for multi-turn. Call `adapter.run(input)` to get an\n * Observable of AG-UI events.\n *\n * **Header forwarding:** CopilotKit Runtime sets `agent.headers` with per-request\n * forwarded headers (e.g. `x-aimock-context`, `x-test-id`). This property is\n * declared here for forward compatibility so the runtime's assignment is not lost.\n * However, headers are NOT functionally forwarded to LLM calls because the Claude\n * Agent SDK is process-based — `query()` spawns a CLI child process, and there is\n * no mechanism to inject HTTP headers into the LLM API calls made by that process.\n *\n * If the Claude Agent SDK adds a `headers` or `extraHeaders` option to its\n * `Options` type in the future, this adapter should wire `this.headers` through\n * at that point.\n */\nexport class ClaudeAgentAdapter extends AbstractAgent {\n  private static readonly DEFAULT_MAX_SESSIONS = 1000;\n  private static readonly DEFAULT_SESSION_TTL_MS = 30 * 60 * 1000;\n\n  /**\n   * Per-request HTTP headers set by CopilotKit Runtime via `configureAgentForRequest()`.\n   *\n   * These headers are NOT functionally forwarded to LLM calls because the Claude\n   * Agent SDK has no per-request HTTP header mechanism (it is process-based, not HTTP).\n   * This property exists for forward compatibility — if Anthropic adds per-request\n   * header support to the SDK Options type, wire it here.\n   */\n  public headers?: Record<string, string>;\n\n  private config: ClaudeAgentAdapterConfig;\n  private activeQueries = new Map<string, Query>();\n  private sessions = new Map<\n    string,\n    { sessionId: string; lastUsed: number; active: boolean }\n  >();\n\n  constructor(config: ClaudeAgentAdapterConfig = {}) {\n    super(config);\n    this.config = config;\n  }\n\n  private evictSessions(): void {\n    const ttlMs =\n      this.config.sessionTtlMs ?? ClaudeAgentAdapter.DEFAULT_SESSION_TTL_MS;\n    const maxSessions =\n      this.config.maxSessions ?? ClaudeAgentAdapter.DEFAULT_MAX_SESSIONS;\n    const now = Date.now();\n\n    // Remove idle entries older than TTL\n    for (const [key, entry] of this.sessions.entries()) {\n      if (!entry.active && now - entry.lastUsed > ttlMs) {\n        this.sessions.delete(key);\n      }\n    }\n\n    // If still over the limit, remove oldest idle entries\n    if (this.sessions.size > maxSessions) {\n      const idle = [...this.sessions.entries()]\n        .filter(([, e]) => !e.active)\n        .sort(([, a], [, b]) => a.lastUsed - b.lastUsed);\n\n      for (const [key] of idle) {\n        if (this.sessions.size <= maxSessions) break;\n        this.sessions.delete(key);\n      }\n    }\n  }\n\n  public clearSession(threadId: string): void {\n    this.sessions.delete(threadId);\n  }\n\n  public clone(): ClaudeAgentAdapter {\n    const cloned = super.clone() as ClaudeAgentAdapter;\n    cloned.config = { ...this.config };\n    if (this.headers) {\n      cloned.headers = { ...this.headers };\n    }\n    return cloned;\n  }\n\n  public async interrupt(): Promise<void> {\n    for (const q of this.activeQueries.values()) {\n      await q.interrupt();\n    }\n  }\n\n  run(input: RunAgentInput): Observable<BaseEvent> {\n    return new Observable<ProcessedEvent>((subscriber) => {\n      if (this.headers && Object.keys(this.headers).length > 0) {\n        console.debug(\n          \"[ClaudeAdapter] headers set but not forwarded (Claude Agent SDK does not support per-request HTTP headers)\",\n        );\n      }\n\n      // Inject resume for known threads\n      const threadId = input.threadId ?? \"default\";\n      let runInput = input;\n      const sessionEntry = this.sessions.get(threadId);\n      if (sessionEntry) {\n        runInput = {\n          ...input,\n          forwardedProps: {\n            ...(input.forwardedProps ?? {}),\n            resume: sessionEntry.sessionId,\n          },\n        };\n        // Mark existing session as active\n        sessionEntry.active = true;\n      }\n\n      const { userMessage } = processMessages(runInput);\n      const options = this.buildOptions(runInput);\n\n      let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n      const abortController = this.config.queryTimeoutMs\n        ? new AbortController()\n        : undefined;\n      if (abortController) {\n        timeoutHandle = setTimeout(\n          () => abortController.abort(),\n          this.config.queryTimeoutMs!,\n        );\n      }\n\n      const queryStream = query({\n        prompt: userMessage,\n        options: {\n          ...options,\n          model: options.model, // SDK picks default if omitted\n          ...(abortController ? { abortController } : {}),\n        },\n      });\n\n      this.activeQueries.set(threadId, queryStream);\n\n      this.translateStream(runInput, queryStream, subscriber)\n        .catch((error) => {\n          subscriber.error(error);\n        })\n        .finally(() => {\n          if (timeoutHandle !== undefined) clearTimeout(timeoutHandle);\n          this.activeQueries.delete(threadId);\n        });\n    });\n  }\n\n  private async translateStream(\n    input: RunAgentInput,\n    messageStream: AsyncIterable<unknown>,\n    subscriber: Subscriber<ProcessedEvent>,\n  ): Promise<void> {\n    const threadId = input.threadId ?? randomUUID();\n    const runId = input.runId ?? randomUUID();\n\n    const runCtx = {\n      currentState: hasState(input.state) ? input.state : null,\n      lastResultData: undefined as Record<string, unknown> | undefined,\n    };\n\n    try {\n      if (input.parentRunId) {\n        console.debug(\n          `[ClaudeAdapter] Run ${runId.slice(0, 8)}... branched from ${input.parentRunId.slice(0, 8)}...`,\n        );\n      }\n\n      subscriber.next({\n        type: EventType.RUN_STARTED,\n        threadId,\n        runId,\n      });\n\n      const frontendToolNames = new Set(\n        input.tools?.length ? extractToolNames(input.tools) : [],\n      );\n      if (frontendToolNames.size > 0) {\n        console.debug(\n          `[ClaudeAdapter] Frontend tools detected: [${[...frontendToolNames].join(\", \")}]`,\n        );\n      }\n\n      if (hasState(input.state)) {\n        subscriber.next({\n          type: EventType.STATE_SNAPSHOT,\n          snapshot: input.state,\n        });\n      }\n\n      await this.streamMessages(\n        messageStream,\n        threadId,\n        runId,\n        input,\n        frontendToolNames,\n        subscriber,\n        runCtx,\n      );\n\n      subscriber.next({\n        type: EventType.RUN_FINISHED,\n        threadId,\n        runId,\n        result: runCtx.lastResultData,\n      });\n\n      subscriber.complete();\n    } catch (error) {\n      console.error(`[ClaudeAdapter] Error:`, error);\n      const errorMessage =\n        error instanceof Error ? error.message : String(error);\n\n      subscriber.next({\n        type: EventType.RUN_ERROR,\n        threadId,\n        runId,\n        message: errorMessage,\n      });\n      subscriber.complete();\n    }\n  }\n\n  /** Build Claude SDK Options from base config + RunAgentInput. */\n  public buildOptions(input: RunAgentInput): Options {\n    // Start with sensible defaults\n    const merged: Record<string, unknown> = {\n      includePartialMessages: true,\n    };\n\n    // Exclude AG-UI specific fields from SDK options\n    const {\n      agentId: _agentId,\n      description: _desc,\n      threadId: _threadId,\n      initialMessages: _msgs,\n      initialState: _state,\n      debug: _debug,\n      ...sdkOptions\n    } = this.config;\n\n    for (const [key, value] of Object.entries(sdkOptions)) {\n      if (value != null) {\n        merged[key] = value;\n      }\n    }\n\n    // Append state and context to the system prompt\n    const addendum = buildStateContextAddendum(input);\n    if (addendum) {\n      const base = (merged.systemPrompt as string) ?? \"\";\n      merged.systemPrompt = base ? `${base}\\n\\n${addendum}` : addendum;\n      console.debug(\n        `[ClaudeAdapter] Appended state/context (${addendum.length} chars) to systemPrompt`,\n      );\n    }\n\n    // Ensure ag_ui tools are always allowed (frontend tools + state management)\n    if (hasState(input.state) || input.tools?.length) {\n      const allowedTools = (merged.allowedTools as string[]) ?? [];\n      const toolsToAdd: string[] = [];\n\n      // Add state management tool if state is provided\n      if (\n        hasState(input.state) &&\n        !allowedTools.includes(STATE_MANAGEMENT_TOOL_FULL_NAME)\n      ) {\n        toolsToAdd.push(STATE_MANAGEMENT_TOOL_FULL_NAME);\n      }\n\n      // Add frontend tools (prefixed with mcp__ag_ui__)\n      if (input.tools?.length) {\n        for (const toolName of extractToolNames(input.tools)) {\n          const prefixedName = `mcp__ag_ui__${toolName}`;\n          if (!allowedTools.includes(prefixedName)) {\n            toolsToAdd.push(prefixedName);\n          }\n        }\n      }\n\n      if (toolsToAdd.length > 0) {\n        merged.allowedTools = [...allowedTools, ...toolsToAdd];\n        console.debug(\n          `[ClaudeAdapter] Auto-granted permission to ag_ui tools: [${toolsToAdd.join(\", \")}]`,\n        );\n      }\n    }\n\n    // Apply forwardedProps as per-run overrides\n    if (hasState(input.forwardedProps)) {\n      applyForwardedProps(\n        input.forwardedProps as Record<string, unknown>,\n        merged,\n        ALLOWED_FORWARDED_PROPS,\n      );\n    }\n\n    // Add dynamic tools from input.tools and state management\n    const existingServers = (merged.mcpServers ?? {}) as Record<\n      string,\n      unknown\n    >;\n    const agUiTools: ReturnType<typeof convertAguiToolToClaudeSdk>[] = [];\n\n    // Add frontend tools from input.tools\n    if (input.tools?.length) {\n      console.debug(\n        `[ClaudeAdapter] Building dynamic MCP server with ${input.tools.length} frontend tools`,\n      );\n      for (const toolDef of input.tools) {\n        try {\n          agUiTools.push(convertAguiToolToClaudeSdk(toolDef));\n        } catch (e) {\n          console.warn(`[ClaudeAdapter] Failed to convert tool:`, e);\n        }\n      }\n    }\n\n    // Add state management tool if meaningful state is provided\n    if (hasState(input.state)) {\n      console.debug(\n        \"[ClaudeAdapter] Adding ag_ui_update_state tool for state management\",\n      );\n      agUiTools.push(createStateManagementTool());\n    }\n\n    // Create ag_ui MCP server if we have any tools\n    if (agUiTools.length > 0) {\n      const agUiServer = createSdkMcpServer({\n        name: AG_UI_MCP_SERVER_NAME,\n        version: \"1.0.0\",\n        tools: agUiTools,\n      });\n\n      merged.mcpServers = {\n        ...existingServers,\n        [AG_UI_MCP_SERVER_NAME]: agUiServer,\n      };\n\n      console.debug(\n        `[ClaudeAdapter] Created ag_ui MCP server with ${agUiTools.length} tools`,\n      );\n    }\n\n    return merged as Options;\n  }\n\n  /** Consume a Claude SDK message stream and emit AG-UI events. */\n  private async streamMessages(\n    messageStream: AsyncIterable<unknown>,\n    threadId: string,\n    runId: string,\n    input: RunAgentInput,\n    frontendToolNames: Set<string>,\n    subscriber: Subscriber<ProcessedEvent>,\n    runCtx: {\n      currentState: unknown;\n      lastResultData: Record<string, unknown> | undefined;\n    },\n  ): Promise<void> {\n    // Per-run state (local to this invocation)\n    let currentMessageId: string | null = null;\n    let inReasoningBlock = false;\n    let reasoningMessageId: string | null = null;\n    let hasStreamedText = false;\n    let accumulatedSignature = \"\";\n\n    // Tool call streaming state\n    let currentToolCallId: string | null = null;\n    let currentToolCallName: string | null = null;\n    let currentToolDisplayName: string | null = null;\n    let accumulatedToolJson = \"\";\n\n    const processedToolIds = new Set<string>();\n\n    let haltEventStream = false;\n\n    // ── MESSAGES_SNAPSHOT accumulation ──\n    const runMessages: Message[] = [];\n\n    const upsertMessage = (msg: Message) => {\n      const idx = runMessages.findIndex((m) => m.id === msg.id);\n      if (idx !== -1) {\n        runMessages[idx] = msg;\n      } else {\n        runMessages.push(msg);\n      }\n    };\n\n    type ToolCallEntry = {\n      id: string;\n      type: \"function\";\n      function: { name: string; arguments: string };\n    };\n    let pendingMsg: {\n      id: string;\n      content: string;\n      toolCalls: ToolCallEntry[];\n    } | null = null;\n\n    const flushPendingMsg = () => {\n      if (!pendingMsg) return;\n      if (pendingMsg.content || pendingMsg.toolCalls.length > 0) {\n        upsertMessage({\n          id: pendingMsg.id,\n          role: \"assistant\" as const,\n          ...(pendingMsg.content ? { content: pendingMsg.content } : {}),\n          ...(pendingMsg.toolCalls.length > 0\n            ? { toolCalls: pendingMsg.toolCalls }\n            : {}),\n        });\n      }\n      pendingMsg = null;\n    };\n\n    let messageCount = 0;\n\n    try {\n      for await (const rawMessage of messageStream) {\n        messageCount++;\n        if (haltEventStream) break;\n\n        const message = rawMessage as Record<string, unknown> & {\n          type: string;\n        };\n\n        // Handle streaming events\n        if (message.type === \"stream_event\") {\n          const streamMsg = message as SDKPartialAssistantMessage;\n          const event = streamMsg.event as unknown as Record<string, unknown>;\n          const eventType = event.type as string;\n\n          if (eventType === \"message_start\") {\n            // Defer TEXT_MESSAGE_START until we get actual text (avoids empty messages from thinking-only blocks)\n            currentMessageId = randomUUID();\n            hasStreamedText = false;\n            pendingMsg = { id: currentMessageId, content: \"\", toolCalls: [] };\n          } else if (eventType === \"content_block_delta\") {\n            const delta = (event.delta as Record<string, unknown>) ?? {};\n            const deltaType = delta.type as string;\n\n            if (deltaType === \"text_delta\") {\n              const text = delta.text as string | undefined;\n              if (text && currentMessageId) {\n                if (!hasStreamedText) {\n                  subscriber.next({\n                    type: EventType.TEXT_MESSAGE_START,\n                    threadId,\n                    runId,\n                    messageId: currentMessageId,\n                    role: \"assistant\",\n                  });\n                }\n                hasStreamedText = true;\n                if (pendingMsg) pendingMsg.content += text;\n\n                subscriber.next({\n                  type: EventType.TEXT_MESSAGE_CONTENT,\n                  threadId,\n                  runId,\n                  messageId: currentMessageId,\n                  delta: text,\n                });\n              }\n            } else if (deltaType === \"thinking_delta\") {\n              const thinking = delta.thinking as string | undefined;\n              if (thinking && reasoningMessageId) {\n                subscriber.next({\n                  type: EventType.REASONING_MESSAGE_CONTENT,\n                  messageId: reasoningMessageId,\n                  delta: thinking,\n                });\n              }\n            } else if (deltaType === \"signature_delta\") {\n              const sig = delta.signature as string | undefined;\n              if (sig) {\n                accumulatedSignature += sig;\n              }\n            } else if (deltaType === \"input_json_delta\") {\n              const partialJson = delta.partial_json as string | undefined;\n              if (partialJson && currentToolCallId) {\n                accumulatedToolJson += partialJson;\n                subscriber.next({\n                  type: EventType.TOOL_CALL_ARGS,\n                  threadId,\n                  runId,\n                  toolCallId: currentToolCallId,\n                  delta: partialJson,\n                });\n              }\n            }\n          } else if (eventType === \"content_block_start\") {\n            const block =\n              (event.content_block as Record<string, unknown>) ?? {};\n\n            if (block.type === \"thinking\") {\n              inReasoningBlock = true;\n              reasoningMessageId = randomUUID();\n              subscriber.next({\n                type: EventType.REASONING_START,\n                messageId: reasoningMessageId,\n              });\n              subscriber.next({\n                type: EventType.REASONING_MESSAGE_START,\n                messageId: reasoningMessageId,\n                role: \"reasoning\",\n              });\n            } else if (block.type === \"tool_use\") {\n              currentToolCallId = (block.id as string) ?? null;\n              currentToolCallName = (block.name as string) ?? \"unknown\";\n              accumulatedToolJson = \"\";\n\n              if (currentToolCallId) {\n                currentToolDisplayName = stripMcpPrefix(currentToolCallName);\n                processedToolIds.add(currentToolCallId);\n\n                subscriber.next({\n                  type: EventType.TOOL_CALL_START,\n                  threadId,\n                  runId,\n                  toolCallId: currentToolCallId,\n                  toolCallName: currentToolDisplayName, // Use unprefixed name for frontend matching!\n                  parentMessageId: currentMessageId ?? undefined, // Link to parent message\n                });\n              }\n            }\n          } else if (eventType === \"content_block_stop\") {\n            if (inReasoningBlock && reasoningMessageId) {\n              inReasoningBlock = false;\n              subscriber.next({\n                type: EventType.REASONING_MESSAGE_END,\n                messageId: reasoningMessageId,\n              });\n              subscriber.next({\n                type: EventType.REASONING_END,\n                messageId: reasoningMessageId,\n              });\n\n              // Emit encrypted signature if present\n              if (accumulatedSignature && currentMessageId) {\n                subscriber.next({\n                  type: EventType.REASONING_ENCRYPTED_VALUE,\n                  subtype: \"message\",\n                  entityId: currentMessageId,\n                  encryptedValue: accumulatedSignature,\n                });\n              }\n\n              accumulatedSignature = \"\";\n              reasoningMessageId = null;\n            }\n\n            // Close tool call if we were streaming one\n            if (currentToolCallId) {\n              // Check if this is the state management tool\n              if (isStateManagementTool(currentToolCallName ?? \"\")) {\n                // Parse accumulated JSON and emit STATE_SNAPSHOT\n                try {\n                  const stateArgs = JSON.parse(accumulatedToolJson);\n                  if (typeof stateArgs === \"object\" && stateArgs !== null) {\n                    let updates = stateArgs.state_updates ?? stateArgs;\n\n                    // Parse nested JSON string if needed\n                    if (typeof updates === \"string\") {\n                      updates = JSON.parse(updates);\n                    }\n\n                    const prevStateJson = JSON.stringify(runCtx.currentState);\n\n                    if (\n                      typeof runCtx.currentState === \"object\" &&\n                      runCtx.currentState !== null &&\n                      typeof updates === \"object\" &&\n                      updates !== null\n                    ) {\n                      runCtx.currentState = {\n                        ...(runCtx.currentState as Record<string, unknown>),\n                        ...(updates as Record<string, unknown>),\n                      };\n                    } else {\n                      runCtx.currentState = updates;\n                    }\n\n                    const newStateJson = JSON.stringify(runCtx.currentState);\n\n                    if (newStateJson !== prevStateJson) {\n                      subscriber.next({\n                        type: EventType.STATE_SNAPSHOT,\n                        snapshot: runCtx.currentState,\n                      });\n                    }\n                  }\n                } catch {\n                  console.warn(\n                    \"[ClaudeAdapter] Failed to parse tool JSON for state update\",\n                  );\n                  subscriber.next({\n                    type: EventType.CUSTOM,\n                    name: \"state_update_error\",\n                    value: { error: \"Failed to parse state update\" },\n                  });\n                }\n              }\n\n              // Push tool call onto in-flight message (skip state management)\n              if (\n                pendingMsg &&\n                currentToolCallId &&\n                currentToolDisplayName &&\n                !isStateManagementTool(currentToolCallName ?? \"\")\n              ) {\n                pendingMsg.toolCalls.push({\n                  id: currentToolCallId,\n                  type: \"function\" as const,\n                  function: {\n                    name: currentToolDisplayName,\n                    arguments: accumulatedToolJson,\n                  },\n                });\n              }\n\n              const isFrontendTool =\n                currentToolDisplayName != null &&\n                frontendToolNames.has(currentToolDisplayName);\n\n              if (isFrontendTool) {\n                flushPendingMsg();\n                subscriber.next({\n                  type: EventType.TOOL_CALL_END,\n                  threadId,\n                  runId,\n                  toolCallId: currentToolCallId,\n                });\n\n                if (currentMessageId && hasStreamedText) {\n                  subscriber.next({\n                    type: EventType.TEXT_MESSAGE_END,\n                    threadId,\n                    runId,\n                    messageId: currentMessageId,\n                  });\n                  currentMessageId = null;\n                }\n\n                console.debug(\n                  `[ClaudeAdapter] Frontend tool halt: ${currentToolDisplayName}`,\n                );\n\n                currentToolCallId = null;\n                currentToolCallName = null;\n                currentToolDisplayName = null;\n                accumulatedToolJson = \"\";\n                haltEventStream = true;\n                continue;\n              }\n\n              // For regular backend tools, emit TOOL_CALL_END at content_block_stop.\n              // The SDK executes backend tools internally and returns results in\n              // a subsequent message (ToolResultBlock in Python, SDKUserMessage in TS).\n              subscriber.next({\n                type: EventType.TOOL_CALL_END,\n                threadId,\n                runId,\n                toolCallId: currentToolCallId,\n              });\n\n              currentToolCallId = null;\n              currentToolCallName = null;\n              currentToolDisplayName = null;\n              accumulatedToolJson = \"\";\n            }\n          } else if (eventType === \"message_stop\") {\n            flushPendingMsg();\n\n            if (currentMessageId && hasStreamedText) {\n              subscriber.next({\n                type: EventType.TEXT_MESSAGE_END,\n                threadId,\n                runId,\n                messageId: currentMessageId,\n              });\n            }\n            currentMessageId = null;\n          } else if (eventType === \"message_delta\") {\n            const delta = (event.delta as Record<string, unknown>) ?? {};\n            const stopReason = delta.stop_reason as string | undefined;\n            if (stopReason) {\n              console.debug(\n                `[ClaudeAdapter] Message stop_reason: ${stopReason}`,\n              );\n            }\n          }\n        }\n        // Handle complete assistant messages\n        else if (message.type === \"assistant\") {\n          const assistantMsg = message as SDKAssistantMessage;\n          const content = assistantMsg.message?.content ?? [];\n\n          {\n            const msgId = currentMessageId ?? randomUUID();\n            const aguiMsg = buildAguiAssistantMessage(assistantMsg, msgId);\n            if (aguiMsg) {\n              upsertMessage(aguiMsg);\n            }\n          }\n\n          // Process any tool_use blocks not already seen via streaming\n          for (const block of content) {\n            if (block.type !== \"tool_use\") continue;\n            const toolBlock = block as BetaToolUseBlock;\n            if (toolBlock.id && processedToolIds.has(toolBlock.id)) continue;\n\n            const { updatedState } = handleToolUseBlock(\n              toolBlock,\n              assistantMsg.parent_tool_use_id ?? undefined,\n              threadId,\n              runId,\n              runCtx.currentState,\n              subscriber,\n            );\n            if (toolBlock.id) processedToolIds.add(toolBlock.id);\n            if (updatedState !== null) runCtx.currentState = updatedState;\n\n            // Check for frontend tool halt (same logic as streaming path)\n            const blockDisplayName = stripMcpPrefix(toolBlock.name ?? \"\");\n            if (blockDisplayName && frontendToolNames.has(blockDisplayName)) {\n              flushPendingMsg();\n\n              if (currentMessageId && hasStreamedText) {\n                subscriber.next({\n                  type: EventType.TEXT_MESSAGE_END,\n                  threadId,\n                  runId,\n                  messageId: currentMessageId,\n                });\n                currentMessageId = null;\n              }\n\n              console.debug(\n                `[ClaudeAdapter] Frontend tool halt (non-streaming): ${blockDisplayName}`,\n              );\n              haltEventStream = true;\n              break;\n            }\n          }\n        }\n        // Handle user messages (tool results)\n        else if (message.type === \"user\") {\n          const userMsg = message as SDKUserMessage;\n\n          const msgContent = (userMsg.message ?? userMsg) as {\n            content?: unknown[];\n          };\n          const contentBlocks = msgContent.content;\n\n          if (Array.isArray(contentBlocks)) {\n            for (const blk of contentBlocks) {\n              const block = blk as Record<string, unknown>;\n              if (block.type === \"tool_result\" && block.tool_use_id) {\n                const toolUseId = block.tool_use_id as string;\n                const resultContent = block.content;\n\n                const toolMsg = buildAguiToolMessage(toolUseId, resultContent);\n                upsertMessage(toolMsg);\n\n                subscriber.next({\n                  type: EventType.TOOL_CALL_RESULT,\n                  threadId,\n                  runId,\n                  messageId: toolMsg.id,\n                  toolCallId: toolUseId,\n                  content: toolMsg.content as string,\n                  role: \"tool\",\n                });\n              }\n            }\n          }\n        }\n        // Handle system messages\n        else if (message.type === \"system\") {\n          const raw = message as unknown as Record<string, unknown>;\n          const subtype = raw.subtype as string | undefined;\n          const data = raw.data as Record<string, unknown> | undefined;\n\n          // Capture session_id for multi-turn resume\n          if (subtype === \"init\") {\n            const sid = (raw.session_id ?? data?.session_id) as\n              | string\n              | undefined;\n            if (sid) {\n              this.sessions.set(threadId, {\n                sessionId: sid,\n                lastUsed: Date.now(),\n                active: false,\n              });\n              this.evictSessions();\n              console.debug(\n                `[ClaudeAdapter] Captured session_id=${sid} for thread=${threadId}`,\n              );\n            }\n          }\n\n          // Emit system messages as CUSTOM events with the raw SDK data\n          subscriber.next({\n            type: EventType.CUSTOM,\n            name: `system:${subtype ?? \"unknown\"}`,\n            value: data ?? raw,\n          });\n        }\n        // Handle result messages\n        else if (message.type === \"result\") {\n          const resultMsg = message as SDKResultMessage;\n\n          runCtx.lastResultData = {\n            isError: (resultMsg as { is_error?: boolean }).is_error ?? false,\n            durationMs: (resultMsg as { duration_ms?: number }).duration_ms,\n            durationApiMs: (resultMsg as { duration_api_ms?: number })\n              .duration_api_ms,\n            numTurns: (resultMsg as { num_turns?: number }).num_turns,\n            totalCostUsd: (resultMsg as { total_cost_usd?: number })\n              .total_cost_usd,\n            usage:\n              (resultMsg as { usage?: Record<string, unknown> }).usage ?? {},\n            structuredOutput: (resultMsg as { structured_output?: unknown })\n              .structured_output,\n          };\n\n          const resultText = (resultMsg as { result?: string }).result;\n          if (!hasStreamedText && resultText) {\n            const resultMsgId = randomUUID();\n            subscriber.next({\n              type: EventType.TEXT_MESSAGE_START,\n              threadId,\n              runId,\n              messageId: resultMsgId,\n              role: \"assistant\",\n            });\n            subscriber.next({\n              type: EventType.TEXT_MESSAGE_CONTENT,\n              threadId,\n              runId,\n              messageId: resultMsgId,\n              delta: resultText,\n            });\n            subscriber.next({\n              type: EventType.TEXT_MESSAGE_END,\n              threadId,\n              runId,\n              messageId: resultMsgId,\n            });\n\n            upsertMessage({\n              id: resultMsgId,\n              role: \"assistant\" as const,\n              content: resultText,\n            });\n          }\n        }\n      }\n    } finally {\n      // ── Event cleanup ──\n      // Close any hanging events so the frontend doesn't get stuck\n      // waiting for END events that will never arrive.\n      if (currentToolCallId) {\n        console.debug(\n          `[ClaudeAdapter] Cleanup: closing hanging TOOL_CALL_START for ${currentToolCallId}`,\n        );\n        subscriber.next({\n          type: EventType.TOOL_CALL_END,\n          threadId,\n          runId,\n          toolCallId: currentToolCallId,\n        });\n        currentToolCallId = null;\n      }\n\n      if (inReasoningBlock && reasoningMessageId) {\n        console.debug(\n          \"[ClaudeAdapter] Cleanup: closing hanging reasoning block\",\n        );\n        subscriber.next({\n          type: EventType.REASONING_MESSAGE_END,\n          messageId: reasoningMessageId,\n        });\n        subscriber.next({\n          type: EventType.REASONING_END,\n          messageId: reasoningMessageId,\n        });\n        inReasoningBlock = false;\n        reasoningMessageId = null;\n      }\n\n      if (hasStreamedText && currentMessageId) {\n        console.debug(\n          `[ClaudeAdapter] Cleanup: closing hanging TEXT_MESSAGE_START for ${currentMessageId}`,\n        );\n        subscriber.next({\n          type: EventType.TEXT_MESSAGE_END,\n          threadId,\n          runId,\n          messageId: currentMessageId,\n        });\n      }\n\n      flushPendingMsg();\n\n      // Mark session as idle after run completes and run TTL/LRU eviction\n      const idleEntry = this.sessions.get(threadId);\n      if (idleEntry) {\n        idleEntry.active = false;\n        idleEntry.lastUsed = Date.now();\n        this.evictSessions();\n      }\n    }\n\n    // Emit MESSAGES_SNAPSHOT with input messages + new messages from this run\n    if (runMessages.length > 0) {\n      const allMessages: Message[] = [\n        ...(input.messages ?? []),\n        ...runMessages,\n      ];\n      console.debug(\n        `[ClaudeAdapter] MESSAGES_SNAPSHOT: ${allMessages.length} msgs (${messageCount} SDK messages processed)`,\n      );\n      subscriber.next({\n        type: EventType.MESSAGES_SNAPSHOT,\n        messages: allMessages,\n      });\n    }\n  }\n}\n","/**\n * Configuration constants for Claude Agent SDK adapter.\n *\n * Defines whitelists, defaults, and configuration options.\n */\n\n/**\n * Whitelist of forwardedProps keys that can be applied as per-run option overrides.\n * These are runtime execution controls, not agent identity/security settings.\n *\n * Uses camelCase to match the TS Claude Agent SDK Options type.\n */\nexport const ALLOWED_FORWARDED_PROPS = new Set<string>([\n  // Session control\n  \"resume\", // Session ID to resume\n  \"forkSession\", // Fork vs continue session\n  \"resumeSessionAt\", // Time travel to specific message\n\n  // Model control\n  \"model\", // Per-run model override\n  \"fallbackModel\", // Fallback if primary fails\n  \"temperature\", // Sampling temperature\n  \"maxTokens\", // Response length limit\n  \"maxThinkingTokens\", // Reasoning depth limit\n  \"maxTurns\", // Conversation turn limit\n  \"maxBudgetUsd\", // Cost limit per run\n\n  // Output control\n  \"outputFormat\", // Structured output schema\n  \"includePartialMessages\", // Streaming granularity\n\n  // Optional features\n  \"enableFileCheckpointing\", // File change tracking\n  \"strictMcpConfig\", // MCP validation strictness\n  \"betas\", // Beta feature flags\n]);\n\n/** Special tool name for state management */\nexport const STATE_MANAGEMENT_TOOL_NAME = \"ag_ui_update_state\";\n\n/** Full prefixed name as it appears from Claude SDK */\nexport const STATE_MANAGEMENT_TOOL_FULL_NAME =\n  \"mcp__ag_ui__ag_ui_update_state\";\n\n/** MCP server name for dynamic AG-UI tools */\nexport const AG_UI_MCP_SERVER_NAME = \"ag_ui\";\n","/**\n * Utility functions for Claude Agent SDK adapter.\n *\n * Helper functions for message processing, tool conversion, and prompt building.\n */\n\nimport { z } from \"zod\";\nimport { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { RunAgentInput, Tool, AssistantMessage, ToolCall, Message } from \"@ag-ui/core\";\nimport type { SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { BetaToolUseBlock } from \"@anthropic-ai/sdk/resources/beta/messages/messages\";\nimport {\n  ALLOWED_FORWARDED_PROPS,\n  STATE_MANAGEMENT_TOOL_NAME,\n  STATE_MANAGEMENT_TOOL_FULL_NAME,\n} from \"./config\";\n\n/**\n * Check if a state value is meaningful (non-null, non-undefined, non-empty object).\n *\n * In Python, `{}` is falsy so `if state:` naturally skips empty objects.\n * In JavaScript, `{}` is truthy, so we need an explicit check.\n * CopilotKit runtime sends `state: {}` even for agents that don't use useCoAgent.\n */\nexport function hasState(state: unknown): boolean {\n  if (state == null) return false;\n  if (typeof state !== \"object\") return true;\n  if (Array.isArray(state)) return state.length > 0;\n  // Empty objects ({}) count as \"has state\"\n  return true;\n}\n\n/**\n * Extract tool names from AG-UI tool definitions.\n */\nexport function extractToolNames(tools: Tool[]): string[] {\n  return tools.map((t) => t.name).filter(Boolean);\n}\n\n/**\n * Strip mcp__servername__ prefix from Claude SDK tool names.\n *\n * Claude SDK prefixes all MCP tools: mcp__weather__get_weather, mcp__ag_ui__generate_haiku\n * Frontend registers unprefixed: get_weather, generate_haiku\n *\n * @example\n * stripMcpPrefix(\"mcp__weather__get_weather\") // \"get_weather\"\n * stripMcpPrefix(\"mcp__ag_ui__generate_haiku\") // \"generate_haiku\"\n * stripMcpPrefix(\"local_tool\") // \"local_tool\" (unchanged)\n */\nexport function stripMcpPrefix(toolName: string): string {\n  if (toolName.startsWith(\"mcp__\")) {\n    const parts = toolName.split(\"__\");\n    if (parts.length >= 3) {\n      // mcp__servername__toolname -- keep just toolname (handles double underscores in names)\n      return parts.slice(2).join(\"__\");\n    }\n  }\n  return toolName;\n}\n\n/**\n * Result from processing messages.\n */\nexport type ProcessMessagesResult = {\n  userMessage: string;\n  hasPendingToolResult: boolean;\n};\n\n/**\n * Process and validate all messages from RunAgentInput.\n *\n * Similar to AWS Strands pattern: validates full message history even though\n * Claude SDK manages conversation via session_id.\n */\nexport function processMessages(input: RunAgentInput): ProcessMessagesResult {\n  const messages = input.messages ?? [];\n\n  // Check if last message is a tool result (for re-submission handling)\n  let hasPendingToolResult = false;\n  if (messages.length > 0) {\n    const lastMsg = messages[messages.length - 1];\n    if (lastMsg.role === \"tool\") {\n      hasPendingToolResult = true;\n      console.debug(\n        `[ClaudeAdapter] Pending tool result detected: toolCallId=${(lastMsg as { toolCallId?: string }).toolCallId ?? \"unknown\"}, threadId=${input.threadId}`\n      );\n    }\n  }\n\n  // Log message counts for debugging\n  console.debug(\n    `[ClaudeAdapter] Processing ${messages.length} messages for threadId=${input.threadId}`\n  );\n\n  // Extract content from the LAST message (any role - user, tool, or assistant)\n  // Claude SDK manages conversation history via session_id, we just need the latest input\n  let userMessage = \"\";\n  if (messages.length > 0) {\n    const lastMsg = messages[messages.length - 1];\n    const content = lastMsg.content;\n\n    if (typeof content === \"string\") {\n      userMessage = content;\n    } else if (Array.isArray(content)) {\n      // Content blocks format - extract text from first text block\n      for (const block of content) {\n        if (typeof block === \"object\" && block !== null && \"text\" in block) {\n          userMessage = (block as { text: string }).text;\n          break;\n        }\n      }\n    }\n  }\n\n  if (!userMessage) {\n    console.warn(\n      `[ClaudeAdapter] No user message found in ${messages.length} messages`\n    );\n  }\n\n  return { userMessage, hasPendingToolResult };\n}\n\n/**\n * Build state and context addendum for injection into the system prompt.\n *\n * Returns the formatted text block describing current state and application\n * context, or an empty string if neither is present.\n *\n * This keeps state/context in the system prompt (where it belongs) rather\n * than polluting the user message.\n */\nexport function buildStateContextAddendum(input: RunAgentInput): string {\n  const parts: string[] = [];\n\n  // Add context if provided\n  if (input.context && input.context.length > 0) {\n    parts.push(\"## Context from the application\");\n    for (const ctx of input.context) {\n      parts.push(`- ${ctx.description}: ${ctx.value}`);\n    }\n    parts.push(\"\");\n  }\n\n  // Add current state if provided (skip empty objects)\n  if (hasState(input.state)) {\n    parts.push(\"## Current Shared State\");\n    parts.push(\n      \"This state is shared with the frontend UI and can be updated.\"\n    );\n    try {\n      const stateJson = JSON.stringify(input.state, null, 2);\n      parts.push(`\\`\\`\\`json\\n${stateJson}\\n\\`\\`\\``);\n    } catch {\n      parts.push(`State: ${String(input.state)}`);\n    }\n    parts.push(\"\");\n    parts.push(\n      \"To update this state, use the `ag_ui_update_state` tool with your changes.\"\n    );\n    parts.push(\"\");\n  }\n\n  return parts.join(\"\\n\");\n}\n\n/**\n * Convert a basic JSON Schema type string to a Zod type.\n * Falls back to z.any() for complex or unknown types.\n */\nfunction jsonSchemaTypeToZod(\n  prop: Record<string, unknown>\n): z.ZodTypeAny {\n  const type = prop.type as string | undefined;\n  const description = prop.description as string | undefined;\n\n  let zodType: z.ZodTypeAny;\n\n  switch (type) {\n    case \"string\":\n      zodType = prop.enum\n        ? z.enum(prop.enum as [string, ...string[]])\n        : z.string();\n      break;\n    case \"number\":\n    case \"integer\":\n      zodType = z.number();\n      break;\n    case \"boolean\":\n      zodType = z.boolean();\n      break;\n    case \"array\":\n      zodType = z.array(z.any());\n      break;\n    case \"object\":\n      zodType = z.record(z.string(), z.any());\n      break;\n    default:\n      zodType = z.any();\n  }\n\n  if (description) {\n    zodType = zodType.describe(description);\n  }\n\n  return zodType;\n}\n\n/**\n * Convert a JSON Schema properties object to a Zod raw shape.\n * This is a pragmatic conversion for stub tools -- handles basic types\n * with z.any() fallback for complex nested schemas.\n */\nfunction jsonSchemaToZodShape(\n  schema: Record<string, unknown>\n): Record<string, z.ZodTypeAny> {\n  const properties = (schema.properties ?? {}) as Record<\n    string,\n    Record<string, unknown>\n  >;\n  const required = (schema.required ?? []) as string[];\n  const shape: Record<string, z.ZodTypeAny> = {};\n\n  for (const [key, prop] of Object.entries(properties)) {\n    let zodType = jsonSchemaTypeToZod(prop);\n    if (!required.includes(key)) {\n      zodType = zodType.optional();\n    }\n    shape[key] = zodType;\n  }\n\n  // If no properties were defined, use a catch-all\n  if (Object.keys(shape).length === 0) {\n    shape[\"args\"] = z.any().optional().describe(\"Tool arguments\");\n  }\n\n  return shape;\n}\n\n/**\n * Convert an AG-UI tool definition to a Claude SDK MCP tool.\n *\n * Creates a proxy tool that Claude can \"see\" and call, but with stub implementation\n * since actual execution happens on the client side.\n */\nexport function convertAguiToolToClaudeSdk(\n  toolDef: Tool\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n  const toolName = toolDef.name ?? \"unknown\";\n  const toolDescription = toolDef.description ?? \"\";\n  const toolParameters = (toolDef.parameters ?? {}) as Record<string, unknown>;\n\n  // Convert JSON Schema to Zod shape for the TS SDK's tool() function\n  const zodShape = jsonSchemaToZodShape(toolParameters);\n\n  // Create stub tool with empty implementation (execution happens client-side)\n  return tool(toolName, toolDescription, zodShape, async () => ({\n    content: [{ type: \"text\" as const, text: \"Tool call forwarded to client\" }],\n  }));\n}\n\n/**\n * Create ag_ui_update_state tool for bidirectional state sync.\n *\n * This tool allows Claude to update the shared application state,\n * which is then emitted to the client via STATE_SNAPSHOT events.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createStateManagementTool(): any {\n  return tool(\n    \"ag_ui_update_state\",\n    \"Update the shared application state. Use this to persist changes that should be visible in the UI. Pass the complete updated state object.\",\n    { state_updates: z.record(z.string(), z.unknown()) },\n    async () => ({\n      content: [\n        { type: \"text\" as const, text: \"State updated successfully\" },\n      ],\n    })\n  );\n}\n\n/**\n * Apply forwardedProps as per-run Claude SDK option overrides.\n *\n * Only whitelisted keys are applied for security. forwardedProps enables\n * runtime control (model selection, limits, session control) without\n * changing agent identity or security boundaries.\n */\nexport function applyForwardedProps(\n  forwardedProps: Record<string, unknown> | undefined,\n  mergedOptions: Record<string, unknown>,\n  allowedKeys: Set<string> = ALLOWED_FORWARDED_PROPS\n): Record<string, unknown> {\n  if (\n    !forwardedProps ||\n    typeof forwardedProps !== \"object\" ||\n    Array.isArray(forwardedProps)\n  ) {\n    return mergedOptions;\n  }\n\n  let appliedCount = 0;\n  for (const [key, value] of Object.entries(forwardedProps)) {\n    if (allowedKeys.has(key) && value != null) {\n      mergedOptions[key] = value;\n      appliedCount++;\n      console.debug(`[ClaudeAdapter] Applied forwarded_prop: ${key} = ${String(value)}`);\n    } else if (!allowedKeys.has(key)) {\n      console.warn(\n        `[ClaudeAdapter] Ignoring non-whitelisted forwarded_prop: ${key}. See ALLOWED_FORWARDED_PROPS for supported keys.`\n      );\n    }\n  }\n\n  if (appliedCount > 0) {\n    console.debug(\n      `[ClaudeAdapter] Applied ${appliedCount} forwarded_props as option overrides`\n    );\n  }\n\n  return mergedOptions;\n}\n\n/**\n * Check whether a tool name is the internal state management tool.\n */\nexport function isStateManagementTool(name: string): boolean {\n  return (\n    name === STATE_MANAGEMENT_TOOL_NAME ||\n    name === STATE_MANAGEMENT_TOOL_FULL_NAME\n  );\n}\n\n/**\n * Convert a complete Claude SDK AssistantMessage into an AG-UI AssistantMessage.\n *\n * Extracts text from TextBlocks and builds ToolCall objects from ToolUseBlocks.\n * Filters out internal state management tool calls and reasoning blocks since\n * they are not part of the user-visible conversation history.\n *\n * @returns AG-UI AssistantMessage, or null if the message has no user-visible content.\n */\nexport function buildAguiAssistantMessage(\n  sdkMessage: SDKAssistantMessage,\n  messageId: string\n): AssistantMessage | null {\n  const contentBlocks = sdkMessage.message?.content ?? [];\n\n  let textContent = \"\";\n  const toolCalls: ToolCall[] = [];\n\n  for (const block of contentBlocks) {\n    if (block.type === \"text\") {\n      textContent += (block as { text: string }).text;\n    } else if (block.type === \"tool_use\") {\n      const toolBlock = block as BetaToolUseBlock;\n      const rawName = toolBlock.name ?? \"unknown\";\n\n      // Skip internal state management tool — not part of conversation history\n      if (isStateManagementTool(rawName)) {\n        continue;\n      }\n\n      toolCalls.push({\n        id: toolBlock.id,\n        type: \"function\" as const,\n        function: {\n          name: stripMcpPrefix(rawName),\n          arguments: JSON.stringify(toolBlock.input ?? {}),\n        },\n      });\n    }\n    // Reasoning/ThinkingBlocks are intentionally skipped — not conversation history\n  }\n\n  // Nothing user-visible (e.g. reasoning-only message)\n  if (!textContent && toolCalls.length === 0) {\n    return null;\n  }\n\n  const msg: AssistantMessage = {\n    id: messageId,\n    role: \"assistant\" as const,\n  };\n\n  if (textContent) {\n    msg.content = textContent;\n  }\n\n  if (toolCalls.length > 0) {\n    msg.toolCalls = toolCalls;\n  }\n\n  return msg;\n}\n\n/**\n * Build an AG-UI ToolMessage from a Claude SDK tool result block.\n *\n * Extracts the text content from the SDK's content block format and\n * normalises it into a simple string for the AG-UI message.\n */\nexport function buildAguiToolMessage(\n  toolUseId: string,\n  content: unknown\n): Message {\n  let resultStr = \"\";\n  try {\n    if (Array.isArray(content) && content.length > 0) {\n      const firstBlock = content[0] as Record<string, unknown>;\n      if (firstBlock?.type === \"text\") {\n        const text = (firstBlock.text as string) ?? \"\";\n        try {\n          resultStr = JSON.stringify(JSON.parse(text));\n        } catch {\n          resultStr = text;\n        }\n      } else {\n        resultStr = JSON.stringify(content);\n      }\n    } else if (content != null) {\n      resultStr = JSON.stringify(content);\n    }\n  } catch {\n    resultStr = String(content ?? \"\");\n  }\n\n  return {\n    id: `${toolUseId}-result`,\n    role: \"tool\" as const,\n    content: resultStr,\n    toolCallId: toolUseId,\n  };\n}\n","/**\n * Event handlers for Claude SDK stream processing.\n *\n * Breaks down stream processing into focused handler functions.\n */\n\nimport { Subscriber } from \"rxjs\";\nimport { EventType, randomUUID } from \"@ag-ui/client\";\nimport type { BetaToolUseBlock } from \"@anthropic-ai/sdk/resources/beta/messages/messages\";\nimport { stripMcpPrefix, isStateManagementTool } from \"./utils\";\nimport type { ProcessedEvent } from \"./types\";\n\n/**\n * Result from handling a ToolUseBlock.\n */\nexport type HandleToolUseResult = {\n  /** Updated state (or null if unchanged) */\n  updatedState: unknown | null;\n};\n\n/**\n * Handle ToolUseBlock from Claude SDK.\n *\n * Intercepts state management tool calls and emits STATE_SNAPSHOT.\n * For regular tools, emits TOOL_CALL_START/ARGS events.\n */\nexport function handleToolUseBlock(\n  block: BetaToolUseBlock,\n  parentToolUseId: string | undefined,\n  threadId: string,\n  runId: string,\n  currentState: unknown,\n  subscriber: Subscriber<ProcessedEvent>\n): HandleToolUseResult {\n  const toolName = block.name ?? \"unknown\";\n  const toolInput = (block.input as Record<string, unknown>) ?? {};\n  const toolId = block.id ?? randomUUID();\n\n  // Strip MCP prefix for client matching (same as streaming path)\n  const toolDisplayName = stripMcpPrefix(toolName);\n  if (toolDisplayName !== toolName) {\n    console.debug(\n      `[ClaudeAdapter] Stripped MCP prefix in handler: ${toolName} -> ${toolDisplayName}`\n    );\n  }\n\n  console.debug(`[ClaudeAdapter] ToolUseBlock detected: ${toolName}`);\n\n  // Intercept state management tool calls (check both prefixed and unprefixed names)\n  if (isStateManagementTool(toolName)) {\n    console.debug(\n      \"[ClaudeAdapter] Intercepting ag_ui_update_state tool call\"\n    );\n\n    // Extract state updates from tool input\n    let stateUpdates: unknown = toolInput.state_updates ?? {};\n\n    // Parse if it's a JSON string\n    if (typeof stateUpdates === \"string\") {\n      try {\n        stateUpdates = JSON.parse(stateUpdates);\n        console.debug(\n          \"[ClaudeAdapter] Parsed state_updates from JSON string\"\n        );\n      } catch {\n        console.warn(\n          \"[ClaudeAdapter] Failed to parse state_updates JSON\"\n        );\n        subscriber.next({\n          type: EventType.CUSTOM,\n          name: \"state_update_error\",\n          value: { error: \"Failed to parse state update\" },\n        });\n        stateUpdates = {};\n      }\n    }\n\n    // Update current state\n    let newState: unknown;\n    if (\n      typeof currentState === \"object\" &&\n      currentState !== null &&\n      typeof stateUpdates === \"object\" &&\n      stateUpdates !== null\n    ) {\n      newState = {\n        ...(currentState as Record<string, unknown>),\n        ...(stateUpdates as Record<string, unknown>),\n      };\n    } else {\n      newState = stateUpdates;\n    }\n\n    if (JSON.stringify(newState) !== JSON.stringify(currentState)) {\n      subscriber.next({\n        type: EventType.STATE_SNAPSHOT,\n        snapshot: newState,\n      });\n      console.debug(\"[ClaudeAdapter] Emitted STATE_SNAPSHOT with updated state\");\n    }\n    return { updatedState: newState };\n  }\n\n  // Regular tool handling for non-state tools\n  subscriber.next({\n    type: EventType.TOOL_CALL_START,\n    threadId,\n    runId,\n    toolCallId: toolId,\n    toolCallName: toolDisplayName, // Use unprefixed name\n    parentMessageId: parentToolUseId,\n  });\n\n  if (toolInput && Object.keys(toolInput).length > 0) {\n    subscriber.next({\n      type: EventType.TOOL_CALL_ARGS,\n      threadId,\n      runId,\n      toolCallId: toolId,\n      delta: JSON.stringify(toolInput),\n    });\n  }\n\n  // Emit TOOL_CALL_END so the runtime doesn't think the tool call is still active.\n  // In the streaming path this is emitted at content_block_stop, but when tools\n  // arrive only via the complete `assistant` message (non-streaming), this fallback\n  // is the only place that closes the tool call.\n  subscriber.next({\n    type: EventType.TOOL_CALL_END,\n    threadId,\n    runId,\n    toolCallId: toolId,\n  });\n\n  return { updatedState: null };\n}\n\n"],"mappings":"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","names":["EventType","randomUUID","randomUUID","EventType"]}