@librechat/agents 3.6.10 → 3.6.12

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 (64) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +63 -10
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +48 -119
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/llm/contextPressureMeter.cjs +132 -0
  6. package/dist/cjs/llm/contextPressureMeter.cjs.map +1 -0
  7. package/dist/cjs/llm/invoke.cjs +46 -75
  8. package/dist/cjs/llm/invoke.cjs.map +1 -1
  9. package/dist/cjs/llm/prepareProviderRequest.cjs +108 -0
  10. package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -0
  11. package/dist/cjs/main.cjs +4 -0
  12. package/dist/cjs/messages/content.cjs +5 -4
  13. package/dist/cjs/messages/content.cjs.map +1 -1
  14. package/dist/cjs/stream.cjs +1 -0
  15. package/dist/cjs/stream.cjs.map +1 -1
  16. package/dist/cjs/tools/CallerCapabilities.cjs +31 -0
  17. package/dist/cjs/tools/CallerCapabilities.cjs.map +1 -1
  18. package/dist/cjs/tools/ToolNode.cjs +23 -6
  19. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  20. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +26 -2
  21. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  22. package/dist/esm/agents/AgentContext.mjs +65 -12
  23. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  24. package/dist/esm/graphs/Graph.mjs +51 -122
  25. package/dist/esm/graphs/Graph.mjs.map +1 -1
  26. package/dist/esm/llm/contextPressureMeter.mjs +132 -0
  27. package/dist/esm/llm/contextPressureMeter.mjs.map +1 -0
  28. package/dist/esm/llm/invoke.mjs +48 -75
  29. package/dist/esm/llm/invoke.mjs.map +1 -1
  30. package/dist/esm/llm/prepareProviderRequest.mjs +105 -0
  31. package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -0
  32. package/dist/esm/main.mjs +3 -2
  33. package/dist/esm/messages/content.mjs +5 -4
  34. package/dist/esm/messages/content.mjs.map +1 -1
  35. package/dist/esm/stream.mjs +1 -0
  36. package/dist/esm/stream.mjs.map +1 -1
  37. package/dist/esm/tools/CallerCapabilities.mjs +29 -1
  38. package/dist/esm/tools/CallerCapabilities.mjs.map +1 -1
  39. package/dist/esm/tools/ToolNode.mjs +24 -7
  40. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  41. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +26 -4
  42. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  43. package/dist/types/agents/AgentContext.d.ts +11 -0
  44. package/dist/types/index.d.ts +2 -0
  45. package/dist/types/llm/contextPressureMeter.d.ts +30 -0
  46. package/dist/types/llm/invoke.d.ts +31 -33
  47. package/dist/types/llm/prepareProviderRequest.d.ts +55 -0
  48. package/dist/types/tools/CallerCapabilities.d.ts +13 -0
  49. package/dist/types/tools/ToolNode.d.ts +9 -1
  50. package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +6 -0
  51. package/dist/types/types/tools.d.ts +17 -0
  52. package/package.json +1 -1
  53. package/src/agents/AgentContext.ts +157 -15
  54. package/src/graphs/Graph.ts +75 -279
  55. package/src/index.ts +8 -0
  56. package/src/llm/contextPressureMeter.ts +284 -0
  57. package/src/llm/invoke.ts +136 -296
  58. package/src/llm/prepareProviderRequest.ts +357 -0
  59. package/src/messages/content.ts +3 -3
  60. package/src/stream.ts +6 -0
  61. package/src/tools/CallerCapabilities.ts +68 -0
  62. package/src/tools/ToolNode.ts +47 -4
  63. package/src/tools/local/resolveLocalExecutionTools.ts +77 -3
  64. package/src/types/tools.ts +18 -0
@@ -34,12 +34,18 @@ import {
34
34
  } from '@/common';
35
35
  import {
36
36
  isProgrammaticRunnerAutoBound,
37
+ isProgrammaticRunnerResolvedDirectly,
38
+ resolveLocalImplementationNames,
37
39
  resolveLocalToolRegistry,
38
40
  } from '@/tools/local/resolveLocalExecutionTools';
