@librechat/agents 3.6.6 → 3.6.8
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/common/constants.cjs +14 -0
- package/dist/cjs/common/constants.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +18 -6
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +6 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +2 -0
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +46 -15
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseOperation.cjs +6 -0
- package/dist/cjs/langfuseOperation.cjs.map +1 -0
- package/dist/cjs/langfuseRuntimeContext.cjs +3 -1
- package/dist/cjs/langfuseRuntimeContext.cjs.map +1 -1
- package/dist/cjs/langfuseRuntimeScope.cjs +11 -1
- package/dist/cjs/langfuseRuntimeScope.cjs.map +1 -1
- package/dist/cjs/langfuseSpanRegistry.cjs +35 -0
- package/dist/cjs/langfuseSpanRegistry.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +1 -6
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/langfuseTraceShaping.cjs +58 -10
- package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +8 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +8 -1
- package/dist/cjs/run.cjs +59 -25
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +1 -1
- package/dist/cjs/tools/ToolNode.cjs +2 -2
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +2 -2
- package/dist/cjs/utils/tokens.cjs +9 -5
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/common/constants.mjs +8 -1
- package/dist/esm/common/constants.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +18 -6
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +6 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +4 -2
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +47 -16
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseOperation.mjs +6 -0
- package/dist/esm/langfuseOperation.mjs.map +1 -0
- package/dist/esm/langfuseRuntimeContext.mjs +3 -2
- package/dist/esm/langfuseRuntimeContext.mjs.map +1 -1
- package/dist/esm/langfuseRuntimeScope.mjs +12 -3
- package/dist/esm/langfuseRuntimeScope.mjs.map +1 -1
- package/dist/esm/langfuseSpanRegistry.mjs +34 -1
- package/dist/esm/langfuseSpanRegistry.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +1 -6
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/langfuseTraceShaping.mjs +58 -10
- package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +8 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +3 -3
- package/dist/esm/run.mjs +59 -25
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +1 -1
- package/dist/esm/tools/ToolNode.mjs +2 -2
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +2 -2
- package/dist/esm/utils/tokens.mjs +9 -5
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/common/constants.d.ts +8 -0
- package/dist/types/graphs/Graph.d.ts +8 -3
- package/dist/types/graphs/MultiAgentGraph.d.ts +1 -0
- package/dist/types/langfuse.d.ts +10 -1
- package/dist/types/langfuseOperation.d.ts +2 -0
- package/dist/types/langfuseRuntimeContext.d.ts +2 -0
- package/dist/types/langfuseRuntimeScope.d.ts +3 -1
- package/dist/types/langfuseSpanRegistry.d.ts +11 -1
- package/dist/types/langfuseTraceShaping.d.ts +8 -6
- package/dist/types/run.d.ts +4 -3
- package/dist/types/types/activityLabel.d.ts +4 -3
- package/dist/types/types/reasoningLabel.d.ts +1 -1
- package/package.json +5 -5
- package/src/common/constants.ts +9 -0
- package/src/graphs/Graph.ts +125 -103
- package/src/graphs/MultiAgentGraph.ts +6 -2
- package/src/instrumentation.ts +12 -0
- package/src/langfuse.ts +83 -17
- package/src/langfuseOperation.ts +2 -0
- package/src/langfuseRuntimeContext.ts +6 -0
- package/src/langfuseRuntimeScope.ts +31 -1
- package/src/langfuseSpanRegistry.ts +78 -2
- package/src/langfuseToolOutputTracing.ts +0 -2
- package/src/langfuseTraceShaping.ts +120 -26
- package/src/llm/openai/index.ts +34 -3
- package/src/run.ts +118 -49
- package/src/types/activityLabel.ts +4 -3
- package/src/types/reasoningLabel.ts +1 -1
- package/src/utils/tokens.ts +21 -15
package/src/run.ts
CHANGED
|
@@ -26,6 +26,16 @@ import type { MultiAgentGraph } from '@/graphs/MultiAgentGraph';
|
|
|
26
26
|
import type { StandardGraph } from '@/graphs/Graph';
|
|
27
27
|
import type { HookRegistry } from '@/hooks';
|
|
28
28
|
import type * as t from '@/types';
|
|
29
|
+
import {
|
|
30
|
+
Callback,
|
|
31
|
+
GraphEvents,
|
|
32
|
+
TitleMethod,
|
|
33
|
+
ACTIVITY_LABEL_RUN_NAME,
|
|
34
|
+
REASONING_LABEL_RUN_NAME,
|
|
35
|
+
ACTIVITY_PHASE_RUN_NAME,
|
|
36
|
+
ACTIVITY_PHASE_LABEL_RUN_NAME,
|
|
37
|
+
DEFAULT_RECURSION_LIMIT,
|
|
38
|
+
} from '@/common';
|
|
29
39
|
import {
|
|
30
40
|
requireValidSubagentResumeManifest,
|
|
31
41
|
stripSubagentResumeManifest,
|
|
@@ -58,6 +68,10 @@ import {
|
|
|
58
68
|
resolveLangfuseConfig,
|
|
59
69
|
resolveToolOutputTracingConfig,
|
|
60
70
|
} from '@/langfuseConfig';
|
|
71
|
+
import {
|
|
72
|
+
resolveLangfuseDestinationKey,
|
|
73
|
+
resolveLangfuseTraceAnchorParent,
|
|
74
|
+
} from '@/langfuseSpanRegistry';
|
|
61
75
|
import {
|
|
62
76
|
appendCallbacks,
|
|
63
77
|
filterCallbacks,
|
|
@@ -72,17 +86,12 @@ import {
|
|
|
72
86
|
getRunStepResumeState,
|
|
73
87
|
stripRunStepResumeState,
|
|
74
88
|
} from '@/tools/runStepResume';
|
|
75
|
-
import {
|
|
76
|
-
Callback,
|
|
77
|
-
GraphEvents,
|
|
78
|
-
TitleMethod,
|
|
79
|
-
DEFAULT_RECURSION_LIMIT,
|
|
80
|
-
} from '@/common';
|
|
81
89
|
import {
|
|
82
90
|
createCompletionTitleRunnable,
|
|
83
91
|
createTitleRunnable,
|
|
84
92
|
} from '@/utils/title';
|
|
85
93
|
import { applyGraphRuntimeConfig } from '@/graphs/applyGraphRuntimeConfig';
|
|
94
|
+
import { LANGFUSE_OPERATION_METADATA_KEY } from '@/langfuseOperation';
|
|
86
95
|
import { createTokenCounter, encodingForModel } from '@/utils/tokens';
|
|
87
96
|
import { initializeLangfuseTracing } from './instrumentation';
|
|
88
97
|
import { seedRunInitialSessions } from '@/utils/toolSessions';
|
|
@@ -986,6 +995,9 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
986
995
|
* instead of `inputs.messages`.
|
|
987
996
|
*/
|
|
988
997
|
const isResume = inputs instanceof Command;
|
|
998
|
+
if (!isResume) {
|
|
999
|
+
graph.startFreshLangfuseExecution();
|
|
1000
|
+
}
|
|
989
1001
|
const stateInputs = isResume ? undefined : (inputs as t.IState);
|
|
990
1002
|
if (stateInputs != null) {
|
|
991
1003
|
this.activityPhaseTraceInput = findActivityPhaseTraceInput(
|
|
@@ -1116,6 +1128,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
1116
1128
|
streamLangfuseConfig?.deterministicTraceId === true
|
|
1117
1129
|
? this.id
|
|
1118
1130
|
: undefined,
|
|
1131
|
+
traceAnchor: graph.langfuseTraceAnchor,
|
|
1119
1132
|
// The graph's per-execution stamp, NOT the public run id: public ids
|
|
1120
1133
|
// may repeat across concurrent executions (retries, tenant-local
|
|
1121
1134
|
// message ids), and equal stamps defeat foreign-scope rejection.
|
|
@@ -1131,6 +1144,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
1131
1144
|
streamLangfuseConfig?.deterministicTraceId === true
|
|
1132
1145
|
? this.id
|
|
1133
1146
|
: undefined,
|
|
1147
|
+
traceAnchor: graph.langfuseTraceAnchor,
|
|
1134
1148
|
runId: graph.langfuseScopeRunId,
|
|
1135
1149
|
// The aggregate multi-agent policy from the runtime scope — the
|
|
1136
1150
|
// handler must restore THIS (not the primary agent's config-derived
|
|
@@ -1139,7 +1153,6 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
1139
1153
|
traceName,
|
|
1140
1154
|
});
|
|
1141
1155
|
if (langfuseHandler != null) {
|
|
1142
|
-
config.runName = traceName;
|
|
1143
1156
|
config.callbacks = appendCallbacks(config.callbacks, [langfuseHandler]);
|
|
1144
1157
|
}
|
|
1145
1158
|
|
|
@@ -1201,18 +1214,22 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
1201
1214
|
* arg to `BaseGraphState`. Cast on the call so the resume path
|
|
1202
1215
|
* type-checks without widening the wrapper for every caller.
|
|
1203
1216
|
*/
|
|
1204
|
-
const stream = graphRunnable.streamEvents(
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1217
|
+
const stream = graphRunnable.streamEvents(
|
|
1218
|
+
inputs as t.IState,
|
|
1219
|
+
{ ...config, runName: graph.runName },
|
|
1220
|
+
{
|
|
1221
|
+
raiseError: true,
|
|
1222
|
+
/**
|
|
1223
|
+
* Prevent EventStreamCallbackHandler from processing custom events.
|
|
1224
|
+
* Custom events are already handled via our createCustomEventCallback()
|
|
1225
|
+
* which routes them through the handlerRegistry.
|
|
1226
|
+
* Without this flag, EventStreamCallbackHandler throws errors when
|
|
1227
|
+
* custom events are dispatched for run IDs not in its internal map
|
|
1228
|
+
* (due to timing issues in parallel execution or after run cleanup).
|
|
1229
|
+
*/
|
|
1230
|
+
ignoreCustomEvent: true,
|
|
1231
|
+
}
|
|
1232
|
+
);
|
|
1216
1233
|
|
|
1217
1234
|
for await (const event of stream) {
|
|
1218
1235
|
const { data, metadata, ...info } = event;
|
|
@@ -2123,6 +2140,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2123
2140
|
const labelAgentName =
|
|
2124
2141
|
labelAgentId == null ? undefined : labelContext?.name;
|
|
2125
2142
|
const labelMetadata: Record<string, unknown> = {
|
|
2143
|
+
[LANGFUSE_OPERATION_METADATA_KEY]: ACTIVITY_LABEL_RUN_NAME,
|
|
2126
2144
|
sourceRunId: this.id,
|
|
2127
2145
|
responseId: this.id,
|
|
2128
2146
|
activityIndex: labelIndex,
|
|
@@ -2132,7 +2150,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2132
2150
|
...(labelAgentId == null ? {} : { agentId: labelAgentId }),
|
|
2133
2151
|
...(labelAgentName == null ? {} : { agentName: labelAgentName }),
|
|
2134
2152
|
};
|
|
2135
|
-
const traceMetadata = {
|
|
2153
|
+
const traceMetadata: Record<string, string> = {
|
|
2136
2154
|
...createLangfuseTraceMetadata({
|
|
2137
2155
|
messageId: 'activity-label-' + this.id,
|
|
2138
2156
|
parentMessageId: labelParentMessageId,
|
|
@@ -2150,16 +2168,9 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2150
2168
|
labelContext?.langfuse
|
|
2151
2169
|
);
|
|
2152
2170
|
initializeLangfuseTracing(labelLangfuseConfig);
|
|
2153
|
-
/**
|
|
2154
|
-
*
|
|
2155
|
-
*
|
|
2156
|
-
* into that trace. When a parent seed is active we must override it
|
|
2157
|
-
* with a per-label one.
|
|
2158
|
-
* 2. Without deterministic tracing there is no parent seed, and forcing
|
|
2159
|
-
* one here would make label trace ids deterministic when neither
|
|
2160
|
-
* `processStream` nor `generateTitle` are — so leave it unset.
|
|
2161
|
-
* Seeded when determinism is opted into OR a parent seed is live;
|
|
2162
|
-
* otherwise unseeded, matching the other generation paths. */
|
|
2171
|
+
/** A captured source observation parents the label in the agent trace.
|
|
2172
|
+
* The distinct seed remains the standalone fallback when labeling runs
|
|
2173
|
+
* before tracing starts or against another Langfuse destination. */
|
|
2163
2174
|
const inheritedTraceSeed = getTraceIdSeed();
|
|
2164
2175
|
const labelTraceSeed =
|
|
2165
2176
|
labelLangfuseConfig?.deterministicTraceId === true ||
|
|
@@ -2174,6 +2185,15 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2174
2185
|
traceIdSeed: labelTraceSeed,
|
|
2175
2186
|
runId: labelScopeRunId,
|
|
2176
2187
|
});
|
|
2188
|
+
const labelParentSpanContext = resolveLangfuseTraceAnchorParent(
|
|
2189
|
+
this.Graph?.langfuseTraceAnchor,
|
|
2190
|
+
resolveLangfuseDestinationKey(labelLangfuseConfig),
|
|
2191
|
+
labelAgentId
|
|
2192
|
+
);
|
|
2193
|
+
if (labelParentSpanContext != null) {
|
|
2194
|
+
labelMetadata.sourceTraceId = labelParentSpanContext.traceId;
|
|
2195
|
+
traceMetadata.sourceTraceId = labelParentSpanContext.traceId;
|
|
2196
|
+
}
|
|
2177
2197
|
/** Handler only when a session id resolved from
|
|
2178
2198
|
* `chainOptions.configurable.thread_id`: without it the label call has
|
|
2179
2199
|
* no conversation identity, and tracing it would create an orphan
|
|
@@ -2187,15 +2207,18 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2187
2207
|
langfuse: labelLangfuseConfig,
|
|
2188
2208
|
userId: labelUserId,
|
|
2189
2209
|
sessionId: labelSessionId,
|
|
2190
|
-
traceMetadata
|
|
2210
|
+
traceMetadata:
|
|
2211
|
+
labelParentSpanContext == null ? traceMetadata : undefined,
|
|
2191
2212
|
tags: labelTags,
|
|
2192
2213
|
traceIdSeed:
|
|
2193
2214
|
labelLangfuseConfig?.deterministicTraceId === true
|
|
2194
2215
|
? labelTraceSeed
|
|
2195
2216
|
: undefined,
|
|
2217
|
+
parentSpanContext: labelParentSpanContext,
|
|
2218
|
+
inheritTraceIdentity: labelParentSpanContext != null,
|
|
2196
2219
|
runId: labelScopeRunId,
|
|
2197
2220
|
toolOutputTracing: labelRuntimeScope.toolOutputTracing,
|
|
2198
|
-
traceName: labelRunName,
|
|
2221
|
+
traceName: labelParentSpanContext == null ? labelRunName : undefined,
|
|
2199
2222
|
});
|
|
2200
2223
|
}
|
|
2201
2224
|
if (labelLangfuseHandler != null) {
|
|
@@ -2297,9 +2320,11 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2297
2320
|
langfuse: labelLangfuseConfig,
|
|
2298
2321
|
userId: labelUserId,
|
|
2299
2322
|
sessionId: labelSessionId,
|
|
2300
|
-
traceName: labelRunName,
|
|
2301
|
-
traceMetadata
|
|
2323
|
+
traceName: labelParentSpanContext == null ? labelRunName : undefined,
|
|
2324
|
+
traceMetadata:
|
|
2325
|
+
labelParentSpanContext == null ? traceMetadata : undefined,
|
|
2302
2326
|
tags: labelTags,
|
|
2327
|
+
inheritTraceIdentity: labelParentSpanContext != null,
|
|
2303
2328
|
},
|
|
2304
2329
|
() =>
|
|
2305
2330
|
model.invoke(
|
|
@@ -2457,6 +2482,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2457
2482
|
const resolvedSourceRunId = sourceRunId ?? this.id;
|
|
2458
2483
|
const reasoningResponseId = responseId ?? this.id;
|
|
2459
2484
|
const reasoningMetadata: Record<string, unknown> = {
|
|
2485
|
+
[LANGFUSE_OPERATION_METADATA_KEY]: REASONING_LABEL_RUN_NAME,
|
|
2460
2486
|
sourceRunId: resolvedSourceRunId,
|
|
2461
2487
|
...(sourceTraceId == null ? {} : { sourceTraceId }),
|
|
2462
2488
|
responseId: reasoningResponseId,
|
|
@@ -2470,7 +2496,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2470
2496
|
...(reasoningAgentId == null ? {} : { agentId: reasoningAgentId }),
|
|
2471
2497
|
...(reasoningAgentName == null ? {} : { agentName: reasoningAgentName }),
|
|
2472
2498
|
};
|
|
2473
|
-
const traceMetadata = {
|
|
2499
|
+
const traceMetadata: Record<string, string> = {
|
|
2474
2500
|
...createLangfuseTraceMetadata({
|
|
2475
2501
|
messageId: `reasoning-label-${reasoningResponseId}`,
|
|
2476
2502
|
parentMessageId: reasoningParentMessageId,
|
|
@@ -2512,21 +2538,40 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2512
2538
|
traceIdSeed: reasoningTraceSeed,
|
|
2513
2539
|
runId: reasoningScopeRunId,
|
|
2514
2540
|
});
|
|
2541
|
+
const candidateReasoningParent = resolveLangfuseTraceAnchorParent(
|
|
2542
|
+
this.Graph?.langfuseTraceAnchor,
|
|
2543
|
+
resolveLangfuseDestinationKey(reasoningLangfuseConfig),
|
|
2544
|
+
reasoningAgentId
|
|
2545
|
+
);
|
|
2546
|
+
const reasoningParentSpanContext =
|
|
2547
|
+
resolvedSourceRunId === this.id &&
|
|
2548
|
+
(sourceTraceId == null ||
|
|
2549
|
+
sourceTraceId === candidateReasoningParent?.traceId)
|
|
2550
|
+
? candidateReasoningParent
|
|
2551
|
+
: undefined;
|
|
2552
|
+
if (reasoningParentSpanContext != null) {
|
|
2553
|
+
reasoningMetadata.sourceTraceId = reasoningParentSpanContext.traceId;
|
|
2554
|
+
traceMetadata.sourceTraceId = reasoningParentSpanContext.traceId;
|
|
2555
|
+
}
|
|
2515
2556
|
let reasoningLangfuseHandler: CallbackEntry | undefined;
|
|
2516
2557
|
if (reasoningSessionId != null) {
|
|
2517
2558
|
reasoningLangfuseHandler = createLangfuseHandler({
|
|
2518
2559
|
langfuse: reasoningLangfuseConfig,
|
|
2519
2560
|
userId: reasoningUserId,
|
|
2520
2561
|
sessionId: reasoningSessionId,
|
|
2521
|
-
traceMetadata
|
|
2562
|
+
traceMetadata:
|
|
2563
|
+
reasoningParentSpanContext == null ? traceMetadata : undefined,
|
|
2522
2564
|
tags: reasoningTags,
|
|
2523
2565
|
traceIdSeed:
|
|
2524
2566
|
reasoningLangfuseConfig?.deterministicTraceId === true
|
|
2525
2567
|
? reasoningTraceSeed
|
|
2526
2568
|
: undefined,
|
|
2569
|
+
parentSpanContext: reasoningParentSpanContext,
|
|
2570
|
+
inheritTraceIdentity: reasoningParentSpanContext != null,
|
|
2527
2571
|
runId: reasoningScopeRunId,
|
|
2528
2572
|
toolOutputTracing: reasoningRuntimeScope.toolOutputTracing,
|
|
2529
|
-
traceName:
|
|
2573
|
+
traceName:
|
|
2574
|
+
reasoningParentSpanContext == null ? reasoningRunName : undefined,
|
|
2530
2575
|
});
|
|
2531
2576
|
}
|
|
2532
2577
|
if (reasoningLangfuseHandler != null) {
|
|
@@ -2585,9 +2630,12 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2585
2630
|
langfuse: reasoningLangfuseConfig,
|
|
2586
2631
|
userId: reasoningUserId,
|
|
2587
2632
|
sessionId: reasoningSessionId,
|
|
2588
|
-
traceName:
|
|
2589
|
-
|
|
2633
|
+
traceName:
|
|
2634
|
+
reasoningParentSpanContext == null ? reasoningRunName : undefined,
|
|
2635
|
+
traceMetadata:
|
|
2636
|
+
reasoningParentSpanContext == null ? traceMetadata : undefined,
|
|
2590
2637
|
tags: reasoningTags,
|
|
2638
|
+
inheritTraceIdentity: reasoningParentSpanContext != null,
|
|
2591
2639
|
},
|
|
2592
2640
|
() =>
|
|
2593
2641
|
model.invoke(
|
|
@@ -2638,9 +2686,10 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2638
2686
|
|
|
2639
2687
|
/**
|
|
2640
2688
|
* Generates one parent summary for two or more logical activities. The
|
|
2641
|
-
* summary model is traced as
|
|
2642
|
-
*
|
|
2643
|
-
*
|
|
2689
|
+
* summary model is traced as an activity-phase chain beneath the source
|
|
2690
|
+
* agent run, with the model callback recorded as its generation child. It
|
|
2691
|
+
* falls back to a dedicated trace when no source observation is available.
|
|
2692
|
+
* No session id means no phase trace, avoiding orphan observations.
|
|
2644
2693
|
*/
|
|
2645
2694
|
async generateActivityPhaseLabel({
|
|
2646
2695
|
provider,
|
|
@@ -2771,6 +2820,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2771
2820
|
const phaseParentMessageId =
|
|
2772
2821
|
phaseChainOptions.configurable?.requestBody?.parentMessageId;
|
|
2773
2822
|
const phaseMetadata: Record<string, unknown> = {
|
|
2823
|
+
[LANGFUSE_OPERATION_METADATA_KEY]: ACTIVITY_PHASE_LABEL_RUN_NAME,
|
|
2774
2824
|
sourceRunId: sourceRunId ?? this.id,
|
|
2775
2825
|
...(sourceTraceId == null ? {} : { sourceTraceId }),
|
|
2776
2826
|
responseId: phaseMessageId,
|
|
@@ -2785,7 +2835,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2785
2835
|
...(phaseAgentName == null ? {} : { agentName: phaseAgentName }),
|
|
2786
2836
|
...(closingTextPhase == null ? {} : { closingTextPhase }),
|
|
2787
2837
|
};
|
|
2788
|
-
const traceMetadata = {
|
|
2838
|
+
const traceMetadata: Record<string, string> = {
|
|
2789
2839
|
...createLangfuseTraceMetadata({
|
|
2790
2840
|
messageId: phaseMessageId,
|
|
2791
2841
|
parentMessageId: phaseParentMessageId,
|
|
@@ -2826,6 +2876,19 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2826
2876
|
traceIdSeed: phaseTraceSeed,
|
|
2827
2877
|
runId: phaseScopeRunId,
|
|
2828
2878
|
});
|
|
2879
|
+
const candidatePhaseParent = resolveLangfuseTraceAnchorParent(
|
|
2880
|
+
this.Graph?.langfuseTraceAnchor,
|
|
2881
|
+
resolveLangfuseDestinationKey(phaseLangfuseConfig)
|
|
2882
|
+
);
|
|
2883
|
+
const phaseParentSpanContext =
|
|
2884
|
+
(sourceRunId == null || sourceRunId === this.id) &&
|
|
2885
|
+
(sourceTraceId == null || sourceTraceId === candidatePhaseParent?.traceId)
|
|
2886
|
+
? candidatePhaseParent
|
|
2887
|
+
: undefined;
|
|
2888
|
+
if (phaseParentSpanContext != null) {
|
|
2889
|
+
phaseMetadata.sourceTraceId = phaseParentSpanContext.traceId;
|
|
2890
|
+
traceMetadata.sourceTraceId = phaseParentSpanContext.traceId;
|
|
2891
|
+
}
|
|
2829
2892
|
let phaseLangfuseHandler: CallbackEntry | undefined;
|
|
2830
2893
|
const sourceUserText =
|
|
2831
2894
|
this.activityPhaseTraceInput ??
|
|
@@ -2835,15 +2898,18 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2835
2898
|
langfuse: phaseLangfuseConfig,
|
|
2836
2899
|
userId: phaseUserId,
|
|
2837
2900
|
sessionId: phaseSessionId,
|
|
2838
|
-
traceMetadata
|
|
2901
|
+
traceMetadata:
|
|
2902
|
+
phaseParentSpanContext == null ? traceMetadata : undefined,
|
|
2839
2903
|
tags: phaseTags,
|
|
2840
2904
|
traceIdSeed:
|
|
2841
2905
|
phaseLangfuseConfig?.deterministicTraceId === true
|
|
2842
2906
|
? phaseTraceSeed
|
|
2843
2907
|
: undefined,
|
|
2908
|
+
parentSpanContext: phaseParentSpanContext,
|
|
2909
|
+
inheritTraceIdentity: phaseParentSpanContext != null,
|
|
2844
2910
|
runId: phaseScopeRunId,
|
|
2845
2911
|
toolOutputTracing: phaseRuntimeScope.toolOutputTracing,
|
|
2846
|
-
traceName: phaseTraceName,
|
|
2912
|
+
traceName: phaseParentSpanContext == null ? phaseTraceName : undefined,
|
|
2847
2913
|
});
|
|
2848
2914
|
}
|
|
2849
2915
|
if (phaseLangfuseHandler != null) {
|
|
@@ -2864,7 +2930,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2864
2930
|
const invokeConfig = Object.assign({}, phaseChainOptions, {
|
|
2865
2931
|
run_id: phaseRunId,
|
|
2866
2932
|
runId: phaseRunId,
|
|
2867
|
-
runName:
|
|
2933
|
+
runName: ACTIVITY_PHASE_RUN_NAME,
|
|
2868
2934
|
tags: [...new Set([...(phaseChainOptions.tags ?? []), ...phaseTags])],
|
|
2869
2935
|
metadata: {
|
|
2870
2936
|
...(phaseChainOptions.metadata ?? {}),
|
|
@@ -2943,7 +3009,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2943
3009
|
? { label, messages: [new AIMessage(label)] }
|
|
2944
3010
|
: { messages: [] };
|
|
2945
3011
|
},
|
|
2946
|
-
}).withConfig({ runName:
|
|
3012
|
+
}).withConfig({ runName: ACTIVITY_PHASE_RUN_NAME });
|
|
2947
3013
|
|
|
2948
3014
|
try {
|
|
2949
3015
|
const result = await withLangfuseRuntimeScope(phaseRuntimeScope, () =>
|
|
@@ -2952,9 +3018,12 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2952
3018
|
langfuse: phaseLangfuseConfig,
|
|
2953
3019
|
userId: phaseUserId,
|
|
2954
3020
|
sessionId: phaseSessionId,
|
|
2955
|
-
traceName:
|
|
2956
|
-
|
|
3021
|
+
traceName:
|
|
3022
|
+
phaseParentSpanContext == null ? phaseTraceName : undefined,
|
|
3023
|
+
traceMetadata:
|
|
3024
|
+
phaseParentSpanContext == null ? traceMetadata : undefined,
|
|
2957
3025
|
tags: phaseTags,
|
|
3026
|
+
inheritTraceIdentity: phaseParentSpanContext != null,
|
|
2958
3027
|
},
|
|
2959
3028
|
() =>
|
|
2960
3029
|
phaseRunnable.invoke(
|
|
@@ -62,8 +62,9 @@ export type RunActivityLabelOptions = {
|
|
|
62
62
|
};
|
|
63
63
|
/**
|
|
64
64
|
* Seed for deterministic Langfuse trace ids (e.g. `${runId}-${slotIndex}`)
|
|
65
|
-
*
|
|
66
|
-
*
|
|
65
|
+
* for a distinct, reproducible fallback trace when the source agent
|
|
66
|
+
* observation is unavailable. Normally the label is parented into the
|
|
67
|
+
* source agent trace instead.
|
|
67
68
|
*/
|
|
68
69
|
traceSeed?: string;
|
|
69
70
|
};
|
|
@@ -112,7 +113,7 @@ export type RunActivityPhaseLabelOptions = {
|
|
|
112
113
|
traceSeed?: string;
|
|
113
114
|
/** Stable source run identifier recorded on the phase observation. */
|
|
114
115
|
sourceRunId?: string;
|
|
115
|
-
/** Source Langfuse trace id
|
|
116
|
+
/** Source Langfuse trace id retained as correlation metadata. */
|
|
116
117
|
sourceTraceId?: string;
|
|
117
118
|
/** Host response/message identifier recorded on the phase observation. */
|
|
118
119
|
responseId?: string;
|
|
@@ -52,7 +52,7 @@ export type RunReasoningLabelOptions = {
|
|
|
52
52
|
traceSeed?: string;
|
|
53
53
|
/** Stable source run identifier recorded on the observation. */
|
|
54
54
|
sourceRunId?: string;
|
|
55
|
-
/** Source Langfuse trace id
|
|
55
|
+
/** Source Langfuse trace id retained as correlation metadata. */
|
|
56
56
|
sourceTraceId?: string;
|
|
57
57
|
/** Host response/message identifier recorded on the observation. */
|
|
58
58
|
responseId?: string;
|
package/src/utils/tokens.ts
CHANGED
|
@@ -120,6 +120,10 @@ const MAX_STRUCTURED_TOKENIZATION_CHARS = 200_000;
|
|
|
120
120
|
/** One UTF-16 character can encode to several tokenizer pieces. */
|
|
121
121
|
const MAX_TOKENS_PER_OMITTED_STRUCTURED_CHAR = 4;
|
|
122
122
|
const MAX_STRUCTURED_SAFETY_INSPECTION_WORK = 10_000;
|
|
123
|
+
/** Bounds BPE work per plain-text segment without omitting any text. */
|
|
124
|
+
const MAX_TEXT_TOKENIZATION_CHARS = 8_192;
|
|
125
|
+
/** Covers tokenizer segmentation changes on both sides of a chunk boundary. */
|
|
126
|
+
const TEXT_TOKEN_CHUNK_BOUNDARY_SAFETY_TOKENS = 4;
|
|
123
127
|
|
|
124
128
|
/**
|
|
125
129
|
* Extracts image dimensions from the first bytes of a base64-encoded
|
|
@@ -886,22 +890,24 @@ function getBoundedTextTokenCount(
|
|
|
886
890
|
value: string,
|
|
887
891
|
getTokenCount: (text: string) => number
|
|
888
892
|
): number {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
893
|
+
let numTokens = 0;
|
|
894
|
+
for (
|
|
895
|
+
let offset = 0;
|
|
896
|
+
offset < value.length;
|
|
897
|
+
offset += MAX_TEXT_TOKENIZATION_CHARS
|
|
898
|
+
) {
|
|
899
|
+
const chunkTokens = ensureSafeTokenMeasurement(
|
|
900
|
+
getTokenCount(value.slice(offset, offset + MAX_TEXT_TOKENIZATION_CHARS)),
|
|
901
|
+
'tokenizer'
|
|
902
|
+
);
|
|
903
|
+
const boundaryTokens =
|
|
904
|
+
offset > 0 ? TEXT_TOKEN_CHUNK_BOUNDARY_SAFETY_TOKENS : 0;
|
|
905
|
+
numTokens = Math.min(
|
|
906
|
+
Number.MAX_SAFE_INTEGER,
|
|
907
|
+
numTokens + chunkTokens + boundaryTokens
|
|
908
|
+
);
|
|
900
909
|
}
|
|
901
|
-
return
|
|
902
|
-
Number.MAX_SAFE_INTEGER,
|
|
903
|
-
previewTokens + omittedChars * MAX_TOKENS_PER_OMITTED_STRUCTURED_CHAR
|
|
904
|
-
);
|
|
910
|
+
return numTokens;
|
|
905
911
|
}
|
|
906
912
|
|
|
907
913
|
function getBoundedStructuredTokenCount(
|