@langchain/langgraph-sdk 1.9.6 → 1.9.8
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/client/stream/handles/subagents.cjs +3 -1
- package/dist/client/stream/handles/subagents.cjs.map +1 -1
- package/dist/client/stream/handles/subagents.d.cts.map +1 -1
- package/dist/client/stream/handles/subagents.d.ts.map +1 -1
- package/dist/client/stream/handles/subagents.js +4 -2
- package/dist/client/stream/handles/subagents.js.map +1 -1
- package/dist/client/stream/handles/tools.cjs +75 -10
- package/dist/client/stream/handles/tools.cjs.map +1 -1
- package/dist/client/stream/handles/tools.d.cts +6 -5
- package/dist/client/stream/handles/tools.d.cts.map +1 -1
- package/dist/client/stream/handles/tools.d.ts +6 -5
- package/dist/client/stream/handles/tools.d.ts.map +1 -1
- package/dist/client/stream/handles/tools.js +75 -11
- package/dist/client/stream/handles/tools.js.map +1 -1
- package/dist/client/stream/index.cjs.map +1 -1
- package/dist/client/stream/index.d.cts +1 -3
- package/dist/client/stream/index.d.cts.map +1 -1
- package/dist/client/stream/index.d.ts +1 -3
- package/dist/client/stream/index.d.ts.map +1 -1
- package/dist/client/stream/index.js.map +1 -1
- package/dist/react/stream.lgp.cjs +15 -1
- package/dist/react/stream.lgp.cjs.map +1 -1
- package/dist/react/stream.lgp.js +15 -1
- package/dist/react/stream.lgp.js.map +1 -1
- package/dist/stream/controller.cjs +19 -2
- package/dist/stream/controller.cjs.map +1 -1
- package/dist/stream/controller.d.cts +11 -3
- package/dist/stream/controller.d.cts.map +1 -1
- package/dist/stream/controller.d.ts +11 -3
- package/dist/stream/controller.d.ts.map +1 -1
- package/dist/stream/controller.js +19 -2
- package/dist/stream/controller.js.map +1 -1
- package/dist/stream/index.d.cts +2 -2
- package/dist/stream/index.d.ts +2 -2
- package/dist/stream/projections/tool-calls.cjs +1 -2
- package/dist/stream/projections/tool-calls.cjs.map +1 -1
- package/dist/stream/projections/tool-calls.d.cts.map +1 -1
- package/dist/stream/projections/tool-calls.d.ts.map +1 -1
- package/dist/stream/projections/tool-calls.js +2 -3
- package/dist/stream/projections/tool-calls.js.map +1 -1
- package/dist/stream/submit-coordinator.cjs +2 -6
- package/dist/stream/submit-coordinator.cjs.map +1 -1
- package/dist/stream/submit-coordinator.js +2 -6
- package/dist/stream/submit-coordinator.js.map +1 -1
- package/dist/stream/types.d.cts +12 -4
- package/dist/stream/types.d.cts.map +1 -1
- package/dist/stream/types.d.ts +12 -4
- package/dist/stream/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","names":[],"sources":["../../../../src/client/stream/handles/tools.ts"],"sourcesContent":["import type {\n ToolsEvent,\n ToolStartedData,\n ToolFinishedData,\n ToolErrorData,\n} from \"@langchain/protocol\";\n\n/**\n * High-level outcome of a single tool call.\n */\nexport type ToolCallStatus = \"running\" | \"finished\" | \"error\";\n\n/** Shared metadata for assembled tool-call handles. */\ninterface ToolCallBase<TName extends string = string, TInput = unknown> {\n readonly name: TName;\n readonly callId: string;\n /**\n * Pre-v1 alias for {@link callId}. Matches `ToolCallWithResult.id` and\n * `ToolCall.id` on message-level tool calls.\n */\n readonly id: string;\n readonly namespace: string[];\n readonly input: TInput;\n /**\n * Pre-v1 alias for {@link input}. Matches `ToolCallFromTool` `args`.\n */\n readonly args: TInput;\n}\n\n/**\n * Script-oriented tool handle from the client SDK (`ThreadStream.toolCalls`,\n * subagent/subgraph projections). Completion and errors are surfaced only\n * through {@link output}.\n */\nexport interface ClientAssembledToolCall<\n TName extends string = string,\n TInput = unknown,\n TOutput = unknown,\n> extends ToolCallBase<TName, TInput> {\n readonly output: Promise<TOutput>;\n}\n\n/**\n * Reactive tool handle for framework bindings (`stream.toolCalls`,\n * `useToolCalls`, `injectToolCalls`).\n *\n * {@link status}, {@link error}, and {@link output} are plain values that\n * the assembler updates in place as tool events arrive. That lets React,\n * Vue, Svelte, and Angular re-render from a snapshot on each store tick\n * without `await`, effects, or Suspense boundaries around a promise.\n * {@link ClientAssembledToolCall} keeps a promise-based {@link output}\n * instead for script consumers that read tool results sequentially.\n *\n * {@link output} is `null` while the call is running or after it fails;\n * successful completion sets it to the parsed tool return value (objects\n * and strings are unwrapped from ToolMessage wire envelopes when needed).\n */\nexport interface AssembledToolCall<\n TName extends string = string,\n TInput = unknown,\n TOutput = unknown,\n> extends ToolCallBase<TName, TInput> {\n readonly output: TOutput | null;\n readonly status: ToolCallStatus;\n readonly error: string | undefined;\n}\n\n/** @internal Mutable runtime handle shared by client and framework views. */\ntype MutableToolCallHandle = {\n name: string;\n callId: string;\n id: string;\n namespace: string[];\n input: unknown;\n args: unknown;\n output: unknown | null;\n status: ToolCallStatus;\n error: string | undefined;\n outputPromise: Promise<unknown>;\n};\n\n/**\n * Project a runtime handle to the client SDK surface (promise-only\n * {@link output}, no {@link status} / {@link error} fields).\n */\nexport function toClientAssembledToolCall(\n handle: MutableToolCallHandle\n): ClientAssembledToolCall {\n return {\n name: handle.name,\n callId: handle.callId,\n id: handle.id,\n namespace: handle.namespace,\n input: handle.input,\n args: handle.args,\n output: handle.outputPromise as Promise<unknown>,\n };\n}\n\n/**\n * Parse wire-format tool payloads into structured values.\n *\n * Tool events may carry JSON-encoded object strings on the wire; this\n * helper normalises them to plain objects for consumers. Non-JSON strings\n * are returned unchanged.\n */\nexport function parseToolPayload(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return value;\n }\n\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n return value;\n }\n}\n\nfunction isToolMessageLike(\n value: unknown\n): value is Record<string, unknown> & { content: unknown } {\n if (!value || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type === \"tool\") return true;\n return typeof record.tool_call_id === \"string\" && \"content\" in record;\n}\n\nfunction textFromContentBlocks(content: unknown[]): string {\n let out = \"\";\n for (const block of content) {\n if (!block || typeof block !== \"object\") continue;\n const record = block as Record<string, unknown>;\n if (record.type === \"text\" && typeof record.text === \"string\") {\n out += record.text;\n }\n }\n return out;\n}\n\n/**\n * Normalise tool-result `content` from a wire ToolMessage into the value\n * a tool implementation returned (object, string, etc.).\n */\nfunction parseToolResultContent(content: unknown): unknown | null {\n if (content == null) return null;\n\n if (typeof content === \"string\") {\n const trimmed = content.trim();\n if (trimmed.length === 0) return null;\n return parseToolPayload(content);\n }\n\n if (Array.isArray(content)) {\n const text = textFromContentBlocks(content);\n if (text.length === 0) return null;\n return parseToolPayload(text);\n }\n\n if (typeof content === \"object\") {\n return content;\n }\n\n return null;\n}\n\n/**\n * Parse a `tool-finished` output payload into the tool's return value.\n *\n * Wire events often wrap structured tool results in a ToolMessage-shaped\n * object (`{ type: \"tool\", content: \"...\" }`). This unwraps that envelope,\n * JSON-decodes string content when possible, and leaves plain strings as-is.\n * Returns `null` when a ToolMessage envelope is present but its content\n * cannot be normalised.\n */\nexport function parseToolOutput(value: unknown): unknown | null {\n const parsed = parseToolPayload(value);\n if (isToolMessageLike(parsed)) {\n return parseToolResultContent(parsed.content);\n }\n return parsed ?? null;\n}\n\ntype ActiveToolCall = {\n handle: MutableToolCallHandle;\n resolveOutput: (value: unknown) => void;\n rejectOutput: (err: Error) => void;\n};\n\n/**\n * Incrementally assembles `tools` events into mutable tool-call handles.\n *\n * Framework consumers store the handle directly; client SDK consumers\n * should map with {@link toClientAssembledToolCall} before yielding.\n */\nexport class ToolCallAssembler {\n private readonly active = new Map<string, ActiveToolCall>();\n\n consume(event: ToolsEvent): MutableToolCallHandle | undefined {\n const data = event.params.data;\n\n if (data.event === \"tool-started\") {\n return this.handleStarted(event, data);\n }\n\n if (data.event === \"tool-finished\") {\n return this.handleFinished(data);\n }\n\n if (data.event === \"tool-error\") {\n return this.handleError(data);\n }\n\n // tool-output-delta: no action needed at assembly level\n return undefined;\n }\n\n /**\n * Reject any in-flight tool calls (e.g. on session close).\n */\n failAll(reason: Error): void {\n for (const entry of this.active.values()) {\n entry.rejectOutput(reason);\n entry.handle.status = \"error\";\n entry.handle.error = reason.message;\n }\n this.active.clear();\n }\n\n private handleStarted(\n event: ToolsEvent,\n data: ToolStartedData\n ): MutableToolCallHandle {\n let resolveOutput!: (value: unknown) => void;\n let rejectOutput!: (err: Error) => void;\n\n const outputPromise = new Promise<unknown>((resolve, reject) => {\n resolveOutput = resolve;\n rejectOutput = reject;\n });\n // Attach a default no-op catch so if no consumer awaits\n // `output` the eventual rejection on `tool-error` / `failAll`\n // doesn't surface as an unhandled Promise rejection.\n outputPromise.catch(() => undefined);\n\n const input = parseToolPayload(data.input);\n const name = data.tool_name;\n const callId = data.tool_call_id;\n const namespace = [...event.params.namespace];\n\n const handle: MutableToolCallHandle = {\n name,\n callId,\n id: callId,\n namespace,\n input,\n args: input,\n output: null,\n status: \"running\",\n error: undefined,\n outputPromise,\n };\n\n this.active.set(callId, {\n handle,\n resolveOutput,\n rejectOutput,\n });\n\n return handle;\n }\n\n private handleFinished(\n data: ToolFinishedData\n ): MutableToolCallHandle | undefined {\n const entry = this.active.get(data.tool_call_id);\n if (!entry) return undefined;\n this.active.delete(data.tool_call_id);\n const value = parseToolOutput(data.output);\n entry.resolveOutput(value);\n entry.handle.output = value;\n entry.handle.status = \"finished\";\n entry.handle.error = undefined;\n return entry.handle;\n }\n\n private handleError(data: ToolErrorData): MutableToolCallHandle | undefined {\n const entry = this.active.get(data.tool_call_id);\n if (!entry) return undefined;\n this.active.delete(data.tool_call_id);\n entry.rejectOutput(new Error(data.message));\n entry.handle.output = null;\n entry.handle.status = \"error\";\n entry.handle.error = data.message;\n return entry.handle;\n }\n}\n"],"mappings":";;;;;AAqFA,SAAgB,0BACd,QACyB;AACzB,QAAO;EACL,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,IAAI,OAAO;EACX,WAAW,OAAO;EAClB,OAAO,OAAO;EACd,MAAM,OAAO;EACb,QAAQ,OAAO;EAChB;;;;;;;;;AAUH,SAAgB,iBAAiB,OAAyB;AACxD,KAAI,OAAO,UAAU,SAAU,QAAO;CACtC,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,QAAQ,WAAW,IAAI,IAAI,CAAC,QAAQ,WAAW,IAAI,CACtD,QAAO;AAGT,KAAI;AACF,SAAO,KAAK,MAAM,QAAQ;SACpB;AACN,SAAO;;;AAIX,SAAS,kBACP,OACyD;AACzD,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAChD,MAAM,SAAS;AACf,KAAI,OAAO,SAAS,OAAQ,QAAO;AACnC,QAAO,OAAO,OAAO,iBAAiB,YAAY,aAAa;;AAGjE,SAAS,sBAAsB,SAA4B;CACzD,IAAI,MAAM;AACV,MAAK,MAAM,SAAS,SAAS;AAC3B,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU;EACzC,MAAM,SAAS;AACf,MAAI,OAAO,SAAS,UAAU,OAAO,OAAO,SAAS,SACnD,QAAO,OAAO;;AAGlB,QAAO;;;;;;AAOT,SAAS,uBAAuB,SAAkC;AAChE,KAAI,WAAW,KAAM,QAAO;AAE5B,KAAI,OAAO,YAAY,UAAU;AAE/B,MADgB,QAAQ,MAAM,CAClB,WAAW,EAAG,QAAO;AACjC,SAAO,iBAAiB,QAAQ;;AAGlC,KAAI,MAAM,QAAQ,QAAQ,EAAE;EAC1B,MAAM,OAAO,sBAAsB,QAAQ;AAC3C,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,SAAO,iBAAiB,KAAK;;AAG/B,KAAI,OAAO,YAAY,SACrB,QAAO;AAGT,QAAO;;;;;;;;;;;AAYT,SAAgB,gBAAgB,OAAgC;CAC9D,MAAM,SAAS,iBAAiB,MAAM;AACtC,KAAI,kBAAkB,OAAO,CAC3B,QAAO,uBAAuB,OAAO,QAAQ;AAE/C,QAAO,UAAU;;;;;;;;AAenB,IAAa,oBAAb,MAA+B;CAC7B,yBAA0B,IAAI,KAA6B;CAE3D,QAAQ,OAAsD;EAC5D,MAAM,OAAO,MAAM,OAAO;AAE1B,MAAI,KAAK,UAAU,eACjB,QAAO,KAAK,cAAc,OAAO,KAAK;AAGxC,MAAI,KAAK,UAAU,gBACjB,QAAO,KAAK,eAAe,KAAK;AAGlC,MAAI,KAAK,UAAU,aACjB,QAAO,KAAK,YAAY,KAAK;;;;;CAUjC,QAAQ,QAAqB;AAC3B,OAAK,MAAM,SAAS,KAAK,OAAO,QAAQ,EAAE;AACxC,SAAM,aAAa,OAAO;AAC1B,SAAM,OAAO,SAAS;AACtB,SAAM,OAAO,QAAQ,OAAO;;AAE9B,OAAK,OAAO,OAAO;;CAGrB,cACE,OACA,MACuB;EACvB,IAAI;EACJ,IAAI;EAEJ,MAAM,gBAAgB,IAAI,SAAkB,SAAS,WAAW;AAC9D,mBAAgB;AAChB,kBAAe;IACf;AAIF,gBAAc,YAAY,KAAA,EAAU;EAEpC,MAAM,QAAQ,iBAAiB,KAAK,MAAM;EAC1C,MAAM,OAAO,KAAK;EAClB,MAAM,SAAS,KAAK;EAGpB,MAAM,SAAgC;GACpC;GACA;GACA,IAAI;GACJ,WANgB,CAAC,GAAG,MAAM,OAAO,UAAU;GAO3C;GACA,MAAM;GACN,QAAQ;GACR,QAAQ;GACR,OAAO,KAAA;GACP;GACD;AAED,OAAK,OAAO,IAAI,QAAQ;GACtB;GACA;GACA;GACD,CAAC;AAEF,SAAO;;CAGT,eACE,MACmC;EACnC,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,aAAa;AAChD,MAAI,CAAC,MAAO,QAAO,KAAA;AACnB,OAAK,OAAO,OAAO,KAAK,aAAa;EACrC,MAAM,QAAQ,gBAAgB,KAAK,OAAO;AAC1C,QAAM,cAAc,MAAM;AAC1B,QAAM,OAAO,SAAS;AACtB,QAAM,OAAO,SAAS;AACtB,QAAM,OAAO,QAAQ,KAAA;AACrB,SAAO,MAAM;;CAGf,YAAoB,MAAwD;EAC1E,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,aAAa;AAChD,MAAI,CAAC,MAAO,QAAO,KAAA;AACnB,OAAK,OAAO,OAAO,KAAK,aAAa;AACrC,QAAM,aAAa,IAAI,MAAM,KAAK,QAAQ,CAAC;AAC3C,QAAM,OAAO,SAAS;AACtB,QAAM,OAAO,SAAS;AACtB,QAAM,OAAO,QAAQ,KAAK;AAC1B,SAAO,MAAM"}
|
|
1
|
+
{"version":3,"file":"tools.js","names":[],"sources":["../../../../src/client/stream/handles/tools.ts"],"sourcesContent":["import type {\n ToolsEvent,\n ToolStartedData,\n ToolFinishedData,\n ToolErrorData,\n} from \"@langchain/protocol\";\n\n/**\n * High-level outcome of a single tool call.\n */\nexport type ToolCallStatus = \"running\" | \"finished\" | \"error\";\n\n/** Shared metadata for assembled tool-call handles. */\ninterface ToolCallBase<TName extends string = string, TInput = unknown> {\n readonly name: TName;\n readonly callId: string;\n /**\n * Pre-v1 alias for {@link callId}. Matches `ToolCallWithResult.id` and\n * `ToolCall.id` on message-level tool calls.\n */\n readonly id: string;\n readonly namespace: string[];\n readonly input: TInput;\n /**\n * Pre-v1 alias for {@link input}. Matches `ToolCallFromTool` `args`.\n */\n readonly args: TInput;\n}\n\n/**\n * Script-oriented tool handle from the client SDK (`ThreadStream.toolCalls`,\n * subagent/subgraph projections). Completion and errors are surfaced only\n * through {@link output}.\n */\nexport interface ClientAssembledToolCall<\n TName extends string = string,\n TInput = unknown,\n TOutput = unknown,\n> extends ToolCallBase<TName, TInput> {\n readonly output: Promise<TOutput>;\n}\n\n/**\n * Reactive tool handle for framework bindings (`stream.toolCalls`,\n * `useToolCalls`, `injectToolCalls`).\n *\n * {@link status}, {@link error}, and {@link output} are plain values that\n * the assembler updates in place as tool events arrive. That lets React,\n * Vue, Svelte, and Angular re-render from a snapshot on each store tick\n * without `await`, effects, or Suspense boundaries around a promise.\n * {@link ClientAssembledToolCall} keeps a promise-based {@link output}\n * instead for script consumers that read tool results sequentially.\n *\n * {@link output} is `null` while the call is running or after it fails;\n * successful completion sets it to the parsed tool return value (objects\n * and strings are unwrapped from ToolMessage wire envelopes when needed).\n */\nexport interface AssembledToolCall<\n TName extends string = string,\n TInput = unknown,\n TOutput = unknown,\n> extends ToolCallBase<TName, TInput> {\n readonly output: TOutput | null;\n readonly status: ToolCallStatus;\n readonly error: string | undefined;\n}\n\n/** @internal Mutable runtime handle shared by client and framework views. */\ntype MutableToolCallHandle = {\n name: string;\n callId: string;\n id: string;\n namespace: string[];\n input: unknown;\n args: unknown;\n output: unknown | null;\n status: ToolCallStatus;\n error: string | undefined;\n outputPromise: Promise<unknown>;\n};\n\n/**\n * Project a runtime handle to the client SDK surface (promise-only\n * {@link output}, no {@link status} / {@link error} fields).\n */\nexport function toClientAssembledToolCall(\n handle: MutableToolCallHandle\n): ClientAssembledToolCall {\n return {\n name: handle.name,\n callId: handle.callId,\n id: handle.id,\n namespace: handle.namespace,\n input: handle.input,\n args: handle.args,\n output: handle.outputPromise as Promise<unknown>,\n };\n}\n\n/**\n * Parse wire-format tool payloads into structured values.\n *\n * Tool events may carry JSON-encoded object strings on the wire; this\n * helper normalises them to plain objects for consumers. Non-JSON strings\n * are returned unchanged.\n */\nexport function parseToolPayload(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return value;\n }\n\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n return value;\n }\n}\n\n/**\n * Skip wrapper `task` tool events scoped to a subagent namespace.\n *\n * Deep-agent subagents are discovered from root-level `task` tool calls;\n * replaying the same dispatch tool inside the worker namespace would\n * otherwise surface as a spurious entry in `sub.toolCalls`.\n */\nexport function shouldIgnoreScopedTaskToolEvent(\n scopeNamespace: readonly string[],\n event: ToolsEvent\n): boolean {\n const data = event.params.data;\n return (\n scopeNamespace.length > 0 &&\n event.params.namespace.length === scopeNamespace.length &&\n event.params.namespace.every(\n (segment, index) => segment === scopeNamespace[index]\n ) &&\n \"tool_name\" in data &&\n data.tool_name === \"task\"\n );\n}\n\nfunction getWireMessageField(message: unknown, field: string): unknown {\n if (!message || typeof message !== \"object\" || Array.isArray(message)) {\n return undefined;\n }\n const record = message as Record<string, unknown>;\n if (field in record) return record[field];\n const kwargs = record.kwargs as Record<string, unknown> | undefined;\n if (kwargs != null && field in kwargs) return kwargs[field];\n const lcKwargs = record.lc_kwargs as Record<string, unknown> | undefined;\n if (lcKwargs != null && field in lcKwargs) return lcKwargs[field];\n return undefined;\n}\n\nfunction isToolMessageLike(\n value: unknown\n): value is Record<string, unknown> & { content: unknown } {\n if (!value || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type === \"tool\") return true;\n const type = getWireMessageField(value, \"type\");\n if (type === \"tool\") return true;\n return (\n typeof getWireMessageField(value, \"tool_call_id\") === \"string\" &&\n getWireMessageField(value, \"content\") !== undefined\n );\n}\n\nfunction isCommandLike(\n value: unknown\n): value is Record<string, unknown> & { update?: unknown } {\n return (\n !!value &&\n typeof value === \"object\" &&\n (value as Record<string, unknown>).lg_name === \"Command\"\n );\n}\n\nfunction textFromContentBlocks(content: unknown[]): string {\n let out = \"\";\n for (const block of content) {\n if (!block || typeof block !== \"object\") continue;\n const record = block as Record<string, unknown>;\n if (record.type === \"text\" && typeof record.text === \"string\") {\n out += record.text;\n }\n }\n return out;\n}\n\n/**\n * Normalise tool-result `content` from a wire ToolMessage into the value\n * a tool implementation returned (object, string, etc.).\n */\nfunction parseToolResultContent(content: unknown): unknown | null {\n if (content == null) return null;\n\n if (typeof content === \"string\") {\n const trimmed = content.trim();\n if (trimmed.length === 0) return null;\n return parseToolPayload(content);\n }\n\n if (Array.isArray(content)) {\n const text = textFromContentBlocks(content);\n if (text.length === 0) return null;\n return parseToolPayload(text);\n }\n\n if (typeof content === \"object\") {\n return content;\n }\n\n return null;\n}\n\nfunction parseToolMessageRecord(message: unknown): unknown | null {\n const content = getWireMessageField(message, \"content\");\n return parseToolResultContent(content);\n}\n\ntype ParsedCommandToolOutput =\n | { found: true; value: unknown | null }\n | { found: false };\n\nfunction parseCommandToolOutput(\n command: Record<string, unknown> & { update?: unknown },\n toolCallId?: string\n): ParsedCommandToolOutput {\n const update = command.update;\n if (update == null || typeof update !== \"object\" || Array.isArray(update)) {\n return { found: false };\n }\n\n const messages = (update as Record<string, unknown>).messages;\n if (!Array.isArray(messages)) return { found: false };\n\n const toolMessages = messages.filter((message) => isToolMessageLike(message));\n if (toolMessages.length === 0) return { found: false };\n\n if (toolCallId != null) {\n for (const message of toolMessages) {\n const callId = getWireMessageField(message, \"tool_call_id\");\n if (callId !== toolCallId) continue;\n return { found: true, value: parseToolMessageRecord(message) };\n }\n return { found: false };\n }\n\n if (toolMessages.length === 1) {\n return { found: true, value: parseToolMessageRecord(toolMessages[0]) };\n }\n\n for (let i = toolMessages.length - 1; i >= 0; i -= 1) {\n const parsed = parseToolMessageRecord(toolMessages[i]);\n if (parsed != null) return { found: true, value: parsed };\n }\n\n return { found: true, value: null };\n}\n\n/**\n * Parse a `tool-finished` output payload into the tool's return value.\n *\n * Wire events often wrap structured tool results in a ToolMessage-shaped\n * object (`{ type: \"tool\", content: \"...\" }`) or a LangGraph\n * {@link Command} whose `update.messages` carries the ToolMessage.\n * This unwraps those envelopes, JSON-decodes string content when possible,\n * and leaves plain strings as-is. Returns `null` when a ToolMessage envelope\n * is present but its content cannot be normalised.\n */\nexport function parseToolOutput(\n value: unknown,\n toolCallId?: string\n): unknown | null {\n const parsed = parseToolPayload(value);\n if (isCommandLike(parsed)) {\n const commandOutput = parseCommandToolOutput(parsed, toolCallId);\n return commandOutput.found ? commandOutput.value : parsed;\n }\n if (isToolMessageLike(parsed)) {\n return parseToolResultContent(getWireMessageField(parsed, \"content\"));\n }\n return parsed ?? null;\n}\n\ntype ActiveToolCall = {\n handle: MutableToolCallHandle;\n resolveOutput: (value: unknown) => void;\n rejectOutput: (err: Error) => void;\n};\n\n/**\n * Incrementally assembles `tools` events into mutable tool-call handles.\n *\n * Framework consumers store the handle directly; client SDK consumers\n * should map with {@link toClientAssembledToolCall} before yielding.\n */\nexport class ToolCallAssembler {\n private readonly active = new Map<string, ActiveToolCall>();\n\n consume(event: ToolsEvent): MutableToolCallHandle | undefined {\n const data = event.params.data;\n\n if (data.event === \"tool-started\") {\n return this.handleStarted(event, data);\n }\n\n if (data.event === \"tool-finished\") {\n return this.handleFinished(data);\n }\n\n if (data.event === \"tool-error\") {\n return this.handleError(data);\n }\n\n // tool-output-delta: no action needed at assembly level\n return undefined;\n }\n\n /**\n * Reject any in-flight tool calls (e.g. on session close).\n */\n failAll(reason: Error): void {\n for (const entry of this.active.values()) {\n entry.rejectOutput(reason);\n entry.handle.status = \"error\";\n entry.handle.error = reason.message;\n }\n this.active.clear();\n }\n\n private handleStarted(\n event: ToolsEvent,\n data: ToolStartedData\n ): MutableToolCallHandle {\n let resolveOutput!: (value: unknown) => void;\n let rejectOutput!: (err: Error) => void;\n\n const outputPromise = new Promise<unknown>((resolve, reject) => {\n resolveOutput = resolve;\n rejectOutput = reject;\n });\n // Attach a default no-op catch so if no consumer awaits\n // `output` the eventual rejection on `tool-error` / `failAll`\n // doesn't surface as an unhandled Promise rejection.\n outputPromise.catch(() => undefined);\n\n const input = parseToolPayload(data.input);\n const name = data.tool_name;\n const callId = data.tool_call_id;\n const namespace = [...event.params.namespace];\n\n const handle: MutableToolCallHandle = {\n name,\n callId,\n id: callId,\n namespace,\n input,\n args: input,\n output: null,\n status: \"running\",\n error: undefined,\n outputPromise,\n };\n\n this.active.set(callId, {\n handle,\n resolveOutput,\n rejectOutput,\n });\n\n return handle;\n }\n\n private handleFinished(\n data: ToolFinishedData\n ): MutableToolCallHandle | undefined {\n const entry = this.active.get(data.tool_call_id);\n if (!entry) return undefined;\n this.active.delete(data.tool_call_id);\n const value = parseToolOutput(data.output, data.tool_call_id);\n entry.resolveOutput(value);\n entry.handle.output = value;\n entry.handle.status = \"finished\";\n entry.handle.error = undefined;\n return entry.handle;\n }\n\n private handleError(data: ToolErrorData): MutableToolCallHandle | undefined {\n const entry = this.active.get(data.tool_call_id);\n if (!entry) return undefined;\n this.active.delete(data.tool_call_id);\n entry.rejectOutput(new Error(data.message));\n entry.handle.output = null;\n entry.handle.status = \"error\";\n entry.handle.error = data.message;\n return entry.handle;\n }\n}\n"],"mappings":"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"}
|