langchain 1.4.6-dev-1781485641139 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/chat_models/universal.cjs +1 -0
  3. package/chat_models/universal.d.cts +1 -0
  4. package/chat_models/universal.d.ts +1 -0
  5. package/chat_models/universal.js +1 -0
  6. package/dist/agents/ReactAgent.cjs +2 -5
  7. package/dist/agents/ReactAgent.cjs.map +1 -1
  8. package/dist/agents/ReactAgent.d.cts +1 -1
  9. package/dist/agents/ReactAgent.d.cts.map +1 -1
  10. package/dist/agents/ReactAgent.d.ts +1 -1
  11. package/dist/agents/ReactAgent.d.ts.map +1 -1
  12. package/dist/agents/ReactAgent.js +1 -4
  13. package/dist/agents/ReactAgent.js.map +1 -1
  14. package/dist/agents/index.cjs +1 -3
  15. package/dist/agents/index.cjs.map +1 -1
  16. package/dist/agents/index.d.cts +1 -3
  17. package/dist/agents/index.d.cts.map +1 -1
  18. package/dist/agents/index.d.ts +1 -3
  19. package/dist/agents/index.d.ts.map +1 -1
  20. package/dist/agents/index.js +1 -3
  21. package/dist/agents/index.js.map +1 -1
  22. package/dist/agents/middleware/hitl.cjs +50 -3
  23. package/dist/agents/middleware/hitl.cjs.map +1 -1
  24. package/dist/agents/middleware/hitl.d.cts +105 -2
  25. package/dist/agents/middleware/hitl.d.cts.map +1 -1
  26. package/dist/agents/middleware/hitl.d.ts +105 -2
  27. package/dist/agents/middleware/hitl.d.ts.map +1 -1
  28. package/dist/agents/middleware/hitl.js +50 -3
  29. package/dist/agents/middleware/hitl.js.map +1 -1
  30. package/dist/agents/middleware/index.cjs +1 -0
  31. package/dist/agents/middleware/index.d.cts +2 -1
  32. package/dist/agents/middleware/index.d.ts +2 -1
  33. package/dist/agents/middleware/index.js +1 -0
  34. package/dist/agents/middleware/provider/aws/promptCaching.cjs +209 -0
  35. package/dist/agents/middleware/provider/aws/promptCaching.cjs.map +1 -0
  36. package/dist/agents/middleware/provider/aws/promptCaching.d.cts +207 -0
  37. package/dist/agents/middleware/provider/aws/promptCaching.d.cts.map +1 -0
  38. package/dist/agents/middleware/provider/aws/promptCaching.d.ts +207 -0
  39. package/dist/agents/middleware/provider/aws/promptCaching.d.ts.map +1 -0
  40. package/dist/agents/middleware/provider/aws/promptCaching.js +208 -0
  41. package/dist/agents/middleware/provider/aws/promptCaching.js.map +1 -0
  42. package/dist/agents/middleware/toolEmulator.cjs +1 -1
  43. package/dist/agents/middleware/toolEmulator.cjs.map +1 -1
  44. package/dist/agents/middleware/toolEmulator.js +1 -1
  45. package/dist/agents/middleware/toolEmulator.js.map +1 -1
  46. package/dist/agents/{transformers/tool-call.cjs → stream.cjs} +15 -3
  47. package/dist/agents/stream.cjs.map +1 -0
  48. package/dist/agents/{transformers/types.d.ts → stream.d.cts} +20 -50
  49. package/dist/agents/stream.d.cts.map +1 -0
  50. package/dist/agents/{transformers/types.d.cts → stream.d.ts} +20 -50
  51. package/dist/agents/stream.d.ts.map +1 -0
  52. package/dist/agents/{transformers/tool-call.js → stream.js} +14 -2
  53. package/dist/agents/stream.js.map +1 -0
  54. package/dist/browser.cjs +6 -6
  55. package/dist/browser.d.cts +4 -5
  56. package/dist/browser.d.ts +4 -5
  57. package/dist/browser.js +4 -4
  58. package/dist/chat_models/universal.cjs +23 -4
  59. package/dist/chat_models/universal.cjs.map +1 -1
  60. package/dist/chat_models/universal.d.cts +27 -2
  61. package/dist/chat_models/universal.d.cts.map +1 -1
  62. package/dist/chat_models/universal.d.ts +27 -2
  63. package/dist/chat_models/universal.d.ts.map +1 -1
  64. package/dist/chat_models/universal.js +23 -4
  65. package/dist/chat_models/universal.js.map +1 -1
  66. package/dist/index.cjs +6 -6
  67. package/dist/index.d.cts +4 -5
  68. package/dist/index.d.ts +4 -5
  69. package/dist/index.js +4 -4
  70. package/hub/node.cjs +1 -0
  71. package/hub/node.d.cts +1 -0
  72. package/hub/node.d.ts +1 -0
  73. package/hub/node.js +1 -0
  74. package/hub.cjs +1 -0
  75. package/hub.d.cts +1 -0
  76. package/hub.d.ts +1 -0
  77. package/hub.js +1 -0
  78. package/load/serializable.cjs +1 -0
  79. package/load/serializable.d.cts +1 -0
  80. package/load/serializable.d.ts +1 -0
  81. package/load/serializable.js +1 -0
  82. package/load.cjs +1 -0
  83. package/load.d.cts +1 -0
  84. package/load.d.ts +1 -0
  85. package/load.js +1 -0
  86. package/package.json +7 -6
  87. package/storage/encoder_backed.cjs +1 -0
  88. package/storage/encoder_backed.d.cts +1 -0
  89. package/storage/encoder_backed.d.ts +1 -0
  90. package/storage/encoder_backed.js +1 -0
  91. package/storage/file_system.cjs +1 -0
  92. package/storage/file_system.d.cts +1 -0
  93. package/storage/file_system.d.ts +1 -0
  94. package/storage/file_system.js +1 -0
  95. package/storage/in_memory.cjs +1 -0
  96. package/storage/in_memory.d.cts +1 -0
  97. package/storage/in_memory.d.ts +1 -0
  98. package/storage/in_memory.js +1 -0
  99. package/dist/agents/transformers/index.cjs +0 -2
  100. package/dist/agents/transformers/index.d.cts +0 -3
  101. package/dist/agents/transformers/index.d.ts +0 -3
  102. package/dist/agents/transformers/index.js +0 -3
  103. package/dist/agents/transformers/subagent.cjs +0 -205
  104. package/dist/agents/transformers/subagent.cjs.map +0 -1
  105. package/dist/agents/transformers/subagent.d.cts +0 -34
  106. package/dist/agents/transformers/subagent.d.cts.map +0 -1
  107. package/dist/agents/transformers/subagent.d.ts +0 -34
  108. package/dist/agents/transformers/subagent.d.ts.map +0 -1
  109. package/dist/agents/transformers/subagent.js +0 -204
  110. package/dist/agents/transformers/subagent.js.map +0 -1
  111. package/dist/agents/transformers/tool-call.cjs.map +0 -1
  112. package/dist/agents/transformers/tool-call.d.cts +0 -17
  113. package/dist/agents/transformers/tool-call.d.cts.map +0 -1
  114. package/dist/agents/transformers/tool-call.d.ts +0 -17
  115. package/dist/agents/transformers/tool-call.d.ts.map +0 -1
  116. package/dist/agents/transformers/tool-call.js.map +0 -1
  117. package/dist/agents/transformers/types.d.cts.map +0 -1
  118. package/dist/agents/transformers/types.d.ts.map +0 -1
