{"version":3,"file":"subagents.cjs","names":["toMessageDict","MessageTupleManager","getToolCallsWithResults"],"sources":["../../src/ui/subagents.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n  Message,\n  DefaultToolCall,\n  AIMessage,\n  ToolCallWithResult,\n} from \"../types.messages.js\";\nimport type {\n  SubagentStreamInterface,\n  SubagentToolCall,\n  SubagentStatus,\n} from \"./types.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\n\n/**\n * Default tool names that indicate subagent invocation.\n * Can be customized via SubagentManager options.\n */\nconst DEFAULT_SUBAGENT_TOOL_NAMES = [\"task\"];\n\n/**\n * Checks if a namespace indicates a subagent/subgraph message.\n *\n * Subagent namespaces contain a \"tools:\" segment indicating they\n * originate from a tool call that spawned a subgraph.\n *\n * @param namespace - The namespace array from stream events (or checkpoint_ns string)\n * @returns True if this is a subagent namespace\n */\nexport function isSubagentNamespace(\n  namespace: string[] | string | undefined\n): boolean {\n  if (!namespace) return false;\n\n  // Handle string namespace (from checkpoint_ns)\n  if (typeof namespace === \"string\") {\n    return namespace.includes(\"tools:\");\n  }\n\n  // Handle array namespace\n  return namespace.some((s) => s.startsWith(\"tools:\"));\n}\n\n/**\n * Extracts the tool call ID from a namespace path.\n *\n * Namespaces follow the pattern: [\"tools:call_abc123\", \"model_request:xyz\", ...]\n * This function extracts \"call_abc123\" from the first \"tools:\" segment.\n *\n * @param namespace - The namespace array from stream events\n * @returns The tool call ID, or undefined if not found\n */\nexport function extractToolCallIdFromNamespace(\n  namespace: string[] | undefined\n): string | undefined {\n  if (!namespace || namespace.length === 0) return undefined;\n\n  // Find the first namespace segment that starts with \"tools:\"\n  for (const segment of namespace) {\n    if (segment.startsWith(\"tools:\")) {\n      return segment.slice(6); // Remove \"tools:\" prefix\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Calculates the depth of a subagent based on its namespace.\n * Counts the number of \"tools:\" segments in the namespace.\n *\n * @param namespace - The namespace array\n * @returns The depth (0 for main agent, 1+ for subagents)\n */\nexport function calculateDepthFromNamespace(\n  namespace: string[] | undefined\n): number {\n  if (!namespace) return 0;\n  return namespace.filter((s) => s.startsWith(\"tools:\")).length;\n}\n\n/**\n * Extracts the parent tool call ID from a namespace.\n *\n * For nested subagents, the namespace looks like:\n * [\"tools:parent_id\", \"tools:child_id\", ...]\n *\n * @param namespace - The namespace array\n * @returns The parent tool call ID, or null if this is a top-level subagent\n */\nexport function extractParentIdFromNamespace(\n  namespace: string[] | undefined\n): string | null {\n  if (!namespace || namespace.length < 2) return null;\n\n  const toolSegments = namespace.filter((s) => s.startsWith(\"tools:\"));\n  if (toolSegments.length < 2) return null;\n\n  // The second-to-last \"tools:\" segment is the parent\n  return toolSegments[toolSegments.length - 2]?.slice(6) ?? null;\n}\n\n/**\n * Options for SubagentManager.\n */\nexport interface SubagentManagerOptions {\n  /**\n   * Tool names that indicate subagent invocation.\n   * Defaults to [\"task\"].\n   */\n  subagentToolNames?: string[];\n\n  /**\n   * Callback when subagent state changes.\n   */\n  onSubagentChange?: () => void;\n\n  /**\n   * Converts a @langchain/core BaseMessage to the desired output format.\n   * Defaults to `toMessageDict` which produces plain Message objects.\n   */\n  toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\n/**\n * Internal base type for SubagentStream storage.\n * Excludes derived properties that are computed on retrieval.\n */\ntype SubagentStreamBase<ToolCall> = Omit<\n  SubagentStreamInterface<Record<string, unknown>, ToolCall>,\n  | \"isLoading\"\n  | \"toolCalls\"\n  | \"getToolCalls\"\n  | \"interrupt\"\n  | \"interrupts\"\n  | \"switchThread\"\n  | \"subagents\"\n  | \"activeSubagents\"\n  | \"getSubagent\"\n  | \"getSubagentsByType\"\n  | \"getSubagentsByMessage\"\n> & {\n  /** Internal: ID of the AI message that triggered this subagent */\n  aiMessageId: string | null;\n};\n\n/**\n * Manages subagent execution state.\n *\n * Tracks subagents from the moment they are invoked (AI message with tool calls)\n * through streaming to completion (tool message result).\n */\nexport class SubagentManager<ToolCall = DefaultToolCall> {\n  private subagents = new Map<string, SubagentStreamBase<ToolCall>>();\n\n  /**\n   * Maps namespace IDs (pregel task IDs) to tool call IDs.\n   * LangGraph subgraphs use internal pregel task IDs in their namespace,\n   * which are different from the tool_call_id used to invoke them.\n   */\n  private namespaceToToolCallId = new Map<string, string>();\n\n  /**\n   * Pending namespace matches that couldn't be resolved immediately.\n   * These are retried when new tool calls are registered.\n   */\n  private pendingMatches = new Map<string, string>(); // namespaceId -> description\n\n  /**\n   * Messages received before we can map a subgraph namespace to the public\n   * subagent tool-call ID. Once the mapping is established, these messages are\n   * replayed so early tool calls are not lost.\n   */\n  private pendingMessages = new Map<\n    string,\n    Array<{\n      serialized: Message<DefaultToolCall>;\n      metadata?: Record<string, unknown>;\n    }>\n  >();\n\n  /**\n   * Message managers for each subagent.\n   * Uses the same MessageTupleManager as the main stream for proper\n   * message chunk concatenation.\n   */\n  private messageManagers = new Map<string, MessageTupleManager>();\n\n  private subagentToolNames: Set<string>;\n\n  private onSubagentChange?: () => void;\n\n  private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n  constructor(options?: SubagentManagerOptions) {\n    this.subagentToolNames = new Set(\n      options?.subagentToolNames ?? DEFAULT_SUBAGENT_TOOL_NAMES\n    );\n    this.onSubagentChange = options?.onSubagentChange;\n    this.toMessage = options?.toMessage ?? toMessageDict;\n  }\n\n  /**\n   * Get or create a MessageTupleManager for a subagent.\n   */\n  private getMessageManager(toolCallId: string): MessageTupleManager {\n    let manager = this.messageManagers.get(toolCallId);\n    if (!manager) {\n      manager = new MessageTupleManager();\n      this.messageManagers.set(toolCallId, manager);\n    }\n    return manager;\n  }\n\n  /**\n   * Get messages for a subagent with proper chunk concatenation.\n   * This mirrors how the main stream handles messages.\n   */\n  private getMessagesForSubagent(toolCallId: string): Message<ToolCall>[] {\n    const manager = this.messageManagers.get(toolCallId);\n    if (!manager) return [];\n\n    const messages: Message<ToolCall>[] = [];\n    for (const entry of Object.values(manager.chunks)) {\n      if (entry.chunk) {\n        messages.push(this.toMessage(entry.chunk) as Message<ToolCall>);\n      }\n    }\n    return messages;\n  }\n\n  /**\n   * Buffer a subagent message until we can resolve its namespace to a tool call.\n   */\n  private queuePendingMessage(\n    namespaceId: string,\n    serialized: Message<DefaultToolCall>,\n    metadata?: Record<string, unknown>\n  ) {\n    const pending = this.pendingMessages.get(namespaceId) ?? [];\n    pending.push({ serialized, metadata });\n    this.pendingMessages.set(namespaceId, pending);\n  }\n\n  /**\n   * Replay any buffered messages once a namespace has been mapped.\n   */\n  private flushPendingMessages(namespaceId: string) {\n    const pending = this.pendingMessages.get(namespaceId);\n    if (!pending?.length) return;\n\n    this.pendingMessages.delete(namespaceId);\n    pending.forEach(({ serialized, metadata }) => {\n      this.addMessageToSubagent(namespaceId, serialized, metadata);\n    });\n  }\n\n  /**\n   * Create a complete SubagentStream object with all derived properties.\n   * This ensures consistency with UseStream interface.\n   */\n  private createSubagentStream(\n    base: SubagentStreamBase<ToolCall>\n  ): SubagentStreamInterface<Record<string, unknown>, ToolCall> {\n    const { messages } = base;\n    const allToolCalls = getToolCallsWithResults<ToolCall>(messages);\n\n    return {\n      ...base,\n      // Derived from status for UseStream consistency\n      isLoading: base.status === \"running\",\n\n      // Tool calls derived from messages\n      toolCalls: allToolCalls,\n\n      // Method to get tool calls for a specific message\n      getToolCalls: (\n        message: AIMessage<ToolCall>\n      ): ToolCallWithResult<ToolCall>[] => {\n        return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n      },\n\n      // Subagents don't have interrupts yet (future enhancement)\n      interrupt: undefined,\n      interrupts: [],\n\n      // Subagents don't support thread switching\n      switchThread: () => {},\n\n      // Nested subagent tracking (empty for now, future enhancement)\n      subagents: new Map<\n        string,\n        SubagentStreamInterface<Record<string, unknown>, ToolCall>\n      >(),\n      activeSubagents: [],\n      getSubagent: () => undefined,\n      getSubagentsByType: () => [],\n      getSubagentsByMessage: () => [],\n    };\n  }\n\n  /**\n   * Get the tool call ID for a given namespace ID.\n   * Returns the namespace ID itself if no mapping exists.\n   */\n  getToolCallIdFromNamespace(namespaceId: string): string {\n    return this.namespaceToToolCallId.get(namespaceId) ?? namespaceId;\n  }\n\n  /**\n   * Try to match a subgraph to a pending subagent by description.\n   * Creates a mapping from namespace ID to tool call ID if a match is found.\n   *\n   * Uses a multi-pass matching strategy:\n   * 1. Exact description match\n   * 2. Description contains/partial match\n   * 3. Any unmapped pending subagent (fallback)\n   *\n   * @param namespaceId - The namespace ID (pregel task ID) from the subgraph\n   * @param description - The description from the subgraph's initial message\n   * @returns The matched tool call ID, or undefined if no match\n   */\n  matchSubgraphToSubagent(\n    namespaceId: string,\n    description: string\n  ): string | undefined {\n    // Skip if we already have a mapping\n    if (this.namespaceToToolCallId.has(namespaceId)) {\n      return this.namespaceToToolCallId.get(namespaceId);\n    }\n\n    // Get all already-mapped tool call IDs\n    const mappedToolCallIds = new Set(this.namespaceToToolCallId.values());\n\n    // Helper to establish mapping and mark as running\n    const establishMapping = (toolCallId: string): string => {\n      this.namespaceToToolCallId.set(namespaceId, toolCallId);\n      // Also mark the subagent as running since we now have its namespace\n      const subagent = this.subagents.get(toolCallId);\n      if (subagent && subagent.status === \"pending\") {\n        this.subagents.set(toolCallId, {\n          ...subagent,\n          status: \"running\",\n          namespace: [namespaceId],\n          startedAt: new Date(),\n        });\n        this.onSubagentChange?.();\n      }\n      this.flushPendingMessages(namespaceId);\n      return toolCallId;\n    };\n\n    // Pass 1: Find a pending subagent with exact description match\n    for (const [toolCallId, subagent] of this.subagents) {\n      if (\n        (subagent.status === \"pending\" || subagent.status === \"running\") &&\n        !mappedToolCallIds.has(toolCallId) &&\n        subagent.toolCall.args.description === description\n      ) {\n        return establishMapping(toolCallId);\n      }\n    }\n\n    // Pass 2: Find a pending subagent where description contains or is contained\n    for (const [toolCallId, subagent] of this.subagents) {\n      if (\n        (subagent.status === \"pending\" || subagent.status === \"running\") &&\n        !mappedToolCallIds.has(toolCallId)\n      ) {\n        const subagentDesc = subagent.toolCall.args.description || \"\";\n        if (\n          (subagentDesc && description.includes(subagentDesc)) ||\n          (subagentDesc && subagentDesc.includes(description))\n        ) {\n          // Update the description if the new one is longer\n          if (description.length > subagentDesc.length) {\n            this.subagents.set(toolCallId, {\n              ...subagent,\n              toolCall: {\n                ...subagent.toolCall,\n                args: {\n                  ...subagent.toolCall.args,\n                  description,\n                },\n              },\n            });\n          }\n          return establishMapping(toolCallId);\n        }\n      }\n    }\n\n    // No match found - store for retry when more tool calls are registered\n    if (description) {\n      this.pendingMatches.set(namespaceId, description);\n    }\n    return undefined;\n  }\n\n  /**\n   * Check if a tool call is a subagent invocation.\n   */\n  isSubagentToolCall(toolName: string): boolean {\n    return this.subagentToolNames.has(toolName);\n  }\n\n  /**\n   * Check if a subagent_type value is valid.\n   * Valid types are proper identifiers like \"weather-scout\", \"experience-curator\".\n   */\n  private isValidSubagentType(type: unknown): boolean {\n    // Must be a non-empty string\n    if (!type || typeof type !== \"string\") {\n      return false;\n    }\n\n    // Must be at least 3 characters (avoids partial streaming like \"ex\")\n    if (type.length < 3) {\n      return false;\n    }\n\n    // Must look like a valid identifier (letters, numbers, hyphens, underscores)\n    // Examples: \"weather-scout\", \"experience_curator\", \"budget-optimizer\"\n    if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(type)) {\n      return false;\n    }\n\n    // Must not be unreasonably long (corruption indicator)\n    if (type.length > 50) {\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Check if a subagent should be exposed through the public API.\n   *\n   * We expose subagents as soon as their parent AI message emits a complete\n   * subagent tool call, which means pending subagents should be visible.\n   *\n   * This still filters out corrupted or partial streaming artifacts by\n   * requiring a valid-looking `subagent_type`.\n   */\n  private isValidSubagent(subagent: SubagentStreamBase<ToolCall>): boolean {\n    return this.isValidSubagentType(subagent.toolCall.args.subagent_type);\n  }\n\n  /**\n   * Build a complete SubagentStream from internal state.\n   * Adds messages and derived properties.\n   */\n  private buildExecution(\n    base: SubagentStreamBase<ToolCall>\n  ): SubagentStreamInterface<Record<string, unknown>, ToolCall> {\n    // Get fresh messages from the streaming manager (populated during live streaming).\n    // Fall back to base.messages, which is populated by updateSubagentFromSubgraphState\n    // when restoring history after page reload.\n    const streamingMessages = this.getMessagesForSubagent(base.id);\n    const messages =\n      streamingMessages.length > 0 ? streamingMessages : base.messages;\n    return this.createSubagentStream({\n      ...base,\n      messages,\n    });\n  }\n\n  /**\n   * Get all subagents as a Map.\n   * Filters out incomplete/phantom subagents that lack subagent_type.\n   */\n  getSubagents(): Map<\n    string,\n    SubagentStreamInterface<Record<string, unknown>, ToolCall>\n  > {\n    const result = new Map<\n      string,\n      SubagentStreamInterface<Record<string, unknown>, ToolCall>\n    >();\n    for (const [id, subagent] of this.subagents) {\n      if (this.isValidSubagent(subagent)) {\n        result.set(id, this.buildExecution(subagent));\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Get all currently running subagents.\n   * Filters out incomplete/phantom subagents.\n   */\n  getActiveSubagents(): SubagentStreamInterface<\n    Record<string, unknown>,\n    ToolCall\n  >[] {\n    return [...this.subagents.values()]\n      .filter((s) => s.status === \"running\" && this.isValidSubagent(s))\n      .map((s) => this.buildExecution(s));\n  }\n\n  /**\n   * Get a specific subagent by tool call ID.\n   */\n  getSubagent(\n    toolCallId: string\n  ): SubagentStreamInterface<Record<string, unknown>, ToolCall> | undefined {\n    const subagent = this.subagents.get(toolCallId);\n    return subagent ? this.buildExecution(subagent) : undefined;\n  }\n\n  /**\n   * Get all subagents of a specific type.\n   */\n  getSubagentsByType(\n    type: string\n  ): SubagentStreamInterface<Record<string, unknown>, ToolCall>[] {\n    return [...this.subagents.values()]\n      .filter((s) => s.toolCall.args.subagent_type === type)\n      .map((s) => this.buildExecution(s));\n  }\n\n  /**\n   * Get all subagents triggered by a specific AI message.\n   *\n   * @param messageId - The ID of the AI message.\n   * @returns Array of subagent streams triggered by that message.\n   */\n  getSubagentsByMessage(\n    messageId: string\n  ): SubagentStreamInterface<Record<string, unknown>, ToolCall>[] {\n    return [...this.subagents.values()]\n      .filter((s) => s.aiMessageId === messageId && this.isValidSubagent(s))\n      .map((s) => this.buildExecution(s));\n  }\n\n  /**\n   * Parse tool call args, handling both object and string formats.\n   * During streaming, args might come as a string that needs parsing.\n   */\n  private parseArgs(\n    args: Record<string, unknown> | string | undefined\n  ): Record<string, unknown> {\n    if (!args) return {};\n    if (typeof args === \"string\") {\n      try {\n        return JSON.parse(args);\n      } catch {\n        return {};\n      }\n    }\n    return args;\n  }\n\n  /**\n   * Register new subagent(s) from AI message tool calls.\n   *\n   * Called when an AI message is received with tool calls.\n   * Creates pending subagent entries for each subagent tool call.\n   *\n   * @param toolCalls - The tool calls from an AI message\n   * @param aiMessageId - The ID of the AI message that triggered the tool calls\n   */\n  registerFromToolCalls(\n    toolCalls: Array<{\n      id?: string;\n      name: string;\n      args: Record<string, unknown> | string;\n    }>,\n    aiMessageId?: string | null\n  ): void {\n    let hasChanges = false;\n\n    for (const toolCall of toolCalls) {\n      if (!toolCall.id) continue;\n      if (!this.isSubagentToolCall(toolCall.name)) continue;\n\n      // Parse args (may be string during streaming)\n      const parsedArgs = this.parseArgs(toolCall.args);\n\n      // Skip tool calls that have no meaningful info (likely streaming artifacts)\n      // We require a valid subagent_type that looks like a proper identifier\n      const hasValidType = this.isValidSubagentType(parsedArgs.subagent_type);\n\n      // If we already have this subagent, update the args if they're now more complete\n      const existing = this.subagents.get(toolCall.id);\n      if (existing) {\n        // Only update if new values are valid AND longer (more complete)\n        const newType = (parsedArgs.subagent_type as string) || \"\";\n        const oldType = existing.toolCall.args.subagent_type || \"\";\n        const newDesc = (parsedArgs.description as string) || \"\";\n        const oldDesc = existing.toolCall.args.description || \"\";\n\n        // Only accept new type if it's valid (not corrupted)\n        const newTypeIsValid = this.isValidSubagentType(newType);\n        const shouldUpdateType =\n          newTypeIsValid && newType.length > oldType.length;\n        const shouldUpdateDesc = newDesc.length > oldDesc.length;\n\n        // Update aiMessageId when the provider replaces it (e.g. OpenAI\n        // changes streaming \"lc_run--...\" IDs to final \"resp_...\" IDs).\n        const shouldUpdateMessageId =\n          aiMessageId != null && aiMessageId !== existing.aiMessageId;\n\n        if (shouldUpdateType || shouldUpdateDesc || shouldUpdateMessageId) {\n          this.subagents.set(toolCall.id, {\n            ...existing,\n            ...(shouldUpdateMessageId ? { aiMessageId } : {}),\n            toolCall: {\n              ...existing.toolCall,\n              args: {\n                ...existing.toolCall.args,\n                ...parsedArgs,\n                description: shouldUpdateDesc ? newDesc : oldDesc,\n                subagent_type: shouldUpdateType ? newType : oldType,\n              },\n            },\n          });\n          hasChanges = true;\n        }\n        continue;\n      }\n\n      // Don't register subagents without at least a valid-looking subagent_type\n      // Partial streaming is OK - we filter by status when displaying\n      if (!hasValidType) {\n        continue;\n      }\n\n      const subagentToolCall: SubagentToolCall = {\n        id: toolCall.id,\n        name: toolCall.name,\n        args: {\n          description: parsedArgs.description as string | undefined,\n          subagent_type: parsedArgs.subagent_type as string | undefined,\n          ...parsedArgs,\n        },\n      };\n\n      const execution: SubagentStreamBase<ToolCall> = {\n        id: toolCall.id,\n        toolCall: subagentToolCall,\n        status: \"pending\",\n        values: {},\n        result: null,\n        error: null,\n        namespace: [],\n        messages: [],\n        aiMessageId: aiMessageId ?? null,\n        parentId: null,\n        depth: 0,\n        startedAt: null,\n        completedAt: null,\n      };\n\n      this.subagents.set(toolCall.id, execution);\n      // Create a message manager for this subagent\n      this.getMessageManager(toolCall.id);\n      this.flushPendingMessages(toolCall.id);\n      hasChanges = true;\n    }\n\n    // Retry any pending matches now that we have new/updated tool calls\n    if (hasChanges) {\n      this.retryPendingMatches();\n      this.onSubagentChange?.();\n    }\n  }\n\n  /**\n   * Retry matching pending namespaces to newly registered tool calls.\n   */\n  private retryPendingMatches(): void {\n    if (this.pendingMatches.size === 0) return;\n\n    // Try to match each pending namespace\n    for (const [namespaceId, description] of this.pendingMatches) {\n      // Skip if already matched\n      if (this.namespaceToToolCallId.has(namespaceId)) {\n        this.pendingMatches.delete(namespaceId);\n        continue;\n      }\n\n      // Try to match - this will establish mapping if successful\n      const matched = this.matchSubgraphToSubagent(namespaceId, description);\n      if (matched) {\n        this.pendingMatches.delete(namespaceId);\n      }\n    }\n  }\n\n  /**\n   * Mark a subagent as running and update its namespace.\n   *\n   * Called when update events are received with a namespace indicating\n   * which subagent is streaming.\n   *\n   * @param toolCallId - The tool call ID of the subagent\n   * @param options - Additional update options\n   */\n  markRunning(\n    toolCallId: string,\n    options?: {\n      namespace?: string[];\n    }\n  ): void {\n    const existing = this.subagents.get(toolCallId);\n    if (!existing) return;\n\n    const namespace = options?.namespace ?? existing.namespace;\n\n    this.subagents.set(toolCallId, {\n      ...existing,\n      status: \"running\",\n      namespace,\n      parentId:\n        existing.parentId ?? extractParentIdFromNamespace(namespace) ?? null,\n      depth: existing.depth || calculateDepthFromNamespace(namespace),\n      startedAt: existing.startedAt ?? new Date(),\n    });\n\n    this.onSubagentChange?.();\n  }\n\n  /**\n   * Mark a subagent as running using a namespace ID.\n   * Resolves the namespace ID to the actual tool call ID via the mapping.\n   *\n   * @param namespaceId - The namespace ID (pregel task ID) from the subgraph\n   * @param namespace - The full namespace array\n   */\n  markRunningFromNamespace(namespaceId: string, namespace?: string[]): void {\n    const toolCallId = this.getToolCallIdFromNamespace(namespaceId);\n    this.markRunning(toolCallId, { namespace });\n  }\n\n  /**\n   * Add a serialized message to a subagent from stream events.\n   *\n   * This method handles the raw serialized message data from SSE events.\n   * Uses MessageTupleManager for proper chunk concatenation, matching\n   * how the main stream handles messages.\n   *\n   * @param namespaceId - The namespace ID (pregel task ID) from the stream\n   * @param serialized - The serialized message from the stream\n   * @param metadata - Optional metadata from the stream event\n   */\n  addMessageToSubagent(\n    namespaceId: string,\n    serialized: Message<DefaultToolCall>,\n    metadata?: Record<string, unknown>\n  ): void {\n    // First, try to match this namespace to an existing subagent\n    // For human messages (which contain the description), try to establish the mapping\n    if (serialized.type === \"human\" && typeof serialized.content === \"string\") {\n      this.matchSubgraphToSubagent(namespaceId, serialized.content);\n    }\n\n    // Resolve the actual tool call ID from the namespace mapping\n    const toolCallId = this.getToolCallIdFromNamespace(namespaceId);\n    const existing = this.subagents.get(toolCallId);\n\n    // If we still don't have a match, the mapping hasn't been established yet.\n    // Buffer the message so early AI/tool-call chunks are replayed once the\n    // values event or a later human message establishes the mapping.\n    if (!existing) {\n      this.queuePendingMessage(namespaceId, serialized, metadata);\n      return;\n    }\n\n    // Use MessageTupleManager for proper chunk concatenation\n    // This is the same approach used by the main stream\n    const manager = this.getMessageManager(toolCallId);\n    const messageId = manager.add(serialized, metadata);\n\n    if (messageId) {\n      // Update the subagent status if this is an AI message with content\n      if (serialized.type === \"ai\") {\n        this.subagents.set(toolCallId, {\n          ...existing,\n          status: \"running\",\n          startedAt: existing.startedAt ?? new Date(),\n          // Messages are derived from the manager, so we update them here\n          messages: this.getMessagesForSubagent(toolCallId),\n        });\n      } else {\n        // For other message types, just update the messages\n        this.subagents.set(toolCallId, {\n          ...existing,\n          messages: this.getMessagesForSubagent(toolCallId),\n        });\n      }\n    }\n\n    this.onSubagentChange?.();\n  }\n\n  /**\n   * Update subagent values from a values stream event.\n   *\n   * Called when a values event is received from a subagent's namespace.\n   * This populates the subagent's state values, making them accessible\n   * via the `values` property.\n   *\n   * @param namespaceId - The namespace ID (pregel task ID) from the stream\n   * @param values - The state values from the stream event\n   */\n  updateSubagentValues(\n    namespaceId: string,\n    values: Record<string, unknown>\n  ): void {\n    // Resolve the actual tool call ID from the namespace mapping\n    const toolCallId = this.getToolCallIdFromNamespace(namespaceId);\n    const existing = this.subagents.get(toolCallId);\n\n    if (!existing) {\n      return;\n    }\n\n    this.subagents.set(toolCallId, {\n      ...existing,\n      values,\n      status: existing.status === \"pending\" ? \"running\" : existing.status,\n      startedAt: existing.startedAt ?? new Date(),\n    });\n\n    this.onSubagentChange?.();\n  }\n\n  /**\n   * Complete a subagent with a result.\n   *\n   * Called when a tool message is received for the subagent.\n   *\n   * @param toolCallId - The tool call ID of the subagent\n   * @param result - The result content\n   * @param status - The final status (complete or error)\n   */\n  complete(\n    toolCallId: string,\n    result: string,\n    status: \"complete\" | \"error\" = \"complete\"\n  ): void {\n    const existing = this.subagents.get(toolCallId);\n    if (!existing) return;\n\n    this.subagents.set(toolCallId, {\n      ...existing,\n      status,\n      result: status === \"complete\" ? result : null,\n      error: status === \"error\" ? result : null,\n      completedAt: new Date(),\n    });\n\n    this.onSubagentChange?.();\n  }\n\n  /**\n   * Clear all subagent state.\n   */\n  clear(): void {\n    this.subagents.clear();\n    this.namespaceToToolCallId.clear();\n    this.messageManagers.clear();\n    this.pendingMatches.clear();\n    this.pendingMessages.clear();\n    this.onSubagentChange?.();\n  }\n\n  /**\n   * Process a tool message to complete a subagent.\n   *\n   * @param toolCallId - The tool call ID from the tool message\n   * @param content - The result content\n   * @param status - Whether the tool execution was successful\n   */\n  processToolMessage(\n    toolCallId: string,\n    content: string,\n    status: \"success\" | \"error\" = \"success\"\n  ): void {\n    const existing = this.subagents.get(toolCallId);\n    if (!existing) return;\n\n    this.complete(\n      toolCallId,\n      content,\n      status === \"success\" ? \"complete\" : \"error\"\n    );\n  }\n\n  /**\n   * Reconstruct subagent state from historical messages.\n   *\n   * This method parses an array of messages (typically from thread history)\n   * to identify subagent executions and their results. It's used to restore\n   * subagent state after:\n   * - Page refresh (when stream has already completed)\n   * - Loading thread history\n   * - Navigating between threads\n   *\n   * The reconstruction process:\n   * 1. Find AI messages with tool calls matching subagent tool names\n   * 2. Find corresponding tool messages with results\n   * 3. Create SubagentStream entries with \"complete\" status\n   *\n   * Note: Internal subagent messages (their streaming conversation) are not\n   * reconstructed since they are not persisted in the main thread state.\n   *\n   * @param messages - Array of messages from thread history\n   * @param options - Optional configuration\n   * @param options.skipIfPopulated - If true, skip reconstruction if subagents already exist\n   */\n  reconstructFromMessages(\n    messages: Message<DefaultToolCall>[],\n    options?: { skipIfPopulated?: boolean }\n  ): void {\n    // Skip if we already have subagents (from active streaming)\n    if (options?.skipIfPopulated && this.subagents.size > 0) {\n      return;\n    }\n\n    // Build a map of tool_call_id -> tool message data for quick lookup\n    const toolResults = new Map<\n      string,\n      { content: string; status: \"success\" | \"error\" }\n    >();\n\n    for (const message of messages) {\n      if (message.type === \"tool\" && \"tool_call_id\" in message) {\n        const toolCallId = message.tool_call_id as string;\n        const content =\n          typeof message.content === \"string\"\n            ? message.content\n            : JSON.stringify(message.content);\n        const status =\n          \"status\" in message && message.status === \"error\"\n            ? \"error\"\n            : \"success\";\n        toolResults.set(toolCallId, { content, status });\n      }\n    }\n\n    // Find AI messages with subagent tool calls\n    let hasChanges = false;\n\n    for (const message of messages) {\n      if (\n        message.type !== \"ai\" ||\n        !(\"tool_calls\" in message) ||\n        !Array.isArray(message.tool_calls)\n      ) {\n        continue;\n      }\n\n      for (const toolCall of message.tool_calls) {\n        if (!toolCall.id) continue;\n        if (!this.isSubagentToolCall(toolCall.name)) continue;\n\n        // Skip if we already have this subagent\n        if (this.subagents.has(toolCall.id)) continue;\n\n        // Parse args\n        const parsedArgs = this.parseArgs(toolCall.args);\n\n        // Skip if no valid subagent_type\n        if (!this.isValidSubagentType(parsedArgs.subagent_type)) continue;\n\n        // Create the subagent tool call\n        const subagentToolCall: SubagentToolCall = {\n          id: toolCall.id,\n          name: toolCall.name,\n          args: {\n            description: parsedArgs.description as string | undefined,\n            subagent_type: parsedArgs.subagent_type as string | undefined,\n            ...parsedArgs,\n          },\n        };\n\n        // Check if we have a result for this tool call\n        const toolResult = toolResults.get(toolCall.id);\n        const isComplete = !!toolResult;\n        // eslint-disable-next-line no-nested-ternary\n        const status: SubagentStatus = isComplete\n          ? toolResult.status === \"error\"\n            ? \"error\"\n            : \"complete\"\n          : \"running\";\n\n        // Create the subagent execution stub. Messages and namespace are empty\n        // here; fetchSubagentHistory will derive the subgraph checkpoint_ns by\n        // inspecting intermediate history tasks and populate messages async.\n        const execution: SubagentStreamBase<ToolCall> = {\n          id: toolCall.id,\n          toolCall: subagentToolCall,\n          status,\n          values: {}, // Values not available from history\n          result:\n            isComplete && status === \"complete\" ? toolResult.content : null,\n          error: isComplete && status === \"error\" ? toolResult.content : null,\n          namespace: [],\n          messages: [], // Restored asynchronously via fetchSubagentHistory\n          aiMessageId: (message.id as string) ?? null,\n          parentId: null,\n          depth: 0,\n          startedAt: null,\n          completedAt: isComplete ? new Date() : null,\n        };\n\n        this.subagents.set(toolCall.id, execution);\n        hasChanges = true;\n      }\n    }\n\n    if (hasChanges) {\n      this.onSubagentChange?.();\n    }\n  }\n\n  /**\n   * Update a reconstructed subagent's messages and values from its subgraph checkpoint state.\n   *\n   * This is called after fetching the subgraph's history to restore the internal\n   * conversation that was lost on page refresh. Only updates if messages are\n   * currently empty (does not overwrite live streaming data).\n   *\n   * @param toolCallId - The tool call ID identifying the subagent\n   * @param messages - Messages from the subgraph's latest checkpoint\n   * @param values - Full state values from the subgraph's latest checkpoint\n   * @returns true if the subagent was updated, false otherwise\n   */\n  updateSubagentFromSubgraphState(\n    toolCallId: string,\n    messages: Message[],\n    values?: Record<string, unknown>\n  ): boolean {\n    const subagent = this.subagents.get(toolCallId);\n    if (!subagent) return false;\n    // Don't overwrite messages from active streaming\n    if (subagent.messages.length > 0) return false;\n    if (messages.length === 0) return false;\n\n    subagent.messages = messages as Message<ToolCall>[];\n    if (values != null) subagent.values = values;\n\n    this.onSubagentChange?.();\n    return true;\n  }\n\n  /**\n   * Check if any subagents are currently tracked.\n   */\n  hasSubagents(): boolean {\n    return this.subagents.size > 0;\n  }\n}\n"],"mappings":"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"}