@librechat/agents 3.1.96 → 3.1.98
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 +60 -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 +476 -0
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -0
- package/dist/cjs/llm/bedrock/index.cjs +10 -0
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/toolCache.cjs +125 -0
- package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -0
- package/dist/cjs/messages/cache.cjs +17 -9
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/run.cjs +142 -69
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +26 -9
- 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 +62 -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 +468 -0
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -0
- package/dist/esm/llm/bedrock/index.mjs +10 -0
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/toolCache.mjs +122 -0
- package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -0
- package/dist/esm/messages/cache.mjs +17 -9
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/run.mjs +144 -71
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +26 -9
- 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/llm/bedrock/index.d.ts +16 -0
- package/dist/types/llm/bedrock/toolCache.d.ts +4 -0
- package/dist/types/messages/cache.d.ts +2 -2
- 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/llm.d.ts +2 -2
- 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/agents/__tests__/AgentContext.anthropic.live.test.ts +332 -0
- package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +504 -0
- package/src/graphs/Graph.ts +104 -34
- package/src/instrumentation.ts +172 -11
- package/src/langfuse.ts +59 -324
- package/src/langfuseToolOutputTracing.ts +702 -0
- package/src/llm/bedrock/index.ts +32 -1
- package/src/llm/bedrock/llm.spec.ts +154 -1
- package/src/llm/bedrock/toolCache.test.ts +131 -0
- package/src/llm/bedrock/toolCache.ts +191 -0
- package/src/messages/cache.test.ts +97 -38
- package/src/messages/cache.ts +18 -10
- 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 +616 -0
- package/src/tools/ToolNode.ts +35 -8
- package/src/tools/__tests__/SubagentExecutor.test.ts +32 -0
- package/src/tools/__tests__/ToolNode.langfuse.test.ts +47 -0
- package/src/tools/subagent/SubagentExecutor.ts +11 -6
- package/src/types/graph.ts +32 -0
- package/src/types/llm.ts +2 -2
- package/src/types/run.ts +6 -0
- package/src/types/tools.ts +7 -0
package/src/graphs/Graph.ts
CHANGED
|
@@ -52,7 +52,11 @@ import { attemptInvoke, tryFallbackProviders } from '@/llm/invoke';
|
|
|
52
52
|
import { shouldTriggerSummarization } from '@/summarization';
|
|
53
53
|
import { createSummarizeNode } from '@/summarization/node';
|
|
54
54
|
import { messagesStateReducer } from '@/messages/reducer';
|
|
55
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
appendCallbacks,
|
|
57
|
+
findCallback,
|
|
58
|
+
type CallbackEntry,
|
|
59
|
+
} from '@/utils/callbacks';
|
|
56
60
|
import { createSchemaOnlyTools } from '@/tools/schema';
|
|
57
61
|
import { AgentContext } from '@/agents/AgentContext';
|
|
58
62
|
import { createFakeStreamingLLM } from '@/llm/fake';
|
|
@@ -64,12 +68,20 @@ import { isThinkingEnabled } from '@/llm/request';
|
|
|
64
68
|
import { initializeModel } from '@/llm/init';
|
|
65
69
|
import {
|
|
66
70
|
createLangfuseHandler,
|
|
67
|
-
disposeLangfuseHandler,
|
|
68
71
|
createLangfuseTraceMetadata,
|
|
72
|
+
disposeLangfuseHandler,
|
|
73
|
+
isLangfuseCallbackHandler,
|
|
69
74
|
} from '@/langfuse';
|
|
75
|
+
import { initializeLangfuseTracing } from '@/instrumentation';
|
|
76
|
+
import {
|
|
77
|
+
resolveLangfuseConfig,
|
|
78
|
+
shouldTraceToolNodeForLangfuse,
|
|
79
|
+
withLangfuseToolOutputTracingConfig,
|
|
80
|
+
} from '@/langfuseToolOutputTracing';
|
|
70
81
|
import { HandlerRegistry } from '@/events';
|
|
71
82
|
import { ChatOpenAI } from '@/llm/openai';
|
|
72
83
|
import { partitionAndMarkOpenRouterToolCache } from '@/llm/openrouter/toolCache';
|
|
84
|
+
import { partitionAndMarkBedrockToolCache } from '@/llm/bedrock/toolCache';
|
|
73
85
|
import type { HookRegistry } from '@/hooks';
|
|
74
86
|
|
|
75
87
|
const { AGENT, TOOLS, SUMMARIZE } = GraphNodeKeys;
|
|
@@ -174,6 +186,10 @@ export abstract class Graph<
|
|
|
174
186
|
* graph compiles.
|
|
175
187
|
*/
|
|
176
188
|
toolOutputReferences: t.ToolOutputReferencesConfig | undefined;
|
|
189
|
+
/**
|
|
190
|
+
* Run-scoped Langfuse defaults. Per-agent config wins when present.
|
|
191
|
+
*/
|
|
192
|
+
langfuse: t.LangfuseConfig | undefined;
|
|
177
193
|
/**
|
|
178
194
|
* Run-scoped opt-in for eager event-driven tool execution. The stream
|
|
179
195
|
* handler may prestart eligible event-driven tools; ToolNode later
|
|
@@ -427,6 +443,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
427
443
|
runId,
|
|
428
444
|
signal,
|
|
429
445
|
agents,
|
|
446
|
+
langfuse,
|
|
430
447
|
tokenCounter,
|
|
431
448
|
indexTokenCountMap,
|
|
432
449
|
calibrationRatio,
|
|
@@ -434,6 +451,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
434
451
|
super();
|
|
435
452
|
this.runId = runId;
|
|
436
453
|
this.signal = signal;
|
|
454
|
+
this.langfuse = langfuse;
|
|
437
455
|
|
|
438
456
|
if (agents.length === 0) {
|
|
439
457
|
throw new Error('At least one agent configuration is required');
|
|
@@ -743,6 +761,10 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
743
761
|
const toolDefinitions = agentContext?.toolDefinitions;
|
|
744
762
|
const eventDrivenMode =
|
|
745
763
|
toolDefinitions != null && toolDefinitions.length > 0;
|
|
764
|
+
const traceToolNode = shouldTraceToolNodeForLangfuse({
|
|
765
|
+
runLangfuse: this.langfuse,
|
|
766
|
+
agentLangfuse: agentContext?.langfuse,
|
|
767
|
+
});
|
|
746
768
|
|
|
747
769
|
if (eventDrivenMode) {
|
|
748
770
|
const schemaTools = createSchemaOnlyTools(toolDefinitions);
|
|
@@ -770,6 +792,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
770
792
|
const node = new CustomToolNode<t.BaseGraphState>({
|
|
771
793
|
tools: allTools,
|
|
772
794
|
toolMap: allToolMap,
|
|
795
|
+
trace: traceToolNode,
|
|
796
|
+
runLangfuse: this.langfuse,
|
|
797
|
+
agentLangfuse: agentContext?.langfuse,
|
|
773
798
|
eventDrivenMode: true,
|
|
774
799
|
sessions: this.sessions,
|
|
775
800
|
toolDefinitions: toolDefMap,
|
|
@@ -815,6 +840,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
815
840
|
const node = new CustomToolNode<t.BaseGraphState>({
|
|
816
841
|
tools: allTraditionalTools,
|
|
817
842
|
toolMap: traditionalToolMap,
|
|
843
|
+
trace: traceToolNode,
|
|
844
|
+
runLangfuse: this.langfuse,
|
|
845
|
+
agentLangfuse: agentContext?.langfuse,
|
|
818
846
|
toolCallStepIds: this.toolCallStepIds,
|
|
819
847
|
errorHandler: (data, metadata): Promise<void> =>
|
|
820
848
|
StandardGraph.handleToolCallErrorStatic(this, data, metadata),
|
|
@@ -935,6 +963,19 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
935
963
|
rawToolsForBinding,
|
|
936
964
|
makeIsDeferred(agentContext.toolDefinitions)
|
|
937
965
|
) ?? rawToolsForBinding;
|
|
966
|
+
} else if (
|
|
967
|
+
agentContext.provider === Providers.BEDROCK &&
|
|
968
|
+
(
|
|
969
|
+
agentContext.clientOptions as
|
|
970
|
+
| t.BedrockAnthropicClientOptions
|
|
971
|
+
| undefined
|
|
972
|
+
)?.promptCache === true
|
|
973
|
+
) {
|
|
974
|
+
toolsForBinding =
|
|
975
|
+
partitionAndMarkBedrockToolCache(
|
|
976
|
+
rawToolsForBinding,
|
|
977
|
+
makeIsDeferred(agentContext.toolDefinitions)
|
|
978
|
+
) ?? rawToolsForBinding;
|
|
938
979
|
}
|
|
939
980
|
|
|
940
981
|
let model =
|
|
@@ -1338,44 +1379,72 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1338
1379
|
{ force: true }
|
|
1339
1380
|
);
|
|
1340
1381
|
|
|
1341
|
-
const
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
}),
|
|
1351
|
-
tags: ['librechat', 'agent'],
|
|
1382
|
+
const langfuse = resolveLangfuseConfig(
|
|
1383
|
+
this.langfuse,
|
|
1384
|
+
agentContext.langfuse
|
|
1385
|
+
);
|
|
1386
|
+
const traceMetadata = createLangfuseTraceMetadata({
|
|
1387
|
+
messageId: this.runId,
|
|
1388
|
+
parentMessageId: config.configurable?.requestBody?.parentMessageId,
|
|
1389
|
+
agentId,
|
|
1390
|
+
agentName: agentContext.name,
|
|
1352
1391
|
});
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1392
|
+
let langfuseHandler: CallbackEntry | undefined;
|
|
1393
|
+
let invokeConfig = {
|
|
1394
|
+
...config,
|
|
1395
|
+
metadata: {
|
|
1396
|
+
...(config.metadata ?? {}),
|
|
1397
|
+
...traceMetadata,
|
|
1398
|
+
},
|
|
1399
|
+
};
|
|
1400
|
+
initializeLangfuseTracing(langfuse);
|
|
1401
|
+
if (findCallback(config.callbacks, isLangfuseCallbackHandler) == null) {
|
|
1402
|
+
langfuseHandler = createLangfuseHandler({
|
|
1403
|
+
langfuse,
|
|
1404
|
+
userId: config.configurable?.user_id as string | undefined,
|
|
1405
|
+
sessionId: config.configurable?.thread_id as string | undefined,
|
|
1406
|
+
traceMetadata,
|
|
1407
|
+
tags: ['librechat', 'agent'],
|
|
1408
|
+
});
|
|
1409
|
+
if (langfuseHandler != null) {
|
|
1410
|
+
invokeConfig = {
|
|
1411
|
+
...invokeConfig,
|
|
1412
|
+
callbacks: appendCallbacks(invokeConfig.callbacks, [
|
|
1413
|
+
langfuseHandler,
|
|
1414
|
+
]),
|
|
1415
|
+
};
|
|
1357
1416
|
}
|
|
1358
|
-
|
|
1417
|
+
}
|
|
1359
1418
|
|
|
1360
1419
|
try {
|
|
1361
|
-
result = await
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1420
|
+
result = await withLangfuseToolOutputTracingConfig(
|
|
1421
|
+
this.langfuse,
|
|
1422
|
+
() =>
|
|
1423
|
+
attemptInvoke(
|
|
1424
|
+
{
|
|
1425
|
+
model: (this.overrideModel ?? model) as t.ChatModel,
|
|
1426
|
+
messages: finalMessages,
|
|
1427
|
+
provider: agentContext.provider,
|
|
1428
|
+
context: this,
|
|
1429
|
+
},
|
|
1430
|
+
invokeConfig
|
|
1431
|
+
),
|
|
1432
|
+
agentContext.langfuse
|
|
1369
1433
|
);
|
|
1370
1434
|
} catch (primaryError) {
|
|
1371
|
-
result = await
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1435
|
+
result = await withLangfuseToolOutputTracingConfig(
|
|
1436
|
+
this.langfuse,
|
|
1437
|
+
() =>
|
|
1438
|
+
tryFallbackProviders({
|
|
1439
|
+
fallbacks,
|
|
1440
|
+
tools: agentContext.tools,
|
|
1441
|
+
messages: finalMessages,
|
|
1442
|
+
config: invokeConfig,
|
|
1443
|
+
primaryError,
|
|
1444
|
+
context: this,
|
|
1445
|
+
}),
|
|
1446
|
+
agentContext.langfuse
|
|
1447
|
+
);
|
|
1379
1448
|
} finally {
|
|
1380
1449
|
await disposeLangfuseHandler(langfuseHandler);
|
|
1381
1450
|
}
|
|
@@ -1599,6 +1668,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1599
1668
|
parentHandlerRegistry: getParentHandlerRegistry,
|
|
1600
1669
|
parentRunId: this.runId ?? '',
|
|
1601
1670
|
parentAgentId: agentContext.agentId,
|
|
1671
|
+
langfuse: this.langfuse,
|
|
1602
1672
|
tokenCounter: agentContext.tokenCounter,
|
|
1603
1673
|
maxDepth: effectiveSubagentDepth,
|
|
1604
1674
|
createChildGraph: (input): StandardGraph => {
|
package/src/instrumentation.ts
CHANGED
|
@@ -1,17 +1,178 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { setLangfuseTracerProvider } from '@langfuse/tracing';
|
|
2
|
+
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
|
|
3
|
+
import { context, ROOT_CONTEXT, createContextKey } from '@opentelemetry/api';
|
|
4
|
+
import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
|
|
5
|
+
import {
|
|
6
|
+
hasLangfuseConfigCredentials,
|
|
7
|
+
hasLangfuseEnvCredentials,
|
|
8
|
+
hasLangfuseEnvConfig,
|
|
9
|
+
} from '@/langfuse';
|
|
10
|
+
import {
|
|
11
|
+
createLangfuseSpanProcessor,
|
|
12
|
+
getContextLangfuseConfig,
|
|
13
|
+
} from '@/langfuseToolOutputTracing';
|
|
3
14
|
import { isPresent } from '@/utils/misc';
|
|
15
|
+
import type {
|
|
16
|
+
ReadableSpan,
|
|
17
|
+
Span,
|
|
18
|
+
SpanProcessor,
|
|
19
|
+
} from '@opentelemetry/sdk-trace-base';
|
|
20
|
+
import type { LangfuseSpanProcessorParams } from '@langfuse/otel';
|
|
21
|
+
import type { Context } from '@opentelemetry/api';
|
|
22
|
+
import type * as t from '@/types';
|
|
4
23
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
)
|
|
10
|
-
const langfuseSpanProcessor = new LangfuseSpanProcessor();
|
|
24
|
+
let langfuseTracerProvider: BasicTracerProvider | undefined;
|
|
25
|
+
let langfuseRoutingSpanProcessor: RoutingLangfuseSpanProcessor | undefined;
|
|
26
|
+
const contextManagerProbeKey = createContextKey(
|
|
27
|
+
'langfuse-context-manager-probe'
|
|
28
|
+
);
|
|
11
29
|
|
|
12
|
-
|
|
13
|
-
|
|
30
|
+
function hasActiveContextManager(): boolean {
|
|
31
|
+
return context.with(
|
|
32
|
+
ROOT_CONTEXT.setValue(contextManagerProbeKey, true),
|
|
33
|
+
() => context.active().getValue(contextManagerProbeKey) === true
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ensureOpenTelemetryContextManager(): void {
|
|
38
|
+
if (hasActiveContextManager()) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const contextManager = new AsyncLocalStorageContextManager();
|
|
43
|
+
contextManager.enable();
|
|
44
|
+
if (!context.setGlobalContextManager(contextManager)) {
|
|
45
|
+
contextManager.disable();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getLangfuseSpanProcessorParams(
|
|
50
|
+
langfuse?: t.LangfuseConfig
|
|
51
|
+
): LangfuseSpanProcessorParams | undefined {
|
|
52
|
+
if (langfuse?.enabled === false) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
if (hasLangfuseConfigCredentials(langfuse)) {
|
|
56
|
+
return {
|
|
57
|
+
publicKey: langfuse.publicKey,
|
|
58
|
+
secretKey: langfuse.secretKey,
|
|
59
|
+
...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (hasLangfuseEnvConfig()) {
|
|
63
|
+
const baseUrl =
|
|
64
|
+
langfuse?.baseUrl ??
|
|
65
|
+
process.env.LANGFUSE_BASE_URL ??
|
|
66
|
+
process.env.LANGFUSE_BASEURL;
|
|
67
|
+
return {
|
|
68
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,
|
|
69
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY as string,
|
|
70
|
+
...(isPresent(baseUrl) ? { baseUrl } : {}),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (isPresent(langfuse?.baseUrl) && hasLangfuseEnvCredentials()) {
|
|
74
|
+
return {
|
|
75
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,
|
|
76
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY as string,
|
|
77
|
+
baseUrl: langfuse.baseUrl,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getLangfuseTracerProviderKey(
|
|
84
|
+
params: LangfuseSpanProcessorParams,
|
|
85
|
+
langfuse?: t.LangfuseConfig
|
|
86
|
+
): string {
|
|
87
|
+
return JSON.stringify({
|
|
88
|
+
publicKey: params.publicKey,
|
|
89
|
+
secretKey: params.secretKey,
|
|
90
|
+
baseUrl: params.baseUrl,
|
|
91
|
+
environment: params.environment,
|
|
92
|
+
toolOutputTracing: langfuse?.toolOutputTracing,
|
|
14
93
|
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
class RoutingLangfuseSpanProcessor implements SpanProcessor {
|
|
97
|
+
private readonly processors = new Map<string, SpanProcessor>();
|
|
98
|
+
private readonly spanProcessors = new WeakMap<object, SpanProcessor>();
|
|
99
|
+
|
|
100
|
+
ensureProcessor(langfuse?: t.LangfuseConfig): SpanProcessor | undefined {
|
|
101
|
+
const params = getLangfuseSpanProcessorParams(langfuse);
|
|
102
|
+
if (params == null) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const processorKey = getLangfuseTracerProviderKey(params, langfuse);
|
|
107
|
+
const existing = this.processors.get(processorKey);
|
|
108
|
+
if (existing != null) {
|
|
109
|
+
return existing;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const processor = createLangfuseSpanProcessor(params, langfuse);
|
|
113
|
+
this.processors.set(processorKey, processor);
|
|
114
|
+
return processor;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
onStart(span: Span, parentContext: Context): void {
|
|
118
|
+
const processor = this.ensureProcessor(
|
|
119
|
+
getContextLangfuseConfig(parentContext)
|
|
120
|
+
);
|
|
121
|
+
if (processor == null) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
15
124
|
|
|
16
|
-
|
|
125
|
+
this.spanProcessors.set(span, processor);
|
|
126
|
+
processor.onStart(span, parentContext);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
onEnd(span: ReadableSpan): void {
|
|
130
|
+
this.spanProcessors.get(span)?.onEnd(span);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async forceFlush(): Promise<void> {
|
|
134
|
+
await Promise.all(
|
|
135
|
+
Array.from(this.processors.values(), (processor) =>
|
|
136
|
+
processor.forceFlush()
|
|
137
|
+
)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async shutdown(): Promise<void> {
|
|
142
|
+
await Promise.all(
|
|
143
|
+
Array.from(this.processors.values(), (processor) => processor.shutdown())
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function initializeLangfuseTracing(
|
|
149
|
+
langfuse?: t.LangfuseConfig
|
|
150
|
+
): BasicTracerProvider | undefined {
|
|
151
|
+
const params = getLangfuseSpanProcessorParams(langfuse);
|
|
152
|
+
if (params == null) {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (langfuseTracerProvider != null) {
|
|
157
|
+
langfuseRoutingSpanProcessor?.ensureProcessor(langfuse);
|
|
158
|
+
return langfuseTracerProvider;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
ensureOpenTelemetryContextManager();
|
|
162
|
+
langfuseRoutingSpanProcessor = new RoutingLangfuseSpanProcessor();
|
|
163
|
+
langfuseRoutingSpanProcessor.ensureProcessor(langfuse);
|
|
164
|
+
langfuseTracerProvider = new BasicTracerProvider({
|
|
165
|
+
spanProcessors: [langfuseRoutingSpanProcessor],
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
setLangfuseTracerProvider(langfuseTracerProvider);
|
|
169
|
+
return langfuseTracerProvider;
|
|
17
170
|
}
|
|
171
|
+
|
|
172
|
+
export function initializeLangfuseTracingFromEnv():
|
|
173
|
+
| BasicTracerProvider
|
|
174
|
+
| undefined {
|
|
175
|
+
return initializeLangfuseTracing();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
initializeLangfuseTracingFromEnv();
|