@langchain/langgraph-sdk 1.7.4 → 1.8.0

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.
Files changed (49) hide show
  1. package/dist/react/stream.custom.cjs +21 -1
  2. package/dist/react/stream.custom.cjs.map +1 -1
  3. package/dist/react/stream.custom.js +21 -1
  4. package/dist/react/stream.custom.js.map +1 -1
  5. package/dist/react/stream.lgp.cjs +11 -1
  6. package/dist/react/stream.lgp.cjs.map +1 -1
  7. package/dist/react/stream.lgp.js +11 -1
  8. package/dist/react/stream.lgp.js.map +1 -1
  9. package/dist/ui/index.cjs +4 -0
  10. package/dist/ui/index.d.cts +3 -1
  11. package/dist/ui/index.d.ts +3 -1
  12. package/dist/ui/index.js +3 -1
  13. package/dist/ui/manager.cjs +181 -0
  14. package/dist/ui/manager.cjs.map +1 -1
  15. package/dist/ui/manager.d.cts +41 -0
  16. package/dist/ui/manager.d.cts.map +1 -1
  17. package/dist/ui/manager.d.ts +41 -0
  18. package/dist/ui/manager.d.ts.map +1 -1
  19. package/dist/ui/manager.js +181 -0
  20. package/dist/ui/manager.js.map +1 -1
  21. package/dist/ui/orchestrator-custom.cjs +372 -0
  22. package/dist/ui/orchestrator-custom.cjs.map +1 -0
  23. package/dist/ui/orchestrator-custom.d.cts +185 -0
  24. package/dist/ui/orchestrator-custom.d.cts.map +1 -0
  25. package/dist/ui/orchestrator-custom.d.ts +185 -0
  26. package/dist/ui/orchestrator-custom.d.ts.map +1 -0
  27. package/dist/ui/orchestrator-custom.js +372 -0
  28. package/dist/ui/orchestrator-custom.js.map +1 -0
  29. package/dist/ui/orchestrator.cjs +866 -0
  30. package/dist/ui/orchestrator.cjs.map +1 -0
  31. package/dist/ui/orchestrator.d.cts +366 -0
  32. package/dist/ui/orchestrator.d.cts.map +1 -0
  33. package/dist/ui/orchestrator.d.ts +366 -0
  34. package/dist/ui/orchestrator.d.ts.map +1 -0
  35. package/dist/ui/orchestrator.js +866 -0
  36. package/dist/ui/orchestrator.js.map +1 -0
  37. package/dist/ui/subagents.cjs +24 -1
  38. package/dist/ui/subagents.cjs.map +1 -1
  39. package/dist/ui/subagents.d.cts +13 -0
  40. package/dist/ui/subagents.d.cts.map +1 -1
  41. package/dist/ui/subagents.d.ts +13 -0
  42. package/dist/ui/subagents.d.ts.map +1 -1
  43. package/dist/ui/subagents.js +24 -1
  44. package/dist/ui/subagents.js.map +1 -1
  45. package/dist/ui/types.d.cts +3 -2
  46. package/dist/ui/types.d.cts.map +1 -1
  47. package/dist/ui/types.d.ts +3 -2
  48. package/dist/ui/types.d.ts.map +1 -1
  49. package/package.json +2 -6
