@librechat/agents 3.1.50 → 3.1.52

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 (85) hide show
  1. package/dist/cjs/graphs/Graph.cjs +43 -16
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/messages/format.cjs +8 -1
  4. package/dist/cjs/messages/format.cjs.map +1 -1
  5. package/dist/cjs/run.cjs +32 -2
  6. package/dist/cjs/run.cjs.map +1 -1
  7. package/dist/cjs/utils/run.cjs +3 -1
  8. package/dist/cjs/utils/run.cjs.map +1 -1
  9. package/dist/esm/graphs/Graph.mjs +43 -16
  10. package/dist/esm/graphs/Graph.mjs.map +1 -1
  11. package/dist/esm/messages/format.mjs +8 -1
  12. package/dist/esm/messages/format.mjs.map +1 -1
  13. package/dist/esm/run.mjs +32 -2
  14. package/dist/esm/run.mjs.map +1 -1
  15. package/dist/esm/utils/run.mjs +3 -1
  16. package/dist/esm/utils/run.mjs.map +1 -1
  17. package/dist/types/graphs/Graph.d.ts +7 -0
  18. package/dist/types/run.d.ts +1 -0
  19. package/dist/types/types/run.d.ts +2 -0
  20. package/package.json +1 -1
  21. package/src/graphs/Graph.ts +49 -20
  22. package/src/messages/format.ts +12 -1
  23. package/src/messages/formatAgentMessages.test.ts +184 -0
  24. package/src/run.ts +40 -2
  25. package/src/scripts/ant_web_search.ts +1 -0
  26. package/src/scripts/ant_web_search_edge_case.ts +1 -0
  27. package/src/scripts/ant_web_search_error_edge_case.ts +1 -0
  28. package/src/scripts/bedrock-content-aggregation-test.ts +1 -0
  29. package/src/scripts/bedrock-parallel-tools-test.ts +1 -0
  30. package/src/scripts/caching.ts +1 -0
  31. package/src/scripts/code_exec.ts +1 -0
  32. package/src/scripts/code_exec_files.ts +1 -0
  33. package/src/scripts/code_exec_multi_session.ts +1 -0
  34. package/src/scripts/code_exec_ptc.ts +1 -0
  35. package/src/scripts/code_exec_session.ts +1 -0
  36. package/src/scripts/code_exec_simple.ts +1 -0
  37. package/src/scripts/content.ts +1 -0
  38. package/src/scripts/image.ts +1 -0
  39. package/src/scripts/memory.ts +16 -6
  40. package/src/scripts/multi-agent-chain.ts +1 -0
  41. package/src/scripts/multi-agent-conditional.ts +1 -0
  42. package/src/scripts/multi-agent-document-review-chain.ts +1 -0
  43. package/src/scripts/multi-agent-hybrid-flow.ts +1 -0
  44. package/src/scripts/multi-agent-parallel-start.ts +1 -0
  45. package/src/scripts/multi-agent-parallel.ts +1 -0
  46. package/src/scripts/multi-agent-sequence.ts +1 -0
  47. package/src/scripts/multi-agent-supervisor.ts +1 -0
  48. package/src/scripts/multi-agent-test.ts +1 -0
  49. package/src/scripts/parallel-asymmetric-tools-test.ts +1 -0
  50. package/src/scripts/parallel-full-metadata-test.ts +1 -0
  51. package/src/scripts/parallel-tools-test.ts +1 -0
  52. package/src/scripts/programmatic_exec_agent.ts +1 -0
  53. package/src/scripts/search.ts +1 -0
  54. package/src/scripts/sequential-full-metadata-test.ts +1 -0
  55. package/src/scripts/simple.ts +2 -1
  56. package/src/scripts/single-agent-metadata-test.ts +1 -0
  57. package/src/scripts/stream.ts +1 -0
  58. package/src/scripts/test-handoff-preamble.ts +1 -0
  59. package/src/scripts/test-handoff-steering.ts +3 -0
  60. package/src/scripts/test-multi-agent-list-handoff.ts +1 -0
  61. package/src/scripts/test-parallel-agent-labeling.ts +2 -0
  62. package/src/scripts/test-parallel-handoffs.ts +1 -0
  63. package/src/scripts/test-thinking-handoff-bedrock.ts +1 -0
  64. package/src/scripts/test-thinking-handoff.ts +1 -0
  65. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +1 -0
  66. package/src/scripts/test-tool-before-handoff-role-order.ts +1 -0
  67. package/src/scripts/test-tools-before-handoff.ts +1 -0
  68. package/src/scripts/thinking-bedrock.ts +1 -0
  69. package/src/scripts/thinking.ts +1 -0
  70. package/src/scripts/tools.ts +1 -0
  71. package/src/specs/agent-handoffs.test.ts +1 -0
  72. package/src/specs/anthropic.simple.test.ts +6 -2
  73. package/src/specs/azure.simple.test.ts +142 -3
  74. package/src/specs/cache.simple.test.ts +8 -0
  75. package/src/specs/custom-event-await.test.ts +2 -0
  76. package/src/specs/deepseek.simple.test.ts +3 -0
  77. package/src/specs/moonshot.simple.test.ts +5 -0
  78. package/src/specs/openai.simple.test.ts +3 -0
  79. package/src/specs/openrouter.simple.test.ts +1 -0
  80. package/src/specs/prune.test.ts +1 -0
  81. package/src/specs/reasoning.test.ts +1 -0
  82. package/src/specs/thinking-handoff.test.ts +1 -0
  83. package/src/specs/tool-error.test.ts +1 -0
  84. package/src/types/run.ts +2 -0
  85. package/src/utils/run.ts +4 -2
