@librechat/agents 3.6.7 → 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/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/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/dist/esm/stream.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { composeAbortSignals } from "./utils/misc.mjs";
|
|
2
1
|
import { CODE_EXECUTION_TOOLS, LOCAL_CODING_BUNDLE_NAMES } from "./common/enum.mjs";
|
|
3
2
|
import "./common/index.mjs";
|
|
3
|
+
import { composeAbortSignals } from "./utils/misc.mjs";
|
|
4
4
|
import { calculateMaxToolResultChars, truncateToolResultContent } from "./utils/truncation.mjs";
|
|
5
5
|
import { serializeStructuredValueBounded, serializeToolContentBounded } from "./utils/toolContent.mjs";
|
|
6
6
|
import { getMessageId } from "./messages/ids.mjs";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { CODE_EXECUTION_TOOLS } from "../common/enum.mjs";
|
|
2
|
+
import "../common/index.mjs";
|
|
1
3
|
import { attachRunStepResumeState } from "./runStepResume.mjs";
|
|
2
4
|
import { SUBAGENT_PARENT_BATCH_CONFIG_KEY, SUBAGENT_REPLAY_CONTROLLER, attachSubagentResumeManifest } from "./subagent/SubagentReplay.mjs";
|
|
3
5
|
import { composeAbortSignals } from "../utils/misc.mjs";
|
|
4
|
-
import { CODE_EXECUTION_TOOLS } from "../common/enum.mjs";
|
|
5
|
-
import "../common/index.mjs";
|
|
6
6
|
import { resolveLangfuseRuntimeScope, withLangfuseRuntimeScope } from "../langfuseRuntimeScope.mjs";
|
|
7
7
|
import { calculateMaxToolResultChars, truncateToolResultContent } from "../utils/truncation.mjs";
|
|
8
8
|
import { cloneToolMessageWithContent, compactToolContent, hasComputerCallOutputMarker, isComputerCallOutputContent, isComputerCallOutputMessage, serializeStructuredValueBounded, serializeToolContentBounded } from "../utils/toolContent.mjs";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import "../../common/enum.mjs";
|
|
2
|
+
import "../../common/index.mjs";
|
|
1
3
|
import { stripRunStepResumeState } from "../runStepResume.mjs";
|
|
2
4
|
import { SUBAGENT_RESUME_ATTEMPT_CONFIG_KEY, SUBAGENT_RESUME_MANIFEST_CONFIG_KEY, attachSubagentResumeManifest, getSubagentResumeManifest } from "./SubagentReplay.mjs";
|
|
3
5
|
import { composeAbortSignals } from "../../utils/misc.mjs";
|
|
4
|
-
import "../../common/enum.mjs";
|
|
5
|
-
import "../../common/index.mjs";
|
|
6
6
|
import { seedAgentInitialSessions } from "../../utils/toolSessions.mjs";
|
|
7
7
|
import { convertInjectedMessages } from "../../messages/injected.mjs";
|
|
8
8
|
import { StreamLimitExceededError } from "../../llm/streamLimits.mjs";
|
|
@@ -29,3 +29,11 @@ export declare const PREEMPT_BOUNDARY_HOOK_TIMEOUT_MS = 120000;
|
|
|
29
29
|
* the stream config; a preemption-enabled run adds its seal budget on top.
|
|
30
30
|
*/
|
|
31
31
|
export declare const DEFAULT_RECURSION_LIMIT = 50;
|
|
32
|
+
/** Stable runtime names used for agent workflow observations. */
|
|
33
|
+
export declare const STANDARD_GRAPH_RUN_NAME = "AgentGraph";
|
|
34
|
+
export declare const MULTI_AGENT_GRAPH_RUN_NAME = "MultiAgentGraph";
|
|
35
|
+
export declare const AGENT_MODEL_CALL_RUN_NAME = "AgentModelCall";
|
|
36
|
+
export declare const ACTIVITY_LABEL_RUN_NAME = "StepLabel";
|
|
37
|
+
export declare const REASONING_LABEL_RUN_NAME = "ReasoningLabel";
|
|
38
|
+
export declare const ACTIVITY_PHASE_RUN_NAME = "MultiStepLabel";
|
|
39
|
+
export declare const ACTIVITY_PHASE_LABEL_RUN_NAME = "MultiStepLabelGeneration";
|
|
@@ -234,6 +234,7 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
|
|
|
234
234
|
getOrCreateFileCheckpointer(): t.LocalFileCheckpointer | undefined;
|
|
235
235
|
}
|
|
236
236
|
export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
237
|
+
readonly runName: string;
|
|
237
238
|
overrideModel?: t.ChatModel;
|
|
238
239
|
private subagentModelOverride?;
|
|
239
240
|
private readonly graphFactory;
|
|
@@ -260,10 +261,12 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
|
|
|
260
261
|
* component: public run ids are unrestricted and may repeat across
|
|
261
262
|
* concurrently executing runs (retries, duplicate submissions,
|
|
262
263
|
* tenant-local message ids), and equal stamps would let those runs adopt
|
|
263
|
-
* each other's scopes.
|
|
264
|
-
*
|
|
264
|
+
* each other's scopes. Fresh stream executions rotate this stamp; resumes
|
|
265
|
+
* retain it so the continuation stays in the interrupted execution.
|
|
265
266
|
*/
|
|
266
|
-
|
|
267
|
+
langfuseScopeRunId: string;
|
|
268
|
+
/** Opaque key for parenting post-processing observations to this run. */
|
|
269
|
+
langfuseTraceAnchor: object;
|
|
267
270
|
/**
|
|
268
271
|
* Boundary between historical messages (loaded from conversation state)
|
|
269
272
|
* and messages produced during the current run. Set once in the state
|
|
@@ -388,6 +391,8 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
|
|
|
388
391
|
*/
|
|
389
392
|
pendingPreemptReturn: Set<string>;
|
|
390
393
|
constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, subagentUsageSink, subagentTasks, subagentScope, subagentExecutionContext, preemption, streamLimits, }: t.StandardGraphInput, dependencies?: GraphFactoryDependencies);
|
|
394
|
+
/** Rotates the Langfuse identities that must never cross fresh executions. */
|
|
395
|
+
startFreshLangfuseExecution(): void;
|
|
391
396
|
resetValues(keepContent?: boolean, checkpointScope?: string): void;
|
|
392
397
|
/** Seeds the sidecar message view that checkpoint restoration bypasses. */
|
|
393
398
|
restoreCheckpointMessages(messages: BaseMessage[], pendingMessages?: BaseMessage[]): void;
|
|
@@ -16,6 +16,7 @@ import { StandardGraph } from './Graph';
|
|
|
16
16
|
* OR continues its workflow (direct edges), but not both simultaneously.
|
|
17
17
|
*/
|
|
18
18
|
export declare class MultiAgentGraph extends StandardGraph {
|
|
19
|
+
readonly runName = "MultiAgentGraph";
|
|
19
20
|
private edges;
|
|
20
21
|
private startingNodes;
|
|
21
22
|
private directEdges;
|
package/dist/types/langfuse.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CallbackHandler } from '@langfuse/langchain';
|
|
2
|
+
import type { SpanContext } from '@opentelemetry/api';
|
|
2
3
|
import type { ResolvedLangfuseToolOutputTracingConfig } from '@/langfuseRuntimeContext';
|
|
3
4
|
import type * as t from '@/types';
|
|
4
5
|
import { hasLangfuseConfigCredentials, hasLangfuseEnvCredentials, hasLangfuseEnvConfig } from '@/langfuseConfig';
|
|
@@ -12,6 +13,14 @@ type LangfuseHandlerParams = {
|
|
|
12
13
|
traceMetadata?: LangfuseTraceMetadata;
|
|
13
14
|
tags?: string[];
|
|
14
15
|
traceIdSeed?: string;
|
|
16
|
+
/** Opaque key used by the span processor to capture this run's parents. */
|
|
17
|
+
traceAnchor?: object;
|
|
18
|
+
/** Agent lane this handler owns when ambient callback scope is unavailable. */
|
|
19
|
+
agentId?: string;
|
|
20
|
+
/** Exported observation that auxiliary work should be nested beneath. */
|
|
21
|
+
parentSpanContext?: SpanContext;
|
|
22
|
+
/** Keep an existing parent trace's user, session, name, and metadata. */
|
|
23
|
+
inheritTraceIdentity?: boolean;
|
|
15
24
|
/** Identity of the run this handler traces; ambient runtime scopes are
|
|
16
25
|
* only adopted when stamped with the same run (see
|
|
17
26
|
* `LangfuseRuntimeContext.runId`). */
|
|
@@ -42,7 +51,7 @@ export declare function createLangfuseTraceMetadata({ messageId, parentMessageId
|
|
|
42
51
|
export declare function getLangfuseTraceName(traceMetadata?: LangfuseTraceMetadata, fallback?: string): string;
|
|
43
52
|
export declare function shouldCreateLangfuseHandler(langfuse?: t.LangfuseConfig): boolean;
|
|
44
53
|
export declare function createLegacyLangfuseHandler(params: LangfuseHandlerParams): CallbackHandler;
|
|
45
|
-
export declare function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, tags, traceIdSeed, runId, toolOutputTracing, traceName, }: AgentLangfuseHandlerParams): CallbackHandler | undefined;
|
|
54
|
+
export declare function createLangfuseHandler({ langfuse, userId, sessionId, traceMetadata, tags, traceIdSeed, traceAnchor, agentId, parentSpanContext, inheritTraceIdentity, runId, toolOutputTracing, traceName, }: AgentLangfuseHandlerParams): CallbackHandler | undefined;
|
|
46
55
|
export declare function withLangfuseAttributes<T>(params: LangfuseAttributeParams, action: () => T): T;
|
|
47
56
|
export declare function hasExplicitLangfuseConfig(contexts: Iterable<{
|
|
48
57
|
langfuse?: t.LangfuseConfig;
|
|
@@ -8,6 +8,8 @@ export type ResolvedLangfuseToolOutputTracingConfig = {
|
|
|
8
8
|
export type LangfuseRuntimeContext = {
|
|
9
9
|
langfuse?: t.LangfuseConfig;
|
|
10
10
|
traceIdSeed?: string;
|
|
11
|
+
/** Opaque run-owned key used to recover the exported trace parent. */
|
|
12
|
+
traceAnchor?: object;
|
|
11
13
|
toolOutputTracing?: ResolvedLangfuseToolOutputTracingConfig;
|
|
12
14
|
/**
|
|
13
15
|
* Identity of the run this scope belongs to. LangChain executes
|
|
@@ -6,6 +6,7 @@ export type ResolveLangfuseRuntimeScopeParams = {
|
|
|
6
6
|
runLangfuse?: t.LangfuseConfig;
|
|
7
7
|
langfuseOverlay?: t.LangfuseConfig;
|
|
8
8
|
traceIdSeed?: string;
|
|
9
|
+
traceAnchor?: object;
|
|
9
10
|
runId?: string;
|
|
10
11
|
agentId?: string;
|
|
11
12
|
};
|
|
@@ -18,6 +19,7 @@ export type LangfuseRuntimeScopeOptions = {
|
|
|
18
19
|
};
|
|
19
20
|
export declare function getOtelLangfuseConfig(activeContext: Context): t.LangfuseConfig | undefined;
|
|
20
21
|
export declare function getOtelTraceIdSeed(activeContext: Context): string | undefined;
|
|
22
|
+
export declare function resolveLangfuseTraceAnchor(activeContext: Context): object | undefined;
|
|
21
23
|
export declare function getOtelToolOutputTracingConfig(activeContext: Context): ResolvedLangfuseToolOutputTracingConfig | undefined;
|
|
22
24
|
export declare function resolveLangfuseConfigForSpan(activeContext: Context): t.LangfuseConfig | undefined;
|
|
23
25
|
export declare function resolveTraceIdSeedForSpan(activeContext: Context): string | undefined;
|
|
@@ -29,4 +31,4 @@ export declare function resolveLangfuseScopeRunId(activeContext: Context): strin
|
|
|
29
31
|
export declare function resolveLangfuseScopeAgentId(activeContext: Context): string | undefined;
|
|
30
32
|
export declare function resolveToolOutputTracingConfigForSpan(activeContext: Context): ResolvedLangfuseToolOutputTracingConfig | undefined;
|
|
31
33
|
export declare function withLangfuseRuntimeScope<T>(scope: LangfuseRuntimeScope, action: () => T, options?: LangfuseRuntimeScopeOptions): T;
|
|
32
|
-
export declare function resolveLangfuseRuntimeScope({ runLangfuse, langfuseOverlay, traceIdSeed, runId, agentId, }: ResolveLangfuseRuntimeScopeParams): LangfuseRuntimeScope;
|
|
34
|
+
export declare function resolveLangfuseRuntimeScope({ runLangfuse, langfuseOverlay, traceIdSeed, traceAnchor, runId, agentId, }: ResolveLangfuseRuntimeScopeParams): LangfuseRuntimeScope;
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import type { LangfuseSpanProcessorParams } from '@langfuse/otel';
|
|
2
|
-
import type { Span } from '@opentelemetry/api';
|
|
2
|
+
import type { Span, SpanContext } from '@opentelemetry/api';
|
|
3
3
|
import type * as t from '@/types';
|
|
4
4
|
export declare function registerLangfuseManagedSpan(span: Span, destinationKey: string): void;
|
|
5
5
|
export declare function getLangfuseManagedSpanDestination(span: Span): string | undefined;
|
|
6
|
+
/** Captures the first exported observation for a run and for each agent lane. */
|
|
7
|
+
export declare function registerLangfuseTraceAnchorSpan(anchor: object, span: Span, destinationKey: string, agentId?: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the most specific safe parent available for auxiliary work. An
|
|
10
|
+
* active observation wins so labels emitted inside a tool or reasoning step
|
|
11
|
+
* stay beside their source; otherwise the run root anchors the label in the
|
|
12
|
+
* same trace. An agent lane is the fallback when its overlay exports to a
|
|
13
|
+
* different destination. Cross-destination parents are never returned.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveLangfuseTraceAnchorParent(anchor: object | undefined, destinationKey: string | undefined, agentId?: string): SpanContext | undefined;
|
|
6
16
|
export declare function getLangfuseSpanProcessorParams(langfuse?: t.LangfuseConfig): LangfuseSpanProcessorParams | undefined;
|
|
7
17
|
/**
|
|
8
18
|
* Identity of an export destination (project credentials + endpoint +
|
|
@@ -13,16 +13,18 @@ export declare function shouldDropLangfuseSpan(spanName: string): boolean;
|
|
|
13
13
|
* (`provider__model`) — strip it so switching models doesn't break
|
|
14
14
|
* name-based logic (item 1). The outer workflow node is named with the
|
|
15
15
|
* bare agent id; ephemeral ids reduce to their stable sender name.
|
|
16
|
+
* - Graph and prompt-to-model framework names become stable SDK operations:
|
|
17
|
+
* `AgentGraph` / `MultiAgentGraph` and `AgentModelCall`.
|
|
16
18
|
* - LLM generation spans keep the provider client class name (`ChatOpenAI`,
|
|
17
|
-
* `AzureChatOpenAI`, …); rename
|
|
18
|
-
*
|
|
19
|
-
* generation's model attribute
|
|
19
|
+
* `AzureChatOpenAI`, …); rename ordinary calls to a provider-agnostic `llm`
|
|
20
|
+
* and label calls by their activity/reasoning role. The model stays on the
|
|
21
|
+
* generation's model attribute.
|
|
20
22
|
* - Agent nodes become `agent` observations, while tool-dispatch nodes become
|
|
21
23
|
* stable `chain` observations whose input is scoped to the pending calls.
|
|
22
24
|
* Individual child calls remain `tool` observations (items 3 & 4).
|
|
23
25
|
* - Agent trace roots become `agent` observations, while title and activity
|
|
24
|
-
* summary
|
|
25
|
-
* reduced to the user question and assistant response when
|
|
26
|
-
* available (item 2).
|
|
26
|
+
* summary operations become `chain` observations. Root-observation
|
|
27
|
+
* input/output are reduced to the user question and assistant response when
|
|
28
|
+
* chat messages are available (item 2).
|
|
27
29
|
*/
|
|
28
30
|
export declare function shapeLangfuseSpan(span: ReadableSpan): void;
|
package/dist/types/run.d.ts
CHANGED
|
@@ -264,9 +264,10 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
264
264
|
generateReasoningLabel({ provider, clientOptions, visibleReasoning, reasoningStepId, revision, status, previousLabel, agentId, prompt, charLimit, chainOptions, traceSeed, sourceRunId, sourceTraceId, responseId, }: t.RunReasoningLabelOptions): Promise<t.ReasoningLabelResult>;
|
|
265
265
|
/**
|
|
266
266
|
* Generates one parent summary for two or more logical activities. The
|
|
267
|
-
* summary model is traced as
|
|
268
|
-
*
|
|
269
|
-
*
|
|
267
|
+
* summary model is traced as an activity-phase chain beneath the source
|
|
268
|
+
* agent run, with the model callback recorded as its generation child. It
|
|
269
|
+
* falls back to a dedicated trace when no source observation is available.
|
|
270
|
+
* No session id means no phase trace, avoiding orphan observations.
|
|
270
271
|
*/
|
|
271
272
|
generateActivityPhaseLabel({ provider, clientOptions, activities, totalActivityCount, assistantContext, closingTextPhase, prompt, charLimit, chainOptions, traceSeed, sourceRunId, sourceTraceId, responseId, phaseIndex, status, agentIds, }: t.RunActivityPhaseLabelOptions): Promise<{
|
|
272
273
|
label?: string;
|
|
@@ -60,8 +60,9 @@ export type RunActivityLabelOptions = {
|
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* Seed for deterministic Langfuse trace ids (e.g. `${runId}-${slotIndex}`)
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* for a distinct, reproducible fallback trace when the source agent
|
|
64
|
+
* observation is unavailable. Normally the label is parented into the
|
|
65
|
+
* source agent trace instead.
|
|
65
66
|
*/
|
|
66
67
|
traceSeed?: string;
|
|
67
68
|
};
|
|
@@ -108,7 +109,7 @@ export type RunActivityPhaseLabelOptions = {
|
|
|
108
109
|
traceSeed?: string;
|
|
109
110
|
/** Stable source run identifier recorded on the phase observation. */
|
|
110
111
|
sourceRunId?: string;
|
|
111
|
-
/** Source Langfuse trace id
|
|
112
|
+
/** Source Langfuse trace id retained as correlation metadata. */
|
|
112
113
|
sourceTraceId?: string;
|
|
113
114
|
/** Host response/message identifier recorded on the phase observation. */
|
|
114
115
|
responseId?: string;
|
|
@@ -49,7 +49,7 @@ export type RunReasoningLabelOptions = {
|
|
|
49
49
|
traceSeed?: string;
|
|
50
50
|
/** Stable source run identifier recorded on the observation. */
|
|
51
51
|
sourceRunId?: string;
|
|
52
|
-
/** Source Langfuse trace id
|
|
52
|
+
/** Source Langfuse trace id retained as correlation metadata. */
|
|
53
53
|
sourceTraceId?: string;
|
|
54
54
|
/** Host response/message identifier recorded on the observation. */
|
|
55
55
|
responseId?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@librechat/agents",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.8",
|
|
4
4
|
"reova": {
|
|
5
5
|
"enabled": true,
|
|
6
6
|
"endpoint": "https://telemetry.reo.dev/data"
|
|
@@ -245,10 +245,10 @@
|
|
|
245
245
|
"@langchain/openai": "1.5.8",
|
|
246
246
|
"@langchain/textsplitters": "^1.0.1",
|
|
247
247
|
"@langchain/xai": "^1.4.3",
|
|
248
|
-
"@langfuse/core": "^5.
|
|
249
|
-
"@langfuse/langchain": "^5.
|
|
250
|
-
"@langfuse/otel": "^5.
|
|
251
|
-
"@langfuse/tracing": "^5.
|
|
248
|
+
"@langfuse/core": "^5.10.1",
|
|
249
|
+
"@langfuse/langchain": "^5.10.1",
|
|
250
|
+
"@langfuse/otel": "^5.10.1",
|
|
251
|
+
"@langfuse/tracing": "^5.10.1",
|
|
252
252
|
"@opentelemetry/context-async-hooks": "^2.9.0",
|
|
253
253
|
"@opentelemetry/sdk-node": "^0.220.0",
|
|
254
254
|
"@types/diff": "^7.0.2",
|
package/src/common/constants.ts
CHANGED
|
@@ -33,3 +33,12 @@ export const PREEMPT_BOUNDARY_HOOK_TIMEOUT_MS = 120_000;
|
|
|
33
33
|
* the stream config; a preemption-enabled run adds its seal budget on top.
|
|
34
34
|
*/
|
|
35
35
|
export const DEFAULT_RECURSION_LIMIT = 50;
|
|
36
|
+
|
|
37
|
+
/** Stable runtime names used for agent workflow observations. */
|
|
38
|
+
export const STANDARD_GRAPH_RUN_NAME = 'AgentGraph';
|
|
39
|
+
export const MULTI_AGENT_GRAPH_RUN_NAME = 'MultiAgentGraph';
|
|
40
|
+
export const AGENT_MODEL_CALL_RUN_NAME = 'AgentModelCall';
|
|
41
|
+
export const ACTIVITY_LABEL_RUN_NAME = 'StepLabel';
|
|
42
|
+
export const REASONING_LABEL_RUN_NAME = 'ReasoningLabel';
|
|
43
|
+
export const ACTIVITY_PHASE_RUN_NAME = 'MultiStepLabel';
|
|
44
|
+
export const ACTIVITY_PHASE_LABEL_RUN_NAME = 'MultiStepLabelGeneration';
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -74,6 +74,17 @@ import {
|
|
|
74
74
|
appendPredecessorHandoffCue,
|
|
75
75
|
removePredecessorHandoffCue,
|
|
76
76
|
} from '@/messages';
|
|
77
|
+
import {
|
|
78
|
+
Constants,
|
|
79
|
+
GraphNodeKeys,
|
|
80
|
+
ContentTypes,
|
|
81
|
+
GraphEvents,
|
|
82
|
+
Providers,
|
|
83
|
+
StepTypes,
|
|
84
|
+
STANDARD_GRAPH_RUN_NAME,
|
|
85
|
+
AGENT_MODEL_CALL_RUN_NAME,
|
|
86
|
+
PREEMPT_BOUNDARY_HOOK_TIMEOUT_MS,
|
|
87
|
+
} from '@/common';
|
|
77
88
|
import {
|
|
78
89
|
resetIfNotEmpty,
|
|
79
90
|
isAnthropicLike,
|
|
@@ -106,15 +117,6 @@ import {
|
|
|
106
117
|
isGraphSubagentConfig,
|
|
107
118
|
normalizeSubagentConfigEntries,
|
|
108
119
|
} from '@/tools/subagent';
|
|
109
|
-
import {
|
|
110
|
-
Constants,
|
|
111
|
-
GraphNodeKeys,
|
|
112
|
-
ContentTypes,
|
|
113
|
-
GraphEvents,
|
|
114
|
-
Providers,
|
|
115
|
-
StepTypes,
|
|
116
|
-
PREEMPT_BOUNDARY_HOOK_TIMEOUT_MS,
|
|
117
|
-
} from '@/common';
|
|
118
120
|
import {
|
|
119
121
|
createLangfuseHandler,
|
|
120
122
|
createLangfuseTraceMetadata,
|
|
@@ -1260,6 +1262,7 @@ export abstract class Graph<
|
|
|
1260
1262
|
}
|
|
1261
1263
|
|
|
1262
1264
|
export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
1265
|
+
readonly runName: string = STANDARD_GRAPH_RUN_NAME;
|
|
1263
1266
|
overrideModel?: t.ChatModel;
|
|
1264
1267
|
private subagentModelOverride?: t.ChatModel;
|
|
1265
1268
|
private readonly graphFactory: GraphFactory;
|
|
@@ -1286,10 +1289,12 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1286
1289
|
* component: public run ids are unrestricted and may repeat across
|
|
1287
1290
|
* concurrently executing runs (retries, duplicate submissions,
|
|
1288
1291
|
* tenant-local message ids), and equal stamps would let those runs adopt
|
|
1289
|
-
* each other's scopes.
|
|
1290
|
-
*
|
|
1292
|
+
* each other's scopes. Fresh stream executions rotate this stamp; resumes
|
|
1293
|
+
* retain it so the continuation stays in the interrupted execution.
|
|
1291
1294
|
*/
|
|
1292
|
-
|
|
1295
|
+
langfuseScopeRunId: string;
|
|
1296
|
+
/** Opaque key for parenting post-processing observations to this run. */
|
|
1297
|
+
langfuseTraceAnchor: object = {};
|
|
1293
1298
|
/**
|
|
1294
1299
|
* Boundary between historical messages (loaded from conversation state)
|
|
1295
1300
|
* and messages produced during the current run. Set once in the state
|
|
@@ -1498,6 +1503,12 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1498
1503
|
this.defaultAgentId = agents[0].agentId;
|
|
1499
1504
|
}
|
|
1500
1505
|
|
|
1506
|
+
/** Rotates the Langfuse identities that must never cross fresh executions. */
|
|
1507
|
+
startFreshLangfuseExecution(): void {
|
|
1508
|
+
this.langfuseTraceAnchor = {};
|
|
1509
|
+
this.langfuseScopeRunId = `${this.runId ?? 'graph'}:${nanoid()}`;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1501
1512
|
/* Init */
|
|
1502
1513
|
|
|
1503
1514
|
resetValues(keepContent?: boolean, checkpointScope?: string): void {
|
|
@@ -2913,7 +2924,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
2913
2924
|
});
|
|
2914
2925
|
|
|
2915
2926
|
if (agentContext.systemRunnable) {
|
|
2916
|
-
model = agentContext.systemRunnable
|
|
2927
|
+
model = agentContext.systemRunnable
|
|
2928
|
+
.pipe(model as Runnable)
|
|
2929
|
+
.withConfig({ runName: AGENT_MODEL_CALL_RUN_NAME });
|
|
2917
2930
|
}
|
|
2918
2931
|
|
|
2919
2932
|
if (agentContext.tokenCalculationPromise) {
|
|
@@ -4010,6 +4023,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4010
4023
|
tags: ['librechat', 'agent'],
|
|
4011
4024
|
traceIdSeed:
|
|
4012
4025
|
langfuse?.deterministicTraceId === true ? this.runId : undefined,
|
|
4026
|
+
traceAnchor: this.langfuseTraceAnchor,
|
|
4027
|
+
agentId,
|
|
4013
4028
|
runId: this.langfuseScopeRunId,
|
|
4014
4029
|
toolOutputTracing: hasToolOutputTracingConfig(
|
|
4015
4030
|
this.langfuse,
|
|
@@ -4052,6 +4067,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4052
4067
|
resolveLangfuseRuntimeScope({
|
|
4053
4068
|
runLangfuse: this.langfuse,
|
|
4054
4069
|
langfuseOverlay: agentContext.langfuse,
|
|
4070
|
+
traceAnchor: this.langfuseTraceAnchor,
|
|
4055
4071
|
runId: this.langfuseScopeRunId,
|
|
4056
4072
|
agentId,
|
|
4057
4073
|
}),
|
|
@@ -4845,94 +4861,98 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4845
4861
|
createChildGraphByKind: createConfiguredChildGraph,
|
|
4846
4862
|
createDetachedChildGraphFactory: (
|
|
4847
4863
|
parentHandlerRegistry
|
|
4848
|
-
): GraphFactory =>
|
|
4849
|
-
snapshotChildGraphFactory(parentHandlerRegistry),
|
|
4864
|
+
): GraphFactory => snapshotChildGraphFactory(parentHandlerRegistry),
|
|
4850
4865
|
});
|
|
4851
4866
|
this.registerSubagentExecutor(executor);
|
|
4852
4867
|
|
|
4853
|
-
const subagentTool = tool(
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
parentToolCallId
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4868
|
+
const subagentTool = tool(
|
|
4869
|
+
async (rawInput, config) => {
|
|
4870
|
+
const input = rawInput as {
|
|
4871
|
+
description?: string;
|
|
4872
|
+
subagent_type?: string;
|
|
4873
|
+
subagent_thread_id?: string;
|
|
4874
|
+
run_in_background?: boolean;
|
|
4875
|
+
};
|
|
4876
|
+
const description =
|
|
4877
|
+
typeof input.description === 'string' &&
|
|
4878
|
+
input.description.trim().length > 0
|
|
4879
|
+
? input.description
|
|
4880
|
+
: DEFAULT_SUBAGENT_DESCRIPTION;
|
|
4881
|
+
const subagentType =
|
|
4882
|
+
typeof input.subagent_type === 'string'
|
|
4883
|
+
? input.subagent_type
|
|
4884
|
+
: '';
|
|
4885
|
+
const subagentThreadId =
|
|
4886
|
+
typeof input.subagent_thread_id === 'string' &&
|
|
4887
|
+
input.subagent_thread_id.trim() !== ''
|
|
4888
|
+
? input.subagent_thread_id.trim()
|
|
4889
|
+
: undefined;
|
|
4890
|
+
const threadId = config.configurable?.thread_id as
|
|
4891
|
+
| string
|
|
4892
|
+
| undefined;
|
|
4893
|
+
/** Surface the parent call id so child checkpoints, interrupts, and
|
|
4894
|
+
* update events remain correlated across replay and resume. */
|
|
4895
|
+
const toolRuntime = config as {
|
|
4896
|
+
toolCallId?: string;
|
|
4897
|
+
toolCall?: { id?: string };
|
|
4898
|
+
};
|
|
4899
|
+
const toolCall = toolRuntime.toolCall;
|
|
4900
|
+
let parentToolCallId: string | undefined;
|
|
4901
|
+
if (
|
|
4902
|
+
typeof toolRuntime.toolCallId === 'string' &&
|
|
4903
|
+
toolRuntime.toolCallId !== ''
|
|
4904
|
+
) {
|
|
4905
|
+
parentToolCallId = toolRuntime.toolCallId;
|
|
4906
|
+
} else if (typeof toolCall?.id === 'string' && toolCall.id !== '') {
|
|
4907
|
+
parentToolCallId = toolCall.id;
|
|
4908
|
+
}
|
|
4909
|
+
/** The parent tool batch's entry-captured scope (stamped by
|
|
4910
|
+
* ToolNode before PreToolUse hooks) — binds this child to the
|
|
4911
|
+
* run that dispatched it, not to whatever controller a reset
|
|
4912
|
+
* installed while the hooks were awaited. */
|
|
4913
|
+
const batchScope = config.configurable?.[
|
|
4914
|
+
RUN_BREAKER_SCOPE_CONFIG_KEY
|
|
4915
|
+
] as RunBreakerScope | undefined;
|
|
4916
|
+
const executeParams = {
|
|
4917
|
+
description,
|
|
4918
|
+
subagentType,
|
|
4919
|
+
threadId,
|
|
4920
|
+
signal: config.signal,
|
|
4921
|
+
parentToolCallId,
|
|
4922
|
+
breaker: batchScope?.controller,
|
|
4923
|
+
/**
|
|
4924
|
+
* Forward the parent's `configurable` so host-set fields
|
|
4925
|
+
* (`requestBody`, `user`, etc.) propagate into the child
|
|
4926
|
+
* workflow. The executor scrubs run-identity fields before
|
|
4927
|
+
* forwarding — see `SubagentExecuteParams.parentConfigurable`.
|
|
4928
|
+
*/
|
|
4929
|
+
parentConfigurable: config.configurable as
|
|
4930
|
+
| Record<string, unknown>
|
|
4931
|
+
| undefined,
|
|
4932
|
+
};
|
|
4933
|
+
if (input.run_in_background === true) {
|
|
4934
|
+
return executor.executeInBackground({
|
|
4935
|
+
...executeParams,
|
|
4936
|
+
...(subagentThreadId == null ? {} : { subagentThreadId }),
|
|
4937
|
+
});
|
|
4938
|
+
}
|
|
4939
|
+
if (subagentThreadId != null) {
|
|
4940
|
+
return JSON.stringify({
|
|
4941
|
+
status: 'rejected',
|
|
4942
|
+
tool: Constants.SUBAGENT,
|
|
4943
|
+
message:
|
|
4944
|
+
'Child-thread continuation requires run_in_background.',
|
|
4945
|
+
});
|
|
4946
|
+
}
|
|
4947
|
+
const result = await executor.execute(executeParams);
|
|
4948
|
+
return result.content;
|
|
4949
|
+
},
|
|
4950
|
+
buildSubagentToolParams(executableConfigs, {
|
|
4951
|
+
background: this.subagentTasks != null,
|
|
4952
|
+
threadContinuation:
|
|
4953
|
+
this.subagentTasks?.store.supportsThreadContinuation === true,
|
|
4954
|
+
})
|
|
4955
|
+
);
|
|
4936
4956
|
const replayableSubagentTool = subagentTool as typeof subagentTool &
|
|
4937
4957
|
ReplayableSubagentTool;
|
|
4938
4958
|
replayableSubagentTool[SUBAGENT_REPLAY_CONTROLLER] = {
|
|
@@ -5218,7 +5238,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5218
5238
|
.addEdge(summarizeNode, agentNode)
|
|
5219
5239
|
.addEdge(toolNode, agentContext.toolEnd ? END : agentNode);
|
|
5220
5240
|
|
|
5221
|
-
return workflow.compile();
|
|
5241
|
+
return workflow.compile({ name: STANDARD_GRAPH_RUN_NAME });
|
|
5222
5242
|
}
|
|
5223
5243
|
|
|
5224
5244
|
createWorkflow(): t.CompiledStateWorkflow {
|
|
@@ -5247,11 +5267,13 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5247
5267
|
>,
|
|
5248
5268
|
{ ends: [END] }
|
|
5249
5269
|
)
|
|
5250
|
-
.addEdge(START, this.defaultAgentId)
|
|
5251
|
-
// LangGraph compile() types are overly strict for opt-in options
|
|
5252
|
-
.compile(this.compileOptions as unknown as never);
|
|
5270
|
+
.addEdge(START, this.defaultAgentId);
|
|
5253
5271
|
|
|
5254
|
-
|
|
5272
|
+
// LangGraph compile() types are overly strict for opt-in options
|
|
5273
|
+
return workflow.compile({
|
|
5274
|
+
...this.compileOptions,
|
|
5275
|
+
name: STANDARD_GRAPH_RUN_NAME,
|
|
5276
|
+
} as unknown as never);
|
|
5255
5277
|
}
|
|
5256
5278
|
|
|
5257
5279
|
/**
|
|
@@ -20,9 +20,9 @@ import type { ToolRuntime } from '@langchain/core/tools';
|
|
|
20
20
|
import type { GraphFactoryDependencies } from '@/graphs/graphFactory';
|
|
21
21
|
import type * as t from '@/types';
|
|
22
22
|
import { serializeToolContentBounded } from '@/utils/toolContent';
|
|
23
|
+
import { Constants, MULTI_AGENT_GRAPH_RUN_NAME } from '@/common';
|
|
23
24
|
import { HARD_MAX_TOOL_RESULT_CHARS } from '@/utils/truncation';
|
|
24
25
|
import { StandardGraph } from './Graph';
|
|
25
|
-
import { Constants } from '@/common';
|
|
26
26
|
|
|
27
27
|
/** Pattern to extract instructions from transfer ToolMessage content */
|
|
28
28
|
const HANDOFF_INSTRUCTIONS_PATTERN = /(?:Instructions?|Context):\s*(.+)/is;
|
|
@@ -177,6 +177,7 @@ function withHandoffGroupMetadata(
|
|
|
177
177
|
* OR continues its workflow (direct edges), but not both simultaneously.
|
|
178
178
|
*/
|
|
179
179
|
export class MultiAgentGraph extends StandardGraph {
|
|
180
|
+
override readonly runName = MULTI_AGENT_GRAPH_RUN_NAME;
|
|
180
181
|
private edges: t.GraphEdge[];
|
|
181
182
|
private startingNodes: Set<string> = new Set();
|
|
182
183
|
private directEdges: t.GraphEdge[] = [];
|
|
@@ -1438,6 +1439,9 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
1438
1439
|
}
|
|
1439
1440
|
}
|
|
1440
1441
|
|
|
1441
|
-
return builder.compile(
|
|
1442
|
+
return builder.compile({
|
|
1443
|
+
...this.compileOptions,
|
|
1444
|
+
name: MULTI_AGENT_GRAPH_RUN_NAME,
|
|
1445
|
+
} as unknown as never);
|
|
1442
1446
|
}
|
|
1443
1447
|
}
|