@langchain/langgraph-sdk 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/error.d.cts.map +1 -1
- package/dist/auth/error.d.ts.map +1 -1
- package/dist/auth/index.d.cts.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/types.d.cts.map +1 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/client.d.cts.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/logging/index.d.cts.map +1 -1
- package/dist/logging/index.d.ts.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/stream.custom.d.cts.map +1 -1
- package/dist/react/stream.custom.d.ts.map +1 -1
- package/dist/react/stream.d.cts +0 -1
- package/dist/react/stream.d.cts.map +1 -1
- package/dist/react/stream.d.ts +0 -1
- package/dist/react/stream.d.ts.map +1 -1
- package/dist/react/types.d.cts +1 -1
- package/dist/react/types.d.cts.map +1 -1
- package/dist/react/types.d.ts +1 -1
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react-ui/client.d.cts.map +1 -1
- package/dist/react-ui/client.d.ts.map +1 -1
- package/dist/react-ui/server/server.d.cts +1 -2
- package/dist/react-ui/server/server.d.cts.map +1 -1
- package/dist/react-ui/server/server.d.ts +1 -2
- package/dist/react-ui/server/server.d.ts.map +1 -1
- package/dist/react-ui/types.d.cts.map +1 -1
- package/dist/react-ui/types.d.ts.map +1 -1
- package/dist/schema.d.cts.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/singletons/fetch.d.cts +0 -3
- package/dist/singletons/fetch.d.cts.map +1 -1
- package/dist/singletons/fetch.d.ts +0 -3
- package/dist/singletons/fetch.d.ts.map +1 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.messages.d.cts.map +1 -1
- package/dist/types.messages.d.ts.map +1 -1
- package/dist/types.stream.d.cts +0 -1
- package/dist/types.stream.d.cts.map +1 -1
- package/dist/types.stream.d.ts +0 -1
- package/dist/types.stream.d.ts.map +1 -1
- package/dist/types.template.d.cts.map +1 -1
- package/dist/types.template.d.ts.map +1 -1
- package/dist/ui/branching.d.cts.map +1 -1
- package/dist/ui/branching.d.ts.map +1 -1
- package/dist/ui/manager.cjs.map +1 -1
- package/dist/ui/manager.js.map +1 -1
- package/dist/ui/stream/agent.d.cts +0 -1
- package/dist/ui/stream/agent.d.cts.map +1 -1
- package/dist/ui/stream/agent.d.ts +0 -1
- package/dist/ui/stream/agent.d.ts.map +1 -1
- package/dist/ui/stream/base.d.cts +0 -1
- package/dist/ui/stream/base.d.cts.map +1 -1
- package/dist/ui/stream/base.d.ts +0 -1
- package/dist/ui/stream/base.d.ts.map +1 -1
- package/dist/ui/stream/deep-agent.d.cts +7 -8
- package/dist/ui/stream/deep-agent.d.cts.map +1 -1
- package/dist/ui/stream/deep-agent.d.ts +7 -8
- package/dist/ui/stream/deep-agent.d.ts.map +1 -1
- package/dist/ui/stream/index.d.cts +0 -1
- package/dist/ui/stream/index.d.cts.map +1 -1
- package/dist/ui/stream/index.d.ts +0 -1
- package/dist/ui/stream/index.d.ts.map +1 -1
- package/dist/ui/subagents.cjs.map +1 -1
- package/dist/ui/subagents.d.cts +6 -7
- package/dist/ui/subagents.d.cts.map +1 -1
- package/dist/ui/subagents.d.ts +6 -7
- package/dist/ui/subagents.d.ts.map +1 -1
- package/dist/ui/subagents.js.map +1 -1
- package/dist/ui/types.d.cts +50 -48
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.ts +50 -48
- package/dist/ui/types.d.ts.map +1 -1
- package/dist/utils/async_caller.d.cts.map +1 -1
- package/dist/utils/async_caller.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { DefaultToolCall } from "../../types.messages.cjs";
|
|
2
2
|
import { BagTemplate } from "../../types.template.cjs";
|
|
3
|
-
import { DefaultSubagentStates,
|
|
3
|
+
import { DefaultSubagentStates, SubagentStreamInterface } from "../types.cjs";
|
|
4
4
|
import { UseAgentStream, UseAgentStreamOptions } from "./agent.cjs";
|
|
5
5
|
|
|
6
6
|
//#region src/ui/stream/deep-agent.d.ts
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Stream interface for DeepAgent instances created with `createDeepAgent`.
|
|
10
9
|
*
|
|
@@ -95,7 +94,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
95
94
|
* const specific = stream.subagents.get("call_abc123");
|
|
96
95
|
* ```
|
|
97
96
|
*/
|
|
98
|
-
subagents: Map<string,
|
|
97
|
+
subagents: Map<string, SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string>>;
|
|
99
98
|
/**
|
|
100
99
|
* Currently active subagents (where status === "running").
|
|
101
100
|
*
|
|
@@ -114,7 +113,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
114
113
|
* ));
|
|
115
114
|
* ```
|
|
116
115
|
*/
|
|
117
|
-
activeSubagents:
|
|
116
|
+
activeSubagents: SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string>[];
|
|
118
117
|
/**
|
|
119
118
|
* Get subagent stream by tool call ID.
|
|
120
119
|
*
|
|
@@ -133,7 +132,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
133
132
|
* }
|
|
134
133
|
* ```
|
|
135
134
|
*/
|
|
136
|
-
getSubagent: (toolCallId: string) =>
|
|
135
|
+
getSubagent: (toolCallId: string) => SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string> | undefined;
|
|
137
136
|
/**
|
|
138
137
|
* Get all subagents of a specific type.
|
|
139
138
|
*
|
|
@@ -165,12 +164,12 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
165
164
|
* Overload for known subagent names - returns typed streams.
|
|
166
165
|
* TypeScript infers the state type from SubagentStates[TName].
|
|
167
166
|
*/
|
|
168
|
-
<TName extends keyof SubagentStates & string>(type: TName):
|
|
167
|
+
<TName extends keyof SubagentStates & string>(type: TName): SubagentStreamInterface<SubagentStates[TName], ToolCall, TName>[];
|
|
169
168
|
/**
|
|
170
169
|
* Overload for unknown names - returns untyped streams.
|
|
171
170
|
* Used when the subagent name is not known at compile time.
|
|
172
171
|
*/
|
|
173
|
-
(type: string):
|
|
172
|
+
(type: string): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
174
173
|
};
|
|
175
174
|
/**
|
|
176
175
|
* Get all subagents triggered by a specific AI message.
|
|
@@ -197,7 +196,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
197
196
|
* ))}
|
|
198
197
|
* ```
|
|
199
198
|
*/
|
|
200
|
-
getSubagentsByMessage: (messageId: string) =>
|
|
199
|
+
getSubagentsByMessage: (messageId: string) => SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string>[];
|
|
201
200
|
}
|
|
202
201
|
/**
|
|
203
202
|
* Options for configuring a deep agent stream.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-agent.d.cts","names":["DefaultToolCall","BagTemplate","SubagentStream","DefaultSubagentStates","UseAgentStream","UseAgentStreamOptions","UseDeepAgentStream","Record","StateType","ToolCall","Bag","SubagentStates","Map","TName","UseDeepAgentStreamOptions"],"sources":["../../../src/ui/stream/deep-agent.d.ts"],"sourcesContent":["/**\n * Stream types for DeepAgent instances created with `createDeepAgent`.\n *\n * This module provides the stream interface that adds subagent streaming\n * capabilities on top of agent streaming functionality.\n *\n * @module\n */\nimport type { DefaultToolCall } from \"../../types.messages.js\";\nimport type { BagTemplate } from \"../../types.template.js\";\nimport type { SubagentStream, DefaultSubagentStates } from \"../types.js\";\nimport type { UseAgentStream, UseAgentStreamOptions } from \"./agent.js\";\n/**\n * Stream interface for DeepAgent instances created with `createDeepAgent`.\n *\n * Extends {@link UseAgentStream} with subagent streaming capabilities. Subagent\n * streams are automatically typed based on the agent's subagent configuration,\n * enabling type-safe access to subagent state and messages.\n *\n * Use this interface when streaming from an agent created with `createDeepAgent`\n * that orchestrates multiple specialized subagents.\n *\n * @experimental This interface is subject to change.\n *\n * @template StateType - The agent's state type\n * @template ToolCall - Tool call type from agent's tools\n * @template SubagentStates - Map of subagent names to their state types\n * @template Bag - Type configuration bag\n *\n * @example\n * ```typescript\n * import { createDeepAgent } from \"deepagents\";\n * import { useStream } from \"@langchain/langgraph-sdk/react\";\n *\n * // Define subagents with typed middleware\n * const agent = createDeepAgent({\n * subagents: [\n * {\n * name: \"researcher\",\n * description: \"Research specialist\",\n * middleware: [ResearchMiddleware],\n * },\n * {\n * name: \"writer\",\n * description: \"Content writer\",\n * middleware: [WriterMiddleware],\n * },\n * ] as const, // Important: use 'as const' for type inference\n * });\n *\n * // In React component:\n * function Chat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * apiUrl: \"http://localhost:2024\",\n * filterSubagentMessages: true, // Only show main agent messages\n * });\n *\n * // Subagent streams are typed!\n * const researchers = stream.getSubagentsByType(\"researcher\");\n * researchers.forEach(subagent => {\n * // subagent.values.messages is typed as Message<ToolCall>[]\n * // subagent.status is \"pending\" | \"running\" | \"complete\" | \"error\"\n * console.log(\"Researcher status:\", subagent.status);\n * });\n *\n * // Track all active subagents\n * stream.activeSubagents.forEach(subagent => {\n * console.log(`${subagent.toolCall.args.subagent_type} is running...`);\n * });\n * }\n * ```\n *\n * @remarks\n * This interface adds subagent streaming on top of {@link UseAgentStream}:\n * - `subagents` - Map of all subagent streams by tool call ID\n * - `activeSubagents` - Array of currently running subagents\n * - `getSubagent(id)` - Get a specific subagent by tool call ID\n * - `getSubagentsByType(type)` - Get all subagents of a specific type with typed state\n * - `getSubagentsByMessage(messageId)` - Get all subagents triggered by a specific AI message\n *\n * It also enables the `filterSubagentMessages` option to exclude subagent\n * messages from the main `messages` array.\n */\nexport interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<string, unknown>, ToolCall = DefaultToolCall, SubagentStates extends Record<string, unknown> = DefaultSubagentStates, Bag extends BagTemplate = BagTemplate> extends UseAgentStream<StateType, ToolCall, Bag> {\n /**\n * All currently active and completed subagent streams.\n *\n * Keyed by tool call ID for easy lookup. Includes subagents in all states:\n * pending, running, complete, and error.\n *\n * @example\n * ```typescript\n * // Iterate over all subagents\n * stream.subagents.forEach((subagent, toolCallId) => {\n * console.log(`Subagent ${toolCallId}: ${subagent.status}`);\n * });\n *\n * // Get a specific subagent\n * const specific = stream.subagents.get(\"call_abc123\");\n * ```\n */\n subagents: Map<string, SubagentStream<SubagentStates[keyof SubagentStates], ToolCall>>;\n /**\n * Currently active subagents (where status === \"running\").\n *\n * Use this to track and display subagents that are actively executing.\n * Completed or errored subagents are not included.\n *\n * @example\n * ```typescript\n * // Show loading indicators for active subagents\n * stream.activeSubagents.map(subagent => (\n * <SubagentCard\n * key={subagent.id}\n * type={subagent.toolCall.args.subagent_type}\n * isLoading={true}\n * />\n * ));\n * ```\n */\n activeSubagents: SubagentStream<SubagentStates[keyof SubagentStates], ToolCall>[];\n /**\n * Get subagent stream by tool call ID.\n *\n * Use this when you have a specific tool call ID and need to access\n * its corresponding subagent stream.\n *\n * @param toolCallId - The tool call ID that initiated the subagent\n * @returns The subagent stream, or undefined if not found\n *\n * @example\n * ```typescript\n * // In a tool call component\n * const subagent = stream.getSubagent(toolCall.id);\n * if (subagent) {\n * return <SubagentProgress subagent={subagent} />;\n * }\n * ```\n */\n getSubagent: (toolCallId: string) => SubagentStream<SubagentStates[keyof SubagentStates], ToolCall> | undefined;\n /**\n * Get all subagents of a specific type.\n *\n * Returns streams with properly inferred state types based on subagent name.\n * When called with a literal string that matches a subagent name, TypeScript\n * will infer the correct state type for that subagent.\n *\n * @param type - The subagent_type to filter by\n * @returns Array of matching subagent streams with inferred state types\n *\n * @example\n * ```typescript\n * // Get all researcher subagents with typed state\n * const researchers = stream.getSubagentsByType(\"researcher\");\n *\n * researchers.forEach(researcher => {\n * // researcher.values is typed based on ResearchMiddleware\n * console.log(\"Research messages:\", researcher.values.messages.length);\n * console.log(\"Status:\", researcher.status);\n * });\n *\n * // Get all writer subagents\n * const writers = stream.getSubagentsByType(\"writer\");\n * // writers have different state type based on WriterMiddleware\n * ```\n */\n getSubagentsByType: {\n /**\n * Overload for known subagent names - returns typed streams.\n * TypeScript infers the state type from SubagentStates[TName].\n */\n <TName extends keyof SubagentStates & string>(type: TName): SubagentStream<SubagentStates[TName], ToolCall>[];\n /**\n * Overload for unknown names - returns untyped streams.\n * Used when the subagent name is not known at compile time.\n */\n (type: string): SubagentStream<Record<string, unknown>, ToolCall>[];\n };\n /**\n * Get all subagents triggered by a specific AI message.\n *\n * Useful for rendering subagent activities grouped by conversation turn.\n * Each AI message that contains subagent tool calls will have its triggered\n * subagents returned by this method.\n *\n * @param messageId - The ID of the AI message that triggered the subagents\n * @returns Array of subagent streams triggered by that message\n *\n * @example\n * ```tsx\n * // Render subagents inline after the AI message that triggered them\n * {stream.messages.map((msg) => (\n * <div key={msg.id}>\n * <MessageBubble message={msg} />\n * {msg.type === \"ai\" && \"tool_calls\" in msg && (\n * <SubagentPipeline\n * subagents={stream.getSubagentsByMessage(msg.id)}\n * />\n * )}\n * </div>\n * ))}\n * ```\n */\n getSubagentsByMessage: (messageId: string) => SubagentStream<SubagentStates[keyof SubagentStates], ToolCall>[];\n}\n/**\n * Options for configuring a deep agent stream.\n *\n * Use this options interface when calling `useStream` with a DeepAgent\n * created via `createDeepAgent`. Includes all agent options plus\n * subagent-specific configuration.\n *\n * @template StateType - The agent's state type\n * @template Bag - Type configuration bag\n *\n * @example\n * ```typescript\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * apiUrl: \"http://localhost:2024\",\n *\n * // DeepAgent-specific options\n * subagentToolNames: [\"task\", \"delegate\"],\n * filterSubagentMessages: true,\n *\n * onError: (error) => console.error(error),\n * });\n * ```\n */\nexport interface UseDeepAgentStreamOptions<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate> extends UseAgentStreamOptions<StateType, Bag> {\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()`, `getSubagentsByType()`, and `getSubagentsByMessage()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"],\n * });\n *\n * // Now stream.subagents will include executions from any of these tools\n * ```\n */\n subagentToolNames?: string[];\n /**\n * Whether to filter out messages from subagent namespaces.\n *\n * When `true`, only messages from the main agent are included in\n * the `messages` array. Subagent messages are still accessible via\n * the `subagents` map and individual subagent streams.\n *\n * This is useful when you want to display subagent progress separately\n * from the main conversation, or when subagent messages would be too\n * verbose in the main message list.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // stream.messages only contains main agent messages\n * // Subagent messages are in stream.getSubagentsByType(\"researcher\")[0].messages\n * ```\n */\n filterSubagentMessages?: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAlJiBM,qCAAqCC,0BAA0BA,oCAAoCP,wCAAwCO,0BAA0BJ,mCAAmCF,cAAcA,qBAAqBG,eAAeI,WAAWC,UAAUC;;;;;;;;;;;;;;;;;;aAkBjRE,YAAYV,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;mBAmB3DP,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;uCAmBjCP,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAgCjEE,+BAA+BE,QAAQX,eAAeS,eAAeE,QAAQJ;;;;;oBAKlFP,eAAeK,yBAAyBE;;;;;;;;;;;;;;;;;;;;;;;;;;;gDA2BdP,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;;;;;;;;UA0BtFK,4CAA4CP,0BAA0BA,qCAAqCN,cAAcA,qBAAqBI,sBAAsBG,WAAWE"}
|
|
1
|
+
{"version":3,"file":"deep-agent.d.cts","names":[],"sources":["../../../src/ui/stream/deep-agent.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyFiB,kBAAA,mBACG,MAAA,oBAA0B,MAAA,8BACjC,eAAA,yBACY,MAAA,oBAA0B,qBAAA,cACrC,WAAA,GAAc,WAAA,UAClB,cAAA,CAAe,SAAA,EAAW,QAAA,EAAU,GAAA;EAyEjB;;;;;;;;;;;;;;;;;EAvD3B,SAAA,EAAW,GAAA,SAET,uBAAA,CACE,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;EA+HR;;;;;;;;AAgCJ;;;;;;;;;;EAzIE,eAAA,EAAiB,uBAAA,CACf,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;EAyIqB;;;;;;;;;;;;;;;;;;EApH7B,WAAA,GACE,UAAA,aAEE,uBAAA,CACE,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BZ,kBAAA;;;;;yBAKuB,cAAA,WACnB,IAAA,EAAM,KAAA,GACL,uBAAA,CAAwB,cAAA,CAAe,KAAA,GAAQ,QAAA,EAAU,KAAA;;;;;KAM3D,IAAA,WAAe,uBAAA,CACd,MAAA,mBACA,QAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BJ,qBAAA,GACE,SAAA,aACG,uBAAA,CACH,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;UA4BO,yBAAA,mBACG,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA,UAClB,qBAAA,CAAsB,SAAA,EAAW,GAAA;;;;;;;;;;;;;;;;;;;;;;EAsBzC,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;EA0BA,sBAAA;AAAA"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { DefaultToolCall } from "../../types.messages.js";
|
|
2
2
|
import { BagTemplate } from "../../types.template.js";
|
|
3
|
-
import { DefaultSubagentStates,
|
|
3
|
+
import { DefaultSubagentStates, SubagentStreamInterface } from "../types.js";
|
|
4
4
|
import { UseAgentStream, UseAgentStreamOptions } from "./agent.js";
|
|
5
5
|
|
|
6
6
|
//#region src/ui/stream/deep-agent.d.ts
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Stream interface for DeepAgent instances created with `createDeepAgent`.
|
|
10
9
|
*
|
|
@@ -95,7 +94,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
95
94
|
* const specific = stream.subagents.get("call_abc123");
|
|
96
95
|
* ```
|
|
97
96
|
*/
|
|
98
|
-
subagents: Map<string,
|
|
97
|
+
subagents: Map<string, SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string>>;
|
|
99
98
|
/**
|
|
100
99
|
* Currently active subagents (where status === "running").
|
|
101
100
|
*
|
|
@@ -114,7 +113,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
114
113
|
* ));
|
|
115
114
|
* ```
|
|
116
115
|
*/
|
|
117
|
-
activeSubagents:
|
|
116
|
+
activeSubagents: SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string>[];
|
|
118
117
|
/**
|
|
119
118
|
* Get subagent stream by tool call ID.
|
|
120
119
|
*
|
|
@@ -133,7 +132,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
133
132
|
* }
|
|
134
133
|
* ```
|
|
135
134
|
*/
|
|
136
|
-
getSubagent: (toolCallId: string) =>
|
|
135
|
+
getSubagent: (toolCallId: string) => SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string> | undefined;
|
|
137
136
|
/**
|
|
138
137
|
* Get all subagents of a specific type.
|
|
139
138
|
*
|
|
@@ -165,12 +164,12 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
165
164
|
* Overload for known subagent names - returns typed streams.
|
|
166
165
|
* TypeScript infers the state type from SubagentStates[TName].
|
|
167
166
|
*/
|
|
168
|
-
<TName extends keyof SubagentStates & string>(type: TName):
|
|
167
|
+
<TName extends keyof SubagentStates & string>(type: TName): SubagentStreamInterface<SubagentStates[TName], ToolCall, TName>[];
|
|
169
168
|
/**
|
|
170
169
|
* Overload for unknown names - returns untyped streams.
|
|
171
170
|
* Used when the subagent name is not known at compile time.
|
|
172
171
|
*/
|
|
173
|
-
(type: string):
|
|
172
|
+
(type: string): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
174
173
|
};
|
|
175
174
|
/**
|
|
176
175
|
* Get all subagents triggered by a specific AI message.
|
|
@@ -197,7 +196,7 @@ interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<
|
|
|
197
196
|
* ))}
|
|
198
197
|
* ```
|
|
199
198
|
*/
|
|
200
|
-
getSubagentsByMessage: (messageId: string) =>
|
|
199
|
+
getSubagentsByMessage: (messageId: string) => SubagentStreamInterface<SubagentStates[keyof SubagentStates], ToolCall, keyof SubagentStates & string>[];
|
|
201
200
|
}
|
|
202
201
|
/**
|
|
203
202
|
* Options for configuring a deep agent stream.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-agent.d.ts","names":["DefaultToolCall","BagTemplate","SubagentStream","DefaultSubagentStates","UseAgentStream","UseAgentStreamOptions","UseDeepAgentStream","Record","StateType","ToolCall","Bag","SubagentStates","Map","TName","UseDeepAgentStreamOptions"],"sources":["../../../src/ui/stream/deep-agent.d.ts"],"sourcesContent":["/**\n * Stream types for DeepAgent instances created with `createDeepAgent`.\n *\n * This module provides the stream interface that adds subagent streaming\n * capabilities on top of agent streaming functionality.\n *\n * @module\n */\nimport type { DefaultToolCall } from \"../../types.messages.js\";\nimport type { BagTemplate } from \"../../types.template.js\";\nimport type { SubagentStream, DefaultSubagentStates } from \"../types.js\";\nimport type { UseAgentStream, UseAgentStreamOptions } from \"./agent.js\";\n/**\n * Stream interface for DeepAgent instances created with `createDeepAgent`.\n *\n * Extends {@link UseAgentStream} with subagent streaming capabilities. Subagent\n * streams are automatically typed based on the agent's subagent configuration,\n * enabling type-safe access to subagent state and messages.\n *\n * Use this interface when streaming from an agent created with `createDeepAgent`\n * that orchestrates multiple specialized subagents.\n *\n * @experimental This interface is subject to change.\n *\n * @template StateType - The agent's state type\n * @template ToolCall - Tool call type from agent's tools\n * @template SubagentStates - Map of subagent names to their state types\n * @template Bag - Type configuration bag\n *\n * @example\n * ```typescript\n * import { createDeepAgent } from \"deepagents\";\n * import { useStream } from \"@langchain/langgraph-sdk/react\";\n *\n * // Define subagents with typed middleware\n * const agent = createDeepAgent({\n * subagents: [\n * {\n * name: \"researcher\",\n * description: \"Research specialist\",\n * middleware: [ResearchMiddleware],\n * },\n * {\n * name: \"writer\",\n * description: \"Content writer\",\n * middleware: [WriterMiddleware],\n * },\n * ] as const, // Important: use 'as const' for type inference\n * });\n *\n * // In React component:\n * function Chat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * apiUrl: \"http://localhost:2024\",\n * filterSubagentMessages: true, // Only show main agent messages\n * });\n *\n * // Subagent streams are typed!\n * const researchers = stream.getSubagentsByType(\"researcher\");\n * researchers.forEach(subagent => {\n * // subagent.values.messages is typed as Message<ToolCall>[]\n * // subagent.status is \"pending\" | \"running\" | \"complete\" | \"error\"\n * console.log(\"Researcher status:\", subagent.status);\n * });\n *\n * // Track all active subagents\n * stream.activeSubagents.forEach(subagent => {\n * console.log(`${subagent.toolCall.args.subagent_type} is running...`);\n * });\n * }\n * ```\n *\n * @remarks\n * This interface adds subagent streaming on top of {@link UseAgentStream}:\n * - `subagents` - Map of all subagent streams by tool call ID\n * - `activeSubagents` - Array of currently running subagents\n * - `getSubagent(id)` - Get a specific subagent by tool call ID\n * - `getSubagentsByType(type)` - Get all subagents of a specific type with typed state\n * - `getSubagentsByMessage(messageId)` - Get all subagents triggered by a specific AI message\n *\n * It also enables the `filterSubagentMessages` option to exclude subagent\n * messages from the main `messages` array.\n */\nexport interface UseDeepAgentStream<StateType extends Record<string, unknown> = Record<string, unknown>, ToolCall = DefaultToolCall, SubagentStates extends Record<string, unknown> = DefaultSubagentStates, Bag extends BagTemplate = BagTemplate> extends UseAgentStream<StateType, ToolCall, Bag> {\n /**\n * All currently active and completed subagent streams.\n *\n * Keyed by tool call ID for easy lookup. Includes subagents in all states:\n * pending, running, complete, and error.\n *\n * @example\n * ```typescript\n * // Iterate over all subagents\n * stream.subagents.forEach((subagent, toolCallId) => {\n * console.log(`Subagent ${toolCallId}: ${subagent.status}`);\n * });\n *\n * // Get a specific subagent\n * const specific = stream.subagents.get(\"call_abc123\");\n * ```\n */\n subagents: Map<string, SubagentStream<SubagentStates[keyof SubagentStates], ToolCall>>;\n /**\n * Currently active subagents (where status === \"running\").\n *\n * Use this to track and display subagents that are actively executing.\n * Completed or errored subagents are not included.\n *\n * @example\n * ```typescript\n * // Show loading indicators for active subagents\n * stream.activeSubagents.map(subagent => (\n * <SubagentCard\n * key={subagent.id}\n * type={subagent.toolCall.args.subagent_type}\n * isLoading={true}\n * />\n * ));\n * ```\n */\n activeSubagents: SubagentStream<SubagentStates[keyof SubagentStates], ToolCall>[];\n /**\n * Get subagent stream by tool call ID.\n *\n * Use this when you have a specific tool call ID and need to access\n * its corresponding subagent stream.\n *\n * @param toolCallId - The tool call ID that initiated the subagent\n * @returns The subagent stream, or undefined if not found\n *\n * @example\n * ```typescript\n * // In a tool call component\n * const subagent = stream.getSubagent(toolCall.id);\n * if (subagent) {\n * return <SubagentProgress subagent={subagent} />;\n * }\n * ```\n */\n getSubagent: (toolCallId: string) => SubagentStream<SubagentStates[keyof SubagentStates], ToolCall> | undefined;\n /**\n * Get all subagents of a specific type.\n *\n * Returns streams with properly inferred state types based on subagent name.\n * When called with a literal string that matches a subagent name, TypeScript\n * will infer the correct state type for that subagent.\n *\n * @param type - The subagent_type to filter by\n * @returns Array of matching subagent streams with inferred state types\n *\n * @example\n * ```typescript\n * // Get all researcher subagents with typed state\n * const researchers = stream.getSubagentsByType(\"researcher\");\n *\n * researchers.forEach(researcher => {\n * // researcher.values is typed based on ResearchMiddleware\n * console.log(\"Research messages:\", researcher.values.messages.length);\n * console.log(\"Status:\", researcher.status);\n * });\n *\n * // Get all writer subagents\n * const writers = stream.getSubagentsByType(\"writer\");\n * // writers have different state type based on WriterMiddleware\n * ```\n */\n getSubagentsByType: {\n /**\n * Overload for known subagent names - returns typed streams.\n * TypeScript infers the state type from SubagentStates[TName].\n */\n <TName extends keyof SubagentStates & string>(type: TName): SubagentStream<SubagentStates[TName], ToolCall>[];\n /**\n * Overload for unknown names - returns untyped streams.\n * Used when the subagent name is not known at compile time.\n */\n (type: string): SubagentStream<Record<string, unknown>, ToolCall>[];\n };\n /**\n * Get all subagents triggered by a specific AI message.\n *\n * Useful for rendering subagent activities grouped by conversation turn.\n * Each AI message that contains subagent tool calls will have its triggered\n * subagents returned by this method.\n *\n * @param messageId - The ID of the AI message that triggered the subagents\n * @returns Array of subagent streams triggered by that message\n *\n * @example\n * ```tsx\n * // Render subagents inline after the AI message that triggered them\n * {stream.messages.map((msg) => (\n * <div key={msg.id}>\n * <MessageBubble message={msg} />\n * {msg.type === \"ai\" && \"tool_calls\" in msg && (\n * <SubagentPipeline\n * subagents={stream.getSubagentsByMessage(msg.id)}\n * />\n * )}\n * </div>\n * ))}\n * ```\n */\n getSubagentsByMessage: (messageId: string) => SubagentStream<SubagentStates[keyof SubagentStates], ToolCall>[];\n}\n/**\n * Options for configuring a deep agent stream.\n *\n * Use this options interface when calling `useStream` with a DeepAgent\n * created via `createDeepAgent`. Includes all agent options plus\n * subagent-specific configuration.\n *\n * @template StateType - The agent's state type\n * @template Bag - Type configuration bag\n *\n * @example\n * ```typescript\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * apiUrl: \"http://localhost:2024\",\n *\n * // DeepAgent-specific options\n * subagentToolNames: [\"task\", \"delegate\"],\n * filterSubagentMessages: true,\n *\n * onError: (error) => console.error(error),\n * });\n * ```\n */\nexport interface UseDeepAgentStreamOptions<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate> extends UseAgentStreamOptions<StateType, Bag> {\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()`, `getSubagentsByType()`, and `getSubagentsByMessage()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"],\n * });\n *\n * // Now stream.subagents will include executions from any of these tools\n * ```\n */\n subagentToolNames?: string[];\n /**\n * Whether to filter out messages from subagent namespaces.\n *\n * When `true`, only messages from the main agent are included in\n * the `messages` array. Subagent messages are still accessible via\n * the `subagents` map and individual subagent streams.\n *\n * This is useful when you want to display subagent progress separately\n * from the main conversation, or when subagent messages would be too\n * verbose in the main message list.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream<typeof agent>({\n * assistantId: \"deep-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // stream.messages only contains main agent messages\n * // Subagent messages are in stream.getSubagentsByType(\"researcher\")[0].messages\n * ```\n */\n filterSubagentMessages?: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAlJiBM,qCAAqCC,0BAA0BA,oCAAoCP,wCAAwCO,0BAA0BJ,mCAAmCF,cAAcA,qBAAqBG,eAAeI,WAAWC,UAAUC;;;;;;;;;;;;;;;;;;aAkBjRE,YAAYV,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;mBAmB3DP,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;uCAmBjCP,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAgCjEE,+BAA+BE,QAAQX,eAAeS,eAAeE,QAAQJ;;;;;oBAKlFP,eAAeK,yBAAyBE;;;;;;;;;;;;;;;;;;;;;;;;;;;gDA2BdP,eAAeS,qBAAqBA,iBAAiBF;;;;;;;;;;;;;;;;;;;;;;;;;;UA0BtFK,4CAA4CP,0BAA0BA,qCAAqCN,cAAcA,qBAAqBI,sBAAsBG,WAAWE"}
|
|
1
|
+
{"version":3,"file":"deep-agent.d.ts","names":[],"sources":["../../../src/ui/stream/deep-agent.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyFiB,kBAAA,mBACG,MAAA,oBAA0B,MAAA,8BACjC,eAAA,yBACY,MAAA,oBAA0B,qBAAA,cACrC,WAAA,GAAc,WAAA,UAClB,cAAA,CAAe,SAAA,EAAW,QAAA,EAAU,GAAA;EAyEjB;;;;;;;;;;;;;;;;;EAvD3B,SAAA,EAAW,GAAA,SAET,uBAAA,CACE,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;EA+HR;;;;;;;;AAgCJ;;;;;;;;;;EAzIE,eAAA,EAAiB,uBAAA,CACf,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;EAyIqB;;;;;;;;;;;;;;;;;;EApH7B,WAAA,GACE,UAAA,aAEE,uBAAA,CACE,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BZ,kBAAA;;;;;yBAKuB,cAAA,WACnB,IAAA,EAAM,KAAA,GACL,uBAAA,CAAwB,cAAA,CAAe,KAAA,GAAQ,QAAA,EAAU,KAAA;;;;;KAM3D,IAAA,WAAe,uBAAA,CACd,MAAA,mBACA,QAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BJ,qBAAA,GACE,SAAA,aACG,uBAAA,CACH,cAAA,OAAqB,cAAA,GACrB,QAAA,QACM,cAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;UA4BO,yBAAA,mBACG,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA,UAClB,qBAAA,CAAsB,SAAA,EAAW,GAAA;;;;;;;;;;;;;;;;;;;;;;EAsBzC,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;EA0BA,sBAAA;AAAA"}
|
|
@@ -6,7 +6,6 @@ import { UseAgentStream, UseAgentStreamOptions } from "./agent.cjs";
|
|
|
6
6
|
import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "./deep-agent.cjs";
|
|
7
7
|
|
|
8
8
|
//#region src/ui/stream/index.d.ts
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* Check if a type is a DeepAgent (has `~deepAgentTypes` phantom property).
|
|
12
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":["DefaultToolCall","BagTemplate","InferAgentState","InferAgentToolCalls","SubagentStateMap","DefaultSubagentStates","AgentTypeConfigLike","DeepAgentTypeConfigLike","UseStreamOptions","BaseStream","UseAgentStream","UseAgentStreamOptions","UseDeepAgentStream","UseDeepAgentStreamOptions","IsDeepAgent","T","IsReactAgent","InferStateType","S","Record","O","InferNodeNames","N","Exclude","InferNodeReturnTypes","R","InferToolCalls","InferSubagentStates","ResolveStreamInterface","Bag","ResolveStreamOptions","InferBag","B"],"sources":["../../../src/ui/stream/index.d.ts"],"sourcesContent":["/**\n * Unified stream type system for LangGraph.\n *\n * This module provides the type resolution system that automatically selects\n * the appropriate stream interface based on the agent/graph type:\n *\n * - **CompiledStateGraph** → {@link UseGraphStream}\n * - **ReactAgent** (createAgent) → {@link UseAgentStream}\n * - **DeepAgent** (createDeepAgent) → {@link UseDeepAgentStream}\n *\n * @module\n */\nimport type { DefaultToolCall } from \"../../types.messages.js\";\nimport type { BagTemplate } from \"../../types.template.js\";\nimport type { InferAgentState, InferAgentToolCalls, SubagentStateMap, DefaultSubagentStates, AgentTypeConfigLike, DeepAgentTypeConfigLike, UseStreamOptions } from \"../types.js\";\nimport type { BaseStream } from \"./base.js\";\nimport type { UseAgentStream, UseAgentStreamOptions } from \"./agent.js\";\nimport type { UseDeepAgentStream, UseDeepAgentStreamOptions } from \"./deep-agent.js\";\nexport type { BaseStream } from \"./base.js\";\nexport type { UseAgentStream, UseAgentStreamOptions } from \"./agent.js\";\nexport type { UseDeepAgentStream, UseDeepAgentStreamOptions, } from \"./deep-agent.js\";\n/**\n * Check if a type is a DeepAgent (has `~deepAgentTypes` phantom property).\n */\ntype IsDeepAgent<T> = T extends {\n \"~deepAgentTypes\": DeepAgentTypeConfigLike;\n} ? true : false;\n/**\n * Check if a type is a ReactAgent (has `~agentTypes` but not `~deepAgentTypes`).\n */\ntype IsReactAgent<T> = T extends {\n \"~agentTypes\": AgentTypeConfigLike;\n} ? T extends {\n \"~deepAgentTypes\": unknown;\n} ? false : true : false;\n/**\n * Infer the state type from an agent, graph, or direct state type.\n *\n * Detection order:\n * 1. Agent-like (`~agentTypes`) → InferAgentState\n * 2. CompiledGraph (`~RunOutput`) → Extract RunOutput\n * 3. Pregel (`~OutputType`) → Extract OutputType\n * 4. Direct state type → Return as-is\n */\nexport type InferStateType<T> = T extends {\n \"~agentTypes\": unknown;\n} ? InferAgentState<T> : T extends {\n \"~RunOutput\": infer S;\n} ? S extends Record<string, unknown> ? S : Record<string, unknown> : T extends {\n \"~OutputType\": infer O;\n} ? O extends Record<string, unknown> ? O : Record<string, unknown> : T extends Record<string, unknown> ? T : Record<string, unknown>;\n/**\n * Infer the node names from a compiled graph.\n *\n * Extracts the `~NodeType` phantom property from CompiledGraph instances,\n * providing a union of all node names defined in the graph.\n *\n * @example\n * ```typescript\n * const graph = new StateGraph(StateAnnotation)\n * .addNode(\"agent\", agentFn)\n * .addNode(\"tool\", toolFn)\n * .compile();\n *\n * type NodeNames = InferNodeNames<typeof graph>; // \"agent\" | \"tool\"\n * ```\n */\nexport type InferNodeNames<T> = T extends {\n \"~NodeType\": infer N;\n} ? N extends string ? Exclude<N, \"__start__\"> : string : string;\n/**\n * Infer the per-node return types from a compiled graph.\n *\n * Extracts the `~NodeReturnType` phantom property from CompiledGraph instances,\n * which is a mapped type of `{ [nodeName]: ReturnType }` for each node.\n *\n * @example\n * ```typescript\n * const graph = new StateGraph(StateAnnotation)\n * .addNode(\"dispatcher\", async () => ({ topic: \"foo\" }))\n * .addNode(\"researcher\", async () => ({ research: \"bar\" }))\n * .compile();\n *\n * type NodeReturns = InferNodeReturnTypes<typeof graph>;\n * // { dispatcher: { topic: string }; researcher: { research: string } }\n * ```\n */\nexport type InferNodeReturnTypes<T> = T extends {\n \"~NodeReturnType\": infer R;\n} ? R extends Record<string, unknown> ? R : Record<string, Record<string, unknown>> : Record<string, Record<string, unknown>>;\n/**\n * Infer tool call types from an agent.\n *\n * For agents, extracts typed tool calls from the agent's tools.\n * For non-agents, returns DefaultToolCall.\n */\nexport type InferToolCalls<T> = T extends {\n \"~agentTypes\": unknown;\n} ? InferAgentToolCalls<T> : DefaultToolCall;\n/**\n * Infer subagent state map from a DeepAgent.\n *\n * For DeepAgent, creates a map of subagent names to their state types.\n * For non-DeepAgent, returns DefaultSubagentStates.\n */\nexport type InferSubagentStates<T> = T extends {\n \"~deepAgentTypes\": unknown;\n} ? SubagentStateMap<T, InferAgentToolCalls<T>> : DefaultSubagentStates;\n/**\n * Resolves the appropriate stream interface based on the agent/graph type.\n *\n * This type automatically selects the correct stream interface based on\n * the type of agent or graph passed to `useStream`:\n *\n * 1. **DeepAgent** (`~deepAgentTypes`) → {@link UseDeepAgentStream}\n * - Includes: values, messages, toolCalls, subagents, getSubagentsByType, getSubagentsByMessage\n *\n * 2. **ReactAgent** (`~agentTypes`) → {@link UseAgentStream}\n * - Includes: values, messages, toolCalls, getToolCalls\n * - Excludes: subagents, getSubagentsByType\n *\n * 3. **CompiledGraph** (`~RunOutput`/`~OutputType`) → {@link UseGraphStream}\n * - Includes: values, messages, submit, stop, nodes, getNodeStreamsByName\n * - Excludes: toolCalls, subagents\n * - Node names are inferred from `~NodeType` for type-safe access\n *\n * 4. **Default** → {@link UseGraphStream}\n *\n * @template T - The agent or graph type (use `typeof agent` or `typeof graph`)\n * @template Bag - Type configuration bag for interrupts, configurable, etc.\n *\n * @example\n * ```typescript\n * // Automatic detection based on agent type\n * type GraphStream = ResolveStreamInterface<typeof compiledGraph, BagTemplate>;\n * // → UseGraphStream (with typed node names)\n *\n * type AgentStream = ResolveStreamInterface<typeof reactAgent, BagTemplate>;\n * // → UseAgentStream (has toolCalls)\n *\n * type DeepStream = ResolveStreamInterface<typeof deepAgent, BagTemplate>;\n * // → UseDeepAgentStream (has toolCalls AND subagents)\n * ```\n */\nexport type ResolveStreamInterface<T, Bag extends BagTemplate = BagTemplate> = IsDeepAgent<T> extends true ? UseDeepAgentStream<InferStateType<T>, InferToolCalls<T>, InferSubagentStates<T>, Bag> : IsReactAgent<T> extends true ? UseAgentStream<InferStateType<T>, InferToolCalls<T>, Bag> : BaseStream<InferStateType<T>, InferToolCalls<T>, Bag>;\n/**\n * Resolves the appropriate options interface based on the agent/graph type.\n *\n * This type automatically selects the correct options interface based on\n * the type of agent or graph:\n *\n * 1. **DeepAgent** → {@link UseDeepAgentStreamOptions}\n * - Includes: `filterSubagentMessages` option\n *\n * 2. **ReactAgent** → {@link UseAgentStreamOptions}\n *\n * 3. **CompiledGraph** / **Default** → {@link UseGraphStreamOptions}\n *\n * @template T - The agent or graph type\n * @template Bag - Type configuration bag\n *\n * @example\n * ```typescript\n * // Only DeepAgent options include filterSubagentMessages\n * type DeepOptions = ResolveStreamOptions<typeof deepAgent, BagTemplate>;\n * // DeepOptions.filterSubagentMessages exists\n *\n * type AgentOptions = ResolveStreamOptions<typeof reactAgent, BagTemplate>;\n * // AgentOptions.filterSubagentMessages does NOT exist\n * ```\n */\nexport type ResolveStreamOptions<T, Bag extends BagTemplate = BagTemplate> = IsDeepAgent<T> extends true ? UseDeepAgentStreamOptions<InferStateType<T>, Bag> : IsReactAgent<T> extends true ? UseAgentStreamOptions<InferStateType<T>, Bag> : UseStreamOptions<InferStateType<T>, Bag>;\n/**\n * Infer the Bag type from an agent, defaulting to the provided Bag.\n *\n * Currently returns the provided Bag for all types.\n * Can be extended in the future to extract Bag from agent types.\n */\nexport type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {\n \"~agentTypes\": unknown;\n} ? BagTemplate : B;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/ui/stream/index.ts"],"mappings":";;;;;;;;;;;KAgDK,WAAA,MAAiB,CAAA;EAAY,iBAAA,EAAmB,uBAAA;AAAA;;;;KAOhD,YAAA,MAAkB,CAAA;EAAY,aAAA,EAAe,mBAAA;AAAA,IAC9C,CAAA;EAAY,iBAAA;AAAA;;;;;;;;;;KAkBJ,cAAA,MAAoB,CAAA;EAAY,aAAA;AAAA,IACxC,eAAA,CAAgB,CAAA,IAChB,CAAA;EAAY,YAAA;AAAA,IACZ,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,oBACF,CAAA;EAAY,aAAA;AAAA,IACZ,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,oBACF,CAAA,SAAU,MAAA,oBACV,CAAA,GACA,MAAA;;;;;;;;;;;;;;;;;KAkBQ,cAAA,MAAoB,CAAA;EAAY,WAAA;AAAA,IACxC,CAAA,kBACE,OAAA,CAAQ,CAAA;;;;;;;;AAFd;;;;;;;;;;KAuBY,oBAAA,MAA0B,CAAA;EAAY,iBAAA;AAAA,IAC9C,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,SAAe,MAAA,qBACjB,MAAA,SAAe,MAAA;;;;;AAJnB;;KAYY,cAAA,MAAoB,CAAA;EAAY,aAAA;AAAA,IACxC,mBAAA,CAAoB,CAAA,IACpB,eAAA;;;;;;;KAQQ,mBAAA,MAAyB,CAAA;EAAY,iBAAA;AAAA,IAC7C,gBAAA,CAAiB,CAAA,EAAG,mBAAA,CAAoB,CAAA,KACxC,qBAAA;;;;;;;;;;;AAZJ;;;;;;;;;;;;;;;;;AAUA;;;;;;;;;KA4CY,sBAAA,gBAEE,WAAA,GAAc,WAAA,IACxB,WAAA,CAAY,CAAA,iBACZ,kBAAA,CACE,cAAA,CAAe,CAAA,GACf,cAAA,CAAe,CAAA,GACf,mBAAA,CAAoB,CAAA,GACpB,GAAA,IAEF,YAAA,CAAa,CAAA,iBACb,cAAA,CAAe,cAAA,CAAe,CAAA,GAAI,cAAA,CAAe,CAAA,GAAI,GAAA,IACrD,UAAA,CAAW,cAAA,CAAe,CAAA,GAAI,cAAA,CAAe,CAAA,GAAI,GAAA;;;;;;;;;;;;AAZrD;;;;;;;;;;;;;;;KA4CY,oBAAA,gBAEE,WAAA,GAAc,WAAA,IACxB,WAAA,CAAY,CAAA,iBACZ,yBAAA,CAA0B,cAAA,CAAe,CAAA,GAAI,GAAA,IAC7C,YAAA,CAAa,CAAA,iBACb,qBAAA,CAAsB,cAAA,CAAe,CAAA,GAAI,GAAA,IACzC,gBAAA,CAAiB,cAAA,CAAe,CAAA,GAAI,GAAA;;;;;;;KAY5B,QAAA,cAAsB,WAAA,GAAc,WAAA,IAAe,CAAA;EAC7D,aAAA;AAAA,IAEE,WAAA,GACA,CAAA"}
|
|
@@ -6,7 +6,6 @@ import { UseAgentStream, UseAgentStreamOptions } from "./agent.js";
|
|
|
6
6
|
import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "./deep-agent.js";
|
|
7
7
|
|
|
8
8
|
//#region src/ui/stream/index.d.ts
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* Check if a type is a DeepAgent (has `~deepAgentTypes` phantom property).
|
|
12
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["DefaultToolCall","BagTemplate","InferAgentState","InferAgentToolCalls","SubagentStateMap","DefaultSubagentStates","AgentTypeConfigLike","DeepAgentTypeConfigLike","UseStreamOptions","BaseStream","UseAgentStream","UseAgentStreamOptions","UseDeepAgentStream","UseDeepAgentStreamOptions","IsDeepAgent","T","IsReactAgent","InferStateType","S","Record","O","InferNodeNames","N","Exclude","InferNodeReturnTypes","R","InferToolCalls","InferSubagentStates","ResolveStreamInterface","Bag","ResolveStreamOptions","InferBag","B"],"sources":["../../../src/ui/stream/index.d.ts"],"sourcesContent":["/**\n * Unified stream type system for LangGraph.\n *\n * This module provides the type resolution system that automatically selects\n * the appropriate stream interface based on the agent/graph type:\n *\n * - **CompiledStateGraph** → {@link UseGraphStream}\n * - **ReactAgent** (createAgent) → {@link UseAgentStream}\n * - **DeepAgent** (createDeepAgent) → {@link UseDeepAgentStream}\n *\n * @module\n */\nimport type { DefaultToolCall } from \"../../types.messages.js\";\nimport type { BagTemplate } from \"../../types.template.js\";\nimport type { InferAgentState, InferAgentToolCalls, SubagentStateMap, DefaultSubagentStates, AgentTypeConfigLike, DeepAgentTypeConfigLike, UseStreamOptions } from \"../types.js\";\nimport type { BaseStream } from \"./base.js\";\nimport type { UseAgentStream, UseAgentStreamOptions } from \"./agent.js\";\nimport type { UseDeepAgentStream, UseDeepAgentStreamOptions } from \"./deep-agent.js\";\nexport type { BaseStream } from \"./base.js\";\nexport type { UseAgentStream, UseAgentStreamOptions } from \"./agent.js\";\nexport type { UseDeepAgentStream, UseDeepAgentStreamOptions, } from \"./deep-agent.js\";\n/**\n * Check if a type is a DeepAgent (has `~deepAgentTypes` phantom property).\n */\ntype IsDeepAgent<T> = T extends {\n \"~deepAgentTypes\": DeepAgentTypeConfigLike;\n} ? true : false;\n/**\n * Check if a type is a ReactAgent (has `~agentTypes` but not `~deepAgentTypes`).\n */\ntype IsReactAgent<T> = T extends {\n \"~agentTypes\": AgentTypeConfigLike;\n} ? T extends {\n \"~deepAgentTypes\": unknown;\n} ? false : true : false;\n/**\n * Infer the state type from an agent, graph, or direct state type.\n *\n * Detection order:\n * 1. Agent-like (`~agentTypes`) → InferAgentState\n * 2. CompiledGraph (`~RunOutput`) → Extract RunOutput\n * 3. Pregel (`~OutputType`) → Extract OutputType\n * 4. Direct state type → Return as-is\n */\nexport type InferStateType<T> = T extends {\n \"~agentTypes\": unknown;\n} ? InferAgentState<T> : T extends {\n \"~RunOutput\": infer S;\n} ? S extends Record<string, unknown> ? S : Record<string, unknown> : T extends {\n \"~OutputType\": infer O;\n} ? O extends Record<string, unknown> ? O : Record<string, unknown> : T extends Record<string, unknown> ? T : Record<string, unknown>;\n/**\n * Infer the node names from a compiled graph.\n *\n * Extracts the `~NodeType` phantom property from CompiledGraph instances,\n * providing a union of all node names defined in the graph.\n *\n * @example\n * ```typescript\n * const graph = new StateGraph(StateAnnotation)\n * .addNode(\"agent\", agentFn)\n * .addNode(\"tool\", toolFn)\n * .compile();\n *\n * type NodeNames = InferNodeNames<typeof graph>; // \"agent\" | \"tool\"\n * ```\n */\nexport type InferNodeNames<T> = T extends {\n \"~NodeType\": infer N;\n} ? N extends string ? Exclude<N, \"__start__\"> : string : string;\n/**\n * Infer the per-node return types from a compiled graph.\n *\n * Extracts the `~NodeReturnType` phantom property from CompiledGraph instances,\n * which is a mapped type of `{ [nodeName]: ReturnType }` for each node.\n *\n * @example\n * ```typescript\n * const graph = new StateGraph(StateAnnotation)\n * .addNode(\"dispatcher\", async () => ({ topic: \"foo\" }))\n * .addNode(\"researcher\", async () => ({ research: \"bar\" }))\n * .compile();\n *\n * type NodeReturns = InferNodeReturnTypes<typeof graph>;\n * // { dispatcher: { topic: string }; researcher: { research: string } }\n * ```\n */\nexport type InferNodeReturnTypes<T> = T extends {\n \"~NodeReturnType\": infer R;\n} ? R extends Record<string, unknown> ? R : Record<string, Record<string, unknown>> : Record<string, Record<string, unknown>>;\n/**\n * Infer tool call types from an agent.\n *\n * For agents, extracts typed tool calls from the agent's tools.\n * For non-agents, returns DefaultToolCall.\n */\nexport type InferToolCalls<T> = T extends {\n \"~agentTypes\": unknown;\n} ? InferAgentToolCalls<T> : DefaultToolCall;\n/**\n * Infer subagent state map from a DeepAgent.\n *\n * For DeepAgent, creates a map of subagent names to their state types.\n * For non-DeepAgent, returns DefaultSubagentStates.\n */\nexport type InferSubagentStates<T> = T extends {\n \"~deepAgentTypes\": unknown;\n} ? SubagentStateMap<T, InferAgentToolCalls<T>> : DefaultSubagentStates;\n/**\n * Resolves the appropriate stream interface based on the agent/graph type.\n *\n * This type automatically selects the correct stream interface based on\n * the type of agent or graph passed to `useStream`:\n *\n * 1. **DeepAgent** (`~deepAgentTypes`) → {@link UseDeepAgentStream}\n * - Includes: values, messages, toolCalls, subagents, getSubagentsByType, getSubagentsByMessage\n *\n * 2. **ReactAgent** (`~agentTypes`) → {@link UseAgentStream}\n * - Includes: values, messages, toolCalls, getToolCalls\n * - Excludes: subagents, getSubagentsByType\n *\n * 3. **CompiledGraph** (`~RunOutput`/`~OutputType`) → {@link UseGraphStream}\n * - Includes: values, messages, submit, stop, nodes, getNodeStreamsByName\n * - Excludes: toolCalls, subagents\n * - Node names are inferred from `~NodeType` for type-safe access\n *\n * 4. **Default** → {@link UseGraphStream}\n *\n * @template T - The agent or graph type (use `typeof agent` or `typeof graph`)\n * @template Bag - Type configuration bag for interrupts, configurable, etc.\n *\n * @example\n * ```typescript\n * // Automatic detection based on agent type\n * type GraphStream = ResolveStreamInterface<typeof compiledGraph, BagTemplate>;\n * // → UseGraphStream (with typed node names)\n *\n * type AgentStream = ResolveStreamInterface<typeof reactAgent, BagTemplate>;\n * // → UseAgentStream (has toolCalls)\n *\n * type DeepStream = ResolveStreamInterface<typeof deepAgent, BagTemplate>;\n * // → UseDeepAgentStream (has toolCalls AND subagents)\n * ```\n */\nexport type ResolveStreamInterface<T, Bag extends BagTemplate = BagTemplate> = IsDeepAgent<T> extends true ? UseDeepAgentStream<InferStateType<T>, InferToolCalls<T>, InferSubagentStates<T>, Bag> : IsReactAgent<T> extends true ? UseAgentStream<InferStateType<T>, InferToolCalls<T>, Bag> : BaseStream<InferStateType<T>, InferToolCalls<T>, Bag>;\n/**\n * Resolves the appropriate options interface based on the agent/graph type.\n *\n * This type automatically selects the correct options interface based on\n * the type of agent or graph:\n *\n * 1. **DeepAgent** → {@link UseDeepAgentStreamOptions}\n * - Includes: `filterSubagentMessages` option\n *\n * 2. **ReactAgent** → {@link UseAgentStreamOptions}\n *\n * 3. **CompiledGraph** / **Default** → {@link UseGraphStreamOptions}\n *\n * @template T - The agent or graph type\n * @template Bag - Type configuration bag\n *\n * @example\n * ```typescript\n * // Only DeepAgent options include filterSubagentMessages\n * type DeepOptions = ResolveStreamOptions<typeof deepAgent, BagTemplate>;\n * // DeepOptions.filterSubagentMessages exists\n *\n * type AgentOptions = ResolveStreamOptions<typeof reactAgent, BagTemplate>;\n * // AgentOptions.filterSubagentMessages does NOT exist\n * ```\n */\nexport type ResolveStreamOptions<T, Bag extends BagTemplate = BagTemplate> = IsDeepAgent<T> extends true ? UseDeepAgentStreamOptions<InferStateType<T>, Bag> : IsReactAgent<T> extends true ? UseAgentStreamOptions<InferStateType<T>, Bag> : UseStreamOptions<InferStateType<T>, Bag>;\n/**\n * Infer the Bag type from an agent, defaulting to the provided Bag.\n *\n * Currently returns the provided Bag for all types.\n * Can be extended in the future to extract Bag from agent types.\n */\nexport type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {\n \"~agentTypes\": unknown;\n} ? BagTemplate : B;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/ui/stream/index.ts"],"mappings":";;;;;;;;;;;KAgDK,WAAA,MAAiB,CAAA;EAAY,iBAAA,EAAmB,uBAAA;AAAA;;;;KAOhD,YAAA,MAAkB,CAAA;EAAY,aAAA,EAAe,mBAAA;AAAA,IAC9C,CAAA;EAAY,iBAAA;AAAA;;;;;;;;;;KAkBJ,cAAA,MAAoB,CAAA;EAAY,aAAA;AAAA,IACxC,eAAA,CAAgB,CAAA,IAChB,CAAA;EAAY,YAAA;AAAA,IACZ,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,oBACF,CAAA;EAAY,aAAA;AAAA,IACZ,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,oBACF,CAAA,SAAU,MAAA,oBACV,CAAA,GACA,MAAA;;;;;;;;;;;;;;;;;KAkBQ,cAAA,MAAoB,CAAA;EAAY,WAAA;AAAA,IACxC,CAAA,kBACE,OAAA,CAAQ,CAAA;;;;;;;;AAFd;;;;;;;;;;KAuBY,oBAAA,MAA0B,CAAA;EAAY,iBAAA;AAAA,IAC9C,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,SAAe,MAAA,qBACjB,MAAA,SAAe,MAAA;;;;;AAJnB;;KAYY,cAAA,MAAoB,CAAA;EAAY,aAAA;AAAA,IACxC,mBAAA,CAAoB,CAAA,IACpB,eAAA;;;;;;;KAQQ,mBAAA,MAAyB,CAAA;EAAY,iBAAA;AAAA,IAC7C,gBAAA,CAAiB,CAAA,EAAG,mBAAA,CAAoB,CAAA,KACxC,qBAAA;;;;;;;;;;;AAZJ;;;;;;;;;;;;;;;;;AAUA;;;;;;;;;KA4CY,sBAAA,gBAEE,WAAA,GAAc,WAAA,IACxB,WAAA,CAAY,CAAA,iBACZ,kBAAA,CACE,cAAA,CAAe,CAAA,GACf,cAAA,CAAe,CAAA,GACf,mBAAA,CAAoB,CAAA,GACpB,GAAA,IAEF,YAAA,CAAa,CAAA,iBACb,cAAA,CAAe,cAAA,CAAe,CAAA,GAAI,cAAA,CAAe,CAAA,GAAI,GAAA,IACrD,UAAA,CAAW,cAAA,CAAe,CAAA,GAAI,cAAA,CAAe,CAAA,GAAI,GAAA;;;;;;;;;;;;AAZrD;;;;;;;;;;;;;;;KA4CY,oBAAA,gBAEE,WAAA,GAAc,WAAA,IACxB,WAAA,CAAY,CAAA,iBACZ,yBAAA,CAA0B,cAAA,CAAe,CAAA,GAAI,GAAA,IAC7C,YAAA,CAAa,CAAA,iBACb,qBAAA,CAAsB,cAAA,CAAe,CAAA,GAAI,GAAA,IACzC,gBAAA,CAAiB,cAAA,CAAe,CAAA,GAAI,GAAA;;;;;;;KAY5B,QAAA,cAAsB,WAAA,GAAc,WAAA,IAAe,CAAA;EAC7D,aAAA;AAAA,IAEE,WAAA,GACA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagents.cjs","names":["MessageTupleManager","toMessageDict","getToolCallsWithResults"],"sources":["../../src/ui/subagents.ts"],"sourcesContent":["import type {\n Message,\n DefaultToolCall,\n AIMessage,\n ToolCallWithResult,\n} from \"../types.messages.js\";\nimport type {\n SubagentStream,\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/**\n * Internal base type for SubagentStream storage.\n * Excludes derived properties that are computed on retrieval.\n */\ntype SubagentStreamBase<ToolCall> = Omit<\n SubagentStream<Record<string, unknown>, ToolCall>,\n | \"isLoading\"\n | \"toolCalls\"\n | \"getToolCalls\"\n | \"interrupt\"\n | \"interrupts\"\n | \"subagents\"\n | \"activeSubagents\"\n | \"getSubagent\"\n | \"getSubagentsByType\"\n | \"getSubagentsByMessage\"\n | \"nodes\"\n | \"activeNodes\"\n | \"getNodeStream\"\n | \"getNodeStreamsByName\"\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 * 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 constructor(options?: SubagentManagerOptions) {\n this.subagentToolNames = new Set(\n options?.subagentToolNames ?? DEFAULT_SUBAGENT_TOOL_NAMES\n );\n this.onSubagentChange = options?.onSubagentChange;\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 // Convert chunks to messages in order\n const messages: Message<ToolCall>[] = [];\n for (const entry of Object.values(manager.chunks)) {\n if (entry.chunk) {\n messages.push(toMessageDict(entry.chunk) as Message<ToolCall>);\n }\n }\n return messages;\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 ): SubagentStream<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 // Nested subagent tracking (empty for now, future enhancement)\n subagents: new Map<\n string,\n SubagentStream<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 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 shown to the user.\n * Subagents are only shown once they've actually started running.\n *\n * This filters out:\n * - Pending subagents that haven't been matched to a namespace yet\n * - Streaming artifacts with partial/corrupted data\n *\n * The idea is: we register subagents internally when we see tool calls,\n * but we only show them to the user once LangGraph confirms they're\n * actually executing (via namespace events).\n */\n private isValidSubagent(subagent: SubagentStreamBase<ToolCall>): boolean {\n // Only show subagents that have started running or completed\n // This ensures we don't show partial/pending subagents\n return subagent.status === \"running\" || subagent.status === \"complete\";\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 ): SubagentStream<Record<string, unknown>, ToolCall> {\n // Get fresh messages from the manager\n const messages = this.getMessagesForSubagent(base.id);\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 SubagentStream<Record<string, unknown>, ToolCall>\n > {\n const result = new Map<\n string,\n SubagentStream<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(): SubagentStream<Record<string, unknown>, ToolCall>[] {\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 ): SubagentStream<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 ): SubagentStream<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 ): SubagentStream<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 if (shouldUpdateType || shouldUpdateDesc) {\n this.subagents.set(toolCall.id, {\n ...existing,\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 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 // Don't create a placeholder - just skip this message.\n // The values event will establish the mapping, and subsequent messages\n // will be routed correctly.\n if (!existing) {\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.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 content 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\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: [], // Internal messages are not available from history\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 * 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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"}
|
|
1
|
+
{"version":3,"file":"subagents.cjs","names":["MessageTupleManager","toMessageDict","getToolCallsWithResults"],"sources":["../../src/ui/subagents.ts"],"sourcesContent":["import 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/**\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 | \"subagents\"\n | \"activeSubagents\"\n | \"getSubagent\"\n | \"getSubagentsByType\"\n | \"getSubagentsByMessage\"\n | \"nodes\"\n | \"activeNodes\"\n | \"getNodeStream\"\n | \"getNodeStreamsByName\"\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 * 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 constructor(options?: SubagentManagerOptions) {\n this.subagentToolNames = new Set(\n options?.subagentToolNames ?? DEFAULT_SUBAGENT_TOOL_NAMES\n );\n this.onSubagentChange = options?.onSubagentChange;\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 // Convert chunks to messages in order\n const messages: Message<ToolCall>[] = [];\n for (const entry of Object.values(manager.chunks)) {\n if (entry.chunk) {\n messages.push(toMessageDict(entry.chunk) as Message<ToolCall>);\n }\n }\n return messages;\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 // 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 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 shown to the user.\n * Subagents are only shown once they've actually started running.\n *\n * This filters out:\n * - Pending subagents that haven't been matched to a namespace yet\n * - Streaming artifacts with partial/corrupted data\n *\n * The idea is: we register subagents internally when we see tool calls,\n * but we only show them to the user once LangGraph confirms they're\n * actually executing (via namespace events).\n */\n private isValidSubagent(subagent: SubagentStreamBase<ToolCall>): boolean {\n // Only show subagents that have started running or completed\n // This ensures we don't show partial/pending subagents\n return subagent.status === \"running\" || subagent.status === \"complete\";\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 manager\n const messages = this.getMessagesForSubagent(base.id);\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 if (shouldUpdateType || shouldUpdateDesc) {\n this.subagents.set(toolCall.id, {\n ...existing,\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 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 // Don't create a placeholder - just skip this message.\n // The values event will establish the mapping, and subsequent messages\n // will be routed correctly.\n if (!existing) {\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.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 content 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\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: [], // Internal messages are not available from history\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 * 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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"}
|
package/dist/ui/subagents.d.cts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { DefaultToolCall, Message } from "../types.messages.cjs";
|
|
2
|
-
import {
|
|
2
|
+
import { SubagentStreamInterface } from "./types.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/ui/subagents.d.ts
|
|
5
|
-
|
|
6
5
|
/**
|
|
7
6
|
* Checks if a namespace indicates a subagent/subgraph message.
|
|
8
7
|
*
|
|
@@ -147,27 +146,27 @@ declare class SubagentManager<ToolCall = DefaultToolCall> {
|
|
|
147
146
|
* Get all subagents as a Map.
|
|
148
147
|
* Filters out incomplete/phantom subagents that lack subagent_type.
|
|
149
148
|
*/
|
|
150
|
-
getSubagents(): Map<string,
|
|
149
|
+
getSubagents(): Map<string, SubagentStreamInterface<Record<string, unknown>, ToolCall>>;
|
|
151
150
|
/**
|
|
152
151
|
* Get all currently running subagents.
|
|
153
152
|
* Filters out incomplete/phantom subagents.
|
|
154
153
|
*/
|
|
155
|
-
getActiveSubagents():
|
|
154
|
+
getActiveSubagents(): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
156
155
|
/**
|
|
157
156
|
* Get a specific subagent by tool call ID.
|
|
158
157
|
*/
|
|
159
|
-
getSubagent(toolCallId: string):
|
|
158
|
+
getSubagent(toolCallId: string): SubagentStreamInterface<Record<string, unknown>, ToolCall> | undefined;
|
|
160
159
|
/**
|
|
161
160
|
* Get all subagents of a specific type.
|
|
162
161
|
*/
|
|
163
|
-
getSubagentsByType(type: string):
|
|
162
|
+
getSubagentsByType(type: string): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
164
163
|
/**
|
|
165
164
|
* Get all subagents triggered by a specific AI message.
|
|
166
165
|
*
|
|
167
166
|
* @param messageId - The ID of the AI message.
|
|
168
167
|
* @returns Array of subagent streams triggered by that message.
|
|
169
168
|
*/
|
|
170
|
-
getSubagentsByMessage(messageId: string):
|
|
169
|
+
getSubagentsByMessage(messageId: string): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
171
170
|
/**
|
|
172
171
|
* Parse tool call args, handling both object and string formats.
|
|
173
172
|
* During streaming, args might come as a string that needs parsing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagents.d.cts","names":["Message","DefaultToolCall","SubagentStream","isSubagentNamespace","extractToolCallIdFromNamespace","calculateDepthFromNamespace","extractParentIdFromNamespace","SubagentManagerOptions","SubagentManager","Record","ToolCall","Map","Array"],"sources":["../../src/ui/subagents.d.ts"],"sourcesContent":["import type { Message, DefaultToolCall } from \"../types.messages.js\";\nimport type { SubagentStream } from \"./types.js\";\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 declare function isSubagentNamespace(namespace: string[] | string | undefined): boolean;\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 declare function extractToolCallIdFromNamespace(namespace: string[] | undefined): string | undefined;\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 declare function calculateDepthFromNamespace(namespace: string[] | undefined): number;\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 declare function extractParentIdFromNamespace(namespace: string[] | undefined): string | null;\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 * Callback when subagent state changes.\n */\n onSubagentChange?: () => void;\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 declare class SubagentManager<ToolCall = DefaultToolCall> {\n private subagents;\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;\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;\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;\n private subagentToolNames;\n private onSubagentChange?;\n constructor(options?: SubagentManagerOptions);\n /**\n * Get or create a MessageTupleManager for a subagent.\n */\n private getMessageManager;\n /**\n * Get messages for a subagent with proper chunk concatenation.\n * This mirrors how the main stream handles messages.\n */\n private getMessagesForSubagent;\n /**\n * Create a complete SubagentStream object with all derived properties.\n * This ensures consistency with UseStream interface.\n */\n private createSubagentStream;\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 /**\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(namespaceId: string, description: string): string | undefined;\n /**\n * Check if a tool call is a subagent invocation.\n */\n isSubagentToolCall(toolName: string): boolean;\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;\n /**\n * Check if a subagent should be shown to the user.\n * Subagents are only shown once they've actually started running.\n *\n * This filters out:\n * - Pending subagents that haven't been matched to a namespace yet\n * - Streaming artifacts with partial/corrupted data\n *\n * The idea is: we register subagents internally when we see tool calls,\n * but we only show them to the user once LangGraph confirms they're\n * actually executing (via namespace events).\n */\n private isValidSubagent;\n /**\n * Build a complete SubagentStream from internal state.\n * Adds messages and derived properties.\n */\n private buildExecution;\n /**\n * Get all subagents as a Map.\n * Filters out incomplete/phantom subagents that lack subagent_type.\n */\n getSubagents(): Map<string, SubagentStream<Record<string, unknown>, ToolCall>>;\n /**\n * Get all currently running subagents.\n * Filters out incomplete/phantom subagents.\n */\n getActiveSubagents(): SubagentStream<Record<string, unknown>, ToolCall>[];\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStream<Record<string, unknown>, ToolCall> | undefined;\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStream<Record<string, unknown>, ToolCall>[];\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(messageId: string): SubagentStream<Record<string, unknown>, ToolCall>[];\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 /**\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(toolCalls: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>, aiMessageId?: string | null): void;\n /**\n * Retry matching pending namespaces to newly registered tool calls.\n */\n private retryPendingMatches;\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(toolCallId: string, options?: {\n namespace?: string[];\n }): void;\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 /**\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(namespaceId: string, serialized: Message<DefaultToolCall>, metadata?: Record<string, unknown>): void;\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(namespaceId: string, values: Record<string, unknown>): void;\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(toolCallId: string, result: string, status?: \"complete\" | \"error\"): void;\n /**\n * Clear all subagent state.\n */\n clear(): void;\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(toolCallId: string, content: string, status?: \"success\" | \"error\"): void;\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(messages: Message<DefaultToolCall>[], options?: {\n skipIfPopulated?: boolean;\n }): void;\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean;\n}\n"],"mappings":";;;;;;;AAWA;AAUA;AAQA;AAUA;AAIA;AAiBA;;AAAgDC,iBAjDxBE,mBAAAA,CAiDwBF,SAAAA,EAAAA,MAAAA,EAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAAA,EAAAA,OAAAA;;;;;;;;;;AA+F6BS,iBAtIrDN,8BAAAA,CAsIqDM,SAAAA,EAAAA,MAAAA,EAAAA,GAAAA,SAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;;;;;;;;AA6B/DD,iBA3JUJ,2BAAAA,CA2JVI,SAAAA,EAAAA,MAAAA,EAAAA,GAAAA,SAAAA,CAAAA,EAAAA,MAAAA;;;;;;;;;;iBAjJUH,4BAAAA;;;;UAIPC,sBAAAA;;;;;;;;;;;;;;;;;cAiBIC,2BAA2BP;;;;;;;;;;;;;;;;;;;;;wBAqBtBM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiENI,YAAYT,eAAeO,yBAAyBC;;;;;wBAK9CR,eAAeO,yBAAyBC;;;;mCAI7BR,eAAeO,yBAAyBC;;;;oCAIvCR,eAAeO,yBAAyBC;;;;;;;4CAOhCR,eAAeO,yBAAyBC;;;;;;;;;;;;;;;mCAejDE;;;UAGvBH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAqC4CT,QAAQC,6BAA6BQ;;;;;;;;;;;oDAWzCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA6ChBT,QAAQC"}
|
|
1
|
+
{"version":3,"file":"subagents.d.cts","names":[],"sources":["../../src/ui/subagents.ts"],"mappings":";;;;;;AA6BA;;;;;AAuBA;;iBAvBgB,mBAAA,CACd,SAAA;;;AA4CF;;;;;AAgBA;;iBAtCgB,8BAAA,CACd,SAAA;;;AAoDF;;;;;iBA/BgB,2BAAA,CACd,SAAA;;;;;;;;;;iBAec,4BAAA,CACd,SAAA;;;;UAce,sBAAA;EA2WY;;;;EAtW3B,iBAAA;EAoXG;;;EA/WH,gBAAA;AAAA;;;;;;;cAkCW,eAAA,YAA2B,eAAA;EAAA,QAC9B,SAAA;EAAA;;;;;EAAA,QAOA,qBAAA;EAmBR;;;;EAAA,QAbQ,cAAA;EAsDA;;;;;EAAA,QA/CA,eAAA;EAAA,QAEA,iBAAA;EAAA,QAEA,gBAAA;EAER,WAAA,CAAY,OAAA,GAAU,sBAAA;EA+Nd;;;EAAA,QArNA,iBAAA;EAgPN;;;;EAAA,QAnOM,sBAAA;EAsPN;;;;EAAA,QApOM,oBAAA;EAiPmB;;;;EAxM3B,0BAAA,CAA2B,WAAA;EAkNA;;;;;;;;;;;;;EAjM3B,uBAAA,CACE,WAAA,UACA,WAAA;EA+OA;;;EAlKF,kBAAA,CAAmB,QAAA;EAoSjB;;;;EAAA,QA5RM,mBAAA;EA0TsC;;;;;;;;;;;;EAAA,QArRtC,eAAA;EAiYN;;;;EAAA,QAvXM,cAAA;EA4ZN;;;;EA7YF,YAAA,CAAA,GAAgB,GAAA,SAEd,uBAAA,CAAwB,MAAA,mBAAyB,QAAA;EAgb/B;;;;EA9ZpB,kBAAA,CAAA,GAAsB,uBAAA,CACpB,MAAA,mBACA,QAAA;EAsgBU;;;EA5fZ,WAAA,CACE,UAAA,WACC,uBAAA,CAAwB,MAAA,mBAAyB,QAAA;;;;EAQpD,kBAAA,CACE,IAAA,WACC,uBAAA,CAAwB,MAAA,mBAAyB,QAAA;;;;;;;EAYpD,qBAAA,CACE,SAAA,WACC,uBAAA,CAAwB,MAAA,mBAAyB,QAAA;;;;;UAU5C,SAAA;;;;;;;;;;EAuBR,qBAAA,CACE,SAAA,EAAW,KAAA;IACT,EAAA;IACA,IAAA;IACA,IAAA,EAAM,MAAA;EAAA,IAER,WAAA;;;;UAgGM,mBAAA;;;;;;;;;;EA4BR,WAAA,CACE,UAAA,UACA,OAAA;IACE,SAAA;EAAA;;;;;;;;EA4BJ,wBAAA,CAAyB,WAAA,UAAqB,SAAA;;;;;;;;;;;;EAgB9C,oBAAA,CACE,WAAA,UACA,UAAA,EAAY,OAAA,CAAQ,eAAA,GACpB,QAAA,GAAW,MAAA;;;;;;;;;;;EAyDb,oBAAA,CACE,WAAA,UACA,MAAA,EAAQ,MAAA;;;;;;;;;;EA6BV,QAAA,CACE,UAAA,UACA,MAAA,UACA,MAAA;;;;EAmBF,KAAA,CAAA;;;;;;;;EAeA,kBAAA,CACE,UAAA,UACA,OAAA,UACA,MAAA;;;;;;;;;;;;;;;;;;;;;;;EAkCF,uBAAA,CACE,QAAA,EAAU,OAAA,CAAQ,eAAA,KAClB,OAAA;IAAY,eAAA;EAAA;;;;EAyGd,YAAA,CAAA;AAAA"}
|
package/dist/ui/subagents.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { DefaultToolCall, Message } from "../types.messages.js";
|
|
2
|
-
import {
|
|
2
|
+
import { SubagentStreamInterface } from "./types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/ui/subagents.d.ts
|
|
5
|
-
|
|
6
5
|
/**
|
|
7
6
|
* Checks if a namespace indicates a subagent/subgraph message.
|
|
8
7
|
*
|
|
@@ -147,27 +146,27 @@ declare class SubagentManager<ToolCall = DefaultToolCall> {
|
|
|
147
146
|
* Get all subagents as a Map.
|
|
148
147
|
* Filters out incomplete/phantom subagents that lack subagent_type.
|
|
149
148
|
*/
|
|
150
|
-
getSubagents(): Map<string,
|
|
149
|
+
getSubagents(): Map<string, SubagentStreamInterface<Record<string, unknown>, ToolCall>>;
|
|
151
150
|
/**
|
|
152
151
|
* Get all currently running subagents.
|
|
153
152
|
* Filters out incomplete/phantom subagents.
|
|
154
153
|
*/
|
|
155
|
-
getActiveSubagents():
|
|
154
|
+
getActiveSubagents(): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
156
155
|
/**
|
|
157
156
|
* Get a specific subagent by tool call ID.
|
|
158
157
|
*/
|
|
159
|
-
getSubagent(toolCallId: string):
|
|
158
|
+
getSubagent(toolCallId: string): SubagentStreamInterface<Record<string, unknown>, ToolCall> | undefined;
|
|
160
159
|
/**
|
|
161
160
|
* Get all subagents of a specific type.
|
|
162
161
|
*/
|
|
163
|
-
getSubagentsByType(type: string):
|
|
162
|
+
getSubagentsByType(type: string): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
164
163
|
/**
|
|
165
164
|
* Get all subagents triggered by a specific AI message.
|
|
166
165
|
*
|
|
167
166
|
* @param messageId - The ID of the AI message.
|
|
168
167
|
* @returns Array of subagent streams triggered by that message.
|
|
169
168
|
*/
|
|
170
|
-
getSubagentsByMessage(messageId: string):
|
|
169
|
+
getSubagentsByMessage(messageId: string): SubagentStreamInterface<Record<string, unknown>, ToolCall>[];
|
|
171
170
|
/**
|
|
172
171
|
* Parse tool call args, handling both object and string formats.
|
|
173
172
|
* During streaming, args might come as a string that needs parsing.
|