@@ -139,6 +139,26 @@ export abstract class Graph<
139
139
  * Currently supports code execution session tracking (session_id, files).
140
140
  */
141
141
  sessions: t.ToolSessionMap = new Map();
142
+
143
+ /**
144
+ * Clears heavy references to allow GC to reclaim memory held by
145
+ * LangGraph's internal config / AsyncLocalStorage RunTree chain.
146
+ * Call after a run completes and content has been extracted.
147
+ */
148
+ clearHeavyState(): void {
149
+ this.config = undefined;
150
+ this.signal = undefined;
151
+ this.contentData = [];
152
+ this.contentIndexMap = new Map();
153
+ this.stepKeyIds = new Map();
154
+ this.toolCallStepIds.clear();
155
+ this.messageIdsByStepKey = new Map();
156
+ this.messageStepHasToolCalls = new Map();
157
+ this.prelimMessageIdsByStepKey = new Map();
158
+ this.invokedToolIds = undefined;
159
+ this.handlerRegistry = undefined;
160
+ this.sessions.clear();
161
+ }
142
162
  }
143
163
 
144
164
  export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
@@ -218,6 +238,15 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
218
238
  }
219
239
  }
220
240
 
241
+ override clearHeavyState(): void {
242
+ super.clearHeavyState();
243
+ this.messages = [];
244
+ this.overrideModel = undefined;
245
+ for (const context of this.agentContexts.values()) {
246
+ context.reset();
247
+ }
248
+ }
249
+
221
250
  /* Run Step Processing */
222
251
 
223
252
  getRunStep(stepId: string): t.RunStep | undefined {
@@ -1039,26 +1068,26 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1039
1068
  },
1040
1069
  metadata
1041
1070
  );
1042
- }
1043
- const stepId = this.getStepIdByKey(stepKey);
1044
- const content = responseMessage.content;
1045
- if (typeof content === 'string') {
1046
- await this.dispatchMessageDelta(stepId, {
1047
- content: [{ type: ContentTypes.TEXT, text: content }],
1048
- });
1049
- } else if (
1050
- Array.isArray(content) &&
1051
- content.every(
1052
- (c) =>
1053
- typeof c === 'object' &&
1054
- 'type' in c &&
1055
- typeof c.type === 'string' &&
1056
- c.type.startsWith('text')
1057
- )
1058
- ) {
1059
- await this.dispatchMessageDelta(stepId, {
1060
- content: content as t.MessageDelta['content'],
1061
- });
1071
+ const stepId = this.getStepIdByKey(stepKey);
1072
+ const content = responseMessage.content;
1073
+ if (typeof content === 'string') {
1074
+ await this.dispatchMessageDelta(stepId, {
1075
+ content: [{ type: ContentTypes.TEXT, text: content }],
1076
+ });
1077
+ } else if (
1078
+ Array.isArray(content) &&
1079
+ content.every(
1080
+ (c) =>
1081
+ typeof c === 'object' &&
1082
+ 'type' in c &&
1083
+ typeof c.type === 'string' &&
1084
+ c.type.startsWith('text')
1085
+ )
1086
+ ) {
1087
+ await this.dispatchMessageDelta(stepId, {
1088
+ content: content as t.MessageDelta['content'],
1089
+ });
1090
+ }
1062
1091
  }
