langchain 1.4.0 → 1.4.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.
@@ -1,3 +1,4 @@
1
+ import { ToolMessage } from "@langchain/core/messages";
1
2
  import { StreamChannel } from "@langchain/langgraph";
2
3
  //#region src/agents/stream.ts
3
4
  /**
@@ -42,6 +43,31 @@ function isHeadlessToolInterruptError(message, toolCallId) {
42
43
  }
43
44
  }
44
45
  /**
46
+ * Detects serialized LangChain `ToolMessage` values that can appear on
47
+ * `tool-finished.output` after crossing a protocol or serialization boundary.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * {
52
+ * lc: 1,
53
+ * type: "constructor",
54
+ * id: ["langchain_core", "messages", "ToolMessage"],
55
+ * kwargs: { content: "raw tool result", tool_call_id: "call_1" }
56
+ * }
57
+ * ```
58
+ */
59
+ function isSerializedToolMessage(value) {
60
+ if (value == null || typeof value !== "object") return false;
61
+ const record = value;
62
+ if (record.type !== "constructor" || !Array.isArray(record.id)) return false;
63
+ return record.id[record.id.length - 1] === "ToolMessage";
64
+ }
65
+ function normalizeToolOutput(output) {
66
+ if (ToolMessage.isInstance(output)) return output.content;
67
+ if (isSerializedToolMessage(output)) return output.kwargs?.content;
68
+ return output;
69
+ }
70
+ /**
45
71
  * Creates a native transformer that correlates `tools` channel events
46
72
  * into per-call {@link ToolCallStream} objects.
47
73
  *
@@ -106,7 +132,7 @@ function createToolCallTransformer(path) {
106
132
  const pending = toolCallId ? pendingCalls.get(toolCallId) : void 0;
107
133
  if (pending) {
108
134
  if (data.event === "tool-finished") {
109
- pending.resolveOutput(data.output);
135
+ pending.resolveOutput(normalizeToolOutput(data.output));
110
136
  pending.resolveStatus("finished");
111
137
  pending.resolveError(void 0);
112
138
  pendingCalls.delete(toolCallId);
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","names":[],"sources":["../../src/agents/stream.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Agent-level streaming support (experimental).\n *\n * Provides native stream transformer factories for tool calls and\n * middleware events. When marked `__native: true`, their projections\n * are assigned directly onto the `GraphRunStream` instance by\n * `createGraphRunStream` in langgraph-core — no subclass or wrapper\n * needed.\n *\n * See protocol proposal §15 (In-Process Streaming Interface) and §16\n * (Native Stream Transformers).\n */\n\nimport {\n GraphRunStream,\n StreamChannel,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type StreamTransformer,\n type ToolCallStream,\n type ToolCallStatus,\n type ToolsEventData,\n type Namespace,\n} from \"@langchain/langgraph\";\nimport type {\n ClientTool,\n ServerTool,\n DynamicStructuredTool,\n StructuredToolInterface,\n} from \"@langchain/core/tools\";\n\n/**\n * Infers the merged extensions shape from a tuple of stream transformer\n * factories. Mirrors `InferExtensions` from `@langchain/langgraph`, which\n * is not exported from the package's public surface.\n *\n * Given `[() => StreamTransformer<{ a: number }>, () => StreamTransformer<{ b: string }>]`,\n * produces `{ a: number } & { b: string }`.\n */\nexport type InferStreamExtensions<\n T extends ReadonlyArray<() => StreamTransformer<any>>,\n> = T extends readonly []\n ? Record<string, never>\n : T extends readonly [\n () => StreamTransformer<infer P>,\n ...infer Rest extends ReadonlyArray<() => StreamTransformer<any>>,\n ]\n ? P & InferStreamExtensions<Rest>\n : Record<string, unknown>;\n\n/** Extract the literal `name` string from a tool type. */\ntype ToolNameOf<T> = T extends { name: infer N extends string } ? N : string;\n\n/** Extract the parsed input type from a tool type. */\ntype ToolInputOf<T> =\n T extends DynamicStructuredTool<any, any, infer SchemaInputT, any, any, any>\n ? SchemaInputT\n : T extends StructuredToolInterface<any, infer SchemaInputT, any>\n ? SchemaInputT\n : unknown;\n\n/** Extract the return/output type from a tool type. */\ntype ToolOutputOf<T> =\n T extends DynamicStructuredTool<any, any, any, infer ToolOutputT, any, any>\n ? ToolOutputT\n : T extends StructuredToolInterface<any, any, infer ToolOutputT>\n ? ToolOutputT\n : unknown;\n\n/**\n * Discriminated union of {@link ToolCallStream} variants, one per tool\n * in `TTools`. Enables TypeScript to narrow `.input` and `.output`\n * when the consumer checks `call.name === \"someToolName\"`.\n *\n * Falls back to `ToolCallStream` (untyped) when the tools tuple is a\n * plain `(ClientTool | ServerTool)[]` without literal name types.\n */\nexport type ToolCallStreamUnion<\n TTools extends readonly (ClientTool | ServerTool)[],\n> = {\n [K in keyof TTools]: ToolCallStream<\n ToolNameOf<TTools[K]>,\n ToolInputOf<TTools[K]>,\n ToolOutputOf<TTools[K]>\n >;\n}[number];\n\n/**\n * A {@link GraphRunStream} with native agent-level projections assigned\n * directly on the instance by `createGraphRunStream` (via `__native`\n * transformers).\n *\n * This is a pure type overlay — no runtime subclass exists. Use the\n * `AgentRunStream` type when you need to describe the return type of\n * `streamEvents(..., { version: \"v3\" })`.\n *\n * @typeParam TValues - Shape of the graph's state values.\n * @typeParam TTools - Tuple of tools registered on the agent, used to type\n * the per-tool `toolCalls` discriminated union.\n * @typeParam TMiddleware - Tuple of middleware registered on the agent, used\n * to type the per-middleware `middleware` event union.\n * @typeParam TExtensions - Shape of `run.extensions` produced by user-supplied\n * stream transformer factories. Derived via\n * `InferExtensions<TStreamTransformers>`.\n */\nexport type AgentRunStream<\n TValues = Record<string, unknown>,\n TTools extends readonly (ClientTool | ServerTool)[] = readonly (\n | ClientTool\n | ServerTool\n )[],\n TExtensions extends Record<string, unknown> = Record<string, unknown>,\n> = GraphRunStream<TValues, TExtensions> & {\n /** Tool call streams from the native ToolCallTransformer. */\n toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;\n};\n\ninterface ToolCallProjection {\n toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n if (ns.length < path.length || ns.length > path.length + 1) return false;\n for (let i = 0; i < path.length; i += 1) {\n if (ns[i] !== path[i]) return false;\n }\n return true;\n}\n\nfunction isHeadlessToolInterruptError(\n message: string,\n toolCallId: string | undefined\n): boolean {\n try {\n const parsed = JSON.parse(message) as unknown;\n if (!Array.isArray(parsed)) return false;\n return parsed.some((entry) => {\n if (entry == null || typeof entry !== \"object\") return false;\n const value = (entry as { value?: unknown }).value;\n if (value == null || typeof value !== \"object\") return false;\n const payload = value as {\n type?: unknown;\n toolCall?: { id?: unknown };\n };\n return (\n payload.type === \"tool\" &&\n (toolCallId == null ||\n payload.toolCall?.id == null ||\n payload.toolCall.id === toolCallId)\n );\n });\n } catch {\n return false;\n }\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n return () => {\n const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n const pendingCalls = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n resolveStatus: (v: ToolCallStatus) => void;\n resolveError: (v: string | undefined) => void;\n }\n >();\n\n function createToolCallEntry(\n callId: string,\n name: string,\n rawInput: unknown\n ): void {\n if (pendingCalls.has(callId)) return;\n const input =\n typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n let resolveStatus!: (v: ToolCallStatus) => void;\n let resolveError!: (v: string | undefined) => void;\n\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n const status = new Promise<ToolCallStatus>((res) => {\n resolveStatus = res;\n });\n const error = new Promise<string | undefined>((res) => {\n resolveError = res;\n });\n\n pendingCalls.set(callId, {\n resolveOutput,\n rejectOutput,\n resolveStatus,\n resolveError,\n });\n\n toolCallsLog.push({\n name,\n callId,\n input,\n output,\n status,\n error,\n } as ToolCallStream);\n }\n\n return {\n __native: true as const,\n\n init: () => ({\n toolCalls: toolCallsLog,\n }),\n\n process(event: ProtocolEvent): boolean {\n /**\n * Only process events that are at the same depth as the agent's graph.\n */\n if (!isOwnEvent(event.params.namespace, path)) return true;\n\n if (event.method === \"messages\") {\n const data = event.params.data as Record<string, unknown>;\n if (data.event === \"content-block-finish\") {\n const cb = (data.contentBlock ?? data.content_block) as\n | Record<string, unknown>\n | undefined;\n if (cb?.type === \"tool_call\") {\n createToolCallEntry(\n String(cb.id ?? \"\"),\n String(cb.name ?? \"\"),\n cb.args ?? cb.input\n );\n }\n }\n }\n\n if (event.method === \"tools\") {\n const data = event.params.data as ToolsEventData;\n const toolCallId = (data as Record<string, unknown>)\n .tool_call_id as string;\n\n if (data.event === \"tool-started\") {\n createToolCallEntry(\n toolCallId,\n ((data as Record<string, unknown>).tool_name as string) ??\n \"unknown\",\n (data as Record<string, unknown>).input\n );\n }\n\n const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput((data as Record<string, unknown>).output);\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pendingCalls.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n if (isHeadlessToolInterruptError(message, toolCallId)) {\n return true;\n }\n pending.rejectOutput(new Error(message));\n pending.resolveStatus(\"error\");\n pending.resolveError(message);\n pendingCalls.delete(toolCallId);\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pending.resolveOutput(undefined);\n }\n pendingCalls.clear();\n toolCallsLog.close();\n },\n\n fail(err: unknown): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"error\");\n pending.resolveError(\n err instanceof Error ? err.message : String(err)\n );\n pending.rejectOutput(err);\n }\n pendingCalls.clear();\n toolCallsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stream.js","names":[],"sources":["../../src/agents/stream.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Agent-level streaming support (experimental).\n *\n * Provides native stream transformer factories for tool calls and\n * middleware events. When marked `__native: true`, their projections\n * are assigned directly onto the `GraphRunStream` instance by\n * `createGraphRunStream` in langgraph-core — no subclass or wrapper\n * needed.\n *\n * See protocol proposal §15 (In-Process Streaming Interface) and §16\n * (Native Stream Transformers).\n */\n\nimport {\n GraphRunStream,\n StreamChannel,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type StreamTransformer,\n type ToolCallStream,\n type ToolCallStatus,\n type ToolsEventData,\n type Namespace,\n} from \"@langchain/langgraph\";\nimport type {\n ClientTool,\n ServerTool,\n DynamicStructuredTool,\n StructuredToolInterface,\n} from \"@langchain/core/tools\";\nimport { ToolMessage } from \"@langchain/core/messages\";\n\n/**\n * Infers the merged extensions shape from a tuple of stream transformer\n * factories. Mirrors `InferExtensions` from `@langchain/langgraph`, which\n * is not exported from the package's public surface.\n *\n * Given `[() => StreamTransformer<{ a: number }>, () => StreamTransformer<{ b: string }>]`,\n * produces `{ a: number } & { b: string }`.\n */\nexport type InferStreamExtensions<\n T extends ReadonlyArray<() => StreamTransformer<any>>,\n> = T extends readonly []\n ? Record<string, never>\n : T extends readonly [\n () => StreamTransformer<infer P>,\n ...infer Rest extends ReadonlyArray<() => StreamTransformer<any>>,\n ]\n ? P & InferStreamExtensions<Rest>\n : Record<string, unknown>;\n\n/** Extract the literal `name` string from a tool type. */\ntype ToolNameOf<T> = T extends { name: infer N extends string } ? N : string;\n\n/** Extract the parsed input type from a tool type. */\ntype ToolInputOf<T> =\n T extends DynamicStructuredTool<any, any, infer SchemaInputT, any, any, any>\n ? SchemaInputT\n : T extends StructuredToolInterface<any, infer SchemaInputT, any>\n ? SchemaInputT\n : unknown;\n\n/** Extract the return/output type from a tool type. */\ntype ToolOutputOf<T> =\n T extends DynamicStructuredTool<any, any, any, infer ToolOutputT, any, any>\n ? ToolOutputT\n : T extends StructuredToolInterface<any, any, infer ToolOutputT>\n ? ToolOutputT\n : unknown;\n\n/**\n * Discriminated union of {@link ToolCallStream} variants, one per tool\n * in `TTools`. Enables TypeScript to narrow `.input` and `.output`\n * when the consumer checks `call.name === \"someToolName\"`.\n *\n * Falls back to `ToolCallStream` (untyped) when the tools tuple is a\n * plain `(ClientTool | ServerTool)[]` without literal name types.\n */\nexport type ToolCallStreamUnion<\n TTools extends readonly (ClientTool | ServerTool)[],\n> = {\n [K in keyof TTools]: ToolCallStream<\n ToolNameOf<TTools[K]>,\n ToolInputOf<TTools[K]>,\n ToolOutputOf<TTools[K]>\n >;\n}[number];\n\n/**\n * A {@link GraphRunStream} with native agent-level projections assigned\n * directly on the instance by `createGraphRunStream` (via `__native`\n * transformers).\n *\n * This is a pure type overlay — no runtime subclass exists. Use the\n * `AgentRunStream` type when you need to describe the return type of\n * `streamEvents(..., { version: \"v3\" })`.\n *\n * @typeParam TValues - Shape of the graph's state values.\n * @typeParam TTools - Tuple of tools registered on the agent, used to type\n * the per-tool `toolCalls` discriminated union.\n * @typeParam TMiddleware - Tuple of middleware registered on the agent, used\n * to type the per-middleware `middleware` event union.\n * @typeParam TExtensions - Shape of `run.extensions` produced by user-supplied\n * stream transformer factories. Derived via\n * `InferExtensions<TStreamTransformers>`.\n */\nexport type AgentRunStream<\n TValues = Record<string, unknown>,\n TTools extends readonly (ClientTool | ServerTool)[] = readonly (\n | ClientTool\n | ServerTool\n )[],\n TExtensions extends Record<string, unknown> = Record<string, unknown>,\n> = GraphRunStream<TValues, TExtensions> & {\n /** Tool call streams from the native ToolCallTransformer. */\n toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;\n};\n\ninterface ToolCallProjection {\n toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n if (ns.length < path.length || ns.length > path.length + 1) return false;\n for (let i = 0; i < path.length; i += 1) {\n if (ns[i] !== path[i]) return false;\n }\n return true;\n}\n\nfunction isHeadlessToolInterruptError(\n message: string,\n toolCallId: string | undefined\n): boolean {\n try {\n const parsed = JSON.parse(message) as unknown;\n if (!Array.isArray(parsed)) return false;\n return parsed.some((entry) => {\n if (entry == null || typeof entry !== \"object\") return false;\n const value = (entry as { value?: unknown }).value;\n if (value == null || typeof value !== \"object\") return false;\n const payload = value as {\n type?: unknown;\n toolCall?: { id?: unknown };\n };\n return (\n payload.type === \"tool\" &&\n (toolCallId == null ||\n payload.toolCall?.id == null ||\n payload.toolCall.id === toolCallId)\n );\n });\n } catch {\n return false;\n }\n}\n\n/**\n * Detects serialized LangChain `ToolMessage` values that can appear on\n * `tool-finished.output` after crossing a protocol or serialization boundary.\n *\n * @example\n * ```ts\n * {\n * lc: 1,\n * type: \"constructor\",\n * id: [\"langchain_core\", \"messages\", \"ToolMessage\"],\n * kwargs: { content: \"raw tool result\", tool_call_id: \"call_1\" }\n * }\n * ```\n */\nfunction isSerializedToolMessage(\n value: unknown\n): value is { kwargs?: { content?: unknown } } {\n if (value == null || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type !== \"constructor\" || !Array.isArray(record.id)) return false;\n return record.id[record.id.length - 1] === \"ToolMessage\";\n}\n\nfunction normalizeToolOutput(output: unknown): unknown {\n if (ToolMessage.isInstance(output)) {\n return output.content;\n }\n if (isSerializedToolMessage(output)) {\n return output.kwargs?.content;\n }\n return output;\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n return () => {\n const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n const pendingCalls = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n resolveStatus: (v: ToolCallStatus) => void;\n resolveError: (v: string | undefined) => void;\n }\n >();\n\n function createToolCallEntry(\n callId: string,\n name: string,\n rawInput: unknown\n ): void {\n if (pendingCalls.has(callId)) return;\n const input =\n typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n let resolveStatus!: (v: ToolCallStatus) => void;\n let resolveError!: (v: string | undefined) => void;\n\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n const status = new Promise<ToolCallStatus>((res) => {\n resolveStatus = res;\n });\n const error = new Promise<string | undefined>((res) => {\n resolveError = res;\n });\n\n pendingCalls.set(callId, {\n resolveOutput,\n rejectOutput,\n resolveStatus,\n resolveError,\n });\n\n toolCallsLog.push({\n name,\n callId,\n input,\n output,\n status,\n error,\n } as ToolCallStream);\n }\n\n return {\n __native: true as const,\n\n init: () => ({\n toolCalls: toolCallsLog,\n }),\n\n process(event: ProtocolEvent): boolean {\n /**\n * Only process events that are at the same depth as the agent's graph.\n */\n if (!isOwnEvent(event.params.namespace, path)) return true;\n\n if (event.method === \"messages\") {\n const data = event.params.data as Record<string, unknown>;\n if (data.event === \"content-block-finish\") {\n const cb = (data.contentBlock ?? data.content_block) as\n | Record<string, unknown>\n | undefined;\n if (cb?.type === \"tool_call\") {\n createToolCallEntry(\n String(cb.id ?? \"\"),\n String(cb.name ?? \"\"),\n cb.args ?? cb.input\n );\n }\n }\n }\n\n if (event.method === \"tools\") {\n const data = event.params.data as ToolsEventData;\n const toolCallId = (data as Record<string, unknown>)\n .tool_call_id as string;\n\n if (data.event === \"tool-started\") {\n createToolCallEntry(\n toolCallId,\n ((data as Record<string, unknown>).tool_name as string) ??\n \"unknown\",\n (data as Record<string, unknown>).input\n );\n }\n\n const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput(\n normalizeToolOutput((data as Record<string, unknown>).output)\n );\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pendingCalls.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n if (isHeadlessToolInterruptError(message, toolCallId)) {\n return true;\n }\n pending.rejectOutput(new Error(message));\n pending.resolveStatus(\"error\");\n pending.resolveError(message);\n pendingCalls.delete(toolCallId);\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pending.resolveOutput(undefined);\n }\n pendingCalls.clear();\n toolCallsLog.close();\n },\n\n fail(err: unknown): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"error\");\n pending.resolveError(\n err instanceof Error ? err.message : String(err)\n );\n pending.rejectOutput(err);\n }\n pendingCalls.clear();\n toolCallsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langchain",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Typescript bindings for langchain",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -38,14 +38,13 @@
38
38
  "@tsconfig/recommended": "^1.0.2",
39
39
  "@types/js-yaml": "^4",
40
40
  "@types/jsdom": "^28.0.1",
41
- "@types/uuid": "^9",
42
41
  "@types/ws": "^8",
43
42
  "@vitest/coverage-v8": "^3.2.4",
44
43
  "cheerio": "1.2.0",
45
44
  "dotenv": "^17.4.0",
46
45
  "dpdm": "^3.14.0",
47
- "hono": "^4.12.12",
48
- "openai": "^6.22.0",
46
+ "hono": "^4.12.18",
47
+ "openai": "^6.37.0",
49
48
  "peggy": "^5.1.0",
50
49
  "reflect-metadata": "^0.2.2",
51
50
  "rimraf": "^6.1.3",
@@ -54,17 +53,17 @@
54
53
  "typescript": "~5.8.3",
55
54
  "vitest": "^4.1.2",
56
55
  "yaml": "^2.8.3",
57
- "@langchain/anthropic": "1.3.28",
58
- "@langchain/core": "^1.1.44",
59
- "@langchain/fireworks": "0.1.3",
60
- "@langchain/openai": "1.4.5",
56
+ "@langchain/anthropic": "1.4.0",
57
+ "@langchain/core": "^1.1.48",
58
+ "@langchain/fireworks": "0.1.5",
59
+ "@langchain/openai": "1.4.7",
61
60
  "@langchain/tsconfig": "0.0.1"
62
61
  },
63
62
  "peerDependencies": {
64
- "@langchain/core": "^1.1.44"
63
+ "@langchain/core": "^1.1.48"
65
64
  },
66
65
  "dependencies": {
67
- "@langchain/langgraph": "^1.3.0",
66
+ "@langchain/langgraph": "^1.3.2",
68
67
  "@langchain/langgraph-checkpoint": "^1.0.1",
69
68
  "langsmith": ">=0.5.0 <1.0.0",
70
69
  "zod": "^3.25.76 || ^4"