@librechat/agents 3.6.9 → 3.6.11

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 (146) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +99 -39
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/agents/projection.cjs +2 -2
  4. package/dist/cjs/agents/projection.cjs.map +1 -1
  5. package/dist/cjs/graphs/Graph.cjs +32 -21
  6. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  7. package/dist/cjs/graphs/MultiAgentGraph.cjs +87 -16
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  9. package/dist/cjs/llm/openai/index.cjs +10 -0
  10. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  11. package/dist/cjs/main.cjs +16 -0
  12. package/dist/cjs/messages/alternation.cjs +125 -20
  13. package/dist/cjs/messages/alternation.cjs.map +1 -1
  14. package/dist/cjs/messages/core.cjs +195 -18
  15. package/dist/cjs/messages/core.cjs.map +1 -1
  16. package/dist/cjs/messages/format.cjs +488 -118
  17. package/dist/cjs/messages/format.cjs.map +1 -1
  18. package/dist/cjs/messages/handoffCue.cjs +3 -2
  19. package/dist/cjs/messages/handoffCue.cjs.map +1 -1
  20. package/dist/cjs/messages/index.cjs +1 -0
  21. package/dist/cjs/messages/injected.cjs +5 -2
  22. package/dist/cjs/messages/injected.cjs.map +1 -1
  23. package/dist/cjs/messages/provenance.cjs +411 -0
  24. package/dist/cjs/messages/provenance.cjs.map +1 -0
  25. package/dist/cjs/messages/prune.cjs +18 -13
  26. package/dist/cjs/messages/prune.cjs.map +1 -1
  27. package/dist/cjs/messages/toolResultTypes.cjs +663 -0
  28. package/dist/cjs/messages/toolResultTypes.cjs.map +1 -0
  29. package/dist/cjs/run.cjs +7 -4
  30. package/dist/cjs/run.cjs.map +1 -1
  31. package/dist/cjs/stream.cjs +1 -0
  32. package/dist/cjs/stream.cjs.map +1 -1
  33. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +21 -4
  34. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  35. package/dist/cjs/tools/CallerCapabilities.cjs +79 -0
  36. package/dist/cjs/tools/CallerCapabilities.cjs.map +1 -0
  37. package/dist/cjs/tools/ProgrammaticCallerPolicy.cjs +34 -0
  38. package/dist/cjs/tools/ProgrammaticCallerPolicy.cjs.map +1 -0
  39. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +21 -4
  40. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  41. package/dist/cjs/tools/ToolNode.cjs +39 -21
  42. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  43. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +12 -4
  44. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  45. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +13 -4
  46. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  47. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +73 -13
  48. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  49. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  50. package/dist/cjs/utils/toolContent.cjs +2 -2
  51. package/dist/cjs/utils/toolContent.cjs.map +1 -1
  52. package/dist/esm/agents/AgentContext.mjs +99 -39
  53. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  54. package/dist/esm/agents/projection.mjs +2 -2
  55. package/dist/esm/agents/projection.mjs.map +1 -1
  56. package/dist/esm/graphs/Graph.mjs +34 -23
  57. package/dist/esm/graphs/Graph.mjs.map +1 -1
  58. package/dist/esm/graphs/MultiAgentGraph.mjs +87 -16
  59. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  60. package/dist/esm/llm/openai/index.mjs +10 -0
  61. package/dist/esm/llm/openai/index.mjs.map +1 -1
  62. package/dist/esm/main.mjs +4 -3
  63. package/dist/esm/messages/alternation.mjs +125 -20
  64. package/dist/esm/messages/alternation.mjs.map +1 -1
  65. package/dist/esm/messages/core.mjs +196 -19
  66. package/dist/esm/messages/core.mjs.map +1 -1
  67. package/dist/esm/messages/format.mjs +488 -119
  68. package/dist/esm/messages/format.mjs.map +1 -1
  69. package/dist/esm/messages/handoffCue.mjs +3 -2
  70. package/dist/esm/messages/handoffCue.mjs.map +1 -1
  71. package/dist/esm/messages/index.mjs +1 -0
  72. package/dist/esm/messages/injected.mjs +5 -2
  73. package/dist/esm/messages/injected.mjs.map +1 -1
  74. package/dist/esm/messages/provenance.mjs +401 -0
  75. package/dist/esm/messages/provenance.mjs.map +1 -0
  76. package/dist/esm/messages/prune.mjs +18 -13
  77. package/dist/esm/messages/prune.mjs.map +1 -1
  78. package/dist/esm/messages/toolResultTypes.mjs +657 -0
  79. package/dist/esm/messages/toolResultTypes.mjs.map +1 -0
  80. package/dist/esm/run.mjs +7 -4
  81. package/dist/esm/run.mjs.map +1 -1
  82. package/dist/esm/stream.mjs +1 -0
  83. package/dist/esm/stream.mjs.map +1 -1
  84. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +21 -4
  85. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  86. package/dist/esm/tools/CallerCapabilities.mjs +73 -0
  87. package/dist/esm/tools/CallerCapabilities.mjs.map +1 -0
  88. package/dist/esm/tools/ProgrammaticCallerPolicy.mjs +32 -0
  89. package/dist/esm/tools/ProgrammaticCallerPolicy.mjs.map +1 -0
  90. package/dist/esm/tools/ProgrammaticToolCalling.mjs +21 -4
  91. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  92. package/dist/esm/tools/ToolNode.mjs +39 -21
  93. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  94. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +14 -6
  95. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  96. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +15 -6
  97. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  98. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +72 -15
  99. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  100. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  101. package/dist/esm/utils/toolContent.mjs +2 -2
  102. package/dist/esm/utils/toolContent.mjs.map +1 -1
  103. package/dist/types/agents/AgentContext.d.ts +19 -13
  104. package/dist/types/agents/projection.d.ts +3 -1
  105. package/dist/types/graphs/Graph.d.ts +1 -1
  106. package/dist/types/llm/openai/index.d.ts +20 -0
  107. package/dist/types/messages/format.d.ts +5 -0
  108. package/dist/types/messages/index.d.ts +1 -0
  109. package/dist/types/messages/provenance.d.ts +85 -0
  110. package/dist/types/messages/toolResultTypes.d.ts +33 -0
  111. package/dist/types/tools/CallerCapabilities.d.ts +25 -0
  112. package/dist/types/tools/ProgrammaticCallerPolicy.d.ts +20 -0
  113. package/dist/types/tools/ToolNode.d.ts +12 -7
  114. package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +10 -0
  115. package/dist/types/tools/ptcTimeout.d.ts +8 -0
  116. package/dist/types/types/graph.d.ts +3 -1
  117. package/dist/types/types/tools.d.ts +30 -2
  118. package/package.json +1 -1
  119. package/src/agents/AgentContext.ts +253 -69
  120. package/src/agents/projection.ts +9 -1
  121. package/src/graphs/Graph.ts +62 -26
  122. package/src/graphs/MultiAgentGraph.ts +175 -33
  123. package/src/llm/openai/index.ts +43 -0
  124. package/src/messages/alternation.ts +217 -34
  125. package/src/messages/core.ts +358 -38
  126. package/src/messages/format.ts +958 -137
  127. package/src/messages/handoffCue.ts +7 -4
  128. package/src/messages/index.ts +1 -0
  129. package/src/messages/injected.ts +9 -6
  130. package/src/messages/provenance.ts +897 -0
  131. package/src/messages/prune.ts +28 -10
  132. package/src/messages/toolResultTypes.ts +1174 -0
  133. package/src/run.ts +9 -4
  134. package/src/stream.ts +6 -0
  135. package/src/tools/BashProgrammaticToolCalling.ts +46 -12
  136. package/src/tools/CallerCapabilities.ts +146 -0
  137. package/src/tools/ProgrammaticCallerPolicy.ts +97 -0
  138. package/src/tools/ProgrammaticToolCalling.ts +41 -7
  139. package/src/tools/ToolNode.ts +111 -50
  140. package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +24 -26
  141. package/src/tools/local/LocalProgrammaticToolCalling.ts +28 -23
  142. package/src/tools/local/resolveLocalExecutionTools.ts +209 -16
  143. package/src/tools/ptcTimeout.ts +6 -0
  144. package/src/types/graph.ts +3 -0
  145. package/src/types/tools.ts +32 -3
  146. package/src/utils/toolContent.ts +2 -2