1063
1092
  }
1064
1093
 
@@ -371,7 +371,12 @@ function formatAssistantMessage(
371
371
  content: output != null ? output : '',
372
372
  })
373
373
  );
374
- } else if (part.type === ContentTypes.THINK) {
374
+ } else if (
375
+ part.type === ContentTypes.THINK ||
376
+ part.type === ContentTypes.THINKING ||
377
+ part.type === ContentTypes.REASONING_CONTENT ||
378
+ part.type === 'redacted_thinking'
379
+ ) {
375
380
  hasReasoning = true;
376
381
  continue;
377
382
  } else if (
@@ -380,6 +385,12 @@ function formatAssistantMessage(
380
385
  ) {
381
386
  continue;
382
387
  } else {
388
+ if (
389
+ part.type === ContentTypes.TEXT &&
390
+ !String(part.text ?? '').trim()
391
+ ) {
392
+ continue;
393
+ }
383
394
  currentContent.push(part);
384
395
  }
385
396
  }
@@ -829,6 +829,190 @@ describe('formatAgentMessages', () => {
829
829
  );
830
830
  });
831
831
 
832
+ it('should strip reasoning_content blocks and join TEXT parts as string', () => {
833
+ const payload = [
834
+ {
835
+ role: 'assistant',
836
+ content: [
837
+ { type: ContentTypes.TEXT, [ContentTypes.TEXT]: '\n\n' },
838
+ {
839
+ type: ContentTypes.REASONING_CONTENT,
840
+ reasoningText: { text: 'Thinking deeply...', signature: 'sig123' },
841
+ index: 0,
842
+ },
843
+ { type: ContentTypes.TEXT, [ContentTypes.TEXT]: 'The answer is 42.' },
844
+ ],
845
+ },
846
+ ];
847
+
848
+ const result = formatAgentMessages(payload);
849
+
850
+ expect(result.messages).toHaveLength(1);
851
+ expect(result.messages[0]).toBeInstanceOf(AIMessage);
852
+ expect(result.messages[0].content).toBe('The answer is 42.');
853
+ expect(JSON.stringify(result.messages[0].content)).not.toContain(
854
+ 'reasoning_content'
855
+ );
856
+ });
857
+
858
+ it('should strip thinking blocks and join TEXT parts as string', () => {
859
+ const payload = [
860
+ {
861
+ role: 'assistant',
862
+ content: [
863
+ {
864
+ type: ContentTypes.THINKING,
865
+ thinking: 'Internal reasoning...',
866
+ signature: 'sig456',
867
+ },
868
+ {
869
+ type: ContentTypes.TEXT,
870
+ [ContentTypes.TEXT]: 'Here is my answer.',
871
+ },
872
+ ],
873
+ },
874
+ ];
875
+
876
+ const result = formatAgentMessages(payload);
877
+
878
+ expect(result.messages).toHaveLength(1);
879
+ expect(result.messages[0]).toBeInstanceOf(AIMessage);
880
+ expect(result.messages[0].content).toBe('Here is my answer.');
881
+ expect(JSON.stringify(result.messages[0].content)).not.toContain(
882
+ 'thinking'
883
+ );
884
+ });
885
+
886
+ it('should strip redacted_thinking blocks and join TEXT parts as string', () => {
887
+ const payload = [
888
+ {
889
+ role: 'assistant',
890
+ content: [
891
+ { type: 'redacted_thinking', data: 'REDACTED_SIGNATURE' },
892
+ {
893
+ type: ContentTypes.TEXT,
894
+ [ContentTypes.TEXT]: 'Here is my answer.',
895
+ },
896
+ ],
897
+ },
898
+ ];
899
+
900
+ const result = formatAgentMessages(payload);
901
+
902
+ expect(result.messages).toHaveLength(1);
903
+ expect(result.messages[0]).toBeInstanceOf(AIMessage);
904
+ expect(result.messages[0].content).toBe('Here is my answer.');
905
+ expect(JSON.stringify(result.messages[0].content)).not.toContain(
906
+ 'redacted_thinking'
907
+ );
908
+ });
909
+
910
+ it('should produce no AIMessage when only reasoning_content and whitespace text are present', () => {
911
+ const payload = [
912
+ {
913
+ role: 'assistant',
914
+ content: [
915
+ { type: ContentTypes.TEXT, [ContentTypes.TEXT]: '\n\n' },
916
+ {
917
+ type: ContentTypes.REASONING_CONTENT,
918
+ reasoningText: { text: 'Silent reasoning', signature: 'sig' },
919
+ },
920
+ ],
921
+ },
922
+ ];
923
+
924
+ const result = formatAgentMessages(payload);
925
+
926
+ expect(result.messages).toHaveLength(0);
927
+ });
928
+
929
+ it('should drop whitespace-only text parts from non-reasoning messages', () => {
930
+ const payload = [
931
+ {
932
+ role: 'assistant',
933
+ content: [
934
+ { type: ContentTypes.TEXT, [ContentTypes.TEXT]: '\n\n' },
935
+ {
936
+ type: ContentTypes.TEXT,
937
+ [ContentTypes.TEXT]: 'Actual content here.',
938
+ },
939
+ { type: ContentTypes.TEXT, [ContentTypes.TEXT]: ' ' },
940
+ ],
941
+ },
942
+ ];
943
+
944
+ const result = formatAgentMessages(payload);
945
+
946
+ expect(result.messages).toHaveLength(1);
947
+ expect(result.messages[0]).toBeInstanceOf(AIMessage);
948
+ const content = result.messages[0].content;
949
+ expect(Array.isArray(content)).toBe(true);
950
+ expect(
951
+ (content as { type: string; text?: string }[]).every(
952
+ (p) => (p.text ?? '').trim() !== ''
953
+ )
954
+ ).toBe(true);
955
+ });
956
+
957
+ it('should preserve whitespace-only text that has tool_call_ids (common Bedrock pattern)', () => {
958
+ const payload = [
959
+ {
960
+ role: 'assistant',
961
+ content: [
962
+ {
963
+ type: ContentTypes.TEXT,
964
+ [ContentTypes.TEXT]: '\n\n',
965
+ tool_call_ids: ['tc-1'],
966
+ },
967
+ {
968
+ type: ContentTypes.TOOL_CALL,
969
+ tool_call: {
970
+ id: 'tc-1',
971
+ name: 'search',
972
+ args: '{"query":"test"}',
973
+ output: 'Results here',
974
+ },
975
+ },
976
+ ],
977
+ },
978
+ ];
979
+
980
+ const result = formatAgentMessages(payload);
981
+
982
+ expect(result.messages).toHaveLength(2);
983
+ expect(result.messages[0]).toBeInstanceOf(AIMessage);
984
+ expect(result.messages[1]).toBeInstanceOf(ToolMessage);
985
+ expect((result.messages[0] as AIMessage).tool_calls).toHaveLength(1);
986
+ expect((result.messages[1] as ToolMessage).tool_call_id).toBe('tc-1');
987
+ });
988
+
989
+ it('should handle whitespace-only text without tool_call_ids before a tool call', () => {
990
+ const payload = [
991
+ {
992
+ role: 'assistant',
993
+ content: [
994
+ { type: ContentTypes.TEXT, [ContentTypes.TEXT]: '\n\n' },
995
+ {
996
+ type: ContentTypes.TOOL_CALL,
997
+ tool_call: {
998
+ id: 'tc-2',
999
+ name: 'search',
1000
+ args: '{"query":"test"}',
1001
+ output: 'Results here',
1002
+ },
1003
+ },
1004
+ ],
1005
+ },
1006
+ ];
1007
+
1008
+ const result = formatAgentMessages(payload);
1009
+
1010
+ expect(result.messages).toHaveLength(2);
1011
+ expect(result.messages[0]).toBeInstanceOf(AIMessage);
1012
+ expect(result.messages[1]).toBeInstanceOf(ToolMessage);
1013
+ expect((result.messages[0] as AIMessage).tool_calls).toHaveLength(1);
1014
+ });
1015
+
832
1016
  it('should exclude ERROR type content parts', () => {
833
1017
  const payload = [
834
1018
  {
package/src/run.ts CHANGED
@@ -45,6 +45,7 @@ export class Run<_T extends t.BaseGraphState> {
45
45
  graphRunnable?: t.CompiledStateWorkflow;
46
46
  Graph: StandardGraph | MultiAgentGraph | undefined;
47
47
  returnContent: boolean = false;
48
+ private skipCleanup: boolean = false;
48
49
 
49
50
  private constructor(config: Partial<t.RunConfig>) {
50
51
  const runId = config.runId ?? '';
@@ -89,6 +90,7 @@ export class Run<_T extends t.BaseGraphState> {
89
90
  }
90
91
 
91
92
  this.returnContent = config.returnContent ?? false;
93
+ this.skipCleanup = config.skipCleanup ?? false;
92
94
  }
93
95
 
94
96
  private createLegacyGraph(
@@ -303,9 +305,45 @@ export class Run<_T extends t.BaseGraphState> {
303
305
  }
304
306
  }
305
307
 
306
- if (this.returnContent) {
307
- return this.Graph.getContentParts();
308
+ /**
309
+ * Break the reference chain that keeps heavy data alive via
310
+ * LangGraph's internal `__pregel_scratchpad.currentTaskInput` →
311
+ * `@langchain/core` `RunTree.extra[lc:child_config]` →
312
+ * Node.js `AsyncLocalStorage` context captured by timers/promises.
313
+ *
314
+ * Without this, base64-encoded images/PDFs in message content remain
315
+ * reachable from lingering `Timeout` handles until GC runs.
316
+ */
317
+ if (!this.skipCleanup) {
318
+ if (
319
+ (config.configurable as Record<string, unknown> | undefined) != null
320
+ ) {
321
+ for (const key of Object.getOwnPropertySymbols(config.configurable)) {
322
+ const val = config.configurable[key as unknown as string] as
323
+ | Record<string, unknown>
324
+ | undefined;
325
+ if (
326
+ val != null &&
327
+ typeof val === 'object' &&
328
+ 'currentTaskInput' in val
329
+ ) {
330
+ (val as Record<string, unknown>).currentTaskInput = undefined;
331
+ }
332
+ delete config.configurable[key as unknown as string];
333
+ }
334
+ config.configurable = undefined;
335
+ }
336
+ config.callbacks = undefined;
337
+ }
338
+
339
+ const result = this.returnContent
340
+ ? this.Graph.getContentParts()
341
+ : undefined;
342
+
343
+ if (!this.skipCleanup) {
344
+ this.Graph.clearHeavyState();
308
345
  }
346
+ return result;
309
347
  }
310
348
 
311
349
  private createSystemCallback<K extends keyof t.ClientCallbacks>(
@@ -98,6 +98,7 @@ async function testStandardStreaming(): Promise<void> {
98
98
  // additional_instructions: `Always address the user by their name. The user's name is ${userName} and they are located in ${location}.`,
99
99
  },
100
100
  returnContent: true,
101
+ skipCleanup: true,
101
102
  customHandlers,
102
103
  });
103
104
 
@@ -100,6 +100,7 @@ async function testStandardStreaming(): Promise<void> {
100
100
  // additional_instructions: `Always address the user by their name. The user's name is ${userName} and they are located in ${location}.`,
101
101
  },
102
102
  returnContent: true,
103
+ skipCleanup: true,
103
104
  customHandlers,
104
105
  });
105
106
 
@@ -97,6 +97,7 @@ async function testStandardStreaming(): Promise<void> {
97
97
  instructions: 'You are a helpful AI research assistant.',
98
98
  },
99
99
  returnContent: true,
100
+ skipCleanup: true,
100
101
  customHandlers,
101
102
  });
