@librechat/agents 3.2.68 → 3.3.1

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 (159) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +117 -3
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/common/enum.cjs +4 -0
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/graphs/Graph.cjs +243 -49
  6. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  7. package/dist/cjs/graphs/MultiAgentGraph.cjs +103 -28
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  9. package/dist/cjs/langfuseToolOutputTracing.cjs +4 -0
  10. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/index.cjs +11 -2
  12. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  13. package/dist/cjs/llm/contextOverflowRecovery.cjs +132 -0
  14. package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -0
  15. package/dist/cjs/llm/google/index.cjs +1 -1
  16. package/dist/cjs/llm/invoke.cjs +60 -3
  17. package/dist/cjs/llm/invoke.cjs.map +1 -1
  18. package/dist/cjs/llm/openai/index.cjs +1 -1
  19. package/dist/cjs/main.cjs +21 -7
  20. package/dist/cjs/messages/format.cjs +136 -4
  21. package/dist/cjs/messages/format.cjs.map +1 -1
  22. package/dist/cjs/messages/prune.cjs +16 -5
  23. package/dist/cjs/messages/prune.cjs.map +1 -1
  24. package/dist/cjs/messages/recency.cjs +2 -0
  25. package/dist/cjs/messages/recency.cjs.map +1 -1
  26. package/dist/cjs/prompts/activityLabel.cjs +101 -0
  27. package/dist/cjs/prompts/activityLabel.cjs.map +1 -0
  28. package/dist/cjs/run.cjs +177 -3
  29. package/dist/cjs/run.cjs.map +1 -1
  30. package/dist/cjs/stream.cjs +205 -49
  31. package/dist/cjs/stream.cjs.map +1 -1
  32. package/dist/cjs/summarization/node.cjs +55 -7
  33. package/dist/cjs/summarization/node.cjs.map +1 -1
  34. package/dist/cjs/tools/BashExecutor.cjs +2 -2
  35. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  36. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +2 -2
  37. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  38. package/dist/cjs/tools/CodeExecutor.cjs +69 -8
  39. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  40. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +19 -15
  41. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  42. package/dist/cjs/tools/ToolNode.cjs +32 -3
  43. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  44. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
  45. package/dist/cjs/utils/errors.cjs +317 -52
  46. package/dist/cjs/utils/errors.cjs.map +1 -1
  47. package/dist/esm/agents/AgentContext.mjs +118 -4
  48. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  49. package/dist/esm/common/enum.mjs +4 -0
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/graphs/Graph.mjs +242 -48
  52. package/dist/esm/graphs/Graph.mjs.map +1 -1
  53. package/dist/esm/graphs/MultiAgentGraph.mjs +103 -28
  54. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  55. package/dist/esm/langfuseToolOutputTracing.mjs +4 -1
  56. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  57. package/dist/esm/llm/bedrock/index.mjs +11 -2
  58. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  59. package/dist/esm/llm/contextOverflowRecovery.mjs +130 -0
  60. package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -0
  61. package/dist/esm/llm/google/index.mjs +1 -1
  62. package/dist/esm/llm/invoke.mjs +59 -4
  63. package/dist/esm/llm/invoke.mjs.map +1 -1
  64. package/dist/esm/llm/openai/index.mjs +1 -1
  65. package/dist/esm/main.mjs +10 -10
  66. package/dist/esm/messages/format.mjs +136 -5
  67. package/dist/esm/messages/format.mjs.map +1 -1
  68. package/dist/esm/messages/prune.mjs +14 -6
  69. package/dist/esm/messages/prune.mjs.map +1 -1
  70. package/dist/esm/messages/recency.mjs +2 -1
  71. package/dist/esm/messages/recency.mjs.map +1 -1
  72. package/dist/esm/prompts/activityLabel.mjs +100 -0
  73. package/dist/esm/prompts/activityLabel.mjs.map +1 -0
  74. package/dist/esm/run.mjs +178 -4
  75. package/dist/esm/run.mjs.map +1 -1
  76. package/dist/esm/stream.mjs +205 -49
  77. package/dist/esm/stream.mjs.map +1 -1
  78. package/dist/esm/summarization/node.mjs +55 -7
  79. package/dist/esm/summarization/node.mjs.map +1 -1
  80. package/dist/esm/tools/BashExecutor.mjs +3 -3
  81. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  82. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +3 -3
  83. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  84. package/dist/esm/tools/CodeExecutor.mjs +62 -9
  85. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  86. package/dist/esm/tools/ProgrammaticToolCalling.mjs +20 -16
  87. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  88. package/dist/esm/tools/ToolNode.mjs +32 -3
  89. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  90. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
  91. package/dist/esm/utils/errors.mjs +317 -53
  92. package/dist/esm/utils/errors.mjs.map +1 -1
  93. package/dist/types/agents/AgentContext.d.ts +62 -3
  94. package/dist/types/common/enum.d.ts +5 -1
  95. package/dist/types/graphs/Graph.d.ts +16 -2
  96. package/dist/types/graphs/MultiAgentGraph.d.ts +1 -0
  97. package/dist/types/langfuseToolOutputTracing.d.ts +4 -0
  98. package/dist/types/llm/contextOverflowRecovery.d.ts +85 -0
  99. package/dist/types/llm/invoke.d.ts +35 -6
  100. package/dist/types/messages/format.d.ts +22 -0
  101. package/dist/types/messages/prune.d.ts +10 -2
  102. package/dist/types/messages/recency.d.ts +1 -0
  103. package/dist/types/prompts/activityLabel.d.ts +31 -0
  104. package/dist/types/run.d.ts +16 -0
  105. package/dist/types/tools/CodeExecutor.d.ts +14 -1
  106. package/dist/types/types/activityLabel.d.ts +53 -0
  107. package/dist/types/types/index.d.ts +1 -0
  108. package/dist/types/types/llm.d.ts +7 -4
  109. package/dist/types/types/stream.d.ts +7 -4
  110. package/dist/types/types/summarize.d.ts +22 -0
  111. package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +40 -0
  112. package/dist/types/utils/errors.d.ts +65 -16
  113. package/dist/types/utils/redactSecrets.d.ts +3 -0
  114. package/package.json +7 -8
  115. package/src/agents/AgentContext.ts +188 -7
  116. package/src/agents/__tests__/AgentContext.overflow.test.ts +205 -0
  117. package/src/common/enum.ts +4 -0
  118. package/src/graphs/Graph.ts +409 -58
  119. package/src/graphs/MultiAgentGraph.ts +184 -46
  120. package/src/graphs/__tests__/Graph.contextOverflow.test.ts +631 -0
  121. package/src/langfuseToolOutputTracing.ts +4 -1
  122. package/src/llm/__tests__/contextOverflowRecovery.test.ts +401 -0
  123. package/src/llm/__tests__/fallbackOverflow.test.ts +287 -0
  124. package/src/llm/bedrock/index.ts +25 -12
  125. package/src/llm/contextOverflowRecovery.ts +292 -0
  126. package/src/llm/invoke.ts +119 -4
  127. package/src/messages/foldToollessToolBlocks.test.ts +438 -0
  128. package/src/messages/format.ts +233 -5
  129. package/src/messages/prune.ts +24 -11
  130. package/src/messages/recency.ts +3 -1
  131. package/src/prompts/activityLabel.ts +177 -0
  132. package/src/run.ts +322 -3
  133. package/src/scripts/context-overflow-probe.ts +997 -0
  134. package/src/specs/activity-label-prompt.test.ts +128 -0
  135. package/src/specs/activity-label-trace-seed.test.ts +47 -0
  136. package/src/specs/agent-handoffs.test.ts +903 -1
  137. package/src/specs/bedrock-toolless.live.test.ts +123 -0
  138. package/src/specs/context-overflow-recovery.live.test.ts +213 -0
  139. package/src/splitStream.test.ts +882 -0
  140. package/src/stream.ts +315 -51
  141. package/src/summarization/__tests__/aggregator.test.ts +83 -0
  142. package/src/summarization/__tests__/node.test.ts +139 -0
  143. package/src/summarization/node.ts +99 -14
  144. package/src/tools/BashExecutor.ts +4 -2
  145. package/src/tools/BashProgrammaticToolCalling.ts +4 -7
  146. package/src/tools/CodeExecutor.ts +119 -8
  147. package/src/tools/ProgrammaticToolCalling.ts +29 -27
  148. package/src/tools/ToolNode.ts +50 -8
  149. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +297 -3
  150. package/src/types/activityLabel.ts +55 -0
  151. package/src/types/index.ts +1 -0
  152. package/src/types/llm.ts +8 -1
  153. package/src/types/stream.ts +7 -4
  154. package/src/types/summarize.ts +22 -0
  155. package/src/utils/__tests__/errors.test.ts +270 -0
  156. package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +336 -0
  157. package/src/utils/__tests__/redactSecrets.test.ts +56 -0
  158. package/src/utils/errors.ts +484 -66
  159. package/src/utils/redactSecrets.ts +61 -0