@@ -4,6 +4,7 @@ import {
4
4
  createLocalProgrammaticToolCallingTool,
5
5
  } from './LocalProgrammaticToolCalling';
6
6
  import {
7
+ CLOUDFLARE_CODING_TOOL_NAMES,
7
8
  createCloudflareCodingToolBundle,
8
9
  createCloudflareCodingTools,
9
10
  createCloudflareExecutionTool,
@@ -17,6 +18,10 @@ import {
17
18
  createLocalBashExecutionTool,
18
19
  createLocalCodeExecutionTool,
19
20
  } from './LocalExecutionTools';
21
+ import {
22
+ allowsToolCaller,
23
+ isToolDefinitionActive,
24
+ } from '@/tools/CallerCapabilities';
20
25
  import {
21
26
  Constants,
22
27
  CODE_EXECUTION_TOOLS,
@@ -26,6 +31,8 @@ import {
26
31
  type ResolveLocalToolsResult = {
27
32
  toolMap: t.ToolMap;
28
33
  directToolNames: Set<string>;
34
+ /** Names whose toolMap entries were created or replaced by this resolver. */
35
+ localImplementationNames: Set<string>;
29
36
  /**
30
37
  * Set when `local.fileCheckpointing === true` AND the auto-bind
31
38
  * coding suite is in use. ToolNode stashes this on the node and
@@ -58,6 +65,48 @@ function shouldIncludeCodingTools(config?: t.ToolExecutionConfig): boolean {
58
65
  );
59
66
  }
60
67
 
68
+ export function isProgrammaticRunnerAutoBound(
69
+ name: string,
70
+ config?: t.ToolExecutionConfig
71
+ ): boolean {
72
+ if (
73
+ !shouldIncludeCodingTools(config) ||
74
+ (name !== Constants.PROGRAMMATIC_TOOL_CALLING &&
75
+ name !== Constants.BASH_PROGRAMMATIC_TOOL_CALLING)
76
+ ) {
77
+ return false;
78
+ }
79
+ if (shouldUseCloudflareSandboxExecution(config)) {
80
+ return getSelectedCloudflareCodingToolNames(
81
+ getCloudflareConfig(config)
82
+ ).has(name);
83
+ }
84
+ return shouldUseLocalExecution(config);
85
+ }
86
+
87
+ /** Mirrors whether resolver policy creates or replaces this runner locally. */
88
+ export function isProgrammaticRunnerResolvedDirectly(
89
+ name: string,
90
+ config?: t.ToolExecutionConfig,
91
+ hasExplicitBinding: boolean = false
92
+ ): boolean {
93
+ if (isProgrammaticRunnerAutoBound(name, config)) {
94
+ return true;
95
+ }
96
+ if (
97
+ !hasExplicitBinding ||
98
+ (name !== Constants.PROGRAMMATIC_TOOL_CALLING &&
99
+ name !== Constants.BASH_PROGRAMMATIC_TOOL_CALLING)
100
+ ) {
101
+ return false;
102
+ }
103
+ return (
104
+ (shouldUseLocalExecution(config) ||
105
+ shouldUseCloudflareSandboxExecution(config)) &&
106
+ !shouldIncludeCodingTools(config)
107
+ );
108
+ }
109
+
61
110
  function getCloudflareConfig(
62
111
  config?: t.ToolExecutionConfig
63
112
  ): t.CloudflareSandboxExecutionConfig {
@@ -72,7 +121,12 @@ function getCloudflareConfig(
72
121
  function getSelectedCloudflareCodingToolNames(
73
122
  config: t.CloudflareSandboxExecutionConfig
74
123
  ): Set<string> {
75
- return new Set(config.codingToolNames ?? LOCAL_CODING_BUNDLE_NAMES);
124
+ const requestedNames = new Set(
125
+ config.codingToolNames ?? CLOUDFLARE_CODING_TOOL_NAMES
126
+ );
127
+ return new Set(
128
+ CLOUDFLARE_CODING_TOOL_NAMES.filter((name) => requestedNames.has(name))
129
+ );
76
130
  }
77
131
 
78
132
  function filterCloudflareCodingToolAllowlist(
@@ -150,9 +204,43 @@ function mergeToolsByName(
150
204
  return orderedTools;
151
205
  }
152
206
 
207
+ function filterToolsForDirectCaller(
208
+ tools: t.GraphTools | undefined,
209
+ toolRegistry?: t.LCToolRegistry,
210
+ discoveredToolNames: ReadonlySet<string> = new Set()
211
+ ): t.GraphTools | undefined {
212
+ if (tools == null || toolRegistry == null) {
213
+ return tools;
214
+ }
215
+ return tools.filter((tool) => {
216
+ if (!('name' in tool) || typeof tool.name !== 'string') {
217
+ return true;
218
+ }
219
+ const toolDef = toolRegistry.get(tool.name);
220
+ return (
221
+ toolDef == null ||
222
+ (allowsToolCaller(toolDef, 'direct') &&
223
+ isToolDefinitionActive(toolDef, discoveredToolNames))
224
+ );
225
+ });
226
+ }
227
+
228
+ function addDirectToolName(
229
+ directToolNames: Set<string>,
230
+ name: string,
231
+ toolRegistry?: t.LCToolRegistry
232
+ ): void {
233
+ const toolDef = toolRegistry?.get(name);
234
+ if (toolDef == null || allowsToolCaller(toolDef, 'direct')) {
235
+ directToolNames.add(name);
236
+ }
237
+ }
238
+
153
239
  export function resolveLocalToolsForBinding(args: {
154
240
  tools?: t.GraphTools;
155
241
  toolExecution?: t.ToolExecutionConfig;
242
+ toolRegistry?: t.LCToolRegistry;
243
+ discoveredToolNames?: ReadonlySet<string>;
156
244
  }): t.GraphTools | undefined {
157
245
  if (
158
246
  !shouldUseLocalExecution(args.toolExecution) &&
@@ -166,9 +254,13 @@ export function resolveLocalToolsForBinding(args: {
166
254
  if (shouldIncludeCodingTools(args.toolExecution)) {
167
255
  const selectedNames =
168
256
  getSelectedCloudflareCodingToolNames(cloudflareConfig);
169
- return mergeToolsByName(
170
- filterCloudflareCodingToolAllowlist(args.tools, selectedNames),
171
- createCloudflareCodingTools(cloudflareConfig)
257
+ return filterToolsForDirectCaller(
258
+ mergeToolsByName(
259
+ filterCloudflareCodingToolAllowlist(args.tools, selectedNames),
260
+ createCloudflareCodingTools(cloudflareConfig)
261
+ ),
262
+ args.toolRegistry,
263
+ args.discoveredToolNames
172
264
  );
173
265
  }
174
266
 
@@ -187,14 +279,23 @@ export function resolveLocalToolsForBinding(args: {
187
279
  cloudflareTool != null
188
280
  );
189
281
 
190
- return replacements.length === 0
282
+ const resolvedTools = replacements.length === 0
191
283
  ? args.tools
192
284
  : mergeToolsByName(args.tools, replacements);
285
+ return filterToolsForDirectCaller(
286
+ resolvedTools,
287
+ args.toolRegistry,
288
+ args.discoveredToolNames
289
+ );
193
290
  }
194
291
 
195
292
  const localConfig = args.toolExecution?.local ?? {};
196
293
  if (shouldIncludeCodingTools(args.toolExecution)) {
197
- return mergeToolsByName(args.tools, createLocalCodingTools(localConfig));
294
+ return filterToolsForDirectCaller(
295
+ mergeToolsByName(args.tools, createLocalCodingTools(localConfig)),
296
+ args.toolRegistry,
297
+ args.discoveredToolNames
298
+ );
198
299
  }
199
300
 
200
301
  const replacements = ((args.tools as t.GenericTool[] | undefined) ?? [])
@@ -209,9 +310,14 @@ export function resolveLocalToolsForBinding(args: {
209
310
  )
210
311
  .filter((localTool): localTool is t.GenericTool => localTool != null);
211
312
 
212
- return replacements.length === 0
313
+ const resolvedTools = replacements.length === 0
213
314
  ? args.tools
214
315
  : mergeToolsByName(args.tools, replacements);
316
+ return filterToolsForDirectCaller(
317
+ resolvedTools,
318
+ args.toolRegistry,
319
+ args.discoveredToolNames
320
+ );
215
321
  }
216
322
 
217
323
  export function resolveLocalToolRegistry(args: {
@@ -228,19 +334,69 @@ export function resolveLocalToolRegistry(args: {
228
334
  getCloudflareConfig(args.toolExecution)
229
335
  )
230
336
  : undefined;
337
+
338
+ if (selectedNames != null) {
339
+ const callableInsideCloudflare = new Set(selectedNames);
340
+ callableInsideCloudflare.delete(Constants.PROGRAMMATIC_TOOL_CALLING);
341
+ callableInsideCloudflare.delete(Constants.BASH_PROGRAMMATIC_TOOL_CALLING);
342
+ for (const [name, definition] of registry) {
343
+ if (callableInsideCloudflare.has(name)) {
344
+ continue;
345
+ }
346
+ const allowedCallers = definition.allowed_callers ?? ['direct'];
347
+ if (allowedCallers.includes('code_execution')) {
348
+ registry.set(name, {
349
+ ...definition,
350
+ allowed_callers: allowedCallers.filter(
351
+ (caller) => caller !== 'code_execution'
352
+ ),
353
+ });
354
+ }
355
+ }
356
+ }
357
+
231
358
  for (const definition of createLocalCodingToolDefinitions()) {
232
359
  if (selectedNames != null && !selectedNames.has(definition.name)) {
233
360
  registry.delete(definition.name);
234
361
  continue;
235
362
  }
236
- registry.set(definition.name, definition);
363
+ const existingDefinition = registry.get(definition.name);
364
+ registry.set(
365
+ definition.name,
366
+ existingDefinition == null
367
+ ? definition
368
+ : { ...definition, ...existingDefinition }
369
+ );
237
370
  }
238
371
  return registry;
239
372
  }
240
373
 
374
+ /** Names that this execution config creates or replaces in the local tool map. */
375
+ export function resolveLocalImplementationNames(
376
+ toolNames: Iterable<string>,
377
+ toolExecution?: t.ToolExecutionConfig
378
+ ): Set<string> {
379
+ if (
380
+ !shouldUseLocalExecution(toolExecution) &&
381
+ !shouldUseCloudflareSandboxExecution(toolExecution)
382
+ ) {
383
+ return new Set();
384
+ }
385
+ if (shouldIncludeCodingTools(toolExecution)) {
386
+ return shouldUseCloudflareSandboxExecution(toolExecution)
387
+ ? getSelectedCloudflareCodingToolNames(getCloudflareConfig(toolExecution))
388
+ : new Set(LOCAL_CODING_BUNDLE_NAMES);
389
+ }
390
+ const existingNames = new Set(toolNames);
391
+ return new Set(
392
+ [...CODE_EXECUTION_TOOLS].filter((name) => existingNames.has(name))
393
+ );
394
+ }
395
+
241
396
  export function resolveLocalExecutionTools(args: {
242
397
  toolMap: t.ToolMap;
243
398
  toolExecution?: t.ToolExecutionConfig;
399
+ toolRegistry?: t.LCToolRegistry;
244
400
  /**
245
401
  * Caller-provided checkpointer that overrides the bundle's
246
402
  * auto-created one. The Graph layer threads a single per-Run
@@ -252,6 +408,10 @@ export function resolveLocalExecutionTools(args: {
252
408
  fileCheckpointer?: t.LocalFileCheckpointer;
253
409
  }): ResolveLocalToolsResult {
254
410
  const directToolNames = new Set<string>();
411
+ const localImplementationNames = resolveLocalImplementationNames(
412
+ args.toolMap.keys(),
413
+ args.toolExecution
414
+ );
255
415
  if (
256
416
  !shouldUseLocalExecution(args.toolExecution) &&
257
417
  !shouldUseCloudflareSandboxExecution(args.toolExecution)
@@ -259,6 +419,7 @@ export function resolveLocalExecutionTools(args: {
259
419
  return {
260
420
  toolMap: args.toolMap,
261
421
  directToolNames,
422
+ localImplementationNames,
262
423
  };
263
424
  }
264
425
 
@@ -281,14 +442,24 @@ export function resolveLocalExecutionTools(args: {
281
442
  fileCheckpointer = bundle.checkpointer;
282
443
  for (const cloudflareTool of bundle.tools) {
283
444
  toolMap.set(cloudflareTool.name, cloudflareTool);
284
- directToolNames.add(cloudflareTool.name);
445
+ localImplementationNames.add(cloudflareTool.name);
446
+ addDirectToolName(
447
+ directToolNames,
448
+ cloudflareTool.name,
449
+ args.toolRegistry
450
+ );
285
451
  }
286
452
  } else {
287
453
  for (const cloudflareTool of createCloudflareCodingTools(
288
454
  cloudflareConfig
289
455
  )) {
290
456
  toolMap.set(cloudflareTool.name, cloudflareTool);
291
- directToolNames.add(cloudflareTool.name);
457
+ localImplementationNames.add(cloudflareTool.name);
458
+ addDirectToolName(
459
+ directToolNames,
460
+ cloudflareTool.name,
461
+ args.toolRegistry
462
+ );
292
463
  }
293
464
  }
294
465
  }
@@ -307,10 +478,16 @@ export function resolveLocalExecutionTools(args: {
307
478
  }
308
479
 
309
480
  toolMap.set(name, cloudflareTool);
310
- directToolNames.add(name);
481
+ localImplementationNames.add(name);
482
+ addDirectToolName(directToolNames, name, args.toolRegistry);
311
483
  }
312
484
 
313
- return { toolMap, directToolNames, fileCheckpointer };
485
+ return {
486
+ toolMap,
487
+ directToolNames,
488
+ localImplementationNames,
489
+ fileCheckpointer,
490
+ };
314
491
  }
315
492
 
316
493
  const localConfig = args.toolExecution?.local ?? {};
@@ -332,12 +509,22 @@ export function resolveLocalExecutionTools(args: {
332
509
  fileCheckpointer = bundle.checkpointer;
333
510
  for (const localTool of bundle.tools) {
334
511
  toolMap.set(localTool.name, localTool);
335
- directToolNames.add(localTool.name);
512
+ localImplementationNames.add(localTool.name);
513
+ addDirectToolName(
514
+ directToolNames,
515
+ localTool.name,
516
+ args.toolRegistry
517
+ );
336
518
  }
337
519
  } else {
338
520
  for (const localTool of createLocalCodingTools(localConfig)) {
339
521
  toolMap.set(localTool.name, localTool);
340
- directToolNames.add(localTool.name);
522
+ localImplementationNames.add(localTool.name);
523
+ addDirectToolName(
524
+ directToolNames,
525
+ localTool.name,
526
+ args.toolRegistry
527
+ );
341
528
  }
342
529
  }
343
530
  }
@@ -363,8 +550,14 @@ export function resolveLocalExecutionTools(args: {
363
550
  }
364
551
 
365
552
  toolMap.set(name, localTool);
366
- directToolNames.add(name);
553
+ localImplementationNames.add(name);
554
+ addDirectToolName(directToolNames, name, args.toolRegistry);
367
555
  }
368
556
 
369
- return { toolMap, directToolNames, fileCheckpointer };
557
+ return {
558
+ toolMap,
559
+ directToolNames,
560
+ localImplementationNames,
561
+ fileCheckpointer,
562
+ };
370
563
  }
@@ -22,6 +22,12 @@ export type ProgrammaticToolCallingJsonSchema = {
22
22
  minLength: number;
23
23
  description: string;
24
24
  };
25
+ tool_manifest: {
26
+ type: 'array';
27
+ items: { type: 'string' };
28
+ uniqueItems: true;
29
+ description: string;
30
+ };
25
31
  timeout: TimeoutSchema;
26
32
  };
27
33
  required: readonly ['code'];
@@ -31,6 +31,7 @@ import type {
31
31
  ToolEndEvent,
32
32
  GenericTool,
33
33
  LCTool,
34
+ ToolExecutionConfig,
34
35
  ToolExecuteBatchRequest,
35
36
  } from '@/types/tools';
36
37
  import type {
@@ -338,6 +339,8 @@ export type StandardGraphInput = {
338
339
  runId?: string;
339
340
  signal?: AbortSignal;
340
341
  agents: AgentInputs[];
342
+ /** Execution backend used to resolve the effective tool registry. */
343
+ toolExecution?: ToolExecutionConfig;
341
344
  langfuse?: LangfuseConfig;
342
345
  tokenCounter?: TokenCounter;
343
346
  indexTokenCountMap?: Record<string, number>;
@@ -1,17 +1,17 @@
1
1
  // src/types/tools.ts
2
- import type { StructuredToolInterface } from '@langchain/core/tools';
3
2
  import type {
4
3
  RunnableConfig,
5
4
  RunnableToolLike,
6
5
  } from '@langchain/core/runnables';
6
+ import type { StructuredToolInterface } from '@langchain/core/tools';
7
7
  import type { ToolCall } from '@langchain/core/messages/tool';
8
- import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
9
- import type { RunBreakerScope } from '@/llm/streamLimits';
10
8
  import type {
11
9
  MessageContentComplex,
12
10
  RunStepResumeState,
13
11
  ToolErrorData,
14
12
  } from './stream';
13
+ import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
14
+ import type { RunBreakerScope } from '@/llm/streamLimits';
15
15
  import type { HumanInTheLoopConfig } from './hitl';
16
16
  import type { LangfuseConfig } from './graph';
17
17
  import type { HookRegistry } from '@/hooks';
@@ -133,6 +133,8 @@ export type ToolNodeOptions = {
133
133
  ) => Promise<boolean | void>;
134
134
  /** Tool registry for lazy computation of programmatic tools and tool search */
135
135
  toolRegistry?: LCToolRegistry;
136
+ /** Returns the owning agent's currently discovered deferred tool names. */
137
+ getDiscoveredToolNames?: () => readonly string[];
136
138
  /** Reference to Graph's sessions map for automatic session injection */
137
139
  sessions?: ToolSessionMap;
138
140
  /** Partition within `sessions` used by this agent's code tools. */
@@ -555,6 +557,19 @@ export type ToolCallRequest = {
555
557
  runtimeSessionHint?: string;
556
558
  };
557
559
 
560
+ /**
561
+ * Serializable view of the active tools grouped by their effective caller
562
+ * capabilities. Event-driven hosts use this snapshot to preserve the SDK's
563
+ * live deferred-tool discovery state without reimplementing its policy.
564
+ */
565
+ export type CallerCapabilityProjectionSnapshot = {
566
+ version: 1;
567
+ directToolNames: string[];
568
+ codeExecutionToolNames: string[];
569
+ directOnlyToolNames: string[];
570
+ codeExecutionOnlyToolNames: string[];
571
+ };
572
+
558
573
  /** Batch request containing ALL tool calls for a graph step */
559
574
  export type ToolExecuteBatchRequest = {
560
575
  /** All tool calls from the AIMessage */
@@ -563,6 +578,11 @@ export type ToolExecuteBatchRequest = {
563
578
  userId?: string;
564
579
  /** Agent ID for context */
565
580
  agentId?: string;
581
+ /**
582
+ * SDK-owned snapshot of the active caller capability projection. Optional
583
+ * so older event handlers remain compatible with newer SDKs.
584
+ */
585
+ callerCapabilityProjection?: CallerCapabilityProjectionSnapshot;
566
586
  /** Runtime configurable from RunnableConfig (includes user, userMCPAuthMap, etc.) */
567
587
  configurable?: Record<string, unknown>;
568
588
  /** Runtime metadata from RunnableConfig (includes thread_id, run_id, provider, etc.) */
@@ -1171,6 +1191,15 @@ export type ToolExecutionConfig = {
1171
1191
  export type ProgrammaticCache = {
1172
1192
  toolMap: ToolMap;
1173
1193
  toolDefs: LCTool[];
1194
+ /** Actual outer runner name used for caller-policy diagnostics. */
1195
+ programmaticToolName?: string;
1196
+ /**
1197
+ * Known tools that cannot be invoked from programmatic execution. Kept
1198
+ * separate from `toolDefs` so the Programmatic Tool Manifest can be
1199
+ * validated before the execution runtime starts without exposing their
1200
+ * schemas to that runtime.
1201
+ */
1202
+ disallowedToolDefs?: LCTool[];
1174
1203
  /**
1175
1204
  * Hook context plumbed through by ToolNode for the local
1176
1205
  * programmatic-tool path so the in-process bridge can run
@@ -1818,7 +1818,7 @@ function classifyToolContentBlock(
1818
1818
  }
1819
1819
  }
1820
1820
  const remaining = { value: MAX_ATOMIC_VALIDATION_WORK };
1821
- let kind = TOOL_BLOCK_OPAQUE;
1821
+ let kind: number;
1822
1822
  try {
1823
1823
  if (
1824
1824
  hasUnsafeCallableToJSON(
@@ -2701,7 +2701,7 @@ export function cloneToolMessageWithContent(
2701
2701
  status: message.status,
2702
2702
  artifact,
2703
2703
  metadata: message.metadata,
2704
- additional_kwargs: message.additional_kwargs,
2704
+ additional_kwargs: { ...message.additional_kwargs },
2705
2705
  response_metadata: message.response_metadata,
2706
2706
  });
2707
2707
  }