102
103
 
@@ -136,6 +136,7 @@ async function testBedrockContentAggregation(): Promise<void> {
136
136
  llmConfig,
137
137
  },
138
138
  returnContent: true,
139
+ skipCleanup: true,
139
140
  customHandlers: customHandlers as t.RunConfig['customHandlers'],
140
141
  });
141
142
 
@@ -123,6 +123,7 @@ async function testParallelToolCalls(): Promise<void> {
123
123
  llmConfig,
124
124
  },
125
125
  returnContent: true,
126
+ skipCleanup: true,
126
127
  customHandlers: customHandlers as t.RunConfig['customHandlers'],
127
128
  });
128
129
 
@@ -74,6 +74,7 @@ ${CACHED_TEXT}`;
74
74
  llmConfig,
75
75
  },
76
76
  returnContent: true,
77
+ skipCleanup: true,
77
78
  customHandlers,
78
79
  });
79
80
 
@@ -93,6 +93,7 @@ async function testCodeExecution(): Promise<void> {
93
93
  additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
94
94
  },
95
95
  returnContent: true,
96
+ skipCleanup: true,
96
97
  customHandlers,
97
98
  });
98
99
 
@@ -127,6 +127,7 @@ async function testCodeExecution(): Promise<void> {
127
127
  additional_instructions: `The user's name is ${userName} and they are located in ${location}. The current date is ${currentDate}.`,