@@ -1 +1 @@
1
- {"version":3,"file":"manager.cjs","names":["toMessageDict","SubagentManager","StreamError","isSubagentNamespace","extractToolCallIdFromNamespace"],"sources":["../../src/ui/manager.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type {\n CheckpointsStreamEvent,\n CustomStreamEvent,\n DebugStreamEvent,\n ErrorStreamEvent,\n EventsStreamEvent,\n FeedbackStreamEvent,\n MessagesTupleStreamEvent,\n MetadataStreamEvent,\n TasksStreamEvent,\n ToolsStreamEvent,\n UpdatesStreamEvent,\n ValuesStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { StreamError } from \"./errors.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport {\n SubagentManager,\n extractToolCallIdFromNamespace,\n isSubagentNamespace,\n} from \"./subagents.js\";\nimport type { SubagentStreamInterface } from \"./types.js\";\n\n/**\n * Special ID used by LangGraph's messagesStateReducer to signal\n * that all messages should be removed from the state.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\ntype GetUpdateType<\n Bag extends BagTemplate,\n StateType extends Record<string, unknown>\n> = Bag extends { UpdateType: unknown }\n ? Bag[\"UpdateType\"]\n : Partial<StateType>;\n\ntype GetCustomEventType<Bag extends BagTemplate> = Bag extends {\n CustomEventType: unknown;\n}\n ? Bag[\"CustomEventType\"]\n : unknown;\n\ntype EventStreamMap<StateType, UpdateType, CustomType> = {\n values: ValuesStreamEvent<StateType>;\n updates: UpdatesStreamEvent<UpdateType>;\n custom: CustomStreamEvent<CustomType>;\n debug: DebugStreamEvent;\n messages: MessagesTupleStreamEvent;\n events: EventsStreamEvent;\n metadata: MetadataStreamEvent;\n checkpoints: CheckpointsStreamEvent<StateType>;\n tasks: TasksStreamEvent<StateType, UpdateType>;\n error: ErrorStreamEvent;\n feedback: FeedbackStreamEvent;\n tools: ToolsStreamEvent;\n};\n\nexport type EventStreamEvent<StateType, UpdateType, CustomType> =\n EventStreamMap<StateType, UpdateType, CustomType>[keyof EventStreamMap<\n StateType,\n UpdateType,\n CustomType\n >];\n\ninterface StreamManagerEventCallbacks<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> {\n onUpdateEvent?: (\n data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onCustomEvent?: (\n data: GetCustomEventType<Bag>,\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onMetadataEvent?: (data: MetadataStreamEvent[\"data\"]) => void;\n onLangChainEvent?: (data: EventsStreamEvent[\"data\"]) => void;\n onDebugEvent?: (\n data: DebugStreamEvent[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onCheckpointEvent?: (\n data: CheckpointsStreamEvent<StateType>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onTaskEvent?: (\n data: TasksStreamEvent<StateType, GetUpdateType<Bag, StateType>>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onToolEvent?: (\n data: ToolsStreamEvent[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n}\n\n/**\n * Options for StreamManager constructor.\n */\nexport interface StreamManagerOptions {\n /**\n * Throttle the stream updates.\n * If a number is provided, updates are throttled to the given milliseconds.\n * If `true`, updates are batched in a single macrotask.\n * If `false`, updates are not throttled.\n */\n throttle: number | boolean;\n\n /**\n * Tool names that indicate subagent invocation.\n *\n * When an AI message contains tool calls with these names, they are\n * automatically tracked as subagent executions. This enables the\n * `subagents`, `activeSubagents`, `getSubagent()`, and `getSubagentsByType()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"]\n * ```\n */\n subagentToolNames?: string[];\n\n /**\n * Filter out messages from subagent streams in the main messages array.\n *\n * When enabled, messages from subagraph executions (those with a `tools:` namespace)\n * are excluded from `stream.messages`. Instead, these messages are tracked\n * per-subagent and accessible via `stream.subagents.get(id).messages`.\n *\n * This is useful for deep agent architectures where you want to display\n * the main conversation separately from subagent activity.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream({\n * assistantId: \"my-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // Main thread messages only (no subagent messages)\n * stream.messages\n *\n * // Access subagent messages individually\n * stream.subagents.get(\"call_xyz\").messages\n * ```\n */\n filterSubagentMessages?: boolean;\n\n /**\n * Converts a @langchain/core BaseMessage to the desired output format.\n *\n * Defaults to `toMessageDict` which produces plain Message objects.\n * Framework SDKs pass `toMessageClass` (identity) to keep class instances.\n */\n toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\nexport class StreamManager<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> {\n private abortRef = new AbortController();\n\n private messages: MessageTupleManager;\n\n private subagentManager: SubagentManager;\n\n private listeners = new Set<() => void>();\n\n private throttle: number | boolean;\n\n private filterSubagentMessages: boolean;\n\n private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n private queueSize: number = 0;\n\n private state: {\n isLoading: boolean;\n values: [values: StateType, kind: \"stream\" | \"stop\"] | null;\n error: unknown;\n /** Version counter to force React re-renders on subagent changes */\n version: number;\n };\n\n constructor(messages: MessageTupleManager, options: StreamManagerOptions) {\n this.messages = messages;\n this.state = {\n isLoading: false,\n values: null,\n error: undefined,\n version: 0,\n };\n this.throttle = options.throttle;\n this.filterSubagentMessages = options.filterSubagentMessages ?? false;\n this.toMessage = options.toMessage ?? toMessageDict;\n this.subagentManager = new SubagentManager({\n subagentToolNames: options.subagentToolNames,\n onSubagentChange: () => this.bumpVersion(),\n toMessage: this.toMessage,\n });\n }\n\n /**\n * Increment version counter to trigger React re-renders.\n * Called when subagent state changes.\n */\n private bumpVersion = () => {\n this.state = { ...this.state, version: this.state.version + 1 };\n this.notifyListeners();\n };\n\n /**\n * Get all subagents as a Map.\n */\n getSubagents(): Map<string, SubagentStreamInterface> {\n return this.subagentManager.getSubagents();\n }\n\n /**\n * Get all currently running subagents.\n */\n getActiveSubagents(): SubagentStreamInterface[] {\n return this.subagentManager.getActiveSubagents();\n }\n\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStreamInterface | undefined {\n return this.subagentManager.getSubagent(toolCallId);\n }\n\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByType(type);\n }\n\n /**\n * Get all subagents triggered by a specific AI message.\n */\n getSubagentsByMessage(messageId: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent state from historical messages.\n *\n * This method should be called when loading thread history to restore\n * subagent visualization after:\n * - Page refresh (when stream has already completed)\n * - Loading thread history\n * - Navigating between threads\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 reconstructSubagents(\n messages: Message[],\n options?: { skipIfPopulated?: boolean }\n ): void {\n this.subagentManager.reconstructFromMessages(messages, options);\n }\n\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean {\n return this.subagentManager.hasSubagents();\n }\n\n private setState = (newState: Partial<typeof this.state>) => {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n };\n\n private notifyListeners = () => {\n this.listeners.forEach((listener) => listener());\n };\n\n subscribe = (listener: () => void): (() => void) => {\n if (this.throttle === false) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n const timeoutMs = this.throttle === true ? 0 : this.throttle;\n let timeoutId: NodeJS.Timeout | number | undefined;\n\n const throttledListener = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n clearTimeout(timeoutId);\n listener();\n }, timeoutMs);\n };\n\n this.listeners.add(throttledListener);\n return () => {\n clearTimeout(timeoutId);\n this.listeners.delete(throttledListener);\n };\n };\n\n getSnapshot = () => this.state;\n\n get isLoading() {\n return this.state.isLoading;\n }\n\n get values() {\n return this.state.values?.[0] ?? null;\n }\n\n get error() {\n return this.state.error;\n }\n\n setStreamValues = (\n values:\n | (StateType | null)\n | ((prev: StateType | null, kind: \"stream\" | \"stop\") => StateType | null),\n kind: \"stream\" | \"stop\" = \"stream\"\n ) => {\n if (typeof values === \"function\") {\n const [prevValues, prevKind] = this.state.values ?? [null, \"stream\"];\n const nextValues = values(prevValues, prevKind);\n this.setState({ values: nextValues != null ? [nextValues, kind] : null });\n } else {\n const nextValues = values != null ? [values, kind] : null;\n this.setState({ values: nextValues as [StateType, \"stream\" | \"stop\"] });\n }\n };\n\n private getMutateFn = (kind: \"stream\" | \"stop\", historyValues: StateType) => {\n return (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => {\n const stateValues = (this.state.values ?? [null, \"stream\"])[0];\n const prev = {\n ...historyValues,\n ...stateValues,\n };\n const next = typeof update === \"function\" ? update(prev) : update;\n this.setStreamValues({ ...prev, ...next }, kind);\n };\n };\n\n private matchEventType = <\n T extends keyof EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >(\n expected: T,\n actual: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"event\"],\n _data: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"data\"]\n ): _data is EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[T][\"data\"] => {\n return expected === actual || actual.startsWith(`${expected}|`);\n };\n\n protected enqueue = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n }\n ) => {\n try {\n this.queueSize = Math.max(0, this.queueSize - 1);\n this.setState({ isLoading: true, error: undefined });\n this.abortRef = new AbortController();\n\n const run = await action(this.abortRef.signal);\n\n let streamError: StreamError | undefined;\n for await (const { event, data } of run) {\n if (event === \"error\") {\n streamError = new StreamError(data);\n break;\n }\n\n const namespace = event.includes(\"|\")\n ? event.split(\"|\").slice(1)\n : undefined;\n\n const mutate = this.getMutateFn(\"stream\", options.initialValues);\n\n if (event === \"metadata\") options.callbacks.onMetadataEvent?.(data);\n if (event === \"events\") options.callbacks.onLangChainEvent?.(data);\n\n if (this.matchEventType(\"updates\", event, data)) {\n options.callbacks.onUpdateEvent?.(data, { namespace, mutate });\n\n // Track subagent streaming updates from subgraph namespaces\n // Mark the subagent as running when we receive updates\n // The actual message content is handled via addMessageToSubagent\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n this.subagentManager.markRunningFromNamespace(\n namespaceId,\n namespace\n );\n }\n }\n\n // Also register subagents from main agent updates (tool_calls in messages)\n // AND process tool results to complete subagents\n // This is needed because tool_calls often appear complete in updates\n // before they appear in the messages stream\n if (!namespace || !isSubagentNamespace(namespace)) {\n const updateData = data as Record<string, unknown>;\n for (const nodeData of Object.values(updateData)) {\n if (\n nodeData &&\n typeof nodeData === \"object\" &&\n \"messages\" in nodeData\n ) {\n const { messages } = nodeData as { messages: unknown[] };\n if (Array.isArray(messages)) {\n for (const msg of messages) {\n if (!msg || typeof msg !== \"object\") continue;\n const msgObj = msg as Record<string, unknown>;\n\n // Register subagents from AI messages with tool_calls\n if (\n msgObj.type === \"ai\" &&\n \"tool_calls\" in msgObj &&\n Array.isArray(msgObj.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgObj.tool_calls as Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>,\n msgObj.id as string | undefined\n );\n }\n\n // Complete subagents from tool messages (task results)\n if (\n msgObj.type === \"tool\" &&\n \"tool_call_id\" in msgObj &&\n typeof msgObj.tool_call_id === \"string\"\n ) {\n const content =\n typeof msgObj.content === \"string\"\n ? msgObj.content\n : JSON.stringify(msgObj.content);\n const status =\n \"status\" in msgObj && msgObj.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(\n msgObj.tool_call_id,\n content,\n status\n );\n }\n }\n }\n }\n }\n }\n }\n\n if (this.matchEventType(\"custom\", event, data)) {\n options.callbacks.onCustomEvent?.(data, { namespace, mutate });\n }\n\n if (this.matchEventType(\"checkpoints\", event, data)) {\n options.callbacks.onCheckpointEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tasks\", event, data)) {\n options.callbacks.onTaskEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"debug\", event, data)) {\n options.callbacks.onDebugEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tools\", event, data)) {\n options.callbacks.onToolEvent?.(data, { namespace, mutate });\n }\n\n // Handle values events - use startsWith to match both \"values\" and \"values|tools:xxx\"\n if (event === \"values\" || event.startsWith(\"values|\")) {\n // Check if this is a subgraph values event (for namespace mapping and values)\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n const valuesData = data as Record<string, unknown>;\n\n // Try to establish namespace mapping from the initial human message\n const messages = valuesData.messages as unknown[];\n if (Array.isArray(messages) && messages.length > 0) {\n const firstMsg = messages[0] as Record<string, unknown>;\n if (\n firstMsg?.type === \"human\" &&\n typeof firstMsg?.content === \"string\"\n ) {\n this.subagentManager.matchSubgraphToSubagent(\n namespaceId,\n firstMsg.content\n );\n }\n }\n\n // Update the subagent's values with the full state\n this.subagentManager.updateSubagentValues(\n namespaceId,\n valuesData\n );\n }\n } else if (\n data &&\n typeof data === \"object\" &&\n \"__interrupt__\" in data\n ) {\n const interruptData = data as Partial<StateType>;\n this.setStreamValues(\n (prev) => ({ ...prev, ...interruptData } as StateType)\n );\n } else {\n this.setStreamValues(data as StateType);\n }\n }\n\n if (this.matchEventType(\"messages\", event, data)) {\n const [serialized, metadata] = data;\n\n // Check if this message is from a subagent namespace\n const rawCheckpointNs =\n (metadata?.langgraph_checkpoint_ns as string | undefined) ||\n (metadata?.checkpoint_ns as string | undefined);\n const checkpointNs: string | undefined =\n typeof rawCheckpointNs === \"string\" ? rawCheckpointNs : undefined;\n const isFromSubagent = isSubagentNamespace(checkpointNs);\n const toolCallId = isFromSubagent\n ? extractToolCallIdFromNamespace(checkpointNs?.split(\"|\"))\n : undefined;\n\n // If filtering is enabled and this is a subagent message,\n // add it to the subagent's messages instead of the main stream\n if (this.filterSubagentMessages && isFromSubagent && toolCallId) {\n // Add to subagent's message list\n this.subagentManager.addMessageToSubagent(\n toolCallId,\n serialized,\n metadata\n );\n continue;\n }\n\n const messageId = this.messages.add(serialized, metadata);\n if (!messageId) {\n console.warn(\n \"Failed to add message to manager, no message ID found\"\n );\n continue;\n }\n\n this.setStreamValues((streamValues) => {\n const values = {\n ...options.initialValues,\n ...streamValues,\n };\n\n // Assumption: we're concatenating the message\n let messages = options.getMessages(values).slice();\n const { chunk, index } =\n this.messages.get(messageId, messages.length) ?? {};\n\n if (!chunk || index == null) return values;\n if (chunk.getType() === \"remove\") {\n // Check for special REMOVE_ALL_MESSAGES sentinel\n if (chunk.id === REMOVE_ALL_MESSAGES) {\n // Clear all messages when __remove_all__ is received\n messages = [];\n } else {\n messages.splice(index, 1);\n }\n } else {\n const msgDict = this.toMessage(chunk) as Message;\n messages[index] = msgDict;\n\n // Track subagents from AI messages with tool calls (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"ai\" &&\n \"tool_calls\" in msgDict &&\n Array.isArray(msgDict.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgDict.tool_calls,\n msgDict.id as string | undefined\n );\n }\n\n // Complete subagents when tool messages arrive (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"tool\" &&\n \"tool_call_id\" in msgDict\n ) {\n const tcId = msgDict.tool_call_id as string;\n const content =\n typeof msgDict.content === \"string\"\n ? msgDict.content\n : JSON.stringify(msgDict.content);\n const status =\n \"status\" in msgDict && msgDict.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(tcId, content, status);\n }\n }\n\n return options.setMessages(values, messages);\n });\n }\n }\n\n if (streamError != null) throw streamError;\n\n // Skip onSuccess when the stream was aborted (e.g., by multitask interrupt).\n // This avoids unnecessary HTTP calls (like history fetching) that would\n // delay the next queued stream from starting.\n if (!this.abortRef.signal.aborted) {\n const values = await options.onSuccess?.();\n if (typeof values !== \"undefined\" && this.queueSize === 0) {\n this.setStreamValues(values);\n }\n }\n } catch (error) {\n if (\n !(\n error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n )\n ) {\n console.error(error);\n this.setState({ error });\n await options.onError?.(error);\n }\n } finally {\n this.setState({ isLoading: false });\n this.abortRef = new AbortController();\n options.onFinish?.();\n }\n };\n\n start = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n },\n startOptions?: {\n /**\n * If true, abort any currently running stream before starting this one.\n * Used for multitask_strategy: \"interrupt\" and \"rollback\" to unblock\n * the queue so the new run request can proceed immediately.\n */\n abortPrevious?: boolean;\n }\n ): Promise<void> => {\n if (startOptions?.abortPrevious) {\n this.abortRef.abort();\n }\n this.queueSize += 1;\n const queued = this.queue.then(() => this.enqueue(action, options));\n this.queue = queued;\n await queued;\n };\n\n stop = async (\n historyValues: StateType,\n options: {\n onStop?: (options: {\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }) => void;\n }\n ): Promise<void> => {\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n options.onStop?.({ mutate: this.getMutateFn(\"stop\", historyValues) });\n };\n\n clear = () => {\n // Cancel any running streams\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n // Set the stream state to null\n this.setState({ error: undefined, values: null, isLoading: false });\n\n // Clear any pending messages\n this.messages.clear();\n\n // Clear subagent state\n this.subagentManager.clear();\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manager.cjs","names":["toMessageDict","SubagentManager","StreamError","isSubagentNamespace","extractToolCallIdFromNamespace"],"sources":["../../src/ui/manager.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type {\n CheckpointsStreamEvent,\n CustomStreamEvent,\n DebugStreamEvent,\n ErrorStreamEvent,\n EventsStreamEvent,\n FeedbackStreamEvent,\n MessagesTupleStreamEvent,\n MetadataStreamEvent,\n TasksStreamEvent,\n ToolsStreamEvent,\n UpdatesStreamEvent,\n ValuesStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { StreamError } from \"./errors.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport {\n SubagentManager,\n extractToolCallIdFromNamespace,\n isSubagentNamespace,\n} from \"./subagents.js\";\nimport type { SubagentStreamInterface } from \"./types.js\";\n\n/**\n * Special ID used by LangGraph's messagesStateReducer to signal\n * that all messages should be removed from the state.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\ntype GetUpdateType<\n Bag extends BagTemplate,\n StateType extends Record<string, unknown>\n> = Bag extends { UpdateType: unknown }\n ? Bag[\"UpdateType\"]\n : Partial<StateType>;\n\ntype GetCustomEventType<Bag extends BagTemplate> = Bag extends {\n CustomEventType: unknown;\n}\n ? Bag[\"CustomEventType\"]\n : unknown;\n\ntype EventStreamMap<StateType, UpdateType, CustomType> = {\n values: ValuesStreamEvent<StateType>;\n updates: UpdatesStreamEvent<UpdateType>;\n custom: CustomStreamEvent<CustomType>;\n debug: DebugStreamEvent;\n messages: MessagesTupleStreamEvent;\n events: EventsStreamEvent;\n metadata: MetadataStreamEvent;\n checkpoints: CheckpointsStreamEvent<StateType>;\n tasks: TasksStreamEvent<StateType, UpdateType>;\n error: ErrorStreamEvent;\n feedback: FeedbackStreamEvent;\n tools: ToolsStreamEvent;\n};\n\nexport type EventStreamEvent<StateType, UpdateType, CustomType> =\n EventStreamMap<StateType, UpdateType, CustomType>[keyof EventStreamMap<\n StateType,\n UpdateType,\n CustomType\n >];\n\ninterface StreamManagerEventCallbacks<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> {\n onUpdateEvent?: (\n data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onCustomEvent?: (\n data: GetCustomEventType<Bag>,\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onMetadataEvent?: (data: MetadataStreamEvent[\"data\"]) => void;\n onLangChainEvent?: (data: EventsStreamEvent[\"data\"]) => void;\n onDebugEvent?: (\n data: DebugStreamEvent[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onCheckpointEvent?: (\n data: CheckpointsStreamEvent<StateType>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onTaskEvent?: (\n data: TasksStreamEvent<StateType, GetUpdateType<Bag, StateType>>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onToolEvent?: (\n data: ToolsStreamEvent[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n}\n\n/**\n * Options for StreamManager constructor.\n */\nexport interface StreamManagerOptions {\n /**\n * Throttle the stream updates.\n * If a number is provided, updates are throttled to the given milliseconds.\n * If `true`, updates are batched in a single macrotask.\n * If `false`, updates are not throttled.\n */\n throttle: number | boolean;\n\n /**\n * Tool names that indicate subagent invocation.\n *\n * When an AI message contains tool calls with these names, they are\n * automatically tracked as subagent executions. This enables the\n * `subagents`, `activeSubagents`, `getSubagent()`, and `getSubagentsByType()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"]\n * ```\n */\n subagentToolNames?: string[];\n\n /**\n * Filter out messages from subagent streams in the main messages array.\n *\n * When enabled, messages from subagraph executions (those with a `tools:` namespace)\n * are excluded from `stream.messages`. Instead, these messages are tracked\n * per-subagent and accessible via `stream.subagents.get(id).messages`.\n *\n * This is useful for deep agent architectures where you want to display\n * the main conversation separately from subagent activity.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream({\n * assistantId: \"my-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // Main thread messages only (no subagent messages)\n * stream.messages\n *\n * // Access subagent messages individually\n * stream.subagents.get(\"call_xyz\").messages\n * ```\n */\n filterSubagentMessages?: boolean;\n\n /**\n * Converts a @langchain/core BaseMessage to the desired output format.\n *\n * Defaults to `toMessageDict` which produces plain Message objects.\n * Framework SDKs pass `toMessageClass` (identity) to keep class instances.\n */\n toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\nexport class StreamManager<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> {\n private abortRef = new AbortController();\n\n private messages: MessageTupleManager;\n\n private subagentManager: SubagentManager;\n\n private listeners = new Set<() => void>();\n\n private throttle: number | boolean;\n\n private filterSubagentMessages: boolean;\n\n private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n private queueSize: number = 0;\n\n private state: {\n isLoading: boolean;\n values: [values: StateType, kind: \"stream\" | \"stop\"] | null;\n error: unknown;\n /** Version counter to force React re-renders on subagent changes */\n version: number;\n };\n\n constructor(messages: MessageTupleManager, options: StreamManagerOptions) {\n this.messages = messages;\n this.state = {\n isLoading: false,\n values: null,\n error: undefined,\n version: 0,\n };\n this.throttle = options.throttle;\n this.filterSubagentMessages = options.filterSubagentMessages ?? false;\n this.toMessage = options.toMessage ?? toMessageDict;\n this.subagentManager = new SubagentManager({\n subagentToolNames: options.subagentToolNames,\n onSubagentChange: () => this.bumpVersion(),\n toMessage: this.toMessage,\n });\n }\n\n /**\n * Increment version counter to trigger React re-renders.\n * Called when subagent state changes.\n */\n private bumpVersion = () => {\n this.state = { ...this.state, version: this.state.version + 1 };\n this.notifyListeners();\n };\n\n /**\n * Get all subagents as a Map.\n */\n getSubagents(): Map<string, SubagentStreamInterface> {\n return this.subagentManager.getSubagents();\n }\n\n /**\n * Get all currently running subagents.\n */\n getActiveSubagents(): SubagentStreamInterface[] {\n return this.subagentManager.getActiveSubagents();\n }\n\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStreamInterface | undefined {\n return this.subagentManager.getSubagent(toolCallId);\n }\n\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByType(type);\n }\n\n /**\n * Get all subagents triggered by a specific AI message.\n */\n getSubagentsByMessage(messageId: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent state from historical messages.\n *\n * This method should be called when loading thread history to restore\n * subagent visualization after:\n * - Page refresh (when stream has already completed)\n * - Loading thread history\n * - Navigating between threads\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 reconstructSubagents(\n messages: Message[],\n options?: { skipIfPopulated?: boolean }\n ): void {\n this.subagentManager.reconstructFromMessages(messages, options);\n }\n\n /**\n * Fetch and restore internal messages for reconstructed subagents from their\n * subgraph checkpoints. Should be called after `reconstructSubagents` to\n * restore the full subagent conversation after a page refresh.\n *\n * Subagent messages are persisted in the LangGraph checkpointer under a\n * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method\n * discovers the correct namespace by inspecting the main thread's intermediate\n * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`\n * identifies the subgraph. Tasks are matched to tool calls by their Send index\n * (`task.path[1]`), which corresponds to the order of tool calls in the AI\n * message — no deepagent-specific metadata required.\n *\n * @param threads - Client with a `getHistory` method (e.g. `client.threads`)\n * @param threadId - The parent thread ID\n * @param options - Optional configuration\n * @param options.messagesKey - Key in state values containing messages (default: \"messages\")\n * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup\n */\n async fetchSubagentHistory(\n threads: {\n getHistory<V extends Record<string, unknown>>(\n threadId: string,\n options?: {\n limit?: number;\n checkpoint?: { checkpoint_ns?: string };\n signal?: AbortSignal;\n }\n ): Promise<\n Array<{\n values: V;\n tasks?: Array<{\n id: string;\n name: string;\n path?: unknown[];\n checkpoint?: { checkpoint_ns?: string } | null;\n }>;\n }>\n >;\n },\n threadId: string,\n options?: { messagesKey?: string; signal?: AbortSignal }\n ): Promise<void> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const signal = options?.signal;\n\n /**\n * Bail immediately if already cancelled (React Strict Mode cleanup)\n */\n if (signal?.aborted) {\n return;\n }\n\n /**\n * Only fetch for subagents that have no messages (reconstructed from history)\n */\n const toFetch = [...this.subagentManager.getSubagents().entries()].filter(\n ([, s]) => s.messages.length === 0\n );\n\n /**\n * Bail immediately if there are no subagents to fetch\n */\n if (toFetch.length === 0) {\n return;\n }\n\n /**\n * Step 1: Discover subgraph namespaces from intermediate history\n *\n * When LangGraph dispatches parallel tool calls (v2 mode), each is a\n * separate Send task with a unique UUID-based checkpoint_ns. The intermediate\n * history checkpoints record these as `tasks[i]` where:\n * - `tasks[i].checkpoint.checkpoint_ns` = \"tools:<uuid>\" for each subgraph\n * - `tasks[i].path = [\"__pregel_push\", sendIndex]` matches tool_calls order\n *\n * By matching task Send index → tool_call position in the AI message we can\n * derive the subgraph namespace for every tool call without any external\n * metadata on the ToolMessage itself.\n */\n let toolCallIdToNamespace: Map<string, string> | undefined;\n\n try {\n /**\n * Fetch enough history to include the intermediate checkpoint where\n * tool-call tasks were pending (typically within the last 10 checkpoints).\n */\n const mainHistory = await threads.getHistory<Record<string, unknown>>(\n threadId,\n { limit: 20, signal }\n );\n\n for (const checkpoint of mainHistory) {\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n /**\n * When a completed checkpoint contains task results, each task.result\n * has a ToolMessage whose tool_call_id directly and unambiguously maps\n * the task to the LLM tool call that triggered it. This is more robust\n * than positional alignment: it works even when a step mixes subagent\n * tool calls with other tool calls, and requires no assumptions about\n * the ordering of tasks vs tool_calls.\n *\n * LangGraph v2 dispatches each parallel tool call as a separate PUSH\n * task (\"__pregel_push\"). The subgraph checkpoint_ns is constructed as\n * `task.name + \":\" + task.id`, mirroring algo.ts:\n * taskCheckpointNamespace = checkpointNamespace + \":\" + taskId\n * where checkpointNamespace = task.name for root-level tasks.\n *\n * task.checkpoint is always null for completed tasks, so we derive the\n * namespace from task.name + task.id rather than task.checkpoint.checkpoint_ns.\n */\n const directMap = new Map<string, string>();\n\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n\n /**\n * Read tool_call_id directly from the task's result ToolMessage.\n */\n const resultMessages = (\n task as unknown as { result?: { messages?: unknown[] } }\n ).result?.messages;\n\n if (Array.isArray(resultMessages)) {\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"tool\" &&\n typeof m.tool_call_id === \"string\" &&\n toFetch.some(([id]) => id === m.tool_call_id)\n ) {\n directMap.set(m.tool_call_id, `${task.name}:${task.id}`);\n }\n }\n }\n }\n\n if (directMap.size > 0) {\n toolCallIdToNamespace = directMap;\n break;\n }\n\n /**\n * Fallback for checkpoints where task results are not yet populated\n * (tasks are still pending). Use positional alignment via the Send\n * index in task.path[1] as a secondary strategy.\n */\n const pushTasks = tasks.filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) continue;\n\n /**\n * Find the AI message with subagent tool calls to align by Send index.\n */\n const msgs = checkpoint.values[messagesKey];\n if (!Array.isArray(msgs)) continue;\n\n let aiMessage: Record<string, unknown> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n Array.isArray(m.tool_calls) &&\n m.tool_calls.length > 0 &&\n (m.tool_calls as Array<{ name: string }>).some((tc) =>\n this.subagentManager.isSubagentToolCall(tc.name)\n )\n ) {\n aiMessage = m;\n break;\n }\n }\n if (!aiMessage) {\n continue;\n }\n\n /**\n * Only consider subagent tool calls from the AI message — not all tool\n * calls. This ensures regular tool calls (searchWeb, queryDatabase, etc.)\n * are never mistaken for subagents even when they appear in the same step.\n */\n const subagentToolCalls = (\n aiMessage.tool_calls as Array<{ id?: string; name: string }>\n ).filter((tc) => this.subagentManager.isSubagentToolCall(tc.name));\n\n if (subagentToolCalls.length === 0) {\n continue;\n }\n\n /**\n * Sort push tasks by Send index (path[1]) to align with tool_calls order\n */\n const sorted = [...pushTasks].sort((a, b) => {\n const ai = Array.isArray(a.path) ? (a.path[1] as number) : 0;\n const bi = Array.isArray(b.path) ? (b.path[1] as number) : 0;\n return ai - bi;\n });\n\n toolCallIdToNamespace = new Map();\n for (\n let i = 0;\n i < sorted.length && i < subagentToolCalls.length;\n i += 1\n ) {\n const tc = subagentToolCalls[i];\n const task = sorted[i];\n if (tc?.id && task.id && task.name) {\n toolCallIdToNamespace.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n\n if (toolCallIdToNamespace.size > 0) break;\n }\n } catch {\n /**\n * Non-fatal: fall back to subagent.namespace below\n */\n }\n\n /**\n * Step 2: Fetch each subagent's conversation from its subgraph checkpoint\n */\n await Promise.all(\n toFetch.map(async ([toolCallId, subagent]) => {\n /**\n * Priority order for the subgraph checkpoint_ns:\n * 1. Derived from main thread's intermediate task list (preferred, no coupling)\n * 2. Already on the subagent's namespace (e.g. populated during streaming)\n * 3. Skip — we cannot reliably identify the namespace\n */\n const checkpointNs =\n toolCallIdToNamespace?.get(toolCallId) ??\n (subagent.namespace.length > 0\n ? subagent.namespace.join(\"|\")\n : undefined);\n\n if (!checkpointNs) return;\n\n try {\n const history = await threads.getHistory<Record<string, unknown>>(\n threadId,\n {\n checkpoint: { checkpoint_ns: checkpointNs },\n limit: 1,\n signal,\n }\n );\n\n /**\n * If the HTTP request was cancelled mid-flight the getHistory call\n * would have thrown an AbortError (caught below). If we reach here the\n * fetch completed successfully, so always process the result.\n */\n const latestState = history[0];\n if (!latestState?.values) return;\n\n const messages = latestState.values[messagesKey];\n if (!Array.isArray(messages) || messages.length === 0) return;\n\n /**\n * Normalize messages: promote tool_calls from additional_kwargs to top\n * level when the checkpointer serialized them in the legacy format.\n */\n const normalizedMessages = messages.map((msg) => {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n (!m.tool_calls || (m.tool_calls as unknown[]).length === 0)\n ) {\n const ak = m.additional_kwargs as\n | Record<string, unknown>\n | undefined;\n const legacy = ak?.tool_calls;\n if (Array.isArray(legacy) && legacy.length > 0) {\n return { ...m, tool_calls: legacy };\n }\n }\n return m;\n });\n\n this.subagentManager.updateSubagentFromSubgraphState(\n toolCallId,\n normalizedMessages as Message[],\n latestState.values\n );\n } catch {\n /**\n * Ignore AbortError and other transient errors\n */\n }\n })\n );\n }\n\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean {\n return this.subagentManager.hasSubagents();\n }\n\n private setState = (newState: Partial<typeof this.state>) => {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n };\n\n private notifyListeners = () => {\n this.listeners.forEach((listener) => listener());\n };\n\n subscribe = (listener: () => void): (() => void) => {\n if (this.throttle === false) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n const timeoutMs = this.throttle === true ? 0 : this.throttle;\n let timeoutId: NodeJS.Timeout | number | undefined;\n\n const throttledListener = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n clearTimeout(timeoutId);\n listener();\n }, timeoutMs);\n };\n\n this.listeners.add(throttledListener);\n return () => {\n clearTimeout(timeoutId);\n this.listeners.delete(throttledListener);\n };\n };\n\n getSnapshot = () => this.state;\n\n get isLoading() {\n return this.state.isLoading;\n }\n\n get values() {\n return this.state.values?.[0] ?? null;\n }\n\n get error() {\n return this.state.error;\n }\n\n setStreamValues = (\n values:\n | (StateType | null)\n | ((prev: StateType | null, kind: \"stream\" | \"stop\") => StateType | null),\n kind: \"stream\" | \"stop\" = \"stream\"\n ) => {\n if (typeof values === \"function\") {\n const [prevValues, prevKind] = this.state.values ?? [null, \"stream\"];\n const nextValues = values(prevValues, prevKind);\n this.setState({ values: nextValues != null ? [nextValues, kind] : null });\n } else {\n const nextValues = values != null ? [values, kind] : null;\n this.setState({ values: nextValues as [StateType, \"stream\" | \"stop\"] });\n }\n };\n\n private getMutateFn = (kind: \"stream\" | \"stop\", historyValues: StateType) => {\n return (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => {\n const stateValues = (this.state.values ?? [null, \"stream\"])[0];\n const prev = {\n ...historyValues,\n ...stateValues,\n };\n const next = typeof update === \"function\" ? update(prev) : update;\n this.setStreamValues({ ...prev, ...next }, kind);\n };\n };\n\n private matchEventType = <\n T extends keyof EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >(\n expected: T,\n actual: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"event\"],\n _data: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"data\"]\n ): _data is EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[T][\"data\"] => {\n return expected === actual || actual.startsWith(`${expected}|`);\n };\n\n protected enqueue = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n }\n ) => {\n try {\n this.queueSize = Math.max(0, this.queueSize - 1);\n this.setState({ isLoading: true, error: undefined });\n this.abortRef = new AbortController();\n\n const run = await action(this.abortRef.signal);\n\n let streamError: StreamError | undefined;\n for await (const { event, data } of run) {\n if (event === \"error\") {\n streamError = new StreamError(data);\n break;\n }\n\n const namespace = event.includes(\"|\")\n ? event.split(\"|\").slice(1)\n : undefined;\n\n const mutate = this.getMutateFn(\"stream\", options.initialValues);\n\n if (event === \"metadata\") options.callbacks.onMetadataEvent?.(data);\n if (event === \"events\") options.callbacks.onLangChainEvent?.(data);\n\n if (this.matchEventType(\"updates\", event, data)) {\n options.callbacks.onUpdateEvent?.(data, { namespace, mutate });\n\n // Track subagent streaming updates from subgraph namespaces\n // Mark the subagent as running when we receive updates\n // The actual message content is handled via addMessageToSubagent\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n this.subagentManager.markRunningFromNamespace(\n namespaceId,\n namespace\n );\n }\n }\n\n // Also register subagents from main agent updates (tool_calls in messages)\n // AND process tool results to complete subagents\n // This is needed because tool_calls often appear complete in updates\n // before they appear in the messages stream\n if (!namespace || !isSubagentNamespace(namespace)) {\n const updateData = data as Record<string, unknown>;\n for (const nodeData of Object.values(updateData)) {\n if (\n nodeData &&\n typeof nodeData === \"object\" &&\n \"messages\" in nodeData\n ) {\n const { messages } = nodeData as { messages: unknown[] };\n if (Array.isArray(messages)) {\n for (const msg of messages) {\n if (!msg || typeof msg !== \"object\") continue;\n const msgObj = msg as Record<string, unknown>;\n\n // Register subagents from AI messages with tool_calls\n if (\n msgObj.type === \"ai\" &&\n \"tool_calls\" in msgObj &&\n Array.isArray(msgObj.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgObj.tool_calls as Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>,\n msgObj.id as string | undefined\n );\n }\n\n // Complete subagents from tool messages (task results)\n if (\n msgObj.type === \"tool\" &&\n \"tool_call_id\" in msgObj &&\n typeof msgObj.tool_call_id === \"string\"\n ) {\n const content =\n typeof msgObj.content === \"string\"\n ? msgObj.content\n : JSON.stringify(msgObj.content);\n const status =\n \"status\" in msgObj && msgObj.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(\n msgObj.tool_call_id,\n content,\n status\n );\n }\n }\n }\n }\n }\n }\n }\n\n if (this.matchEventType(\"custom\", event, data)) {\n options.callbacks.onCustomEvent?.(data, { namespace, mutate });\n }\n\n if (this.matchEventType(\"checkpoints\", event, data)) {\n options.callbacks.onCheckpointEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tasks\", event, data)) {\n options.callbacks.onTaskEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"debug\", event, data)) {\n options.callbacks.onDebugEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tools\", event, data)) {\n options.callbacks.onToolEvent?.(data, { namespace, mutate });\n }\n\n // Handle values events - use startsWith to match both \"values\" and \"values|tools:xxx\"\n if (event === \"values\" || event.startsWith(\"values|\")) {\n // Check if this is a subgraph values event (for namespace mapping and values)\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n const valuesData = data as Record<string, unknown>;\n\n // Try to establish namespace mapping from the initial human message\n const messages = valuesData.messages as unknown[];\n if (Array.isArray(messages) && messages.length > 0) {\n const firstMsg = messages[0] as Record<string, unknown>;\n if (\n firstMsg?.type === \"human\" &&\n typeof firstMsg?.content === \"string\"\n ) {\n this.subagentManager.matchSubgraphToSubagent(\n namespaceId,\n firstMsg.content\n );\n }\n }\n\n // Update the subagent's values with the full state\n this.subagentManager.updateSubagentValues(\n namespaceId,\n valuesData\n );\n }\n } else if (\n data &&\n typeof data === \"object\" &&\n \"__interrupt__\" in data\n ) {\n const interruptData = data as Partial<StateType>;\n this.setStreamValues(\n (prev) => ({ ...prev, ...interruptData } as StateType)\n );\n } else {\n this.setStreamValues(data as StateType);\n }\n }\n\n if (this.matchEventType(\"messages\", event, data)) {\n const [serialized, metadata] = data;\n\n // Check if this message is from a subagent namespace\n const rawCheckpointNs =\n (metadata?.langgraph_checkpoint_ns as string | undefined) ||\n (metadata?.checkpoint_ns as string | undefined);\n const checkpointNs: string | undefined =\n typeof rawCheckpointNs === \"string\" ? rawCheckpointNs : undefined;\n const isFromSubagent = isSubagentNamespace(checkpointNs);\n const toolCallId = isFromSubagent\n ? extractToolCallIdFromNamespace(checkpointNs?.split(\"|\"))\n : undefined;\n\n // If filtering is enabled and this is a subagent message,\n // add it to the subagent's messages instead of the main stream\n if (this.filterSubagentMessages && isFromSubagent && toolCallId) {\n // Add to subagent's message list\n this.subagentManager.addMessageToSubagent(\n toolCallId,\n serialized,\n metadata\n );\n continue;\n }\n\n const messageId = this.messages.add(serialized, metadata);\n if (!messageId) {\n console.warn(\n \"Failed to add message to manager, no message ID found\"\n );\n continue;\n }\n\n this.setStreamValues((streamValues) => {\n const values = {\n ...options.initialValues,\n ...streamValues,\n };\n\n // Assumption: we're concatenating the message\n let messages = options.getMessages(values).slice();\n const { chunk, index } =\n this.messages.get(messageId, messages.length) ?? {};\n\n if (!chunk || index == null) return values;\n if (chunk.getType() === \"remove\") {\n // Check for special REMOVE_ALL_MESSAGES sentinel\n if (chunk.id === REMOVE_ALL_MESSAGES) {\n // Clear all messages when __remove_all__ is received\n messages = [];\n } else {\n messages.splice(index, 1);\n }\n } else {\n const msgDict = this.toMessage(chunk) as Message;\n messages[index] = msgDict;\n\n // Track subagents from AI messages with tool calls (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"ai\" &&\n \"tool_calls\" in msgDict &&\n Array.isArray(msgDict.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgDict.tool_calls,\n msgDict.id as string | undefined\n );\n }\n\n // Complete subagents when tool messages arrive (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"tool\" &&\n \"tool_call_id\" in msgDict\n ) {\n const tcId = msgDict.tool_call_id as string;\n const content =\n typeof msgDict.content === \"string\"\n ? msgDict.content\n : JSON.stringify(msgDict.content);\n const status =\n \"status\" in msgDict && msgDict.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(tcId, content, status);\n }\n }\n\n return options.setMessages(values, messages);\n });\n }\n }\n\n if (streamError != null) throw streamError;\n\n // Skip onSuccess when the stream was aborted (e.g., by multitask interrupt).\n // This avoids unnecessary HTTP calls (like history fetching) that would\n // delay the next queued stream from starting.\n if (!this.abortRef.signal.aborted) {\n const values = await options.onSuccess?.();\n if (typeof values !== \"undefined\" && this.queueSize === 0) {\n this.setStreamValues(values);\n }\n }\n } catch (error) {\n if (\n !(\n error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n )\n ) {\n console.error(error);\n this.setState({ error });\n await options.onError?.(error);\n }\n } finally {\n this.setState({ isLoading: false });\n this.abortRef = new AbortController();\n options.onFinish?.();\n }\n };\n\n start = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n },\n startOptions?: {\n /**\n * If true, abort any currently running stream before starting this one.\n * Used for multitask_strategy: \"interrupt\" and \"rollback\" to unblock\n * the queue so the new run request can proceed immediately.\n */\n abortPrevious?: boolean;\n }\n ): Promise<void> => {\n if (startOptions?.abortPrevious) {\n this.abortRef.abort();\n }\n this.queueSize += 1;\n const queued = this.queue.then(() => this.enqueue(action, options));\n this.queue = queued;\n await queued;\n };\n\n stop = async (\n historyValues: StateType,\n options: {\n onStop?: (options: {\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }) => void;\n }\n ): Promise<void> => {\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n options.onStop?.({ mutate: this.getMutateFn(\"stop\", historyValues) });\n };\n\n clear = () => {\n // Cancel any running streams\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n // Set the stream state to null\n this.setState({ error: undefined, values: null, isLoading: false });\n\n // Clear any pending messages\n this.messages.clear();\n\n // Clear subagent state\n this.subagentManager.clear();\n };\n}\n"],"mappings":"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"}
@@ -168,6 +168,47 @@ declare class StreamManager<StateType extends Record<string, unknown>, Bag exten
168
168
  reconstructSubagents(messages: Message[], options?: {
169
169
  skipIfPopulated?: boolean;
170
170
  }): void;
171
+ /**
172
+ * Fetch and restore internal messages for reconstructed subagents from their
173
+ * subgraph checkpoints. Should be called after `reconstructSubagents` to
174
+ * restore the full subagent conversation after a page refresh.
175
+ *
176
+ * Subagent messages are persisted in the LangGraph checkpointer under a
177
+ * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method
178
+ * discovers the correct namespace by inspecting the main thread's intermediate
179
+ * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`
180
+ * identifies the subgraph. Tasks are matched to tool calls by their Send index
181
+ * (`task.path[1]`), which corresponds to the order of tool calls in the AI
182
+ * message — no deepagent-specific metadata required.
183
+ *
184
+ * @param threads - Client with a `getHistory` method (e.g. `client.threads`)
185
+ * @param threadId - The parent thread ID
186
+ * @param options - Optional configuration
187
+ * @param options.messagesKey - Key in state values containing messages (default: "messages")
188
+ * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup
189
+ */
190
+ fetchSubagentHistory(threads: {
191
+ getHistory<V extends Record<string, unknown>>(threadId: string, options?: {
192
+ limit?: number;
193
+ checkpoint?: {
194
+ checkpoint_ns?: string;
195
+ };
196
+ signal?: AbortSignal;
197
+ }): Promise<Array<{
198
+ values: V;
199
+ tasks?: Array<{
200
+ id: string;
201
+ name: string;
202
+ path?: unknown[];
203
+ checkpoint?: {
204
+ checkpoint_ns?: string;
205
+ } | null;
206
+ }>;
207
+ }>>;
208
+ }, threadId: string, options?: {
209
+ messagesKey?: string;
210
+ signal?: AbortSignal;
211
+ }): Promise<void>;
171
212
  /**
172
213
  * Check if any subagents are currently tracked.
173
214
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.cts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.cts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}
@@ -168,6 +168,47 @@ declare class StreamManager<StateType extends Record<string, unknown>, Bag exten
168
168
  reconstructSubagents(messages: Message[], options?: {
169
169
  skipIfPopulated?: boolean;
170
170
  }): void;
171
+ /**
172
+ * Fetch and restore internal messages for reconstructed subagents from their
173
+ * subgraph checkpoints. Should be called after `reconstructSubagents` to
174
+ * restore the full subagent conversation after a page refresh.
175
+ *
176
+ * Subagent messages are persisted in the LangGraph checkpointer under a
177
+ * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method
178
+ * discovers the correct namespace by inspecting the main thread's intermediate
179
+ * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`
180
+ * identifies the subgraph. Tasks are matched to tool calls by their Send index
181
+ * (`task.path[1]`), which corresponds to the order of tool calls in the AI
182
+ * message — no deepagent-specific metadata required.
183
+ *
184
+ * @param threads - Client with a `getHistory` method (e.g. `client.threads`)
185
+ * @param threadId - The parent thread ID
186
+ * @param options - Optional configuration
187
+ * @param options.messagesKey - Key in state values containing messages (default: "messages")
188
+ * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup
189
+ */
190
+ fetchSubagentHistory(threads: {
191
+ getHistory<V extends Record<string, unknown>>(threadId: string, options?: {
192
+ limit?: number;
193
+ checkpoint?: {
194
+ checkpoint_ns?: string;
195
+ };
196
+ signal?: AbortSignal;
197
+ }): Promise<Array<{
198
+ values: V;
199
+ tasks?: Array<{
200
+ id: string;
201
+ name: string;
202
+ path?: unknown[];
203
+ checkpoint?: {
204
+ checkpoint_ns?: string;
205
+ } | null;
206
+ }>;
207
+ }>>;
208
+ }, threadId: string, options?: {
209
+ messagesKey?: string;
210
+ signal?: AbortSignal;
211
+ }): Promise<void>;
171
212
  /**
172
213
  * Check if any subagents are currently tracked.
173
214
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}
@@ -87,6 +87,187 @@ var StreamManager = class {
87
87
  this.subagentManager.reconstructFromMessages(messages, options);
88
88
  }
89
89
  /**
90
+ * Fetch and restore internal messages for reconstructed subagents from their
91
+ * subgraph checkpoints. Should be called after `reconstructSubagents` to
92
+ * restore the full subagent conversation after a page refresh.
93
+ *
94
+ * Subagent messages are persisted in the LangGraph checkpointer under a
95
+ * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method
96
+ * discovers the correct namespace by inspecting the main thread's intermediate
97
+ * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`
98
+ * identifies the subgraph. Tasks are matched to tool calls by their Send index
99
+ * (`task.path[1]`), which corresponds to the order of tool calls in the AI
100
+ * message — no deepagent-specific metadata required.
101
+ *
102
+ * @param threads - Client with a `getHistory` method (e.g. `client.threads`)
103
+ * @param threadId - The parent thread ID
104
+ * @param options - Optional configuration
105
+ * @param options.messagesKey - Key in state values containing messages (default: "messages")
106
+ * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup
107
+ */
108
+ async fetchSubagentHistory(threads, threadId, options) {
109
+ const messagesKey = options?.messagesKey ?? "messages";
110
+ const signal = options?.signal;
111
+ /**
112
+ * Bail immediately if already cancelled (React Strict Mode cleanup)
113
+ */
114
+ if (signal?.aborted) return;
115
+ /**
116
+ * Only fetch for subagents that have no messages (reconstructed from history)
117
+ */
118
+ const toFetch = [...this.subagentManager.getSubagents().entries()].filter(([, s]) => s.messages.length === 0);
119
+ /**
120
+ * Bail immediately if there are no subagents to fetch
121
+ */
122
+ if (toFetch.length === 0) return;
123
+ /**
124
+ * Step 1: Discover subgraph namespaces from intermediate history
125
+ *
126
+ * When LangGraph dispatches parallel tool calls (v2 mode), each is a
127
+ * separate Send task with a unique UUID-based checkpoint_ns. The intermediate
128
+ * history checkpoints record these as `tasks[i]` where:
129
+ * - `tasks[i].checkpoint.checkpoint_ns` = "tools:<uuid>" for each subgraph
130
+ * - `tasks[i].path = ["__pregel_push", sendIndex]` matches tool_calls order
131
+ *
132
+ * By matching task Send index → tool_call position in the AI message we can
133
+ * derive the subgraph namespace for every tool call without any external
134
+ * metadata on the ToolMessage itself.
135
+ */
136
+ let toolCallIdToNamespace;
137
+ try {
138
+ /**
139
+ * Fetch enough history to include the intermediate checkpoint where
140
+ * tool-call tasks were pending (typically within the last 10 checkpoints).
141
+ */
142
+ const mainHistory = await threads.getHistory(threadId, {
143
+ limit: 20,
144
+ signal
145
+ });
146
+ for (const checkpoint of mainHistory) {
147
+ const { tasks } = checkpoint;
148
+ if (!tasks || tasks.length === 0) continue;
149
+ /**
150
+ * When a completed checkpoint contains task results, each task.result
151
+ * has a ToolMessage whose tool_call_id directly and unambiguously maps
152
+ * the task to the LLM tool call that triggered it. This is more robust
153
+ * than positional alignment: it works even when a step mixes subagent
154
+ * tool calls with other tool calls, and requires no assumptions about
155
+ * the ordering of tasks vs tool_calls.
156
+ *
157
+ * LangGraph v2 dispatches each parallel tool call as a separate PUSH
158
+ * task ("__pregel_push"). The subgraph checkpoint_ns is constructed as
159
+ * `task.name + ":" + task.id`, mirroring algo.ts:
160
+ * taskCheckpointNamespace = checkpointNamespace + ":" + taskId
161
+ * where checkpointNamespace = task.name for root-level tasks.
162
+ *
163
+ * task.checkpoint is always null for completed tasks, so we derive the
164
+ * namespace from task.name + task.id rather than task.checkpoint.checkpoint_ns.
165
+ */
166
+ const directMap = /* @__PURE__ */ new Map();
167
+ for (const task of tasks) {
168
+ if (!Array.isArray(task.path) || task.path[0] !== "__pregel_push" || typeof task.id !== "string" || typeof task.name !== "string") continue;
169
+ /**
170
+ * Read tool_call_id directly from the task's result ToolMessage.
171
+ */
172
+ const resultMessages = task.result?.messages;
173
+ if (Array.isArray(resultMessages)) for (const msg of resultMessages) {
174
+ const m = msg;
175
+ if (m.type === "tool" && typeof m.tool_call_id === "string" && toFetch.some(([id]) => id === m.tool_call_id)) directMap.set(m.tool_call_id, `${task.name}:${task.id}`);
176
+ }
177
+ }
178
+ if (directMap.size > 0) {
179
+ toolCallIdToNamespace = directMap;
180
+ break;
181
+ }
182
+ /**
183
+ * Fallback for checkpoints where task results are not yet populated
184
+ * (tasks are still pending). Use positional alignment via the Send
185
+ * index in task.path[1] as a secondary strategy.
186
+ */
187
+ const pushTasks = tasks.filter((t) => Array.isArray(t.path) && t.path[0] === "__pregel_push" && typeof t.path[1] === "number" && typeof t.id === "string" && typeof t.name === "string");
188
+ if (pushTasks.length === 0) continue;
189
+ /**
190
+ * Find the AI message with subagent tool calls to align by Send index.
191
+ */
192
+ const msgs = checkpoint.values[messagesKey];
193
+ if (!Array.isArray(msgs)) continue;
194
+ let aiMessage;
195
+ for (let i = msgs.length - 1; i >= 0; i -= 1) {
196
+ const m = msgs[i];
197
+ if (m.type === "ai" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0 && m.tool_calls.some((tc) => this.subagentManager.isSubagentToolCall(tc.name))) {
198
+ aiMessage = m;
199
+ break;
200
+ }
201
+ }
202
+ if (!aiMessage) continue;
203
+ /**
204
+ * Only consider subagent tool calls from the AI message — not all tool
205
+ * calls. This ensures regular tool calls (searchWeb, queryDatabase, etc.)
206
+ * are never mistaken for subagents even when they appear in the same step.
207
+ */
208
+ const subagentToolCalls = aiMessage.tool_calls.filter((tc) => this.subagentManager.isSubagentToolCall(tc.name));
209
+ if (subagentToolCalls.length === 0) continue;
210
+ /**
211
+ * Sort push tasks by Send index (path[1]) to align with tool_calls order
212
+ */
213
+ const sorted = [...pushTasks].sort((a, b) => {
214
+ return (Array.isArray(a.path) ? a.path[1] : 0) - (Array.isArray(b.path) ? b.path[1] : 0);
215
+ });
216
+ toolCallIdToNamespace = /* @__PURE__ */ new Map();
217
+ for (let i = 0; i < sorted.length && i < subagentToolCalls.length; i += 1) {
218
+ const tc = subagentToolCalls[i];
219
+ const task = sorted[i];
220
+ if (tc?.id && task.id && task.name) toolCallIdToNamespace.set(tc.id, `${task.name}:${task.id}`);
221
+ }
222
+ if (toolCallIdToNamespace.size > 0) break;
223
+ }
224
+ } catch {}
225
+ /**
226
+ * Step 2: Fetch each subagent's conversation from its subgraph checkpoint
227
+ */
228
+ await Promise.all(toFetch.map(async ([toolCallId, subagent]) => {
229
+ /**
230
+ * Priority order for the subgraph checkpoint_ns:
231
+ * 1. Derived from main thread's intermediate task list (preferred, no coupling)
232
+ * 2. Already on the subagent's namespace (e.g. populated during streaming)
233
+ * 3. Skip — we cannot reliably identify the namespace
234
+ */
235
+ const checkpointNs = toolCallIdToNamespace?.get(toolCallId) ?? (subagent.namespace.length > 0 ? subagent.namespace.join("|") : void 0);
236
+ if (!checkpointNs) return;
237
+ try {
238
+ /**
239
+ * If the HTTP request was cancelled mid-flight the getHistory call
240
+ * would have thrown an AbortError (caught below). If we reach here the
241
+ * fetch completed successfully, so always process the result.
242
+ */
243
+ const latestState = (await threads.getHistory(threadId, {
244
+ checkpoint: { checkpoint_ns: checkpointNs },
245
+ limit: 1,
246
+ signal
247
+ }))[0];
248
+ if (!latestState?.values) return;
249
+ const messages = latestState.values[messagesKey];
250
+ if (!Array.isArray(messages) || messages.length === 0) return;
251
+ /**
252
+ * Normalize messages: promote tool_calls from additional_kwargs to top
253
+ * level when the checkpointer serialized them in the legacy format.
254
+ */
255
+ const normalizedMessages = messages.map((msg) => {
256
+ const m = msg;
257
+ if (m.type === "ai" && (!m.tool_calls || m.tool_calls.length === 0)) {
258
+ const legacy = m.additional_kwargs?.tool_calls;
259
+ if (Array.isArray(legacy) && legacy.length > 0) return {
260
+ ...m,
261
+ tool_calls: legacy
262
+ };
263
+ }
264
+ return m;
265
+ });
266
+ this.subagentManager.updateSubagentFromSubgraphState(toolCallId, normalizedMessages, latestState.values);
267
+ } catch {}
268
+ }));
269
+ }
270
+ /**
90
271
  * Check if any subagents are currently tracked.
91
272
  */
92
273
  hasSubagents() {