@@ -0,0 +1,208 @@
1
+ import { createMiddleware } from "../../../middleware.js";
2
+ import { z } from "zod/v3";
3
+ //#region src/agents/middleware/provider/aws/promptCaching.ts
4
+ const DEFAULT_ENABLE_CACHING = true;
5
+ const DEFAULT_TTL = "5m";
6
+ const DEFAULT_MIN_MESSAGES_TO_CACHE = 1;
7
+ const DEFAULT_UNSUPPORTED_MODEL_BEHAVIOR = "warn";
8
+ const contextSchema = z.object({
9
+ /**
10
+ * Whether to enable prompt caching.
11
+ * @default true
12
+ */
13
+ enableCaching: z.boolean().optional(),
14
+ /**
15
+ * The time-to-live for the cached prompt.
16
+ * @default "5m"
17
+ */
18
+ ttl: z.enum(["5m", "1h"]).optional(),
19
+ /**
20
+ * The minimum number of messages required before caching is applied.
21
+ * @default 1
22
+ */
23
+ minMessagesToCache: z.number().optional(),
24
+ /**
25
+ * The behavior to take when an unsupported model is used.
26
+ * - "ignore" will ignore the unsupported model and continue without caching.
27
+ * - "warn" will warn the user and continue without caching.
28
+ * - "raise" will raise an error and stop the agent.
29
+ * @default "warn"
30
+ */
31
+ unsupportedModelBehavior: z.enum([
32
+ "ignore",
33
+ "warn",
34
+ "raise"
35
+ ]).optional()
36
+ });
37
+ var BedrockPromptCachingMiddlewareError = class extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "BedrockPromptCachingMiddlewareError";
41
+ }
42
+ };
43
+ /**
44
+ * Creates a prompt caching middleware for AWS Bedrock Converse models to optimize API usage.
45
+ *
46
+ * This middleware automatically enables Bedrock's prompt caching when using AWS Bedrock Converse
47
+ * models. This can significantly reduce costs for applications with repetitive prompts, long
48
+ * system messages, or extensive conversation histories.
49
+ *
50
+ * ## How It Works
51
+ *
52
+ * The middleware intercepts model requests and sets a cache control signal that
53
+ * `ChatBedrockConverse` translates into Bedrock `cachePoint` breakpoints. Cache points are
54
+ * inserted after the system prompt, after the tool definitions, and after the final message, so
55
+ * the stable prefix of each request is cached. On subsequent requests with a matching prefix, the
56
+ * cached representations are reused, skipping redundant token processing. Exact placement varies
57
+ * by model (e.g. Amazon Nova models cache fewer breakpoints and ignore the `"1h"` TTL).
58
+ *
59
+ * ## Benefits
60
+ *
61
+ * - **Cost Reduction**: Avoid reprocessing the same tokens repeatedly
62
+ * - **Lower Latency**: Cached prompts are processed faster as embeddings are pre-computed
63
+ * - **Better Scalability**: Reduced computational load enables handling more requests
64
+ * - **Consistent Performance**: Stable response times for repetitive queries
65
+ *
66
+ * @param middlewareOptions - Configuration options for the caching behavior
67
+ * @param middlewareOptions.enableCaching - Whether to enable prompt caching (default: `true`)
68
+ * @param middlewareOptions.ttl - Cache time-to-live: `"5m"` for 5 minutes or `"1h"` for 1 hour (default: `"5m"`)
69
+ * @param middlewareOptions.minMessagesToCache - Minimum number of messages required before caching is applied (default: `1`)
70
+ * @param middlewareOptions.unsupportedModelBehavior - The behavior to take when an unsupported model is used (default: `"warn"`)
71
+ *
72
+ * @returns A middleware instance that can be passed to `createAgent`
73
+ *
74
+ * @throws {Error} When `unsupportedModelBehavior` is `"raise"` and the model is not a
75
+ * cache-capable Bedrock Converse model — either a non-Bedrock provider, or a Bedrock
76
+ * Converse model outside the Anthropic Claude / Amazon Nova families.
77
+ *
78
+ * @example
79
+ * Basic usage with default settings
80
+ * ```typescript
81
+ * import { createAgent } from "langchain";
82
+ * import { bedrockPromptCachingMiddleware } from "langchain";
83
+ *
84
+ * const agent = createAgent({
85
+ * model: "bedrock:anthropic.claude-haiku-4-5-20251001-v1:0",
86
+ * middleware: [
87
+ * bedrockPromptCachingMiddleware()
88
+ * ]
89
+ * });
90
+ * ```
91
+ *
92
+ * @example
93
+ * Custom configuration for longer conversations
94
+ * ```typescript
95
+ * const cachingMiddleware = bedrockPromptCachingMiddleware({
96
+ * ttl: "1h", // Cache for 1 hour instead of default 5 minutes
97
+ * minMessagesToCache: 5 // Only cache after 5 messages
98
+ * });
99
+ *
100
+ * const agent = createAgent({
101
+ * model: "bedrock:anthropic.claude-haiku-4-5-20251001-v1:0",
102
+ * systemPrompt: "You are a helpful assistant with deep knowledge of...", // Long system prompt
103
+ * middleware: [cachingMiddleware]
104
+ * });
105
+ * ```
106
+ *
107
+ * @example
108
+ * Conditional caching based on runtime context
109
+ * ```typescript
110
+ * const agent = createAgent({
111
+ * model: "bedrock:anthropic.claude-haiku-4-5-20251001-v1:0",
112
+ * middleware: [
113
+ * bedrockPromptCachingMiddleware({
114
+ * enableCaching: true,
115
+ * ttl: "5m"
116
+ * })
117
+ * ]
118
+ * });
119
+ *
120
+ * // Disable caching for specific requests
121
+ * await agent.invoke(
122
+ * { messages: [new HumanMessage("Process this without caching")] },
123
+ * {
124
+ * configurable: {
125
+ * middleware_context: { enableCaching: false }
126
+ * }
127
+ * }
128
+ * );
129
+ * ```
130
+ *
131
+ * @example
132
+ * Optimal setup for customer support chatbot
133
+ * ```typescript
134
+ * const supportAgent = createAgent({
135
+ * model: "bedrock:anthropic.claude-haiku-4-5-20251001-v1:0",
136
+ * systemPrompt: `You are a customer support agent for ACME Corp.
137
+ *
138
+ * Company policies:
139
+ * - Always be polite and professional
140
+ * - Refer to knowledge base for product information
141
+ * - Escalate billing issues to human agents
142
+ * ... (extensive policies and guidelines)
143
+ * `,
144
+ * tools: [searchKnowledgeBase, createTicket, checkOrderStatus],
145
+ * middleware: [
146
+ * bedrockPromptCachingMiddleware({
147
+ * ttl: "1h", // Long TTL for stable system prompt
148
+ * minMessagesToCache: 1 // Cache immediately due to large system prompt
149
+ * })
150
+ * ]
151
+ * });
152
+ * ```
153
+ *
154
+ * @remarks
155
+ * - **Bedrock Converse Only**: This middleware only applies caching to AWS Bedrock Converse models. Other providers are handled per `unsupportedModelBehavior`
156
+ * - **Supported Families**: Bedrock prompt caching is only available on the **Anthropic Claude** and **Amazon Nova** model families. Other Bedrock Converse models (e.g. Mistral, Cohere, Meta) reject cache points at request time, so they are treated as unsupported and routed through `unsupportedModelBehavior`
157
+ * - **Automatic Application**: Caching is applied automatically when the message count reaches `minMessagesToCache`
158
+ * - **TTL Options**: Only supports "5m" (5 minutes) and "1h" (1 hour) as TTL values; actual support varies by model
159
+ * - **Best Use Cases**: Long system prompts, multi-turn conversations, repetitive queries, RAG applications
160
+ *
161
+ * @see {@link createAgent} for agent creation
162
+ * @see {@link https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html} AWS Bedrock prompt caching documentation
163
+ * @public
164
+ */
165
+ function bedrockPromptCachingMiddleware(middlewareOptions) {
166
+ return createMiddleware({
167
+ name: "BedrockPromptCachingMiddleware",
168
+ contextSchema,
169
+ wrapModelCall: (request, handler) => {
170
+ const enableCaching = request.runtime.context.enableCaching ?? middlewareOptions?.enableCaching ?? DEFAULT_ENABLE_CACHING;
171
+ const ttl = request.runtime.context.ttl ?? middlewareOptions?.ttl ?? DEFAULT_TTL;
172
+ const minMessagesToCache = request.runtime.context.minMessagesToCache ?? middlewareOptions?.minMessagesToCache ?? DEFAULT_MIN_MESSAGES_TO_CACHE;
173
+ const unsupportedModelBehavior = request.runtime.context.unsupportedModelBehavior ?? middlewareOptions?.unsupportedModelBehavior ?? DEFAULT_UNSUPPORTED_MODEL_BEHAVIOR;
174
+ if (!enableCaching || !request.model) return handler(request);
175
+ const modelName = request.model.getName();
176
+ const isBedrockConverseModel = modelName === "ChatBedrockConverse" || modelName === "ConfigurableModel" && (request.model._defaultConfig?.modelProvider === "bedrock" || request.model._defaultConfig?.modelProvider === "aws");
177
+ const modelId = modelName === "ConfigurableModel" ? request.model._defaultConfig?.model : request.model.model;
178
+ if (!(isBedrockConverseModel && typeof modelId === "string" && (modelId.toLowerCase().includes("anthropic.claude") || modelId.toLowerCase().includes("amazon.nova")))) {
179
+ const modelInfo = modelName === "ConfigurableModel" ? `${modelName} (${request.model._defaultConfig?.modelProvider})` : modelName;
180
+ const baseMessage = isBedrockConverseModel ? `Unsupported model '${modelInfo}'. Bedrock prompt caching is only supported on Anthropic Claude and Amazon Nova models` : `Unsupported model '${modelInfo}'. Prompt caching requires an AWS Bedrock Converse model`;
181
+ if (unsupportedModelBehavior === "raise") throw new BedrockPromptCachingMiddlewareError(`${baseMessage} (e.g., 'bedrock:anthropic.claude-haiku-4-5-20251001-v1:0').`);
182
+ else if (unsupportedModelBehavior === "warn") console.warn(`BedrockPromptCachingMiddleware: Skipping caching for ${modelName}. Consider switching to an Anthropic Claude or Amazon Nova model for caching benefits.`);
183
+ return handler(request);
184
+ }
185
+ if (request.state.messages.length + (request.systemPrompt ? 1 : 0) < minMessagesToCache) return handler(request);
186
+ /**
187
+ * The cache_control is applied at the final message formatting layer in
188
+ * ChatBedrockConverse (translated into Converse `cachePoint` blocks).
189
+ *
190
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html
191
+ */
192
+ return handler({
193
+ ...request,
194
+ modelSettings: {
195
+ ...request.modelSettings,
196
+ cache_control: {
197
+ type: "ephemeral",
198
+ ttl
199
+ }
200
+ }
201
+ });
202
+ }
203
+ });
204
+ }
205
+ //#endregion
206
+ export { bedrockPromptCachingMiddleware };
207
+
208
+ //# sourceMappingURL=promptCaching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptCaching.js","names":[],"sources":["../../../../../src/agents/middleware/provider/aws/promptCaching.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\n\nimport type { ConfigurableModel } from \"../../../../chat_models/universal.js\";\nimport { createMiddleware } from \"../../../middleware.js\";\n\nconst DEFAULT_ENABLE_CACHING = true;\nconst DEFAULT_TTL = \"5m\";\nconst DEFAULT_MIN_MESSAGES_TO_CACHE = 1;\nconst DEFAULT_UNSUPPORTED_MODEL_BEHAVIOR = \"warn\";\n\nconst contextSchema = z.object({\n /**\n * Whether to enable prompt caching.\n * @default true\n */\n enableCaching: z.boolean().optional(),\n /**\n * The time-to-live for the cached prompt.\n * @default \"5m\"\n */\n ttl: z.enum([\"5m\", \"1h\"]).optional(),\n /**\n * The minimum number of messages required before caching is applied.\n * @default 1\n */\n minMessagesToCache: z.number().optional(),\n /**\n * The behavior to take when an unsupported model is used.\n * - \"ignore\" will ignore the unsupported model and continue without caching.\n * - \"warn\" will warn the user and continue without caching.\n * - \"raise\" will raise an error and stop the agent.\n * @default \"warn\"\n */\n unsupportedModelBehavior: z.enum([\"ignore\", \"warn\", \"raise\"]).optional(),\n});\nexport type BedrockConversePromptCachingMiddlewareConfig = Partial<\n InferInteropZodInput<typeof contextSchema>\n>;\n\nclass BedrockPromptCachingMiddlewareError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BedrockPromptCachingMiddlewareError\";\n }\n}\n\n/**\n * Creates a prompt caching middleware for AWS Bedrock Converse models to optimize API usage.\n *\n * This middleware automatically enables Bedrock's prompt caching when using AWS Bedrock Converse\n * models. This can significantly reduce costs for applications with repetitive prompts, long\n * system messages, or extensive conversation histories.\n *\n * ## How It Works\n *\n * The middleware intercepts model requests and sets a cache control signal that\n * `ChatBedrockConverse` translates into Bedrock `cachePoint` breakpoints. Cache points are\n * inserted after the system prompt, after the tool definitions, and after the final message, so\n * the stable prefix of each request is cached. On subsequent requests with a matching prefix, the\n * cached representations are reused, skipping redundant token processing. Exact placement varies\n * by model (e.g. Amazon Nova models cache fewer breakpoints and ignore the `\"1h\"` TTL).\n *\n * ## Benefits\n *\n * - **Cost Reduction**: Avoid reprocessing the same tokens repeatedly\n * - **Lower Latency**: Cached prompts are processed faster as embeddings are pre-computed\n * - **Better Scalability**: Reduced computational load enables handling more requests\n * - **Consistent Performance**: Stable response times for repetitive queries\n *\n * @param middlewareOptions - Configuration options for the caching behavior\n * @param middlewareOptions.enableCaching - Whether to enable prompt caching (default: `true`)\n * @param middlewareOptions.ttl - Cache time-to-live: `\"5m\"` for 5 minutes or `\"1h\"` for 1 hour (default: `\"5m\"`)\n * @param middlewareOptions.minMessagesToCache - Minimum number of messages required before caching is applied (default: `1`)\n * @param middlewareOptions.unsupportedModelBehavior - The behavior to take when an unsupported model is used (default: `\"warn\"`)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {Error} When `unsupportedModelBehavior` is `\"raise\"` and the model is not a\n * cache-capable Bedrock Converse model — either a non-Bedrock provider, or a Bedrock\n * Converse model outside the Anthropic Claude / Amazon Nova families.\n *\n * @example\n * Basic usage with default settings\n * ```typescript\n * import { createAgent } from \"langchain\";\n * import { bedrockPromptCachingMiddleware } from \"langchain\";\n *\n * const agent = createAgent({\n * model: \"bedrock:anthropic.claude-haiku-4-5-20251001-v1:0\",\n * middleware: [\n * bedrockPromptCachingMiddleware()\n * ]\n * });\n * ```\n *\n * @example\n * Custom configuration for longer conversations\n * ```typescript\n * const cachingMiddleware = bedrockPromptCachingMiddleware({\n * ttl: \"1h\", // Cache for 1 hour instead of default 5 minutes\n * minMessagesToCache: 5 // Only cache after 5 messages\n * });\n *\n * const agent = createAgent({\n * model: \"bedrock:anthropic.claude-haiku-4-5-20251001-v1:0\",\n * systemPrompt: \"You are a helpful assistant with deep knowledge of...\", // Long system prompt\n * middleware: [cachingMiddleware]\n * });\n * ```\n *\n * @example\n * Conditional caching based on runtime context\n * ```typescript\n * const agent = createAgent({\n * model: \"bedrock:anthropic.claude-haiku-4-5-20251001-v1:0\",\n * middleware: [\n * bedrockPromptCachingMiddleware({\n * enableCaching: true,\n * ttl: \"5m\"\n * })\n * ]\n * });\n *\n * // Disable caching for specific requests\n * await agent.invoke(\n * { messages: [new HumanMessage(\"Process this without caching\")] },\n * {\n * configurable: {\n * middleware_context: { enableCaching: false }\n * }\n * }\n * );\n * ```\n *\n * @example\n * Optimal setup for customer support chatbot\n * ```typescript\n * const supportAgent = createAgent({\n * model: \"bedrock:anthropic.claude-haiku-4-5-20251001-v1:0\",\n * systemPrompt: `You are a customer support agent for ACME Corp.\n *\n * Company policies:\n * - Always be polite and professional\n * - Refer to knowledge base for product information\n * - Escalate billing issues to human agents\n * ... (extensive policies and guidelines)\n * `,\n * tools: [searchKnowledgeBase, createTicket, checkOrderStatus],\n * middleware: [\n * bedrockPromptCachingMiddleware({\n * ttl: \"1h\", // Long TTL for stable system prompt\n * minMessagesToCache: 1 // Cache immediately due to large system prompt\n * })\n * ]\n * });\n * ```\n *\n * @remarks\n * - **Bedrock Converse Only**: This middleware only applies caching to AWS Bedrock Converse models. Other providers are handled per `unsupportedModelBehavior`\n * - **Supported Families**: Bedrock prompt caching is only available on the **Anthropic Claude** and **Amazon Nova** model families. Other Bedrock Converse models (e.g. Mistral, Cohere, Meta) reject cache points at request time, so they are treated as unsupported and routed through `unsupportedModelBehavior`\n * - **Automatic Application**: Caching is applied automatically when the message count reaches `minMessagesToCache`\n * - **TTL Options**: Only supports \"5m\" (5 minutes) and \"1h\" (1 hour) as TTL values; actual support varies by model\n * - **Best Use Cases**: Long system prompts, multi-turn conversations, repetitive queries, RAG applications\n *\n * @see {@link createAgent} for agent creation\n * @see {@link https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html} AWS Bedrock prompt caching documentation\n * @public\n */\nexport function bedrockPromptCachingMiddleware(\n middlewareOptions?: BedrockConversePromptCachingMiddlewareConfig\n) {\n return createMiddleware({\n name: \"BedrockPromptCachingMiddleware\",\n contextSchema,\n wrapModelCall: (request, handler) => {\n const enableCaching =\n request.runtime.context.enableCaching ??\n middlewareOptions?.enableCaching ??\n DEFAULT_ENABLE_CACHING;\n const ttl =\n request.runtime.context.ttl ?? middlewareOptions?.ttl ?? DEFAULT_TTL;\n const minMessagesToCache =\n request.runtime.context.minMessagesToCache ??\n middlewareOptions?.minMessagesToCache ??\n DEFAULT_MIN_MESSAGES_TO_CACHE;\n const unsupportedModelBehavior =\n request.runtime.context.unsupportedModelBehavior ??\n middlewareOptions?.unsupportedModelBehavior ??\n DEFAULT_UNSUPPORTED_MODEL_BEHAVIOR;\n\n // Skip if caching is disabled\n if (!enableCaching || !request.model) {\n return handler(request);\n }\n\n const modelName = request.model.getName();\n const isBedrockConverseModel =\n modelName === \"ChatBedrockConverse\" ||\n (modelName === \"ConfigurableModel\" &&\n ((request.model as ConfigurableModel)._defaultConfig\n ?.modelProvider === \"bedrock\" ||\n (request.model as ConfigurableModel)._defaultConfig\n ?.modelProvider === \"aws\"));\n\n // Resolve the underlying Bedrock model id for cache-capability detection.\n const modelId =\n modelName === \"ConfigurableModel\"\n ? ((request.model as ConfigurableModel)._defaultConfig?.model as\n | string\n | undefined)\n : (request.model as { model?: string }).model;\n\n // Bedrock prompt caching is only supported on the Anthropic Claude and\n // Amazon Nova model families. Other Converse models (Mistral, Cohere,\n // Meta, etc.) reject `cachePoint` blocks with an AccessDeniedException, so\n // they are treated as unsupported.\n const isCacheCapableModel =\n isBedrockConverseModel &&\n typeof modelId === \"string\" &&\n (modelId.toLowerCase().includes(\"anthropic.claude\") ||\n modelId.toLowerCase().includes(\"amazon.nova\"));\n\n if (!isCacheCapableModel) {\n const modelInfo =\n modelName === \"ConfigurableModel\"\n ? `${modelName} (${\n (request.model as ConfigurableModel)._defaultConfig\n ?.modelProvider\n })`\n : modelName;\n\n const baseMessage = isBedrockConverseModel\n ? `Unsupported model '${modelInfo}'. Bedrock prompt caching is only supported on Anthropic Claude and Amazon Nova models`\n : `Unsupported model '${modelInfo}'. Prompt caching requires an AWS Bedrock Converse model`;\n\n if (unsupportedModelBehavior === \"raise\") {\n throw new BedrockPromptCachingMiddlewareError(\n `${baseMessage} (e.g., 'bedrock:anthropic.claude-haiku-4-5-20251001-v1:0').`\n );\n } else if (unsupportedModelBehavior === \"warn\") {\n console.warn(\n `BedrockPromptCachingMiddleware: Skipping caching for ${modelName}. Consider switching to an Anthropic Claude or Amazon Nova model for caching benefits.`\n );\n }\n return handler(request);\n }\n\n const messagesCount =\n request.state.messages.length + (request.systemPrompt ? 1 : 0);\n\n if (messagesCount < minMessagesToCache) {\n return handler(request);\n }\n\n /**\n * The cache_control is applied at the final message formatting layer in\n * ChatBedrockConverse (translated into Converse `cachePoint` blocks).\n *\n * @see https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html\n */\n return handler({\n ...request,\n modelSettings: {\n ...request.modelSettings,\n cache_control: {\n type: \"ephemeral\" as const,\n ttl,\n },\n },\n });\n },\n });\n}\n"],"mappings":";;;AAMA,MAAM,yBAAyB;AAC/B,MAAM,cAAc;AACpB,MAAM,gCAAgC;AACtC,MAAM,qCAAqC;AAE3C,MAAM,gBAAgB,EAAE,OAAO;;;;;CAK7B,eAAe,EAAE,SAAS,CAAC,UAAU;;;;;CAKrC,KAAK,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,UAAU;;;;;CAKpC,oBAAoB,EAAE,QAAQ,CAAC,UAAU;;;;;;;;CAQzC,0BAA0B,EAAE,KAAK;EAAC;EAAU;EAAQ;EAAQ,CAAC,CAAC,UAAU;CACzE,CAAC;AAKF,IAAM,sCAAN,cAAkD,MAAM;CACtD,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8HhB,SAAgB,+BACd,mBACA;AACA,QAAO,iBAAiB;EACtB,MAAM;EACN;EACA,gBAAgB,SAAS,YAAY;GACnC,MAAM,gBACJ,QAAQ,QAAQ,QAAQ,iBACxB,mBAAmB,iBACnB;GACF,MAAM,MACJ,QAAQ,QAAQ,QAAQ,OAAO,mBAAmB,OAAO;GAC3D,MAAM,qBACJ,QAAQ,QAAQ,QAAQ,sBACxB,mBAAmB,sBACnB;GACF,MAAM,2BACJ,QAAQ,QAAQ,QAAQ,4BACxB,mBAAmB,4BACnB;AAGF,OAAI,CAAC,iBAAiB,CAAC,QAAQ,MAC7B,QAAO,QAAQ,QAAQ;GAGzB,MAAM,YAAY,QAAQ,MAAM,SAAS;GACzC,MAAM,yBACJ,cAAc,yBACb,cAAc,wBACX,QAAQ,MAA4B,gBAClC,kBAAkB,aACnB,QAAQ,MAA4B,gBACjC,kBAAkB;GAG5B,MAAM,UACJ,cAAc,sBACR,QAAQ,MAA4B,gBAAgB,QAGrD,QAAQ,MAA6B;AAY5C,OAAI,EALF,0BACA,OAAO,YAAY,aAClB,QAAQ,aAAa,CAAC,SAAS,mBAAmB,IACjD,QAAQ,aAAa,CAAC,SAAS,cAAc,IAEvB;IACxB,MAAM,YACJ,cAAc,sBACV,GAAG,UAAU,IACV,QAAQ,MAA4B,gBACjC,cACL,KACD;IAEN,MAAM,cAAc,yBAChB,sBAAsB,UAAU,0FAChC,sBAAsB,UAAU;AAEpC,QAAI,6BAA6B,QAC/B,OAAM,IAAI,oCACR,GAAG,YAAY,8DAChB;aACQ,6BAA6B,OACtC,SAAQ,KACN,wDAAwD,UAAU,wFACnE;AAEH,WAAO,QAAQ,QAAQ;;AAMzB,OAFE,QAAQ,MAAM,SAAS,UAAU,QAAQ,eAAe,IAAI,KAE1C,mBAClB,QAAO,QAAQ,QAAQ;;;;;;;AASzB,UAAO,QAAQ;IACb,GAAG;IACH,eAAe;KACb,GAAG,QAAQ;KACX,eAAe;MACb,MAAM;MACN;MACD;KACF;IACF,CAAC;;EAEL,CAAC"}
@@ -75,7 +75,7 @@ function toolEmulatorMiddleware(options = {}) {
75
75
  console.error("Error initializing emulator model, using agent model:", err);
76
76
  return agentModel;
77
77
  });