128
128
  },
129
129
  returnContent: true,
130
+ skipCleanup: true,
130
131
  customHandlers,
131
132
  });
132
133
 
@@ -73,6 +73,7 @@ When reading files, print their contents.
73
73
  Be concise in responses.`,
74
74
  },
75
75
  returnContent: true,
76
+ skipCleanup: true,
76
77
  customHandlers,
77
78
  });
78
79
 
@@ -217,6 +217,7 @@ async function testProgrammaticToolCalling(): Promise<void> {
217
217
  ],
218
218
  },
219
219
  returnContent: true,
220
+ skipCleanup: true,
220
221
  customHandlers,
221
222
  });
222
223
 
@@ -141,6 +141,7 @@ When writing Python code:
141
141
  additional_instructions: `User: ${userName}, Location: ${location}, Date: ${currentDate}.`,
142
142
  },
143
143
  returnContent: true,
144
+ skipCleanup: true,
144
145
  customHandlers,
145
146
  });
146
147
 
@@ -101,6 +101,7 @@ async function testCodeExecution(): Promise<void> {
101
101
  maxContextTokens: 8000,
102
102
  },
103
103
  returnContent: true,
104
+ skipCleanup: true,
104
105
  customHandlers,
105
106
  indexTokenCountMap,
106
107
  tokenCounter,
@@ -88,6 +88,7 @@ async function testStandardStreaming(): Promise<void> {
88
88
  additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
89
89
  },
90
90
  returnContent: true,
91
+ skipCleanup: true,
91
92
  customHandlers,
92
93
  });
93
94
 
@@ -94,6 +94,7 @@ async function testCodeExecution(): Promise<void> {
94
94
  additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
95
95
  },
96
96
  returnContent: true,
97
+ skipCleanup: true,
97
98
  customHandlers,
98
99
  });
99
100
 
@@ -17,19 +17,27 @@ const memoryKv: Record<string, string> = {};
17
17
  const setMemory = tool(
18
18
  async ({ key, value }) => {
19
19
  if (!/^[a-z_]+$/.test(key)) {
20
- throw new Error('Key must only contain lowercase letters and underscores');
20
+ throw new Error(
21
+ 'Key must only contain lowercase letters and underscores'
22
+ );
21
23
  }
22
-
24
+
23
25
  memoryKv[key] = value;
24
-
26
+
25
27
  return { ok: true };
26
28
  },
27
29
  {
28
30
  name: 'set_memory',
29
31
  description: 'Saves important data about the user into memory.',
30
32
  schema: z.object({
31
- key: z.string().describe('The key of the memory value. Always use lowercase and underscores, no other characters.'),
32
- value: z.string().describe('Value can be anything represented as a string')
33
+ key: z
34
+ .string()
35
+ .describe(
36
+ 'The key of the memory value. Always use lowercase and underscores, no other characters.'
37
+ ),
38
+ value: z
39
+ .string()
40
+ .describe('Value can be anything represented as a string'),
33
41
  }),
34
42
  }
35
43
  );
@@ -48,10 +56,12 @@ async function testStandardStreaming(): Promise<void> {
48
56
  streaming: false,
49
57
  },
50
58
  tools: [setMemory],
51
- instructions: 'You can use the `set_memory` tool to save important data about the user into memory. If there is nothing to note about the user specifically, respond with `nothing`.',
59
+ instructions:
60
+ 'You can use the `set_memory` tool to save important data about the user into memory. If there is nothing to note about the user specifically, respond with `nothing`.',
52
61
  toolEnd: true,
53
62
  },
54
63
  returnContent: true,
64
+ skipCleanup: true,
55
65
  });
56
66
 
57
67
  const config = {
@@ -258,6 +258,7 @@ async function testSequentialAgentChain() {
258
258
  },
259
259
  customHandlers,
260
260
  returnContent: true,
261
+ skipCleanup: true,
261
262
  };
262
263
 
263
264
  try {
@@ -166,6 +166,7 @@ async function testConditionalMultiAgent() {
166
166
  },
167
167
  customHandlers,
168
168
  returnContent: true,
169
+ skipCleanup: true,
169
170
  };
170
171
 
171
172
  try {
@@ -142,6 +142,7 @@ async function testDocumentReviewChain() {
142
142
  },
143
143
  customHandlers,
144
144
  returnContent: true,
145
+ skipCleanup: true,
145
146
  };
146
147
 
147
148
  try {
@@ -240,6 +240,7 @@ async function testHybridMultiAgent() {
240
240
  },
241
241
  customHandlers,
242
242
  returnContent: true,
243
+ skipCleanup: true,
243
244
  };
244
245
 
245
246
  // Create and execute a new run for this test
@@ -170,6 +170,7 @@ async function testParallelFromStart() {
170
170
  },
171
171
  customHandlers,
172
172
  returnContent: true,
173
+ skipCleanup: true,
173
174
  };
174
175
 
175
176
  try {
@@ -322,6 +322,7 @@ async function testParallelMultiAgent() {
322
322
  },
323
323
  customHandlers,
324
324
  returnContent: true,
325
+ skipCleanup: true,
325
326
  };
326
327
 
327
328
  try {
@@ -158,6 +158,7 @@ async function testSequentialMultiAgent() {
158
158
  },
159
159
  customHandlers,
160
160
  returnContent: true,
161
+ skipCleanup: true,
161
162
  };
162
163
 
163
164
  try {
@@ -293,6 +293,7 @@ async function testSupervisorMultiAgent() {
293
293
  },
294
294
  customHandlers,
295
295
  returnContent: true,
296
+ skipCleanup: true,
296
297
  };
297
298
  }
298
299
 
@@ -141,6 +141,7 @@ async function testMultiAgentHandoff() {
141
141
  },
142
142
  customHandlers,
143
143
  returnContent: true,
144
+ skipCleanup: true,
144
145
  };
145
146
 
146
147
  try {
@@ -182,6 +182,7 @@ async function testAsymmetricParallelTools() {
182
182
  },
183
183
  customHandlers,
184
184
  returnContent: true,
185
+ skipCleanup: true,
185
186
  };
186
187
 
187
188
  try {
@@ -148,6 +148,7 @@ async function testFullMetadata() {
148
148
  },
149
149
  customHandlers,
150
150
  returnContent: true,
151
+ skipCleanup: true,
151
152
  };
152
153
 
153
154
  try {
@@ -222,6 +222,7 @@ async function testParallelWithTools() {
222
222
  },
223
223
  customHandlers,
224
224
  returnContent: true,
225
+ skipCleanup: true,
225
226
  };
226
227
 
227
228
  try {
@@ -138,6 +138,7 @@ async function main(): Promise<void> {
138
138
  ],
139
139
  },
140
140
  returnContent: true,
141
+ skipCleanup: true,
141
142
  });
142
143
 
143
144
  const config: Partial<RunnableConfig> & {
@@ -91,6 +91,7 @@ async function testStandardStreaming(): Promise<void> {
91
91
  // additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
92
92
  },
93
93
  returnContent: true,
94
+ skipCleanup: true,
94
95
  customHandlers,
95
96
  });
96
97