39
41
  import {
42
+ type CallerCapabilityProjection,
40
43
  allowsToolCaller,
44
+ applyCallerCapabilityDefinitionOverrides,
45
+ createCallerCapabilityProjectionSnapshot,
41
46
  isToolDefinitionActive,
42
47
  isProgrammaticControlTool,
48
+ mergeCallerCapabilityDefinitions,
43
49
  resolveCallerCapabilityProjection,
44
50
  } from '@/tools/CallerCapabilities';
45
51
  import { createSchemaOnlyTools } from '@/tools/schema';
@@ -59,6 +65,12 @@ type AgentSystemContentBlock =
59
65
 
60
66
  type PromptCacheProvider = Providers.ANTHROPIC | Providers.OPENROUTER;
61
67
 
68
+ type ProgrammaticToolInstructionTarget = {
69
+ name: string;
70
+ codeGuidance: string;
71
+ executesDirectly: boolean;
72
+ };
73
+
62
74
  /**
63
75
  * Encapsulates agent-specific state that can vary between agents in a multi-agent system
64
76
  */
@@ -483,12 +495,53 @@ export class AgentContext {
483
495
 
484
496
  /** Builds the caller boundary and schemas for programmatic-only tools. */
485
497
  private buildProgrammaticOnlyToolsInstructions(): string {
486
- if (!this.toolRegistry) return '';
487
-
488
- const capabilities = resolveCallerCapabilityProjection(
489
- this.toolRegistry.values(),
490
- (toolDef) => isToolDefinitionActive(toolDef, this.discoveredToolNames)
498
+ const programmaticTools = this.getProgrammaticToolInstructionTargets();
499
+ if (programmaticTools.length === 0) return '';
500
+ const directProgrammaticTools = programmaticTools.filter(
501
+ (tool) => tool.executesDirectly
491
502
  );
503
+ const eventProgrammaticTools = programmaticTools.filter(
504
+ (tool) => !tool.executesDirectly
505
+ );
506
+ const groups: Array<{
507
+ tools: ProgrammaticToolInstructionTarget[];
508
+ capabilities: CallerCapabilityProjection;
509
+ label: string;
510
+ }> = [];
511
+ if (directProgrammaticTools.length > 0) {
512
+ groups.push({
513
+ tools: directProgrammaticTools,
514
+ capabilities: this.getDirectProgrammaticCapabilityProjection(),
515
+ label: 'Direct programmatic runners',
516
+ });
517
+ }
518
+ if (eventProgrammaticTools.length > 0) {
519
+ groups.push({
520
+ tools: eventProgrammaticTools,
521
+ capabilities: this.getCallerCapabilityProjection(),
522
+ label: 'Event-dispatched programmatic runners',
523
+ });
524
+ }
525
+ if (groups.length === 0) {
526
+ return '';
527
+ }
528
+ const showGroupLabels = groups.length > 1;
529
+ return (
530
+ '\n\n## Programmatic Tool Calling' +
531
+ groups
532
+ .map(
533
+ ({ tools, capabilities, label }) =>
534
+ (showGroupLabels ? `\n\n### ${label}` : '') +
535
+ this.buildProgrammaticToolGroupInstructions(tools, capabilities)
536
+ )
537
+ .join('')
538
+ );
539
+ }
540
+
541
+ private buildProgrammaticToolGroupInstructions(
542
+ programmaticTools: ProgrammaticToolInstructionTarget[],
543
+ capabilities: CallerCapabilityProjection
544
+ ): string {
492
545
  const programmaticOnlyTools = capabilities.codeExecutionOnlyTools;
493
546
  const programmaticToolNames = capabilities.codeExecutionTools.map(
494
547
  (toolDef) => toolDef.name
@@ -497,8 +550,6 @@ export class AgentContext {
497
550
  .map((toolDef) => toolDef.name)
498
551
  .filter((name) => !isProgrammaticControlTool(name));
499
552
 
500
- const programmaticTools = this.getProgrammaticToolInstructionTargets();
501
- if (programmaticTools.length === 0) return '';
502
553
  const programmaticRunnerNames = programmaticTools
503
554
  .map((tool) => `\`${tool.name}\``)
504
555
  .join(' or ');
@@ -513,7 +564,7 @@ export class AgentContext {
513
564
  .join(', ')}. Every ${programmaticRunnerNames} call must include a \`tool_manifest\` containing the exact registered names used by its code; the manifest is validated before execution starts.`
514
565
  : '';
515
566
  const boundary =
516
- '\n\n## Programmatic Tool Calling\n\n' +
567
+ '\n\n' +
517
568
  `Only these tools may be invoked inside ${programmaticRunnerNames}: ${quotedProgrammaticNames}.` +
518
569
  directOnlyBoundary;
519
570
 
@@ -548,11 +599,8 @@ export class AgentContext {
548
599
  );
549
600
  }
550
601
 
551
- private getProgrammaticToolInstructionTargets(): Array<{
552
- name: string;
553
- codeGuidance: string;
554
- }> {
555
- const targets: Array<{ name: string; codeGuidance: string }> = [];
602
+ private getProgrammaticToolInstructionTargets(): ProgrammaticToolInstructionTarget[] {
603
+ const targets: ProgrammaticToolInstructionTarget[] = [];
556
604
  if (
557
605
  this.hasBoundTool(Constants.BASH_PROGRAMMATIC_TOOL_CALLING) ||
558
606
  isProgrammaticRunnerAutoBound(
@@ -563,6 +611,9 @@ export class AgentContext {
563
611
  targets.push({
564
612
  name: Constants.BASH_PROGRAMMATIC_TOOL_CALLING,
565
613
  codeGuidance: 'Bash code',
614
+ executesDirectly: this.isProgrammaticRunnerDirectlyBound(
615
+ Constants.BASH_PROGRAMMATIC_TOOL_CALLING
616
+ ),
566
617
  });
567
618
  }
568
619
 
@@ -581,12 +632,73 @@ export class AgentContext {
581
632
  codeGuidance: localDefault
582
633
  ? 'Bash code by default, or set `lang: "py"` to use Python code'
583
634
  : 'Python code',
635
+ executesDirectly: this.isProgrammaticRunnerDirectlyBound(
636
+ Constants.PROGRAMMATIC_TOOL_CALLING
637
+ ),
584
638
  });
585
639
  }
586
640
 
587
641
  return targets;
588
642
  }
589
643
 
644
+ /** Whether ToolNode executes this runner in-process instead of via an event. */
645
+ private isProgrammaticRunnerDirectlyBound(name: string): boolean {
646
+ return (
647
+ isProgrammaticRunnerResolvedDirectly(
648
+ name,
649
+ this.toolExecution,
650
+ this.toolDefinitions?.some((toolDef) => toolDef.name === name) === true
651
+ ) ||
652
+ this.graphTools?.some(
653
+ (tool) => 'name' in tool && tool.name === name
654
+ ) === true
655
+ );
656
+ }
657
+
658
+ /** Mirrors ToolNode's executable implementation gate for direct runners. */
659
+ private getDirectProgrammaticCapabilityProjection(): CallerCapabilityProjection {
660
+ const implementationNames = new Set<string>();
661
+ const isEventDriven = (this.toolDefinitions?.length ?? 0) > 0;
662
+ const resolverInputNames = new Set<string>();
663
+ if (isEventDriven) {
664
+ for (const toolDef of this.toolDefinitions ?? []) {
665
+ resolverInputNames.add(toolDef.name);
666
+ }
667
+ } else {
668
+ for (const tool of (this.tools as t.GenericTool[] | undefined) ?? []) {
669
+ if ('name' in tool && typeof tool.name === 'string') {
670
+ implementationNames.add(tool.name);
671
+ resolverInputNames.add(tool.name);
672
+ }
673
+ }
674
+ }
675
+ for (const tool of (this.graphTools as t.GenericTool[] | undefined) ?? []) {
676
+ if ('name' in tool && typeof tool.name === 'string') {
677
+ implementationNames.add(tool.name);
678
+ resolverInputNames.add(tool.name);
679
+ }
680
+ }
681
+ for (const name of resolveLocalImplementationNames(
682
+ resolverInputNames,
683
+ this.toolExecution
684
+ )) {
685
+ implementationNames.add(name);
686
+ }
687
+ const activeCapabilities = this.getCallerCapabilityProjection();
688
+ const executableCapabilities = resolveCallerCapabilityProjection(
689
+ this.toolRegistry?.values() ?? [],
690
+ (toolDef) =>
691
+ implementationNames.has(toolDef.name) &&
692
+ isToolDefinitionActive(toolDef, this.discoveredToolNames)
693
+ );
694
+ return {
695
+ directTools: activeCapabilities.directTools,
696
+ directOnlyTools: activeCapabilities.directOnlyTools,
697
+ codeExecutionTools: executableCapabilities.codeExecutionTools,
698
+ codeExecutionOnlyTools: executableCapabilities.codeExecutionOnlyTools,
699
+ };
700
+ }
701
+
590
702
  private hasBoundTool(name: string): boolean {
591
703
  return (
592
704
  this.getToolsForBinding()?.some(
@@ -1123,9 +1235,21 @@ export class AgentContext {
1123
1235
  this.indexTokenCountMap = { ...baseTokenMap };
1124
1236
  }
1125
1237
 
1238
+ /** Event definitions with matching runtime caller/defer metadata applied. */
1239
+ getEffectiveToolDefinitions(): t.LCTool[] | undefined {
1240
+ if (!this.toolDefinitions) {
1241
+ return undefined;
1242
+ }
1243
+ return applyCallerCapabilityDefinitionOverrides(
1244
+ this.toolDefinitions,
1245
+ this.toolRegistry?.values()
1246
+ );
1247
+ }
1248
+
1126
1249
  /** Active tool definitions for token accounting (excludes deferred-and-undiscovered entries). */
1127
1250
  private getActiveToolDefinitions(): t.LCTool[] {
1128
- if (!this.toolDefinitions) {
1251
+ const effectiveToolDefinitions = this.getEffectiveToolDefinitions();
1252
+ if (!effectiveToolDefinitions) {
1129
1253
  return [];
1130
1254
  }
1131
1255
  /**
@@ -1136,7 +1260,7 @@ export class AgentContext {
1136
1260
  * `toolSchemaTokens` even though they were never bound.
1137
1261
  */
1138
1262
  return resolveCallerCapabilityProjection(
1139
- this.toolDefinitions,
1263
+ effectiveToolDefinitions,
1140
1264
  (toolDef) => isToolDefinitionActive(toolDef, this.discoveredToolNames)
1141
1265
  ).directTools;
1142
1266
  }
@@ -1767,6 +1891,24 @@ export class AgentContext {
1767
1891
  return Array.from(this.discoveredToolNames);
1768
1892
  }
1769
1893
 
1894
+ /** Returns the live projection shared by prompt and event execution. */
1895
+ private getCallerCapabilityProjection(): CallerCapabilityProjection {
1896
+ return resolveCallerCapabilityProjection(
1897
+ mergeCallerCapabilityDefinitions(
1898
+ this.toolDefinitions,
1899
+ this.toolRegistry?.values()
1900
+ ),
1901
+ (toolDef) => isToolDefinitionActive(toolDef, this.discoveredToolNames)
1902
+ );
1903
+ }
1904
+
1905
+ /** Returns the SDK-owned active caller projection for event-driven hosts. */
1906
+ getCallerCapabilityProjectionSnapshot(): t.CallerCapabilityProjectionSnapshot {
1907
+ return createCallerCapabilityProjectionSnapshot(
1908
+ this.getCallerCapabilityProjection()
1909
+ );
1910
+ }
1911
+
1770
1912
  /**
1771
1913
  * Marks tools as discovered via tool search.
1772
1914
  * Discovered tools will be included in the next model binding.