@@ -0,0 +1,128 @@
1
+ import type { ActivityLabelToolEntry } from '@/types/activityLabel';
2
+ import { LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT } from '@/langfuseToolOutputTracing';
3
+ import { buildActivityLabelPrompt } from '@/prompts/activityLabel';
4
+ import { resolveToolOutputTracingConfig } from '@/langfuseConfig';
5
+
6
+ const entries: ActivityLabelToolEntry[] = [
7
+ {
8
+ toolName: 'web_search',
9
+ toolInput: { query: 'runtime versions' },
10
+ toolOutput: 'PUBLIC_SEARCH_RESULTS',
11
+ status: 'success',
12
+ },
13
+ {
14
+ toolName: 'db_query',
15
+ toolInput: { sql: 'select 1' },
16
+ error: 'SECRET_CONNECTION_STRING_LEAK',
17
+ status: 'error',
18
+ },
19
+ ];
20
+
21
+ describe('buildActivityLabelPrompt redaction', () => {
22
+ it('embeds raw outputs and errors when no redaction policy resolves', () => {
23
+ const prompt = buildActivityLabelPrompt({ entries, charLimit: 600 });
24
+ expect(prompt).toContain('PUBLIC_SEARCH_RESULTS');
25
+ expect(prompt).toContain('SECRET_CONNECTION_STRING_LEAK');
26
+ });
27
+
28
+ it('redacts every outcome when tool-output tracing is globally disabled', () => {
29
+ const redaction = resolveToolOutputTracingConfig({
30
+ toolOutputTracing: { enabled: false },
31
+ });
32
+ const prompt = buildActivityLabelPrompt({
33
+ entries,
34
+ charLimit: 600,
35
+ redaction,
36
+ });
37
+ expect(prompt).not.toContain('PUBLIC_SEARCH_RESULTS');
38
+ expect(prompt).not.toContain('SECRET_CONNECTION_STRING_LEAK');
39
+ expect(prompt).toContain(LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT);
40
+ /** Tool names and inputs stay — matching the span processor, which
41
+ * redacts output fields only. */
42
+ expect(prompt).toContain('web_search');
43
+ expect(prompt).toContain('runtime versions');
44
+ });
45
+
46
+ it('drops reasoning excerpts when any batch entry is redacted', () => {
47
+ const redaction = resolveToolOutputTracingConfig({
48
+ toolOutputTracing: { redactedToolNames: ['db_query'] },
49
+ });
50
+ const prompt = buildActivityLabelPrompt({
51
+ entries,
52
+ charLimit: 600,
53
+ thinkingExcerpts: [
54
+ 'The db_query returned SECRET_CONNECTION_STRING_LEAK earlier',
55
+ ],
56
+ redaction,
57
+ });
58
+ expect(prompt).not.toContain('Reasoning excerpts');
59
+ expect(prompt).not.toContain('SECRET_CONNECTION_STRING_LEAK');
60
+ });
61
+
62
+ it('drops free-form context under ANY active policy, even with no matching entry', () => {
63
+ /** Reasoning/intent can quote output from an EARLIER call to the
64
+ * redacted tool that this batch does not contain, so an active policy
65
+ * suppresses free-form prose regardless of this batch's entries. */
66
+ const redaction = resolveToolOutputTracingConfig({
67
+ toolOutputTracing: { redactedToolNames: ['unrelated_tool'] },
68
+ });
69
+ const prompt = buildActivityLabelPrompt({
70
+ entries,
71
+ charLimit: 600,
72
+ thinkingExcerpts: ['Comparing versions across sources'],
73
+ lastAssistantText: 'Checking the unrelated_tool result from before',
74
+ redaction,
75
+ });
76
+ expect(prompt).not.toContain('Comparing versions across sources');
77
+ expect(prompt).not.toContain('Intent');
78
+ /** Non-matching entries keep their own outcomes. */
79
+ expect(prompt).toContain('PUBLIC_SEARCH_RESULTS');
80
+ });
81
+
82
+ it('keeps free-form context when no redaction policy is configured', () => {
83
+ const prompt = buildActivityLabelPrompt({
84
+ entries,
85
+ charLimit: 600,
86
+ thinkingExcerpts: ['Comparing versions across sources'],
87
+ lastAssistantText: 'Verifying each runtime',
88
+ redaction: undefined,
89
+ });
90
+ expect(prompt).toContain('Comparing versions across sources');
91
+ expect(prompt).toContain('Verifying each runtime');
92
+ });
93
+
94
+ it('bounds serialization of oversized structured tool output', () => {
95
+ const huge = Array.from({ length: 50_000 }, (_, i) => ({
96
+ id: i,
97
+ blob: 'x'.repeat(200),
98
+ }));
99
+ const prompt = buildActivityLabelPrompt({
100
+ entries: [
101
+ {
102
+ toolName: 'db_rows',
103
+ toolInput: { sql: 'select *' },
104
+ toolOutput: huge,
105
+ status: 'success',
106
+ },
107
+ ],
108
+ charLimit: 600,
109
+ });
110
+ /** Degrades to a shape summary instead of materializing ~10MB of JSON. */
111
+ expect(prompt).toContain('[Array(50000)]');
112
+ expect(prompt.length).toBeLessThan(2000);
113
+ });
114
+
115
+ it('redacts only named tools, including their error text', () => {
116
+ const redaction = resolveToolOutputTracingConfig({
117
+ toolOutputTracing: { redactedToolNames: ['db_query'] },
118
+ });
119
+ const prompt = buildActivityLabelPrompt({
120
+ entries,
121
+ charLimit: 600,
122
+ redaction,
123
+ });
124
+ expect(prompt).toContain('PUBLIC_SEARCH_RESULTS');
125
+ expect(prompt).not.toContain('SECRET_CONNECTION_STRING_LEAK');
126
+ expect(prompt).toContain(LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT);
127
+ });
128
+ });
@@ -0,0 +1,47 @@
1
+ import {
2
+ resolveLangfuseRuntimeScope,
3
+ withLangfuseRuntimeScope,
4
+ } from '@/langfuseRuntimeScope';
5
+ import { getTraceIdSeed } from '@/langfuseRuntimeContext';
6
+
7
+ /**
8
+ * `generateActivityLabel` passes one label seed to both the Langfuse handler
9
+ * and the runtime scope it invokes under. This proves the mechanism: a label
10
+ * scope's seed must override an inherited (parent run) seed for the duration
11
+ * of the label call, then restore — otherwise per-batch label generations
12
+ * collapse into the main run trace under deterministic tracing.
13
+ *
14
+ * Asserted through the ALS runtime-context channel (`getTraceIdSeed`), which
15
+ * the trace id generator consults alongside OTel context; tests run without
16
+ * a registered OTel context manager, so the OTel channel is a no-op here.
17
+ */
18
+ describe('activity-label trace seed scoping', () => {
19
+ it('overrides an inherited run seed for the nested scope only', () => {
20
+ const runScope = resolveLangfuseRuntimeScope({ traceIdSeed: 'run-seed' });
21
+ withLangfuseRuntimeScope(runScope, () => {
22
+ expect(getTraceIdSeed()).toBe('run-seed');
23
+
24
+ const labelScope = resolveLangfuseRuntimeScope({
25
+ traceIdSeed: 'run-1-activity-3',
26
+ });
27
+ withLangfuseRuntimeScope(labelScope, () => {
28
+ expect(getTraceIdSeed()).toBe('run-1-activity-3');
29
+ });
30
+
31
+ expect(getTraceIdSeed()).toBe('run-seed');
32
+ });
33
+ });
34
+
35
+ it('keeps distinct seeds for successive label scopes', () => {
36
+ const seeds: Array<string | undefined> = [];
37
+ for (const seed of ['run-1-activity-0', 'run-1-activity-1']) {
38
+ withLangfuseRuntimeScope(
39
+ resolveLangfuseRuntimeScope({ traceIdSeed: seed }),
40
+ () => {
41
+ seeds.push(getTraceIdSeed());
42
+ }
43
+ );
44
+ }
45
+ expect(seeds).toEqual(['run-1-activity-0', 'run-1-activity-1']);
46
+ });
47
+ });