78
- return emulatorModel;
78
+ return emulatorModel ?? agentModel;
79
79
  }
80
80
  return agentModel;
81
81
  };
@@ -1 +1 @@
1
- {"version":3,"file":"toolEmulator.cjs","names":["initChatModel","createMiddleware","HumanMessage","ToolMessage"],"sources":["../../../src/agents/middleware/toolEmulator.ts"],"sourcesContent":["import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport function toolEmulatorMiddleware(options: ToolEmulatorOptions = {}) {\n let agentModel: BaseChatModel | undefined;\n const { tools, model } = options;\n\n /**\n * Extract tool names from tools\n */\n const emulateAll = !tools || tools.length === 0;\n const toolsToEmulate = new Set<string>();\n\n if (!emulateAll && tools) {\n for (const tool of tools) {\n if (typeof tool === \"string\") {\n toolsToEmulate.add(tool);\n } else {\n // Assume tool instance with .name property\n const toolName =\n typeof tool.name === \"string\" ? tool.name : String(tool.name);\n toolsToEmulate.add(toolName);\n }\n }\n }\n\n /**\n * Initialize emulator model\n * We'll initialize it lazily in wrapToolCall to handle async initChatModel\n */\n let emulatorModel: BaseChatModel | undefined;\n const getEmulatorModel = async (): Promise<BaseChatModel> => {\n if (typeof model === \"object\") {\n return model;\n }\n if (typeof model === \"string\") {\n emulatorModel =\n emulatorModel ??\n (await initChatModel(model, { temperature: 1 }).catch((err) => {\n console.error(\n \"Error initializing emulator model, using agent model:\",\n err\n );\n return agentModel as BaseChatModel;\n }));\n return emulatorModel;\n }\n return agentModel as BaseChatModel;\n };\n\n return createMiddleware({\n name: \"ToolEmulatorMiddleware\",\n wrapModelCall: async (request, handler) => {\n agentModel = request.model as BaseChatModel;\n return handler(request);\n },\n wrapToolCall: async (request, handler) => {\n const toolName = request.toolCall.name;\n\n // Check if this tool should be emulated\n const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);\n\n if (!shouldEmulate) {\n // Let it execute normally by calling the handler\n return handler(request);\n }\n\n // Extract tool information for emulation\n const toolArgs = request.toolCall.args;\n const toolDescription =\n request.tool?.description || \"No description available\";\n\n // Build prompt for emulator LLM\n const toolArgsString =\n typeof toolArgs === \"string\" ? toolArgs : JSON.stringify(toolArgs);\n const prompt = `You are emulating a tool call for testing purposes.\n\nTool: ${toolName}\nDescription: ${toolDescription}\nArguments: ${toolArgsString}\n\nGenerate a realistic response that this tool would return given these arguments.\nReturn ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;\n\n // Get emulated response from LLM\n const emulator = await getEmulatorModel();\n const response = await emulator.invoke([new HumanMessage(prompt)]);\n\n // Extract content from response\n const content =\n typeof response.content === \"string\"\n ? response.content\n : JSON.stringify(response.content);\n\n // Short-circuit: return emulated result without executing real tool\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n name: toolName,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,uBAAuB,UAA+B,EAAE,EAAE;CACxE,IAAI;CACJ,MAAM,EAAE,OAAO,UAAU;;;;CAKzB,MAAM,aAAa,CAAC,SAAS,MAAM,WAAW;CAC9C,MAAM,iCAAiB,IAAI,KAAa;AAExC,KAAI,CAAC,cAAc,MACjB,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,SAClB,gBAAe,IAAI,KAAK;MACnB;EAEL,MAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK;AAC/D,iBAAe,IAAI,SAAS;;;;;;CASlC,IAAI;CACJ,MAAM,mBAAmB,YAAoC;AAC3D,MAAI,OAAO,UAAU,SACnB,QAAO;AAET,MAAI,OAAO,UAAU,UAAU;AAC7B,mBACE,iBACC,MAAMA,8BAAAA,cAAc,OAAO,EAAE,aAAa,GAAG,CAAC,CAAC,OAAO,QAAQ;AAC7D,YAAQ,MACN,yDACA,IACD;AACD,WAAO;KACP;AACJ,UAAO;;AAET,SAAO;;AAGT,QAAOC,mBAAAA,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;AACzC,gBAAa,QAAQ;AACrB,UAAO,QAAQ,QAAQ;;EAEzB,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,SAAS;AAKlC,OAAI,EAFkB,cAAc,eAAe,IAAI,SAAS,EAI9D,QAAO,QAAQ,QAAQ;GAIzB,MAAM,WAAW,QAAQ,SAAS;GAOlC,MAAM,SAAS;;QAEb,SAAS;eAPT,QAAQ,MAAM,eAAe,2BAQN;aAJvB,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS,CAK9C;;;;GAOtB,MAAM,WAAW,OAAM,MADA,kBAAkB,EACT,OAAO,CAAC,IAAIC,yBAAAA,aAAa,OAAO,CAAC,CAAC;AASlE,UAAO,IAAIC,yBAAAA,YAAY;IACrB,SANA,OAAO,SAAS,YAAY,WACxB,SAAS,UACT,KAAK,UAAU,SAAS,QAAQ;IAKpC,cAAc,QAAQ,SAAS,MAAM;IACrC,MAAM;IACP,CAAC;;EAEL,CAAC"}
1
+ {"version":3,"file":"toolEmulator.cjs","names":["initChatModel","createMiddleware","HumanMessage","ToolMessage"],"sources":["../../../src/agents/middleware/toolEmulator.ts"],"sourcesContent":["import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport function toolEmulatorMiddleware(options: ToolEmulatorOptions = {}) {\n let agentModel: BaseChatModel | undefined;\n const { tools, model } = options;\n\n /**\n * Extract tool names from tools\n */\n const emulateAll = !tools || tools.length === 0;\n const toolsToEmulate = new Set<string>();\n\n if (!emulateAll && tools) {\n for (const tool of tools) {\n if (typeof tool === \"string\") {\n toolsToEmulate.add(tool);\n } else {\n // Assume tool instance with .name property\n const toolName =\n typeof tool.name === \"string\" ? tool.name : String(tool.name);\n toolsToEmulate.add(toolName);\n }\n }\n }\n\n /**\n * Initialize emulator model\n * We'll initialize it lazily in wrapToolCall to handle async initChatModel\n */\n let emulatorModel: BaseChatModel | undefined;\n const getEmulatorModel = async (): Promise<BaseChatModel> => {\n if (typeof model === \"object\") {\n return model;\n }\n if (typeof model === \"string\") {\n emulatorModel =\n emulatorModel ??\n (await initChatModel(model, { temperature: 1 }).catch((err) => {\n console.error(\n \"Error initializing emulator model, using agent model:\",\n err\n );\n return agentModel as BaseChatModel;\n }));\n return emulatorModel ?? (agentModel as BaseChatModel);\n }\n return agentModel as BaseChatModel;\n };\n\n return createMiddleware({\n name: \"ToolEmulatorMiddleware\",\n wrapModelCall: async (request, handler) => {\n agentModel = request.model as BaseChatModel;\n return handler(request);\n },\n wrapToolCall: async (request, handler) => {\n const toolName = request.toolCall.name;\n\n // Check if this tool should be emulated\n const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);\n\n if (!shouldEmulate) {\n // Let it execute normally by calling the handler\n return handler(request);\n }\n\n // Extract tool information for emulation\n const toolArgs = request.toolCall.args;\n const toolDescription =\n request.tool?.description || \"No description available\";\n\n // Build prompt for emulator LLM\n const toolArgsString =\n typeof toolArgs === \"string\" ? toolArgs : JSON.stringify(toolArgs);\n const prompt = `You are emulating a tool call for testing purposes.\n\nTool: ${toolName}\nDescription: ${toolDescription}\nArguments: ${toolArgsString}\n\nGenerate a realistic response that this tool would return given these arguments.\nReturn ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;\n\n // Get emulated response from LLM\n const emulator = await getEmulatorModel();\n const response = await emulator.invoke([new HumanMessage(prompt)]);\n\n // Extract content from response\n const content =\n typeof response.content === \"string\"\n ? response.content\n : JSON.stringify(response.content);\n\n // Short-circuit: return emulated result without executing real tool\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n name: toolName,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,uBAAuB,UAA+B,EAAE,EAAE;CACxE,IAAI;CACJ,MAAM,EAAE,OAAO,UAAU;;;;CAKzB,MAAM,aAAa,CAAC,SAAS,MAAM,WAAW;CAC9C,MAAM,iCAAiB,IAAI,KAAa;AAExC,KAAI,CAAC,cAAc,MACjB,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,SAClB,gBAAe,IAAI,KAAK;MACnB;EAEL,MAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK;AAC/D,iBAAe,IAAI,SAAS;;;;;;CASlC,IAAI;CACJ,MAAM,mBAAmB,YAAoC;AAC3D,MAAI,OAAO,UAAU,SACnB,QAAO;AAET,MAAI,OAAO,UAAU,UAAU;AAC7B,mBACE,iBACC,MAAMA,8BAAAA,cAAc,OAAO,EAAE,aAAa,GAAG,CAAC,CAAC,OAAO,QAAQ;AAC7D,YAAQ,MACN,yDACA,IACD;AACD,WAAO;KACP;AACJ,UAAO,iBAAkB;;AAE3B,SAAO;;AAGT,QAAOC,mBAAAA,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;AACzC,gBAAa,QAAQ;AACrB,UAAO,QAAQ,QAAQ;;EAEzB,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,SAAS;AAKlC,OAAI,EAFkB,cAAc,eAAe,IAAI,SAAS,EAI9D,QAAO,QAAQ,QAAQ;GAIzB,MAAM,WAAW,QAAQ,SAAS;GAOlC,MAAM,SAAS;;QAEb,SAAS;eAPT,QAAQ,MAAM,eAAe,2BAQN;aAJvB,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS,CAK9C;;;;GAOtB,MAAM,WAAW,OAAM,MADA,kBAAkB,EACT,OAAO,CAAC,IAAIC,yBAAAA,aAAa,OAAO,CAAC,CAAC;AASlE,UAAO,IAAIC,yBAAAA,YAAY;IACrB,SANA,OAAO,SAAS,YAAY,WACxB,SAAS,UACT,KAAK,UAAU,SAAS,QAAQ;IAKpC,cAAc,QAAQ,SAAS,MAAM;IACrC,MAAM;IACP,CAAC;;EAEL,CAAC"}
@@ -74,7 +74,7 @@ function toolEmulatorMiddleware(options = {}) {
74
74
  console.error("Error initializing emulator model, using agent model:", err);
75
75
  return agentModel;
76
76
  });
77
- return emulatorModel;
77
+ return emulatorModel ?? agentModel;
78
78
  }
