@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.
- package/dist/cjs/agents/AgentContext.cjs +117 -3
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +4 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +243 -49
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +103 -28
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +4 -0
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +11 -2
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/contextOverflowRecovery.cjs +132 -0
- package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -0
- package/dist/cjs/llm/google/index.cjs +1 -1
- package/dist/cjs/llm/invoke.cjs +60 -3
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +1 -1
- package/dist/cjs/main.cjs +21 -7
- package/dist/cjs/messages/format.cjs +136 -4
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +16 -5
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/recency.cjs +2 -0
- package/dist/cjs/messages/recency.cjs.map +1 -1
- package/dist/cjs/prompts/activityLabel.cjs +101 -0
- package/dist/cjs/prompts/activityLabel.cjs.map +1 -0
- package/dist/cjs/run.cjs +177 -3
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +205 -49
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +55 -7
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +2 -2
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +2 -2
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +69 -8
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +19 -15
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +32 -3
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
- package/dist/cjs/utils/errors.cjs +317 -52
- package/dist/cjs/utils/errors.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +118 -4
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +4 -0
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +242 -48
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +103 -28
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +4 -1
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +11 -2
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/contextOverflowRecovery.mjs +130 -0
- package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -0
- package/dist/esm/llm/google/index.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +59 -4
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +1 -1
- package/dist/esm/main.mjs +10 -10
- package/dist/esm/messages/format.mjs +136 -5
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +14 -6
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/recency.mjs +2 -1
- package/dist/esm/messages/recency.mjs.map +1 -1
- package/dist/esm/prompts/activityLabel.mjs +100 -0
- package/dist/esm/prompts/activityLabel.mjs.map +1 -0
- package/dist/esm/run.mjs +178 -4
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +205 -49
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +55 -7
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +3 -3
- package/dist/esm/tools/BashExecutor.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +3 -3
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +62 -9
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +20 -16
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +32 -3
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
- package/dist/esm/utils/errors.mjs +317 -53
- package/dist/esm/utils/errors.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +62 -3
- package/dist/types/common/enum.d.ts +5 -1
- package/dist/types/graphs/Graph.d.ts +16 -2
- package/dist/types/graphs/MultiAgentGraph.d.ts +1 -0
- package/dist/types/langfuseToolOutputTracing.d.ts +4 -0
- package/dist/types/llm/contextOverflowRecovery.d.ts +85 -0
- package/dist/types/llm/invoke.d.ts +35 -6
- package/dist/types/messages/format.d.ts +22 -0
- package/dist/types/messages/prune.d.ts +10 -2
- package/dist/types/messages/recency.d.ts +1 -0
- package/dist/types/prompts/activityLabel.d.ts +31 -0
- package/dist/types/run.d.ts +16 -0
- package/dist/types/tools/CodeExecutor.d.ts +14 -1
- package/dist/types/types/activityLabel.d.ts +53 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/llm.d.ts +7 -4
- package/dist/types/types/stream.d.ts +7 -4
- package/dist/types/types/summarize.d.ts +22 -0
- package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +40 -0
- package/dist/types/utils/errors.d.ts +65 -16
- package/dist/types/utils/redactSecrets.d.ts +3 -0
- package/package.json +7 -8
- package/src/agents/AgentContext.ts +188 -7
- package/src/agents/__tests__/AgentContext.overflow.test.ts +205 -0
- package/src/common/enum.ts +4 -0
- package/src/graphs/Graph.ts +409 -58
- package/src/graphs/MultiAgentGraph.ts +184 -46
- package/src/graphs/__tests__/Graph.contextOverflow.test.ts +631 -0
- package/src/langfuseToolOutputTracing.ts +4 -1
- package/src/llm/__tests__/contextOverflowRecovery.test.ts +401 -0
- package/src/llm/__tests__/fallbackOverflow.test.ts +287 -0
- package/src/llm/bedrock/index.ts +25 -12
- package/src/llm/contextOverflowRecovery.ts +292 -0
- package/src/llm/invoke.ts +119 -4
- package/src/messages/foldToollessToolBlocks.test.ts +438 -0
- package/src/messages/format.ts +233 -5
- package/src/messages/prune.ts +24 -11
- package/src/messages/recency.ts +3 -1
- package/src/prompts/activityLabel.ts +177 -0
- package/src/run.ts +322 -3
- package/src/scripts/context-overflow-probe.ts +997 -0
- package/src/specs/activity-label-prompt.test.ts +128 -0
- package/src/specs/activity-label-trace-seed.test.ts +47 -0
- package/src/specs/agent-handoffs.test.ts +903 -1
- package/src/specs/bedrock-toolless.live.test.ts +123 -0
- package/src/specs/context-overflow-recovery.live.test.ts +213 -0
- package/src/splitStream.test.ts +882 -0
- package/src/stream.ts +315 -51
- package/src/summarization/__tests__/aggregator.test.ts +83 -0
- package/src/summarization/__tests__/node.test.ts +139 -0
- package/src/summarization/node.ts +99 -14
- package/src/tools/BashExecutor.ts +4 -2
- package/src/tools/BashProgrammaticToolCalling.ts +4 -7
- package/src/tools/CodeExecutor.ts +119 -8
- package/src/tools/ProgrammaticToolCalling.ts +29 -27
- package/src/tools/ToolNode.ts +50 -8
- package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +297 -3
- package/src/types/activityLabel.ts +55 -0
- package/src/types/index.ts +1 -0
- package/src/types/llm.ts +8 -1
- package/src/types/stream.ts +7 -4
- package/src/types/summarize.ts +22 -0
- package/src/utils/__tests__/errors.test.ts +270 -0
- package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +336 -0
- package/src/utils/__tests__/redactSecrets.test.ts +56 -0
- package/src/utils/errors.ts +484 -66
- package/src/utils/redactSecrets.ts +61 -0
|
@@ -145,6 +145,38 @@ describe('CodeAPI auth header injection', () => {
|
|
|
145
145
|
);
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
+
it('maps dynamic auth-header failures to the safe authorization error', async () => {
|
|
149
|
+
const authHeaders = jest.fn(async () => {
|
|
150
|
+
throw new Error(
|
|
151
|
+
'credential helper failed for secret codeapi-signing-key in namespace internal-auth'
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
const tool = createProgrammaticToolCallingTool({ authHeaders });
|
|
155
|
+
|
|
156
|
+
const error = await tool
|
|
157
|
+
.invoke(
|
|
158
|
+
{ code: 'print("hello")' },
|
|
159
|
+
{
|
|
160
|
+
toolCall: {
|
|
161
|
+
name: 'programmatic_code_execution',
|
|
162
|
+
args: {},
|
|
163
|
+
toolMap: toolMap(),
|
|
164
|
+
toolDefs,
|
|
165
|
+
},
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
.catch((caught: unknown) => caught);
|
|
169
|
+
|
|
170
|
+
expect(error).toBeInstanceOf(Error);
|
|
171
|
+
expect((error as Error).message).toContain(
|
|
172
|
+
'Code execution is not authorized. Verify access before trying again.'
|
|
173
|
+
);
|
|
174
|
+
expect((error as Error).message).not.toContain('Please retry');
|
|
175
|
+
expect((error as Error).message).not.toContain('codeapi-signing-key');
|
|
176
|
+
expect((error as Error).message).not.toContain('internal-auth');
|
|
177
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
178
|
+
});
|
|
179
|
+
|
|
148
180
|
it('forwards Authorization for direct code execution', async () => {
|
|
149
181
|
fetchMock.mockResolvedValueOnce(
|
|
150
182
|
jsonResponse({ session_id: 'session_123', stdout: '1\n' })
|
|
@@ -202,12 +234,274 @@ describe('CodeAPI auth header injection', () => {
|
|
|
202
234
|
).not.toHaveProperty('authHeaders');
|
|
203
235
|
});
|
|
204
236
|
|
|
205
|
-
it('
|
|
237
|
+
it('redacts the CodeAPI endpoint and response body on direct execution failures', async () => {
|
|
206
238
|
fetchMock.mockResolvedValueOnce(errorResponse(404, 'Cannot POST /exec'));
|
|
207
239
|
const tool = createBashExecutionTool();
|
|
208
240
|
|
|
209
|
-
|
|
210
|
-
|
|
241
|
+
const error = await tool
|
|
242
|
+
.invoke({ command: 'echo 1' })
|
|
243
|
+
.catch((caught: unknown) => caught);
|
|
244
|
+
|
|
245
|
+
expect(error).toBeInstanceOf(Error);
|
|
246
|
+
expect((error as Error).message).toContain(
|
|
247
|
+
'Code execution is temporarily unavailable. Please retry.'
|
|
248
|
+
);
|
|
249
|
+
expect((error as Error).message).not.toContain('/exec');
|
|
250
|
+
expect((error as Error).message).not.toContain('Cannot POST');
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it.each([401, 403])(
|
|
254
|
+
'reports CodeAPI HTTP %s authorization failures as non-retryable',
|
|
255
|
+
async (status) => {
|
|
256
|
+
fetchMock.mockResolvedValueOnce(
|
|
257
|
+
errorResponse(
|
|
258
|
+
status,
|
|
259
|
+
'Invalid bearer token for codeapi.internal.svc.cluster.local'
|
|
260
|
+
)
|
|
261
|
+
);
|
|
262
|
+
const tool = createBashExecutionTool();
|
|
263
|
+
|
|
264
|
+
const error = await tool
|
|
265
|
+
.invoke({ command: 'echo 1' })
|
|
266
|
+
.catch((caught: unknown) => caught);
|
|
267
|
+
|
|
268
|
+
expect(error).toBeInstanceOf(Error);
|
|
269
|
+
expect((error as Error).message).toContain(
|
|
270
|
+
'Code execution is not authorized. Verify access before trying again.'
|
|
271
|
+
);
|
|
272
|
+
expect((error as Error).message).not.toContain('Please retry');
|
|
273
|
+
expect((error as Error).message).not.toContain('svc.cluster.local');
|
|
274
|
+
expect((error as Error).message).not.toContain('Invalid bearer token');
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
it('preserves only a bounded retry delay from CodeAPI rate-limit failures', async () => {
|
|
279
|
+
fetchMock.mockResolvedValueOnce(
|
|
280
|
+
errorResponse(
|
|
281
|
+
429,
|
|
282
|
+
JSON.stringify({
|
|
283
|
+
error: 'rate_limited',
|
|
284
|
+
message:
|
|
285
|
+
'Too many CodeAPI execution requests from internal deployment details.',
|
|
286
|
+
retry_after_seconds: 8.2,
|
|
287
|
+
})
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
const tool = createBashExecutionTool();
|
|
291
|
+
|
|
292
|
+
const error = await tool
|
|
293
|
+
.invoke({ command: 'echo 1' })
|
|
294
|
+
.catch((caught: unknown) => caught);
|
|
295
|
+
|
|
296
|
+
expect(error).toBeInstanceOf(Error);
|
|
297
|
+
expect((error as Error).message).toContain(
|
|
298
|
+
'Code execution is temporarily rate-limited. Retry after 9 seconds.'
|
|
299
|
+
);
|
|
300
|
+
expect((error as Error).message).not.toContain('CodeAPI');
|
|
301
|
+
expect((error as Error).message).not.toContain('internal deployment');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('redacts network details from direct execution failures', async () => {
|
|
305
|
+
fetchMock.mockRejectedValueOnce(
|
|
306
|
+
new Error(
|
|
307
|
+
'request to http://codeapi.internal.svc.cluster.local/exec failed: getaddrinfo ENOTFOUND'
|
|
308
|
+
)
|
|
309
|
+
);
|
|
310
|
+
const tool = createBashExecutionTool();
|
|
311
|
+
|
|
312
|
+
const error = await tool
|
|
313
|
+
.invoke({ command: 'echo 1' })
|
|
314
|
+
.catch((caught: unknown) => caught);
|
|
315
|
+
|
|
316
|
+
expect(error).toBeInstanceOf(Error);
|
|
317
|
+
expect((error as Error).message).toContain(
|
|
318
|
+
'Code execution is temporarily unavailable. Please retry.'
|
|
319
|
+
);
|
|
320
|
+
expect((error as Error).message).not.toContain('svc.cluster.local');
|
|
321
|
+
expect((error as Error).message).not.toContain('ENOTFOUND');
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('redacts network details from programmatic execution failures', async () => {
|
|
325
|
+
fetchMock.mockRejectedValueOnce(
|
|
326
|
+
new Error(
|
|
327
|
+
'request to http://codeapi.internal.svc.cluster.local/exec/programmatic failed'
|
|
328
|
+
)
|
|
329
|
+
);
|
|
330
|
+
const tool = createProgrammaticToolCallingTool();
|
|
331
|
+
|
|
332
|
+
const error = await tool
|
|
333
|
+
.invoke(
|
|
334
|
+
{ code: 'print("hello")' },
|
|
335
|
+
{
|
|
336
|
+
toolCall: {
|
|
337
|
+
name: 'programmatic_code_execution',
|
|
338
|
+
args: {},
|
|
339
|
+
toolMap: toolMap(),
|
|
340
|
+
toolDefs,
|
|
341
|
+
},
|
|
342
|
+
}
|
|
343
|
+
)
|
|
344
|
+
.catch((caught: unknown) => caught);
|
|
345
|
+
|
|
346
|
+
expect(error).toBeInstanceOf(Error);
|
|
347
|
+
expect((error as Error).message).toContain(
|
|
348
|
+
'Code execution is temporarily unavailable. Please retry.'
|
|
349
|
+
);
|
|
350
|
+
expect((error as Error).message).not.toContain('svc.cluster.local');
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('redacts CodeAPI programmatic errors while preserving execution stderr', async () => {
|
|
354
|
+
fetchMock.mockResolvedValueOnce(
|
|
355
|
+
jsonResponse({
|
|
356
|
+
status: 'error',
|
|
357
|
+
error:
|
|
358
|
+
'sandbox worker codeapi-runtime-7f9d failed in internal namespace',
|
|
359
|
+
stderr: 'NameError: tenant_variable is not defined',
|
|
360
|
+
})
|
|
361
|
+
);
|
|
362
|
+
const tool = createProgrammaticToolCallingTool();
|
|
363
|
+
|
|
364
|
+
const error = await tool
|
|
365
|
+
.invoke(
|
|
366
|
+
{ code: 'print(tenant_variable)' },
|
|
367
|
+
{
|
|
368
|
+
toolCall: {
|
|
369
|
+
name: 'programmatic_code_execution',
|
|
370
|
+
args: {},
|
|
371
|
+
toolMap: toolMap(),
|
|
372
|
+
toolDefs,
|
|
373
|
+
},
|
|
374
|
+
}
|
|
375
|
+
)
|
|
376
|
+
.catch((caught: unknown) => caught);
|
|
377
|
+
|
|
378
|
+
expect(error).toBeInstanceOf(Error);
|
|
379
|
+
expect((error as Error).message).toContain('Code execution failed.');
|
|
380
|
+
expect((error as Error).message).toContain(
|
|
381
|
+
'NameError: tenant_variable is not defined'
|
|
382
|
+
);
|
|
383
|
+
expect((error as Error).message).not.toContain('codeapi-runtime');
|
|
384
|
+
expect((error as Error).message).not.toContain('internal namespace');
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it('preserves an allowlisted programmatic execution error when stderr is absent', async () => {
|
|
388
|
+
fetchMock.mockResolvedValueOnce(
|
|
389
|
+
jsonResponse({
|
|
390
|
+
status: 'error',
|
|
391
|
+
error: 'Time limit exceeded',
|
|
392
|
+
})
|
|
393
|
+
);
|
|
394
|
+
const tool = createProgrammaticToolCallingTool();
|
|
395
|
+
|
|
396
|
+
const error = await tool
|
|
397
|
+
.invoke(
|
|
398
|
+
{ code: 'while True: pass' },
|
|
399
|
+
{
|
|
400
|
+
toolCall: {
|
|
401
|
+
name: 'programmatic_code_execution',
|
|
402
|
+
args: {},
|
|
403
|
+
toolMap: toolMap(),
|
|
404
|
+
toolDefs,
|
|
405
|
+
},
|
|
406
|
+
}
|
|
407
|
+
)
|
|
408
|
+
.catch((caught: unknown) => caught);
|
|
409
|
+
|
|
410
|
+
expect(error).toBeInstanceOf(Error);
|
|
411
|
+
expect((error as Error).message).toContain(
|
|
412
|
+
'Code execution failed. Execution exceeded the time limit.'
|
|
413
|
+
);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('preserves an allowlisted execution error alongside stderr', async () => {
|
|
417
|
+
fetchMock.mockResolvedValueOnce(
|
|
418
|
+
jsonResponse({
|
|
419
|
+
status: 'error',
|
|
420
|
+
error: 'Time limit exceeded',
|
|
421
|
+
stderr: 'processed 42 records before termination',
|
|
422
|
+
})
|
|
423
|
+
);
|
|
424
|
+
const tool = createProgrammaticToolCallingTool();
|
|
425
|
+
|
|
426
|
+
const error = await tool
|
|
427
|
+
.invoke(
|
|
428
|
+
{ code: 'while True: process_next_record()' },
|
|
429
|
+
{
|
|
430
|
+
toolCall: {
|
|
431
|
+
name: 'programmatic_code_execution',
|
|
432
|
+
args: {},
|
|
433
|
+
toolMap: toolMap(),
|
|
434
|
+
toolDefs,
|
|
435
|
+
},
|
|
436
|
+
}
|
|
437
|
+
)
|
|
438
|
+
.catch((caught: unknown) => caught);
|
|
439
|
+
|
|
440
|
+
expect(error).toBeInstanceOf(Error);
|
|
441
|
+
expect((error as Error).message).toContain(
|
|
442
|
+
'Code execution failed. Execution exceeded the time limit.'
|
|
443
|
+
);
|
|
444
|
+
expect((error as Error).message).toContain(
|
|
445
|
+
'Stderr:\nprocessed 42 records before termination'
|
|
446
|
+
);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it('keeps arbitrary programmatic execution errors redacted when stderr is absent', async () => {
|
|
450
|
+
fetchMock.mockResolvedValueOnce(
|
|
451
|
+
jsonResponse({
|
|
452
|
+
status: 'error',
|
|
453
|
+
error:
|
|
454
|
+
'sandbox worker codeapi-runtime-7f9d failed in internal namespace',
|
|
455
|
+
})
|
|
456
|
+
);
|
|
457
|
+
const tool = createProgrammaticToolCallingTool();
|
|
458
|
+
|
|
459
|
+
const error = await tool
|
|
460
|
+
.invoke(
|
|
461
|
+
{ code: 'print("hello")' },
|
|
462
|
+
{
|
|
463
|
+
toolCall: {
|
|
464
|
+
name: 'programmatic_code_execution',
|
|
465
|
+
args: {},
|
|
466
|
+
toolMap: toolMap(),
|
|
467
|
+
toolDefs,
|
|
468
|
+
},
|
|
469
|
+
}
|
|
470
|
+
)
|
|
471
|
+
.catch((caught: unknown) => caught);
|
|
472
|
+
|
|
473
|
+
expect(error).toBeInstanceOf(Error);
|
|
474
|
+
expect((error as Error).message).toContain('Code execution failed.');
|
|
475
|
+
expect((error as Error).message).not.toContain('codeapi-runtime');
|
|
476
|
+
expect((error as Error).message).not.toContain('internal namespace');
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it('preserves an allowlisted bash execution error when stderr is absent', async () => {
|
|
480
|
+
fetchMock.mockResolvedValueOnce(
|
|
481
|
+
jsonResponse({
|
|
482
|
+
status: 'error',
|
|
483
|
+
error: 'Out of memory',
|
|
484
|
+
})
|
|
485
|
+
);
|
|
486
|
+
const tool = createBashProgrammaticToolCallingTool();
|
|
487
|
+
|
|
488
|
+
const error = await tool
|
|
489
|
+
.invoke(
|
|
490
|
+
{ code: 'lookup_user "{}"' },
|
|
491
|
+
{
|
|
492
|
+
toolCall: {
|
|
493
|
+
name: 'bash_programmatic_code_execution',
|
|
494
|
+
args: {},
|
|
495
|
+
toolMap: toolMap(),
|
|
496
|
+
toolDefs,
|
|
497
|
+
},
|
|
498
|
+
}
|
|
499
|
+
)
|
|
500
|
+
.catch((caught: unknown) => caught);
|
|
501
|
+
|
|
502
|
+
expect(error).toBeInstanceOf(Error);
|
|
503
|
+
expect((error as Error).message).toContain(
|
|
504
|
+
'Code execution failed. Execution exceeded the memory limit.'
|
|
211
505
|
);
|
|
212
506
|
});
|
|
213
507
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
+
import type { ClientOptions } from '@/types/llm';
|
|
3
|
+
import type { Providers } from '@/common';
|
|
4
|
+
|
|
5
|
+
/** One tool call's contribution to the label payload (host-assembled). */
|
|
6
|
+
export type ActivityLabelToolEntry = {
|
|
7
|
+
toolName: string;
|
|
8
|
+
toolInput: unknown;
|
|
9
|
+
toolOutput?: unknown;
|
|
10
|
+
error?: string;
|
|
11
|
+
status: 'success' | 'error';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Options for `Run.generateActivityLabel`. The payload deliberately contains
|
|
16
|
+
* NO human messages: intent context comes from the assistant's own last text
|
|
17
|
+
* (Claude Code's pattern) and the block's reasoning excerpts (claude.ai's
|
|
18
|
+
* pattern) — user text stays out of this low-scrutiny pathway entirely.
|
|
19
|
+
*
|
|
20
|
+
* This SDK defines NO activity-label graph event and never dispatches one.
|
|
21
|
+
* Label lifecycle streaming is entirely host-owned: a host claims its own
|
|
22
|
+
* content slots and emits on its own transport, with a payload shape only
|
|
23
|
+
* it defines. The SDK surface here is exactly this method plus the
|
|
24
|
+
* `activity_label` content type's formatter exclusions.
|
|
25
|
+
*/
|
|
26
|
+
export type RunActivityLabelOptions = {
|
|
27
|
+
provider: Providers;
|
|
28
|
+
clientOptions?: ClientOptions;
|
|
29
|
+
/**
|
|
30
|
+
* Agent that executed the labeled batch. Selects that agent's Langfuse
|
|
31
|
+
* overlay (trace metadata AND tool-output redaction policy) instead of
|
|
32
|
+
* the graph default — a stricter per-agent policy must not be bypassed
|
|
33
|
+
* by labeling work the default agent never performed.
|
|
34
|
+
*/
|
|
35
|
+
agentId?: string;
|
|
36
|
+
entries: ActivityLabelToolEntry[];
|
|
37
|
+
/** Truncated reasoning excerpts from the block being labeled. */
|
|
38
|
+
thinkingExcerpts?: string[];
|
|
39
|
+
/** Assistant's last text before the block (~200 chars), as intent context. */
|
|
40
|
+
lastAssistantText?: string;
|
|
41
|
+
/** Override for the default label system prompt. */
|
|
42
|
+
prompt?: string;
|
|
43
|
+
/** Per-entry serialization cap for the prompt. Default 600. */
|
|
44
|
+
charLimit?: number;
|
|
45
|
+
/** LangChain runnable config carrier (signal, callbacks, thread/user ids). */
|
|
46
|
+
chainOptions?: Partial<RunnableConfig> & {
|
|
47
|
+
configurable?: Record<string, unknown>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Seed for deterministic Langfuse trace ids (e.g. `${runId}-${slotIndex}`)
|
|
51
|
+
* so each batch's label gets a distinct, reproducible trace. When omitted,
|
|
52
|
+
* a per-run sequence keeps batches from collapsing into one trace.
|
|
53
|
+
*/
|
|
54
|
+
traceSeed?: string;
|
|
55
|
+
};
|
package/src/types/index.ts
CHANGED
package/src/types/llm.ts
CHANGED
|
@@ -137,10 +137,17 @@ export type SharedLLMConfig = {
|
|
|
137
137
|
_lc_stream_delay?: number;
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
+
export interface FallbackConfig {
|
|
141
|
+
provider: Providers;
|
|
142
|
+
clientOptions?: ClientOptions;
|
|
143
|
+
/** Context window used to corroborate ambiguous fallback overflow errors. */
|
|
144
|
+
maxContextTokens?: number;
|
|
145
|
+
}
|
|
146
|
+
|
|
140
147
|
export type LLMConfig = SharedLLMConfig &
|
|
141
148
|
ClientOptions & {
|
|
142
149
|
/** Optional provider fallbacks in order of attempt */
|
|
143
|
-
fallbacks?:
|
|
150
|
+
fallbacks?: FallbackConfig[];
|
|
144
151
|
};
|
|
145
152
|
|
|
146
153
|
export type ProviderOptionsMap = {
|
package/src/types/stream.ts
CHANGED
|
@@ -68,13 +68,14 @@ export type RunStep = {
|
|
|
68
68
|
runId?: string; // #new
|
|
69
69
|
agentId?: string; // #new - tracks which agent this step belongs to
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
* Agents with the same groupId
|
|
73
|
-
*
|
|
71
|
+
* Opaque positive safe-integer identifier for parallel execution.
|
|
72
|
+
* Agents with the same groupId should be rendered together.
|
|
73
|
+
* Consumers must use content indexes, not groupId ordering, for execution order.
|
|
74
|
+
* undefined means the agent runs sequentially (not part of a parallel group).
|
|
74
75
|
*
|
|
75
76
|
* Example for: researcher -> [analyst1, analyst2, analyst3] -> summarizer
|
|
76
77
|
* - researcher: undefined (sequential)
|
|
77
|
-
* - analyst1, analyst2, analyst3:
|
|
78
|
+
* - analyst1, analyst2, analyst3: the same groupId (parallel group)
|
|
78
79
|
* - summarizer: undefined (sequential)
|
|
79
80
|
*/
|
|
80
81
|
groupId?: number; // #new
|
|
@@ -191,6 +192,8 @@ export interface ExtendedMessageContent {
|
|
|
191
192
|
type?: string;
|
|
192
193
|
text?: string;
|
|
193
194
|
input?: string;
|
|
195
|
+
/** Tool-call arguments on a v1 standard-content `tool_call` block. */
|
|
196
|
+
args?: ToolCallPart['args'];
|
|
194
197
|
index?: string | number;
|
|
195
198
|
id?: string;
|
|
196
199
|
name?: string;
|
package/src/types/summarize.ts
CHANGED
|
@@ -63,6 +63,28 @@ export interface SummarizeResult {
|
|
|
63
63
|
export interface SummarizationNodeInput {
|
|
64
64
|
remainingContextTokens: number;
|
|
65
65
|
agentId: string;
|
|
66
|
+
/**
|
|
67
|
+
* Why the detour was requested.
|
|
68
|
+
*
|
|
69
|
+
* - `trigger` (default): the configured summarization trigger fired during
|
|
70
|
+
* the pre-call budget check.
|
|
71
|
+
* - `overflow`: the provider rejected the prompt as too large and the run
|
|
72
|
+
* is compacting to recover. When summarization is not enabled, this
|
|
73
|
+
* variant performs no model call — the corrected budget alone is what the
|
|
74
|
+
* retry needs.
|
|
75
|
+
*/
|
|
76
|
+
reason?: 'trigger' | 'overflow';
|
|
77
|
+
/**
|
|
78
|
+
* Whether an overflow recovery may spend a summarization model call.
|
|
79
|
+
*
|
|
80
|
+
* The first recovery deliberately does not: re-pruning against the
|
|
81
|
+
* corrected budget raises context pressure, which drives the pruner's
|
|
82
|
+
* existing tool-output compression and masking. That is cheaper, needs no
|
|
83
|
+
* model call, and cannot lose message content the way a summary can. Only
|
|
84
|
+
* when deterministic compression proves insufficient does the next attempt
|
|
85
|
+
* allow the summarizer to run.
|
|
86
|
+
*/
|
|
87
|
+
allowSummarization?: boolean;
|
|
66
88
|
}
|
|
67
89
|
|
|
68
90
|
export interface SummarizeStartEvent {
|