@librechat/agents 3.1.96 → 3.1.97
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/graphs/Graph.cjs +54 -21
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +120 -9
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +30 -226
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +465 -0
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -0
- package/dist/cjs/run.cjs +142 -69
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +20 -8
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +10 -6
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +56 -23
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +118 -9
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +28 -224
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +457 -0
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -0
- package/dist/esm/run.mjs +144 -71
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +20 -8
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +10 -6
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +5 -1
- package/dist/types/instrumentation.d.ts +5 -1
- package/dist/types/langfuse.d.ts +6 -28
- package/dist/types/langfuseToolOutputTracing.d.ts +20 -0
- package/dist/types/run.d.ts +5 -1
- package/dist/types/tools/ToolNode.d.ts +4 -1
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +2 -0
- package/dist/types/types/graph.d.ts +30 -0
- package/dist/types/types/run.d.ts +6 -0
- package/dist/types/types/tools.d.ts +7 -0
- package/package.json +2 -1
- package/src/graphs/Graph.ts +90 -34
- package/src/instrumentation.ts +172 -11
- package/src/langfuse.ts +59 -324
- package/src/langfuseToolOutputTracing.ts +683 -0
- package/src/run.ts +190 -87
- package/src/specs/langfuse-callbacks.test.ts +178 -1
- package/src/specs/langfuse-config.test.ts +112 -76
- package/src/specs/langfuse-instrumentation.test.ts +283 -0
- package/src/specs/langfuse-metadata.test.ts +54 -1
- package/src/specs/langfuse-tool-output-tracing.test.ts +588 -0
- package/src/tools/ToolNode.ts +28 -7
- package/src/tools/__tests__/SubagentExecutor.test.ts +32 -0
- package/src/tools/__tests__/ToolNode.langfuse.test.ts +41 -0
- package/src/tools/subagent/SubagentExecutor.ts +11 -6
- package/src/types/graph.ts +32 -0
- package/src/types/run.ts +6 -0
- package/src/types/tools.ts +7 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const mockWithLangfuseToolOutputTracingConfig = jest.fn(
|
|
2
|
+
(_runLangfuse: unknown, action: () => unknown, _agentLangfuse: unknown) =>
|
|
3
|
+
action()
|
|
4
|
+
);
|
|
5
|
+
|
|
6
|
+
jest.mock('@/langfuseToolOutputTracing', () => ({
|
|
7
|
+
...jest.requireActual('@/langfuseToolOutputTracing'),
|
|
8
|
+
withLangfuseToolOutputTracingConfig: mockWithLangfuseToolOutputTracingConfig,
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
import { ToolNode } from '../ToolNode';
|
|
12
|
+
|
|
13
|
+
describe('ToolNode Langfuse redaction context', () => {
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
mockWithLangfuseToolOutputTracingConfig.mockClear();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('scopes ToolNode invocation with run and agent Langfuse config', async () => {
|
|
19
|
+
const runLangfuse = {
|
|
20
|
+
toolOutputTracing: { enabled: true },
|
|
21
|
+
};
|
|
22
|
+
const agentLangfuse = {
|
|
23
|
+
toolOutputTracing: { enabled: false },
|
|
24
|
+
};
|
|
25
|
+
const node = new ToolNode({
|
|
26
|
+
tools: [],
|
|
27
|
+
runLangfuse,
|
|
28
|
+
agentLangfuse,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await expect(node.invoke([])).rejects.toThrow(
|
|
32
|
+
'ToolNode only accepts AIMessages'
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(mockWithLangfuseToolOutputTracingConfig).toHaveBeenCalledWith(
|
|
36
|
+
runLangfuse,
|
|
37
|
+
expect.any(Function),
|
|
38
|
+
agentLangfuse
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -213,6 +213,7 @@ export type SubagentExecutorOptions = {
|
|
|
213
213
|
hookRegistry?: HookRegistry;
|
|
214
214
|
parentRunId: string;
|
|
215
215
|
parentAgentId?: string;
|
|
216
|
+
langfuse?: StandardGraphInput['langfuse'];
|
|
216
217
|
tokenCounter?: TokenCounter;
|
|
217
218
|
/** Remaining nesting budget. 0 or negative blocks execution. */
|
|
218
219
|
maxDepth?: number;
|
|
@@ -243,6 +244,7 @@ export class SubagentExecutor {
|
|
|
243
244
|
private readonly hookRegistry?: HookRegistry;
|
|
244
245
|
private readonly parentRunId: string;
|
|
245
246
|
private readonly parentAgentId?: string;
|
|
247
|
+
private readonly langfuse?: StandardGraphInput['langfuse'];
|
|
246
248
|
private readonly tokenCounter?: TokenCounter;
|
|
247
249
|
private readonly maxDepth: number;
|
|
248
250
|
private readonly createChildGraph: ChildGraphFactory;
|
|
@@ -256,6 +258,7 @@ export class SubagentExecutor {
|
|
|
256
258
|
this.hookRegistry = options.hookRegistry;
|
|
257
259
|
this.parentRunId = options.parentRunId;
|
|
258
260
|
this.parentAgentId = options.parentAgentId;
|
|
261
|
+
this.langfuse = options.langfuse;
|
|
259
262
|
this.tokenCounter = options.tokenCounter;
|
|
260
263
|
this.maxDepth = options.maxDepth ?? 1;
|
|
261
264
|
this.createChildGraph = options.createChildGraph;
|
|
@@ -352,18 +355,20 @@ export class SubagentExecutor {
|
|
|
352
355
|
runId: childRunId,
|
|
353
356
|
signal: this.parentSignal,
|
|
354
357
|
agents: [childInputs],
|
|
358
|
+
langfuse: this.langfuse,
|
|
355
359
|
tokenCounter: this.tokenCounter,
|
|
356
360
|
});
|
|
357
361
|
|
|
358
|
-
|
|
359
|
-
|
|
362
|
+
let forwarding: ForwarderCallback | undefined;
|
|
363
|
+
if (forwardingEnabled) {
|
|
364
|
+
forwarding = this.createForwarderCallback({
|
|
360
365
|
parentRegistry: parentRegistry!,
|
|
361
366
|
subagentType,
|
|
362
367
|
subagentAgentId: childAgentId,
|
|
363
368
|
childRunId,
|
|
364
369
|
parentToolCallId,
|
|
365
|
-
})
|
|
366
|
-
|
|
370
|
+
});
|
|
371
|
+
}
|
|
367
372
|
const forwarder = forwarding?.handler;
|
|
368
373
|
|
|
369
374
|
if (forwarder) {
|
|
@@ -444,7 +449,7 @@ export class SubagentExecutor {
|
|
|
444
449
|
);
|
|
445
450
|
} catch (error) {
|
|
446
451
|
const errorMessage = truncateErrorMessage(error);
|
|
447
|
-
if (
|
|
452
|
+
if (forwarding) {
|
|
448
453
|
await forwarding.drain();
|
|
449
454
|
await this.emitSubagentUpdate(parentRegistry!, {
|
|
450
455
|
childRunId,
|
|
@@ -491,7 +496,7 @@ export class SubagentExecutor {
|
|
|
491
496
|
});
|
|
492
497
|
}
|
|
493
498
|
|
|
494
|
-
if (
|
|
499
|
+
if (forwarding) {
|
|
495
500
|
await forwarding.drain();
|
|
496
501
|
await this.emitSubagentUpdate(parentRegistry!, {
|
|
497
502
|
childRunId,
|
package/src/types/graph.ts
CHANGED
|
@@ -295,6 +295,7 @@ export type StandardGraphInput = {
|
|
|
295
295
|
runId?: string;
|
|
296
296
|
signal?: AbortSignal;
|
|
297
297
|
agents: AgentInputs[];
|
|
298
|
+
langfuse?: LangfuseConfig;
|
|
298
299
|
tokenCounter?: TokenCounter;
|
|
299
300
|
indexTokenCountMap?: Record<string, number>;
|
|
300
301
|
calibrationRatio?: number;
|
|
@@ -408,11 +409,42 @@ export interface SubagentUpdateEvent {
|
|
|
408
409
|
timestamp: string;
|
|
409
410
|
}
|
|
410
411
|
|
|
412
|
+
export type LangfuseToolOutputTracingConfig = {
|
|
413
|
+
/**
|
|
414
|
+
* Whether tool outputs should be exported to Langfuse. Defaults to
|
|
415
|
+
* `true`. Set to `false` to keep tool spans and redact their output.
|
|
416
|
+
*/
|
|
417
|
+
enabled?: boolean;
|
|
418
|
+
/**
|
|
419
|
+
* Optional allowlist of tool names whose outputs should be redacted even
|
|
420
|
+
* when `enabled` is true.
|
|
421
|
+
*/
|
|
422
|
+
redactedToolNames?: string[];
|
|
423
|
+
/**
|
|
424
|
+
* Match strategy for `redactedToolNames`. Defaults to `exact`; use
|
|
425
|
+
* `partial` to redact tools whose names contain a configured value.
|
|
426
|
+
*/
|
|
427
|
+
redactedToolNameMatchMode?: 'exact' | 'partial';
|
|
428
|
+
/** Replacement text used for redacted tool outputs. */
|
|
429
|
+
redactionText?: string;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
export type LangfuseToolNodeTracingConfig = {
|
|
433
|
+
/**
|
|
434
|
+
* Overrides ToolNode callback tracing. ToolNode spans are exported by the
|
|
435
|
+
* env-backed Langfuse callback, so this only enables tracing when that
|
|
436
|
+
* callback is configured.
|
|
437
|
+
*/
|
|
438
|
+
enabled?: boolean;
|
|
439
|
+
};
|
|
440
|
+
|
|
411
441
|
export interface LangfuseConfig {
|
|
412
442
|
enabled?: boolean;
|
|
413
443
|
publicKey?: string;
|
|
414
444
|
secretKey?: string;
|
|
415
445
|
baseUrl?: string;
|
|
446
|
+
toolNodeTracing?: LangfuseToolNodeTracingConfig;
|
|
447
|
+
toolOutputTracing?: LangfuseToolOutputTracingConfig;
|
|
416
448
|
}
|
|
417
449
|
|
|
418
450
|
export interface AgentInputs {
|
package/src/types/run.ts
CHANGED
|
@@ -118,6 +118,12 @@ export type StandardGraphConfig = Omit<
|
|
|
118
118
|
export type RunConfig = {
|
|
119
119
|
runId: string;
|
|
120
120
|
graphConfig: LegacyGraphConfig | StandardGraphConfig | MultiAgentGraphConfig;
|
|
121
|
+
/**
|
|
122
|
+
* Run-scoped Langfuse configuration. Per-agent `AgentInputs.langfuse`
|
|
123
|
+
* takes precedence for agent-specific spans; this object supplies defaults
|
|
124
|
+
* for run-wide tracing controls such as tool-output redaction.
|
|
125
|
+
*/
|
|
126
|
+
langfuse?: g.LangfuseConfig;
|
|
121
127
|
customHandlers?: Record<string, g.EventHandler>;
|
|
122
128
|
/**
|
|
123
129
|
* Pre-constructed hook registry for this run. Hooks fire at lifecycle
|
package/src/types/tools.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { HookRegistry } from '@/hooks';
|
|
|
6
6
|
import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
|
|
7
7
|
import type { MessageContentComplex, ToolErrorData } from './stream';
|
|
8
8
|
import type { HumanInTheLoopConfig } from './hitl';
|
|
9
|
+
import type { LangfuseConfig } from './graph';
|
|
9
10
|
|
|
10
11
|
/** Replacement type for `import type { ToolCall } from '@langchain/core/messages/tool'` in order to have stringified args typed */
|
|
11
12
|
export type CustomToolCall = {
|
|
@@ -69,6 +70,12 @@ export type EagerEventToolCallChunkState = {
|
|
|
69
70
|
export type ToolNodeOptions = {
|
|
70
71
|
name?: string;
|
|
71
72
|
tags?: string[];
|
|
73
|
+
/** Enables LangChain/LangGraph tracing for this ToolNode. Defaults to false. */
|
|
74
|
+
trace?: boolean;
|
|
75
|
+
/** Run-level Langfuse config used to scope ToolNode trace redaction. */
|
|
76
|
+
runLangfuse?: LangfuseConfig;
|
|
77
|
+
/** Agent-level Langfuse config used to scope ToolNode trace redaction. */
|
|
78
|
+
agentLangfuse?: LangfuseConfig;
|
|
72
79
|
handleToolErrors?: boolean;
|
|
73
80
|
loadRuntimeTools?: ToolRefGenerator;
|
|
74
81
|
toolCallStepIds?: Map<string, string>;
|