79
79
  return agentModel;
80
80
  };
@@ -1 +1 @@
1
- {"version":3,"file":"toolEmulator.js","names":[],"sources":["../../../src/agents/middleware/toolEmulator.ts"],"sourcesContent":["import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport function toolEmulatorMiddleware(options: ToolEmulatorOptions = {}) {\n let agentModel: BaseChatModel | undefined;\n const { tools, model } = options;\n\n /**\n * Extract tool names from tools\n */\n const emulateAll = !tools || tools.length === 0;\n const toolsToEmulate = new Set<string>();\n\n if (!emulateAll && tools) {\n for (const tool of tools) {\n if (typeof tool === \"string\") {\n toolsToEmulate.add(tool);\n } else {\n // Assume tool instance with .name property\n const toolName =\n typeof tool.name === \"string\" ? tool.name : String(tool.name);\n toolsToEmulate.add(toolName);\n }\n }\n }\n\n /**\n * Initialize emulator model\n * We'll initialize it lazily in wrapToolCall to handle async initChatModel\n */\n let emulatorModel: BaseChatModel | undefined;\n const getEmulatorModel = async (): Promise<BaseChatModel> => {\n if (typeof model === \"object\") {\n return model;\n }\n if (typeof model === \"string\") {\n emulatorModel =\n emulatorModel ??\n (await initChatModel(model, { temperature: 1 }).catch((err) => {\n console.error(\n \"Error initializing emulator model, using agent model:\",\n err\n );\n return agentModel as BaseChatModel;\n }));\n return emulatorModel;\n }\n return agentModel as BaseChatModel;\n };\n\n return createMiddleware({\n name: \"ToolEmulatorMiddleware\",\n wrapModelCall: async (request, handler) => {\n agentModel = request.model as BaseChatModel;\n return handler(request);\n },\n wrapToolCall: async (request, handler) => {\n const toolName = request.toolCall.name;\n\n // Check if this tool should be emulated\n const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);\n\n if (!shouldEmulate) {\n // Let it execute normally by calling the handler\n return handler(request);\n }\n\n // Extract tool information for emulation\n const toolArgs = request.toolCall.args;\n const toolDescription =\n request.tool?.description || \"No description available\";\n\n // Build prompt for emulator LLM\n const toolArgsString =\n typeof toolArgs === \"string\" ? toolArgs : JSON.stringify(toolArgs);\n const prompt = `You are emulating a tool call for testing purposes.\n\nTool: ${toolName}\nDescription: ${toolDescription}\nArguments: ${toolArgsString}\n\nGenerate a realistic response that this tool would return given these arguments.\nReturn ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;\n\n // Get emulated response from LLM\n const emulator = await getEmulatorModel();\n const response = await emulator.invoke([new HumanMessage(prompt)]);\n\n // Extract content from response\n const content =\n typeof response.content === \"string\"\n ? response.content\n : JSON.stringify(response.content);\n\n // Short-circuit: return emulated result without executing real tool\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n name: toolName,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,uBAAuB,UAA+B,EAAE,EAAE;CACxE,IAAI;CACJ,MAAM,EAAE,OAAO,UAAU;;;;CAKzB,MAAM,aAAa,CAAC,SAAS,MAAM,WAAW;CAC9C,MAAM,iCAAiB,IAAI,KAAa;AAExC,KAAI,CAAC,cAAc,MACjB,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,SAClB,gBAAe,IAAI,KAAK;MACnB;EAEL,MAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK;AAC/D,iBAAe,IAAI,SAAS;;;;;;CASlC,IAAI;CACJ,MAAM,mBAAmB,YAAoC;AAC3D,MAAI,OAAO,UAAU,SACnB,QAAO;AAET,MAAI,OAAO,UAAU,UAAU;AAC7B,mBACE,iBACC,MAAM,cAAc,OAAO,EAAE,aAAa,GAAG,CAAC,CAAC,OAAO,QAAQ;AAC7D,YAAQ,MACN,yDACA,IACD;AACD,WAAO;KACP;AACJ,UAAO;;AAET,SAAO;;AAGT,QAAO,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;AACzC,gBAAa,QAAQ;AACrB,UAAO,QAAQ,QAAQ;;EAEzB,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,SAAS;AAKlC,OAAI,EAFkB,cAAc,eAAe,IAAI,SAAS,EAI9D,QAAO,QAAQ,QAAQ;GAIzB,MAAM,WAAW,QAAQ,SAAS;GAOlC,MAAM,SAAS;;QAEb,SAAS;eAPT,QAAQ,MAAM,eAAe,2BAQN;aAJvB,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS,CAK9C;;;;GAOtB,MAAM,WAAW,OAAM,MADA,kBAAkB,EACT,OAAO,CAAC,IAAI,aAAa,OAAO,CAAC,CAAC;AASlE,UAAO,IAAI,YAAY;IACrB,SANA,OAAO,SAAS,YAAY,WACxB,SAAS,UACT,KAAK,UAAU,SAAS,QAAQ;IAKpC,cAAc,QAAQ,SAAS,MAAM;IACrC,MAAM;IACP,CAAC;;EAEL,CAAC"}
1
+ {"version":3,"file":"toolEmulator.js","names":[],"sources":["../../../src/agents/middleware/toolEmulator.ts"],"sourcesContent":["import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport function toolEmulatorMiddleware(options: ToolEmulatorOptions = {}) {\n let agentModel: BaseChatModel | undefined;\n const { tools, model } = options;\n\n /**\n * Extract tool names from tools\n */\n const emulateAll = !tools || tools.length === 0;\n const toolsToEmulate = new Set<string>();\n\n if (!emulateAll && tools) {\n for (const tool of tools) {\n if (typeof tool === \"string\") {\n toolsToEmulate.add(tool);\n } else {\n // Assume tool instance with .name property\n const toolName =\n typeof tool.name === \"string\" ? tool.name : String(tool.name);\n toolsToEmulate.add(toolName);\n }\n }\n }\n\n /**\n * Initialize emulator model\n * We'll initialize it lazily in wrapToolCall to handle async initChatModel\n */\n let emulatorModel: BaseChatModel | undefined;\n const getEmulatorModel = async (): Promise<BaseChatModel> => {\n if (typeof model === \"object\") {\n return model;\n }\n if (typeof model === \"string\") {\n emulatorModel =\n emulatorModel ??\n (await initChatModel(model, { temperature: 1 }).catch((err) => {\n console.error(\n \"Error initializing emulator model, using agent model:\",\n err\n );\n return agentModel as BaseChatModel;\n }));\n return emulatorModel ?? (agentModel as BaseChatModel);\n }\n return agentModel as BaseChatModel;\n };\n\n return createMiddleware({\n name: \"ToolEmulatorMiddleware\",\n wrapModelCall: async (request, handler) => {\n agentModel = request.model as BaseChatModel;\n return handler(request);\n },\n wrapToolCall: async (request, handler) => {\n const toolName = request.toolCall.name;\n\n // Check if this tool should be emulated\n const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);\n\n if (!shouldEmulate) {\n // Let it execute normally by calling the handler\n return handler(request);\n }\n\n // Extract tool information for emulation\n const toolArgs = request.toolCall.args;\n const toolDescription =\n request.tool?.description || \"No description available\";\n\n // Build prompt for emulator LLM\n const toolArgsString =\n typeof toolArgs === \"string\" ? toolArgs : JSON.stringify(toolArgs);\n const prompt = `You are emulating a tool call for testing purposes.\n\nTool: ${toolName}\nDescription: ${toolDescription}\nArguments: ${toolArgsString}\n\nGenerate a realistic response that this tool would return given these arguments.\nReturn ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;\n\n // Get emulated response from LLM\n const emulator = await getEmulatorModel();\n const response = await emulator.invoke([new HumanMessage(prompt)]);\n\n // Extract content from response\n const content =\n typeof response.content === \"string\"\n ? response.content\n : JSON.stringify(response.content);\n\n // Short-circuit: return emulated result without executing real tool\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n name: toolName,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,uBAAuB,UAA+B,EAAE,EAAE;CACxE,IAAI;CACJ,MAAM,EAAE,OAAO,UAAU;;;;CAKzB,MAAM,aAAa,CAAC,SAAS,MAAM,WAAW;CAC9C,MAAM,iCAAiB,IAAI,KAAa;AAExC,KAAI,CAAC,cAAc,MACjB,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,SAClB,gBAAe,IAAI,KAAK;MACnB;EAEL,MAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK;AAC/D,iBAAe,IAAI,SAAS;;;;;;CASlC,IAAI;CACJ,MAAM,mBAAmB,YAAoC;AAC3D,MAAI,OAAO,UAAU,SACnB,QAAO;AAET,MAAI,OAAO,UAAU,UAAU;AAC7B,mBACE,iBACC,MAAM,cAAc,OAAO,EAAE,aAAa,GAAG,CAAC,CAAC,OAAO,QAAQ;AAC7D,YAAQ,MACN,yDACA,IACD;AACD,WAAO;KACP;AACJ,UAAO,iBAAkB;;AAE3B,SAAO;;AAGT,QAAO,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;AACzC,gBAAa,QAAQ;AACrB,UAAO,QAAQ,QAAQ;;EAEzB,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,SAAS;AAKlC,OAAI,EAFkB,cAAc,eAAe,IAAI,SAAS,EAI9D,QAAO,QAAQ,QAAQ;GAIzB,MAAM,WAAW,QAAQ,SAAS;GAOlC,MAAM,SAAS;;QAEb,SAAS;eAPT,QAAQ,MAAM,eAAe,2BAQN;aAJvB,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS,CAK9C;;;;GAOtB,MAAM,WAAW,OAAM,MADA,kBAAkB,EACT,OAAO,CAAC,IAAI,aAAa,OAAO,CAAC,CAAC;AASlE,UAAO,IAAI,YAAY;IACrB,SANA,OAAO,SAAS,YAAY,WACxB,SAAS,UACT,KAAK,UAAU,SAAS,QAAQ;IAKpC,cAAc,QAAQ,SAAS,MAAM;IACrC,MAAM;IACP,CAAC;;EAEL,CAAC"}
@@ -1,7 +1,19 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");
1
+ require("../_virtual/_rolldown/runtime.cjs");
2
2
  let _langchain_core_messages = require("@langchain/core/messages");
3
3
  let _langchain_langgraph = require("@langchain/langgraph");
4
- //#region src/agents/transformers/tool-call.ts
4
+ //#region src/agents/stream.ts
5
+ /**
6
+ * Agent-level streaming support (experimental).
7
+ *
8
+ * Provides native stream transformer factories for tool calls and
9
+ * middleware events. When marked `__native: true`, their projections
10
+ * are assigned directly onto the `GraphRunStream` instance by
11
+ * `createGraphRunStream` in langgraph-core — no subclass or wrapper
12
+ * needed.
13
+ *
14
+ * See protocol proposal §15 (In-Process Streaming Interface) and §16
15
+ * (Native Stream Transformers).
16
+ */
5
17
  /**
6
18
  * Returns true when `ns` belongs to the agent's own graph — i.e. it
7
19
  * starts with `path` and is at most one level deeper (the agent's
@@ -161,4 +173,4 @@ function createToolCallTransformer(path) {
161
173
  //#endregion
162
174
  exports.createToolCallTransformer = createToolCallTransformer;
163
175
 
164
- //# sourceMappingURL=tool-call.cjs.map
176
+ //# sourceMappingURL=stream.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.cjs","names":["ToolMessage","StreamChannel"],"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":";;;;;;;;;;;;;;;;;;;;;;;;;AAqIA,SAAS,WAAW,IAAe,MAA0B;AAC3D,KAAI,GAAG,SAAS,KAAK,UAAU,GAAG,SAAS,KAAK,SAAS,EAAG,QAAO;AACnE,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,EACpC,KAAI,GAAG,OAAO,KAAK,GAAI,QAAO;AAEhC,QAAO;;AAGT,SAAS,6BACP,SACA,YACS;AACT,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,QAAQ;AAClC,MAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,SAAO,OAAO,MAAM,UAAU;AAC5B,OAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO;GACvD,MAAM,QAAS,MAA8B;AAC7C,OAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO;GACvD,MAAM,UAAU;AAIhB,UACE,QAAQ,SAAS,WAChB,cAAc,QACb,QAAQ,UAAU,MAAM,QACxB,QAAQ,SAAS,OAAO;IAE5B;SACI;AACN,SAAO;;;;;;;;;;;;;;;;;AAkBX,SAAS,wBACP,OAC6C;AAC7C,KAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO;CACvD,MAAM,SAAS;AACf,KAAI,OAAO,SAAS,iBAAiB,CAAC,MAAM,QAAQ,OAAO,GAAG,CAAE,QAAO;AACvE,QAAO,OAAO,GAAG,OAAO,GAAG,SAAS,OAAO;;AAG7C,SAAS,oBAAoB,QAA0B;AACrD,KAAIA,yBAAAA,YAAY,WAAW,OAAO,CAChC,QAAO,OAAO;AAEhB,KAAI,wBAAwB,OAAO,CACjC,QAAO,OAAO,QAAQ;AAExB,QAAO;;;;;;;;;AAUT,SAAgB,0BACd,MACmD;AACnD,cAAa;EACX,MAAM,eAAeC,qBAAAA,cAAc,OAAuB;EAE1D,MAAM,+BAAe,IAAI,KAQtB;EAEH,SAAS,oBACP,QACA,MACA,UACM;AACN,OAAI,aAAa,IAAI,OAAO,CAAE;GAC9B,MAAM,QACJ,OAAO,aAAa,WAAW,KAAK,MAAM,SAAS,GAAG;GAExD,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GAEJ,MAAM,SAAS,IAAI,SAAkB,KAAK,QAAQ;AAChD,oBAAgB;AAChB,mBAAe;KACf;GACF,MAAM,SAAS,IAAI,SAAyB,QAAQ;AAClD,oBAAgB;KAChB;GACF,MAAM,QAAQ,IAAI,SAA6B,QAAQ;AACrD,mBAAe;KACf;AAEF,gBAAa,IAAI,QAAQ;IACvB;IACA;IACA;IACA;IACD,CAAC;AAEF,gBAAa,KAAK;IAChB;IACA;IACA;IACA;IACA;IACA;IACD,CAAmB;;AAGtB,SAAO;GACL,UAAU;GAEV,aAAa,EACX,WAAW,cACZ;GAED,QAAQ,OAA+B;;;;AAIrC,QAAI,CAAC,WAAW,MAAM,OAAO,WAAW,KAAK,CAAE,QAAO;AAEtD,QAAI,MAAM,WAAW,YAAY;KAC/B,MAAM,OAAO,MAAM,OAAO;AAC1B,SAAI,KAAK,UAAU,wBAAwB;MACzC,MAAM,KAAM,KAAK,gBAAgB,KAAK;AAGtC,UAAI,IAAI,SAAS,YACf,qBACE,OAAO,GAAG,MAAM,GAAG,EACnB,OAAO,GAAG,QAAQ,GAAG,EACrB,GAAG,QAAQ,GAAG,MACf;;;AAKP,QAAI,MAAM,WAAW,SAAS;KAC5B,MAAM,OAAO,MAAM,OAAO;KAC1B,MAAM,aAAc,KACjB;AAEH,SAAI,KAAK,UAAU,eACjB,qBACE,YACE,KAAiC,aACjC,WACD,KAAiC,MACnC;KAGH,MAAM,UAAU,aAAa,aAAa,IAAI,WAAW,GAAG,KAAA;AAE5D,SAAI;UACE,KAAK,UAAU,iBAAiB;AAClC,eAAQ,cACN,oBAAqB,KAAiC,OAAO,CAC9D;AACD,eAAQ,cAAc,WAAW;AACjC,eAAQ,aAAa,KAAA,EAAU;AAC/B,oBAAa,OAAO,WAAW;iBACtB,KAAK,UAAU,cAAc;OACtC,MAAM,UACF,KAAiC,WACnC;AACF,WAAI,6BAA6B,SAAS,WAAW,CACnD,QAAO;AAET,eAAQ,aAAa,IAAI,MAAM,QAAQ,CAAC;AACxC,eAAQ,cAAc,QAAQ;AAC9B,eAAQ,aAAa,QAAQ;AAC7B,oBAAa,OAAO,WAAW;;;;AAKrC,WAAO;;GAGT,WAAiB;AACf,SAAK,MAAM,WAAW,aAAa,QAAQ,EAAE;AAC3C,aAAQ,cAAc,WAAW;AACjC,aAAQ,aAAa,KAAA,EAAU;AAC/B,aAAQ,cAAc,KAAA,EAAU;;AAElC,iBAAa,OAAO;AACpB,iBAAa,OAAO;;GAGtB,KAAK,KAAoB;AACvB,SAAK,MAAM,WAAW,aAAa,QAAQ,EAAE;AAC3C,aAAQ,cAAc,QAAQ;AAC9B,aAAQ,aACN,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CACjD;AACD,aAAQ,aAAa,IAAI;;AAE3B,iBAAa,OAAO;AACpB,iBAAa,KAAK,IAAI;;GAEzB"}
@@ -1,10 +1,11 @@
1
1
  import { ClientTool, DynamicStructuredTool, ServerTool, StructuredToolInterface } from "@langchain/core/tools";
2
- import { ChatModelStream, GraphRunStream, LifecycleCause, StreamTransformer, ToolCallStream } from "@langchain/langgraph";
2
+ import { GraphRunStream, Namespace, NativeStreamTransformer, StreamTransformer, ToolCallStream } from "@langchain/langgraph";
3
3
 
4
- //#region src/agents/transformers/types.d.ts
4
+ //#region src/agents/stream.d.ts
5
5
  /**
6
6
  * Infers the merged extensions shape from a tuple of stream transformer
7
- * factories.
7
+ * factories. Mirrors `InferExtensions` from `@langchain/langgraph`, which
8
+ * is not exported from the package's public surface.
8
9
  *
9
10
  * Given `[() => StreamTransformer<{ a: number }>, () => StreamTransformer<{ b: string }>]`,
10
11
  * produces `{ a: number } & { b: string }`.
@@ -27,41 +28,6 @@ type ToolOutputOf<T> = T extends DynamicStructuredTool<any, any, any, infer Tool
27
28
  * plain `(ClientTool | ServerTool)[]` without literal name types.
28
29
  */
29
30
  type ToolCallStreamUnion<TTools extends readonly (ClientTool | ServerTool)[]> = { [K in keyof TTools]: ToolCallStream<ToolNameOf<TTools[K]>, ToolInputOf<TTools[K]>, ToolOutputOf<TTools[K]>> }[number];
30
- /**
31
- * A nested named-agent execution surfaced on `run.subagents`.
32
- *
33
- * A subagent is a nested `createAgent` run whose `lc_agent_name` differs from
34
- * its parent's — e.g. a `createAgent({ name })` invoked inside a tool body. The
35
- * handle exposes scoped projections (`messages`, `toolCalls`, nested
36
- * `subagents`) plus the resolved {@link name}, the {@link cause} that triggered
37
- * it, and the subagent's final {@link output} state.
38
- *
39
- * This is a self-contained handle (no subclass of `SubgraphRunStream`): its
40
- * projections are produced by per-subagent transformer instances that
41
- * {@link createSubagentTransformer} drives directly.
42
- *
43
- * @typeParam TValues - Shape of the subagent's final output state.
44
- * @typeParam TTools - Tuple of tools the subagent may call, used to type
45
- * {@link toolCalls}.
46
- */
47
- interface SubagentRunStream<TValues = Record<string, unknown>, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[]> {
48
- /** The subagent's `lc_agent_name` (set by `createAgent({ name })`). */
49
- readonly name: string;
50
- /**
51
- * The tool call that dispatched this subagent, as
52
- * `{ type: "toolCall", tool_call_id }`, or `undefined` when the originating
53
- * tool call could not be recovered (e.g. it was not triggered from a tool).
54
- */
55
- readonly cause: LifecycleCause | undefined;
56
- /** Resolves with the subagent's final state once it completes. */
57
- readonly output: Promise<TValues>;
58
- /** Per-message chat-model token streams scoped to this subagent. */
59
- readonly messages: AsyncIterable<Omit<ChatModelStream, "then">>;
60
- /** The subagent's own tool-call streams. */
61
- readonly toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;
62
- /** Nested subagents this subagent dispatches from its own tools. */
63
- readonly subagents: AsyncIterable<SubagentRunStream>;
64
- }
65
31
  /**
66
32
  * A {@link GraphRunStream} with native agent-level projections assigned
67
33
  * directly on the instance by `createGraphRunStream` (via `__native`
@@ -74,22 +40,26 @@ interface SubagentRunStream<TValues = Record<string, unknown>, TTools extends re
74
40
  * @typeParam TValues - Shape of the graph's state values.
75
41
  * @typeParam TTools - Tuple of tools registered on the agent, used to type
76
42
  * the per-tool `toolCalls` discriminated union.
43
+ * @typeParam TMiddleware - Tuple of middleware registered on the agent, used
44
+ * to type the per-middleware `middleware` event union.
77
45
  * @typeParam TExtensions - Shape of `run.extensions` produced by user-supplied
78
46
  * stream transformer factories. Derived via
79
- * `InferStreamExtensions<TStreamTransformers>`.
47
+ * `InferExtensions<TStreamTransformers>`.
80
48
  */
81
49
  type AgentRunStream<TValues = Record<string, unknown>, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[], TExtensions extends Record<string, unknown> = Record<string, unknown>> = GraphRunStream<TValues, TExtensions> & {
82
50
  /** Tool call streams from the native ToolCallTransformer. */toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;
83
- /**
84
- * Named subagent runs dispatched from tools, surfaced by the native
85
- * {@link createSubagentTransformer}. Each yielded {@link SubagentRunStream}
86
- * is a nested `createAgent` run whose `lc_agent_name` differs from this
87
- * agent's — for example a `createAgent({ name })` invoked inside a tool body.
88
- * Unlike `run.subgraphs` (which also yields the agent's own internal nodes),
89
- * `run.subagents` only yields real named-agent invocations.
90
- */
91
- subagents: AsyncIterable<SubagentRunStream<TValues>>;
92
51
  };
52
+ interface ToolCallProjection {
53
+ toolCalls: AsyncIterable<ToolCallStream>;
54
+ }
55
+ /**
56
+ * Creates a native transformer that correlates `tools` channel events
57
+ * into per-call {@link ToolCallStream} objects.
58
+ *
59
+ * Marked `__native: true` — projection keys land directly on the
60
+ * `GraphRunStream` instance as `run.toolCalls`.
61
+ */
62
+ declare function createToolCallTransformer(path: Namespace): () => NativeStreamTransformer<ToolCallProjection>;
93
63
  //#endregion
94
- export { AgentRunStream, InferStreamExtensions, SubagentRunStream, ToolCallStreamUnion };
95
- //# sourceMappingURL=types.d.ts.map
64
+ export { AgentRunStream, InferStreamExtensions, ToolCallStreamUnion, createToolCallTransformer };
65
+ //# sourceMappingURL=stream.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.cts","names":[],"sources":["../../src/agents/stream.ts"],"mappings":";;;;;;;;;;;;KA0CY,qBAAA,WACA,aAAA,OAAoB,iBAAA,UAC5B,CAAA,uBACA,MAAA,kBACA,CAAA,yBACU,iBAAA,iCACgB,aAAA,OAAoB,iBAAA,UAE5C,CAAA,GAAI,qBAAA,CAAsB,IAAA,IAC1B,MAAA;;KAGD,UAAA,MAAgB,CAAA;EAAY,IAAA;AAAA,IAAiC,CAAA;;KAG7D,WAAA,MACH,CAAA,SAAU,qBAAA,gDACN,YAAA,GACA,CAAA,SAAU,uBAAA,iCACR,YAAA;;KAIH,YAAA,MACH,CAAA,SAAU,qBAAA,+CACN,WAAA,GACA,CAAA,SAAU,uBAAA,gCACR,WAAA;;;;;AAlBsB;;;;KA6BlB,mBAAA,0BACe,UAAA,GAAa,UAAA,qBAE1B,MAAA,GAAS,cAAA,CACnB,UAAA,CAAW,MAAA,CAAO,CAAA,IAClB,WAAA,CAAY,MAAA,CAAO,CAAA,IACnB,YAAA,CAAa,MAAA,CAAO,CAAA;;;;;AAhC2C;;;;;;;;;;;;;;KAsDvD,cAAA,WACA,MAAA,4CACe,UAAA,GAAa,UAAA,gBAClC,UAAA,GACA,UAAA,yBAEgB,MAAA,oBAA0B,MAAA,qBAC5C,cAAA,CAAe,OAAA,EAAS,WAAA;EAvDZ,6DAyDd,SAAA,EAAW,aAAA,CAAc,mBAAA,CAAoB,MAAA;AAAA;AAAA,UAGrC,kBAAA;EACR,SAAA,EAAW,aAAA,CAAc,cAAA;AAAA;;;;;;;;iBAuFX,yBAAA,CACd,IAAA,EAAM,SAAA,SACC,uBAAA,CAAwB,kBAAA"}
@@ -1,10 +1,11 @@
1
1
  import { ClientTool, DynamicStructuredTool, ServerTool, StructuredToolInterface } from "@langchain/core/tools";
2
- import { ChatModelStream, GraphRunStream, LifecycleCause, StreamTransformer, ToolCallStream } from "@langchain/langgraph";
2
+ import { GraphRunStream, Namespace, NativeStreamTransformer, StreamTransformer, ToolCallStream } from "@langchain/langgraph";
3
3
 
4
- //#region src/agents/transformers/types.d.ts
4
+ //#region src/agents/stream.d.ts
5
5
  /**
6
6
  * Infers the merged extensions shape from a tuple of stream transformer
7
- * factories.
7
+ * factories. Mirrors `InferExtensions` from `@langchain/langgraph`, which
8
+ * is not exported from the package's public surface.
8
9
  *
9
10
  * Given `[() => StreamTransformer<{ a: number }>, () => StreamTransformer<{ b: string }>]`,
10
11
  * produces `{ a: number } & { b: string }`.
@@ -27,41 +28,6 @@ type ToolOutputOf<T> = T extends DynamicStructuredTool<any, any, any, infer Tool
27
28
  * plain `(ClientTool | ServerTool)[]` without literal name types.
28
29
  */
29
30
  type ToolCallStreamUnion<TTools extends readonly (ClientTool | ServerTool)[]> = { [K in keyof TTools]: ToolCallStream<ToolNameOf<TTools[K]>, ToolInputOf<TTools[K]>, ToolOutputOf<TTools[K]>> }[number];
30
- /**
31
- * A nested named-agent execution surfaced on `run.subagents`.
32
- *
33
- * A subagent is a nested `createAgent` run whose `lc_agent_name` differs from
34
- * its parent's — e.g. a `createAgent({ name })` invoked inside a tool body. The
35
- * handle exposes scoped projections (`messages`, `toolCalls`, nested
36
- * `subagents`) plus the resolved {@link name}, the {@link cause} that triggered
37
- * it, and the subagent's final {@link output} state.
38
- *
39
- * This is a self-contained handle (no subclass of `SubgraphRunStream`): its
40
- * projections are produced by per-subagent transformer instances that
41
- * {@link createSubagentTransformer} drives directly.
42
- *
43
- * @typeParam TValues - Shape of the subagent's final output state.
44
- * @typeParam TTools - Tuple of tools the subagent may call, used to type
45
- * {@link toolCalls}.
46
- */
47
- interface SubagentRunStream<TValues = Record<string, unknown>, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[]> {
48
- /** The subagent's `lc_agent_name` (set by `createAgent({ name })`). */
49
- readonly name: string;
50
- /**
51
- * The tool call that dispatched this subagent, as
52
- * `{ type: "toolCall", tool_call_id }`, or `undefined` when the originating
53
- * tool call could not be recovered (e.g. it was not triggered from a tool).
54
- */
55
- readonly cause: LifecycleCause | undefined;
56
- /** Resolves with the subagent's final state once it completes. */
57
- readonly output: Promise<TValues>;
58
- /** Per-message chat-model token streams scoped to this subagent. */
59
- readonly messages: AsyncIterable<Omit<ChatModelStream, "then">>;
60
- /** The subagent's own tool-call streams. */
61
- readonly toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;
62
- /** Nested subagents this subagent dispatches from its own tools. */
63
- readonly subagents: AsyncIterable<SubagentRunStream>;
64
- }
65
31
  /**
66
32
  * A {@link GraphRunStream} with native agent-level projections assigned
67
33
  * directly on the instance by `createGraphRunStream` (via `__native`
@@ -74,22 +40,26 @@ interface SubagentRunStream<TValues = Record<string, unknown>, TTools extends re
74
40
  * @typeParam TValues - Shape of the graph's state values.
75
41
  * @typeParam TTools - Tuple of tools registered on the agent, used to type
76
42
  * the per-tool `toolCalls` discriminated union.
43
+ * @typeParam TMiddleware - Tuple of middleware registered on the agent, used
44
+ * to type the per-middleware `middleware` event union.
77
45
  * @typeParam TExtensions - Shape of `run.extensions` produced by user-supplied
78
46
  * stream transformer factories. Derived via
79
- * `InferStreamExtensions<TStreamTransformers>`.
47
+ * `InferExtensions<TStreamTransformers>`.
80
48
  */
81
49
  type AgentRunStream<TValues = Record<string, unknown>, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[], TExtensions extends Record<string, unknown> = Record<string, unknown>> = GraphRunStream<TValues, TExtensions> & {
82
50
  /** Tool call streams from the native ToolCallTransformer. */toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;
83
- /**
84
- * Named subagent runs dispatched from tools, surfaced by the native
85
- * {@link createSubagentTransformer}. Each yielded {@link SubagentRunStream}
86
- * is a nested `createAgent` run whose `lc_agent_name` differs from this
87
- * agent's — for example a `createAgent({ name })` invoked inside a tool body.
88
- * Unlike `run.subgraphs` (which also yields the agent's own internal nodes),
89
- * `run.subagents` only yields real named-agent invocations.
90
- */
91
- subagents: AsyncIterable<SubagentRunStream<TValues>>;
92
51
  };
52
+ interface ToolCallProjection {
53
+ toolCalls: AsyncIterable<ToolCallStream>;
54
+ }
55
+ /**
56
+ * Creates a native transformer that correlates `tools` channel events
57
+ * into per-call {@link ToolCallStream} objects.
58
+ *
59
+ * Marked `__native: true` — projection keys land directly on the
60
+ * `GraphRunStream` instance as `run.toolCalls`.
61
+ */
62
+ declare function createToolCallTransformer(path: Namespace): () => NativeStreamTransformer<ToolCallProjection>;
93
63
  //#endregion
94
- export { AgentRunStream, InferStreamExtensions, SubagentRunStream, ToolCallStreamUnion };
95
- //# sourceMappingURL=types.d.cts.map
64
+ export { AgentRunStream, InferStreamExtensions, ToolCallStreamUnion, createToolCallTransformer };
65
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","names":[],"sources":["../../src/agents/stream.ts"],"mappings":";;;;;;;;;;;;KA0CY,qBAAA,WACA,aAAA,OAAoB,iBAAA,UAC5B,CAAA,uBACA,MAAA,kBACA,CAAA,yBACU,iBAAA,iCACgB,aAAA,OAAoB,iBAAA,UAE5C,CAAA,GAAI,qBAAA,CAAsB,IAAA,IAC1B,MAAA;;KAGD,UAAA,MAAgB,CAAA;EAAY,IAAA;AAAA,IAAiC,CAAA;;KAG7D,WAAA,MACH,CAAA,SAAU,qBAAA,gDACN,YAAA,GACA,CAAA,SAAU,uBAAA,iCACR,YAAA;;KAIH,YAAA,MACH,CAAA,SAAU,qBAAA,+CACN,WAAA,GACA,CAAA,SAAU,uBAAA,gCACR,WAAA;;;;;AAlBsB;;;;KA6BlB,mBAAA,0BACe,UAAA,GAAa,UAAA,qBAE1B,MAAA,GAAS,cAAA,CACnB,UAAA,CAAW,MAAA,CAAO,CAAA,IAClB,WAAA,CAAY,MAAA,CAAO,CAAA,IACnB,YAAA,CAAa,MAAA,CAAO,CAAA;;;;;AAhC2C;;;;;;;;;;;;;;KAsDvD,cAAA,WACA,MAAA,4CACe,UAAA,GAAa,UAAA,gBAClC,UAAA,GACA,UAAA,yBAEgB,MAAA,oBAA0B,MAAA,qBAC5C,cAAA,CAAe,OAAA,EAAS,WAAA;EAvDZ,6DAyDd,SAAA,EAAW,aAAA,CAAc,mBAAA,CAAoB,MAAA;AAAA;AAAA,UAGrC,kBAAA;EACR,SAAA,EAAW,aAAA,CAAc,cAAA;AAAA;;;;;;;;iBAuFX,yBAAA,CACd,IAAA,EAAM,SAAA,SACC,uBAAA,CAAwB,kBAAA"}
@@ -1,6 +1,18 @@
1
1
  import { ToolMessage } from "@langchain/core/messages";
2
2
  import { StreamChannel } from "@langchain/langgraph";
3
- //#region src/agents/transformers/tool-call.ts
3
+ //#region src/agents/stream.ts
4
+ /**
5
+ * Agent-level streaming support (experimental).
6
+ *
7
+ * Provides native stream transformer factories for tool calls and
8
+ * middleware events. When marked `__native: true`, their projections
9
+ * are assigned directly onto the `GraphRunStream` instance by
10
+ * `createGraphRunStream` in langgraph-core — no subclass or wrapper
11
+ * needed.
12
+ *
13
+ * See protocol proposal §15 (In-Process Streaming Interface) and §16
14
+ * (Native Stream Transformers).
15
+ */
4
16
  /**
5
17
  * Returns true when `ns` belongs to the agent's own graph — i.e. it
6
18
  * starts with `path` and is at most one level deeper (the agent's
@@ -160,4 +172,4 @@ function createToolCallTransformer(path) {
160
172
  //#endregion
161
173
  export { createToolCallTransformer };
162
174
 
163
- //# sourceMappingURL=tool-call.js.map
175
+ //# sourceMappingURL=stream.js.map