@librechat/agents 3.1.61 → 3.1.63

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.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Anthropic direct API tool schema overhead multiplier.
3
+ * Empirically calibrated against real MCP tool sets (29 tools).
4
+ * Accounts for Anthropic's internal XML-like tool encoding plus
5
+ * a ~300-token hidden tool-system preamble.
6
+ */
7
+ export const ANTHROPIC_TOOL_TOKEN_MULTIPLIER = 2.6;
8
+
9
+ /**
10
+ * Default tool schema overhead multiplier for all non-Anthropic providers.
11
+ * Covers OpenAI function-calling format, Bedrock, and other providers.
12
+ * Empirically calibrated at ~1.4× the raw JSON token count.
13
+ */
14
+ export const DEFAULT_TOOL_TOKEN_MULTIPLIER = 1.4;
@@ -1,2 +1,3 @@
1
1
  // src/common/index.ts
2
- export * from './enum';
2
+ export * from './constants';
3
+ export * from './enum';
package/src/run.ts CHANGED
@@ -305,9 +305,13 @@ export class Run<_T extends t.BaseGraphState> {
305
305
  ) {
306
306
  const userId = config.configurable?.user_id;
307
307
  const sessionId = config.configurable?.thread_id;
308
+ const primaryContext = this.Graph.agentContexts.get(
309
+ this.Graph.defaultAgentId
310
+ );
308
311
  const traceMetadata = {
309
312
  messageId: this.id,
310
313
  parentMessageId: config.configurable?.requestBody?.parentMessageId,
314
+ agentName: primaryContext?.name,
311
315
  };
312
316
  const handler = new CallbackHandler({
313
317
  userId,
@@ -453,8 +457,12 @@ export class Run<_T extends t.BaseGraphState> {
453
457
  ) {
454
458
  const userId = chainOptions.configurable?.user_id;
455
459
  const sessionId = chainOptions.configurable?.thread_id;
460
+ const titleContext = this.Graph?.agentContexts.get(
461
+ this.Graph.defaultAgentId
462
+ );
456
463
  const traceMetadata = {
457
464
  messageId: 'title-' + this.id,
465
+ agentName: titleContext?.name,
458
466
  };
459
467
  const handler = new CallbackHandler({
460
468
  userId,
@@ -0,0 +1,91 @@
1
+ import { CallbackHandler } from '@langfuse/langchain';
2
+ import { Providers } from '@/common';
3
+ import { Run } from '@/run';
4
+
5
+ jest.mock('@langfuse/langchain', () => ({
6
+ CallbackHandler: jest.fn().mockImplementation(() => ({})),
7
+ }));
8
+
9
+ const MockedCallbackHandler = CallbackHandler as jest.MockedClass<
10
+ typeof CallbackHandler
11
+ >;
12
+
13
+ async function createTestRun(agentName?: string): Promise<Run<never>> {
14
+ const run = await Run.create({
15
+ runId: 'test-run-id',
16
+ graphConfig: {
17
+ type: 'standard',
18
+ agents: [
19
+ {
20
+ agentId: 'agent_abc123',
21
+ ...(agentName != null && { name: agentName }),
22
+ provider: Providers.OPENAI,
23
+ clientOptions: { model: 'gpt-4' },
24
+ tools: [],
25
+ },
26
+ ],
27
+ },
28
+ });
29
+
30
+ const emptyStream = (async function* (): AsyncGenerator {
31
+ /* no events */
32
+ })();
33
+ run.graphRunnable = { streamEvents: () => emptyStream } as never;
34
+
35
+ return run;
36
+ }
37
+
38
+ describe('Langfuse trace metadata includes agentName', () => {
39
+ const originalEnv = process.env;
40
+
41
+ beforeEach(() => {
42
+ jest.clearAllMocks();
43
+ process.env = {
44
+ ...originalEnv,
45
+ LANGFUSE_SECRET_KEY: 'sk-test',
46
+ LANGFUSE_PUBLIC_KEY: 'pk-test',
47
+ LANGFUSE_BASE_URL: 'https://langfuse.test',
48
+ };
49
+ });
50
+
51
+ afterEach(() => {
52
+ process.env = originalEnv;
53
+ });
54
+
55
+ it('passes agentName in processStream traceMetadata when agent has a name', async () => {
56
+ const run = await createTestRun('DWAINE');
57
+ await run.processStream(
58
+ { messages: [] },
59
+ { configurable: { thread_id: 't1', user_id: 'u1' }, version: 'v2' }
60
+ );
61
+
62
+ expect(MockedCallbackHandler).toHaveBeenCalledTimes(1);
63
+ const ctorArgs = MockedCallbackHandler.mock.calls[0][0];
64
+ expect(ctorArgs?.traceMetadata).toMatchObject({ agentName: 'DWAINE' });
65
+ });
66
+
67
+ it('falls back to agentId when agent has no explicit name', async () => {
68
+ const run = await createTestRun();
69
+ await run.processStream(
70
+ { messages: [] },
71
+ { configurable: { thread_id: 't1', user_id: 'u1' }, version: 'v2' }
72
+ );
73
+
74
+ expect(MockedCallbackHandler).toHaveBeenCalledTimes(1);
75
+ const ctorArgs = MockedCallbackHandler.mock.calls[0][0];
76
+ expect(ctorArgs?.traceMetadata).toMatchObject({
77
+ agentName: 'agent_abc123',
78
+ });
79
+ });
80
+
81
+ it('does not create CallbackHandler when Langfuse env vars are missing', async () => {
82
+ delete process.env.LANGFUSE_SECRET_KEY;
83
+ const run = await createTestRun('MAIA');
84
+ await run.processStream(
85
+ { messages: [] },
86
+ { configurable: { thread_id: 't1', user_id: 'u1' }, version: 'v2' }
87
+ );
88
+
89
+ expect(MockedCallbackHandler).not.toHaveBeenCalled();
90
+ });
91
+ });
@@ -31,7 +31,7 @@ const SUMMARY_WRAPPER_OVERHEAD_TOKENS = 33;
31
31
  /** Structured checkpoint prompt for fresh summarization (no prior summary). */
32
32
  export const DEFAULT_SUMMARIZATION_PROMPT = `Hold on, before you continue I need you to write me a checkpoint of everything so far. Your context window is filling up and this checkpoint replaces the messages above, so capture everything you need to pick right back up.
33
33
 
34
- Don't second-guess or fact-check anything you did, your tool results reflect exactly what happened. Just record what you did and what you observed. Only the checkpoint, don't respond to me or continue the conversation.
34
+ Don't second-guess or fact-check anything you did, your tool results reflect exactly what happened. If a tool result appears truncated, that's just a display artifact from context management: the tool executed fully. Just record what you did and what you observed. Only the checkpoint, don't respond to me or continue the conversation.
35
35
 
36
36
  ## Checkpoint
37
37
 
@@ -69,7 +69,7 @@ export const DEFAULT_UPDATE_SUMMARIZATION_PROMPT = `Hold on again, update your c
69
69
 
70
70
  Keep it roughly the same length as your last checkpoint. Compress older details to make room for what's new, don't just append. Give recent actions more detail, compress older items to one-liners.
71
71
 
72
- Don't fact-check or second-guess anything, your tool results are ground truth. Only the checkpoint, don't respond to me or continue the conversation.
72
+ Don't fact-check or second-guess anything, your tool results are ground truth. If a tool result appears truncated, that's just a display artifact: the tool executed fully. Only the checkpoint, don't respond to me or continue the conversation.
73
73
 
74
74
  Rules:
75
75
  - Merge new progress into existing sections, don't duplicate headers
@@ -429,6 +429,8 @@ export interface AgentInputs {
429
429
  initialSummary?: { text: string; tokenCount: number };
430
430
  contextPruningConfig?: ContextPruningConfig;
431
431
  maxToolResultChars?: number;
432
+ /** Pre-computed tool schema token count (from cache). Skips recalculation when provided. */
433
+ toolSchemaTokens?: number;
432
434
  }
433
435
 
434
436
  export interface ContextPruningConfig {