@librechat/agents 3.6.0 → 3.6.1
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/prompts/activityLabel.cjs +1 -0
- package/dist/cjs/prompts/reasoningLabel.cjs +60 -0
- package/dist/cjs/prompts/reasoningLabel.cjs.map +1 -0
- package/dist/cjs/run.cjs +132 -0
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/esm/prompts/activityLabel.mjs +1 -1
- package/dist/esm/prompts/reasoningLabel.mjs +57 -0
- package/dist/esm/prompts/reasoningLabel.mjs.map +1 -0
- package/dist/esm/run.mjs +132 -0
- package/dist/esm/run.mjs.map +1 -1
- package/dist/types/prompts/reasoningLabel.d.ts +17 -0
- package/dist/types/run.d.ts +8 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/reasoningLabel.d.ts +56 -0
- package/package.json +1 -1
- package/src/prompts/reasoningLabel.ts +118 -0
- package/src/run.ts +272 -5
- package/src/types/index.ts +1 -0
- package/src/types/reasoningLabel.ts +59 -0
package/src/run.ts
CHANGED
|
@@ -16,8 +16,11 @@ import {
|
|
|
16
16
|
HumanMessage,
|
|
17
17
|
SystemMessage,
|
|
18
18
|
} from '@langchain/core/messages';
|
|
19
|
+
import type {
|
|
20
|
+
MessageContentComplex,
|
|
21
|
+
UsageMetadata,
|
|
22
|
+
} from '@langchain/core/messages';
|
|
19
23
|
import type { StringPromptValue } from '@langchain/core/prompt_values';
|
|
20
|
-
import type { MessageContentComplex } from '@langchain/core/messages';
|
|
21
24
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
22
25
|
import type { MultiAgentGraph } from '@/graphs/MultiAgentGraph';
|
|
23
26
|
import type { StandardGraph } from '@/graphs/Graph';
|
|
@@ -29,10 +32,6 @@ import {
|
|
|
29
32
|
SUBAGENT_RESUME_ATTEMPT_CONFIG_KEY,
|
|
30
33
|
SUBAGENT_RESUME_MANIFEST_CONFIG_KEY,
|
|
31
34
|
} from '@/tools/subagent/SubagentReplay';
|
|
32
|
-
import {
|
|
33
|
-
getRunStepResumeState,
|
|
34
|
-
stripRunStepResumeState,
|
|
35
|
-
} from '@/tools/runStepResume';
|
|
36
35
|
import {
|
|
37
36
|
ACTIVITY_PHASE_LABEL_PROMPT,
|
|
38
37
|
ACTIVITY_LABEL_PROMPT,
|
|
@@ -48,6 +47,12 @@ import {
|
|
|
48
47
|
isLangfuseCallbackHandler,
|
|
49
48
|
withLangfuseAttributes,
|
|
50
49
|
} from '@/langfuse';
|
|
50
|
+
import {
|
|
51
|
+
REASONING_LABEL_PROMPT,
|
|
52
|
+
buildReasoningLabelTraceSeed,
|
|
53
|
+
buildReasoningLabelPrompt,
|
|
54
|
+
normalizeReasoningLabel,
|
|
55
|
+
} from '@/prompts/reasoningLabel';
|
|
51
56
|
import {
|
|
52
57
|
hasToolOutputTracingConfig,
|
|
53
58
|
resolveLangfuseConfig,
|
|
@@ -63,6 +68,10 @@ import {
|
|
|
63
68
|
resolveLangfuseRuntimeScope,
|
|
64
69
|
withLangfuseRuntimeScope,
|
|
65
70
|
} from '@/langfuseRuntimeScope';
|
|
71
|
+
import {
|
|
72
|
+
getRunStepResumeState,
|
|
73
|
+
stripRunStepResumeState,
|
|
74
|
+
} from '@/tools/runStepResume';
|
|
66
75
|
import {
|
|
67
76
|
Callback,
|
|
68
77
|
GraphEvents,
|
|
@@ -100,6 +109,7 @@ export const defaultOmitOptions = new Set([
|
|
|
100
109
|
|
|
101
110
|
const ACTIVITY_LABEL_TRACE_NAME = 'LibreChat Activity Label';
|
|
102
111
|
const ACTIVITY_PHASE_TRACE_NAME = 'LibreChat Activity Phase';
|
|
112
|
+
const REASONING_LABEL_TRACE_NAME = 'LibreChat Reasoning Label';
|
|
103
113
|
|
|
104
114
|
const CUSTOM_GRAPH_EVENTS = new Set<string>([
|
|
105
115
|
GraphEvents.ON_AGENT_UPDATE,
|
|
@@ -312,6 +322,8 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
312
322
|
private activityLabelSeq = 0;
|
|
313
323
|
/** Per-run sequence for parent activity-phase trace and invocation ids. */
|
|
314
324
|
private activityPhaseLabelSeq = 0;
|
|
325
|
+
/** Per-run sequence for reasoning-label trace and invocation ids. */
|
|
326
|
+
private reasoningLabelSeq = 0;
|
|
315
327
|
/** Latest user turn used to keep detached phase roots conversation-shaped. */
|
|
316
328
|
private activityPhaseTraceInput?: string;
|
|
317
329
|
/** Distinguishes sibling forks started from the same explicit checkpoint. */
|
|
@@ -2354,6 +2366,261 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
2354
2366
|
}
|
|
2355
2367
|
}
|
|
2356
2368
|
|
|
2369
|
+
/**
|
|
2370
|
+
* Generates one replacement title for a user-visible reasoning step. Hosts
|
|
2371
|
+
* own accumulation, scheduling, revision ordering, durable delivery, and
|
|
2372
|
+
* billing; the SDK only performs one bounded, redaction-aware generation.
|
|
2373
|
+
*/
|
|
2374
|
+
async generateReasoningLabel({
|
|
2375
|
+
provider,
|
|
2376
|
+
clientOptions,
|
|
2377
|
+
visibleReasoning,
|
|
2378
|
+
reasoningStepId,
|
|
2379
|
+
revision,
|
|
2380
|
+
status = 'streaming',
|
|
2381
|
+
previousLabel,
|
|
2382
|
+
agentId,
|
|
2383
|
+
prompt,
|
|
2384
|
+
charLimit = 6_000,
|
|
2385
|
+
chainOptions,
|
|
2386
|
+
traceSeed,
|
|
2387
|
+
sourceRunId,
|
|
2388
|
+
sourceTraceId,
|
|
2389
|
+
responseId,
|
|
2390
|
+
}: t.RunReasoningLabelOptions): Promise<t.ReasoningLabelResult> {
|
|
2391
|
+
const normalizedStepId = reasoningStepId.trim();
|
|
2392
|
+
const snapshotChars = visibleReasoning.trim().length;
|
|
2393
|
+
if (
|
|
2394
|
+
normalizedStepId === '' ||
|
|
2395
|
+
snapshotChars === 0 ||
|
|
2396
|
+
!Number.isInteger(revision) ||
|
|
2397
|
+
revision < 0
|
|
2398
|
+
) {
|
|
2399
|
+
return {};
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
const reasoningSeq = ++this.reasoningLabelSeq;
|
|
2403
|
+
const requestedContext =
|
|
2404
|
+
this.Graph == null || agentId == null
|
|
2405
|
+
? undefined
|
|
2406
|
+
: this.Graph.agentContexts.get(agentId);
|
|
2407
|
+
if (agentId != null && requestedContext == null) {
|
|
2408
|
+
return {};
|
|
2409
|
+
}
|
|
2410
|
+
if (agentId == null && (this.Graph?.agentContexts.size ?? 0) > 1) {
|
|
2411
|
+
return {};
|
|
2412
|
+
}
|
|
2413
|
+
const reasoningContext =
|
|
2414
|
+
this.Graph == null
|
|
2415
|
+
? undefined
|
|
2416
|
+
: (requestedContext ??
|
|
2417
|
+
this.Graph.agentContexts.get(this.Graph.defaultAgentId));
|
|
2418
|
+
const reasoningChainOptions = {
|
|
2419
|
+
...(chainOptions ?? {}),
|
|
2420
|
+
} as Partial<RunnableConfig> & {
|
|
2421
|
+
configurable?: Record<string, unknown> & {
|
|
2422
|
+
requestBody?: { parentMessageId?: unknown };
|
|
2423
|
+
};
|
|
2424
|
+
};
|
|
2425
|
+
const reasoningUserId =
|
|
2426
|
+
typeof reasoningChainOptions.configurable?.user_id === 'string'
|
|
2427
|
+
? reasoningChainOptions.configurable.user_id
|
|
2428
|
+
: undefined;
|
|
2429
|
+
const reasoningSessionId =
|
|
2430
|
+
typeof reasoningChainOptions.configurable?.thread_id === 'string'
|
|
2431
|
+
? reasoningChainOptions.configurable.thread_id
|
|
2432
|
+
: undefined;
|
|
2433
|
+
const reasoningParentMessageId =
|
|
2434
|
+
reasoningChainOptions.configurable?.requestBody?.parentMessageId;
|
|
2435
|
+
const reasoningAgentId =
|
|
2436
|
+
agentId ??
|
|
2437
|
+
(this.Graph?.agentContexts.size === 1
|
|
2438
|
+
? this.Graph.defaultAgentId
|
|
2439
|
+
: undefined);
|
|
2440
|
+
const reasoningAgentName =
|
|
2441
|
+
reasoningAgentId == null ? undefined : reasoningContext?.name;
|
|
2442
|
+
const resolvedSourceRunId = sourceRunId ?? this.id;
|
|
2443
|
+
const reasoningResponseId = responseId ?? this.id;
|
|
2444
|
+
const reasoningMetadata: Record<string, unknown> = {
|
|
2445
|
+
sourceRunId: resolvedSourceRunId,
|
|
2446
|
+
...(sourceTraceId == null ? {} : { sourceTraceId }),
|
|
2447
|
+
responseId: reasoningResponseId,
|
|
2448
|
+
reasoningStepId: normalizedStepId,
|
|
2449
|
+
revision,
|
|
2450
|
+
status,
|
|
2451
|
+
snapshotChars,
|
|
2452
|
+
...(typeof reasoningParentMessageId === 'string'
|
|
2453
|
+
? { parentMessageId: reasoningParentMessageId }
|
|
2454
|
+
: {}),
|
|
2455
|
+
...(reasoningAgentId == null ? {} : { agentId: reasoningAgentId }),
|
|
2456
|
+
...(reasoningAgentName == null ? {} : { agentName: reasoningAgentName }),
|
|
2457
|
+
};
|
|
2458
|
+
const traceMetadata = {
|
|
2459
|
+
...createLangfuseTraceMetadata({
|
|
2460
|
+
messageId: `reasoning-label-${reasoningResponseId}`,
|
|
2461
|
+
parentMessageId: reasoningParentMessageId,
|
|
2462
|
+
agentId: reasoningAgentId,
|
|
2463
|
+
agentName: reasoningAgentName,
|
|
2464
|
+
}),
|
|
2465
|
+
sourceRunId: resolvedSourceRunId,
|
|
2466
|
+
...(sourceTraceId == null ? {} : { sourceTraceId }),
|
|
2467
|
+
responseId: reasoningResponseId,
|
|
2468
|
+
reasoningStepId: normalizedStepId,
|
|
2469
|
+
revision: String(revision),
|
|
2470
|
+
status,
|
|
2471
|
+
snapshotChars: String(snapshotChars),
|
|
2472
|
+
};
|
|
2473
|
+
const reasoningRunName =
|
|
2474
|
+
reasoningChainOptions.runName ?? REASONING_LABEL_TRACE_NAME;
|
|
2475
|
+
const reasoningTags = ['librechat', 'reasoning-label', 'reasoning-step'];
|
|
2476
|
+
const reasoningLangfuseConfig = resolveLangfuseConfig(
|
|
2477
|
+
this.langfuse,
|
|
2478
|
+
reasoningContext?.langfuse
|
|
2479
|
+
);
|
|
2480
|
+
initializeLangfuseTracing(reasoningLangfuseConfig);
|
|
2481
|
+
|
|
2482
|
+
const inheritedTraceSeed = getTraceIdSeed();
|
|
2483
|
+
const reasoningTraceSeed =
|
|
2484
|
+
reasoningLangfuseConfig?.deterministicTraceId === true ||
|
|
2485
|
+
inheritedTraceSeed != null
|
|
2486
|
+
? (traceSeed ??
|
|
2487
|
+
buildReasoningLabelTraceSeed(
|
|
2488
|
+
resolvedSourceRunId,
|
|
2489
|
+
normalizedStepId,
|
|
2490
|
+
revision
|
|
2491
|
+
))
|
|
2492
|
+
: undefined;
|
|
2493
|
+
const reasoningScopeRunId = `reasoning-label:${this.id}:${reasoningSeq}:${nanoid()}`;
|
|
2494
|
+
const reasoningRuntimeScope = resolveLangfuseRuntimeScope({
|
|
2495
|
+
runLangfuse: this.langfuse,
|
|
2496
|
+
langfuseOverlay: reasoningContext?.langfuse,
|
|
2497
|
+
traceIdSeed: reasoningTraceSeed,
|
|
2498
|
+
runId: reasoningScopeRunId,
|
|
2499
|
+
});
|
|
2500
|
+
let reasoningLangfuseHandler: CallbackEntry | undefined;
|
|
2501
|
+
if (reasoningSessionId != null) {
|
|
2502
|
+
reasoningLangfuseHandler = createLangfuseHandler({
|
|
2503
|
+
langfuse: reasoningLangfuseConfig,
|
|
2504
|
+
userId: reasoningUserId,
|
|
2505
|
+
sessionId: reasoningSessionId,
|
|
2506
|
+
traceMetadata,
|
|
2507
|
+
tags: reasoningTags,
|
|
2508
|
+
traceIdSeed:
|
|
2509
|
+
reasoningLangfuseConfig?.deterministicTraceId === true
|
|
2510
|
+
? reasoningTraceSeed
|
|
2511
|
+
: undefined,
|
|
2512
|
+
runId: reasoningScopeRunId,
|
|
2513
|
+
toolOutputTracing: reasoningRuntimeScope.toolOutputTracing,
|
|
2514
|
+
traceName: reasoningRunName,
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
if (reasoningLangfuseHandler != null) {
|
|
2518
|
+
reasoningChainOptions.callbacks = appendCallbacks(
|
|
2519
|
+
reasoningChainOptions.callbacks,
|
|
2520
|
+
[reasoningLangfuseHandler]
|
|
2521
|
+
);
|
|
2522
|
+
}
|
|
2523
|
+
|
|
2524
|
+
const redaction = hasToolOutputTracingConfig(
|
|
2525
|
+
this.langfuse,
|
|
2526
|
+
reasoningContext?.langfuse
|
|
2527
|
+
)
|
|
2528
|
+
? resolveToolOutputTracingConfig(
|
|
2529
|
+
this.langfuse,
|
|
2530
|
+
reasoningContext?.langfuse
|
|
2531
|
+
)
|
|
2532
|
+
: undefined;
|
|
2533
|
+
const userPrompt = buildReasoningLabelPrompt({
|
|
2534
|
+
visibleReasoning,
|
|
2535
|
+
status,
|
|
2536
|
+
charLimit,
|
|
2537
|
+
previousLabel,
|
|
2538
|
+
redaction,
|
|
2539
|
+
});
|
|
2540
|
+
if (userPrompt === '') {
|
|
2541
|
+
await disposeLangfuseHandler(reasoningLangfuseHandler);
|
|
2542
|
+
return {};
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
const model = initializeModel({
|
|
2546
|
+
provider,
|
|
2547
|
+
clientOptions: {
|
|
2548
|
+
...(clientOptions ?? {}),
|
|
2549
|
+
streaming: false,
|
|
2550
|
+
} as t.ClientOptions,
|
|
2551
|
+
}) as t.ChatModelInstance;
|
|
2552
|
+
const reasoningRunId = `${this.id}-reasoning-${reasoningSeq}`;
|
|
2553
|
+
const invokeConfig = Object.assign({}, reasoningChainOptions, {
|
|
2554
|
+
run_id: reasoningRunId,
|
|
2555
|
+
runId: reasoningRunId,
|
|
2556
|
+
runName: reasoningRunName,
|
|
2557
|
+
tags: [
|
|
2558
|
+
...new Set([...(reasoningChainOptions.tags ?? []), ...reasoningTags]),
|
|
2559
|
+
],
|
|
2560
|
+
metadata: {
|
|
2561
|
+
...(reasoningChainOptions.metadata ?? {}),
|
|
2562
|
+
...reasoningMetadata,
|
|
2563
|
+
},
|
|
2564
|
+
}) as Partial<RunnableConfig>;
|
|
2565
|
+
const invokeLabel = (
|
|
2566
|
+
runtimeConfig: Partial<RunnableConfig>
|
|
2567
|
+
): Promise<unknown> =>
|
|
2568
|
+
withLangfuseAttributes(
|
|
2569
|
+
{
|
|
2570
|
+
langfuse: reasoningLangfuseConfig,
|
|
2571
|
+
userId: reasoningUserId,
|
|
2572
|
+
sessionId: reasoningSessionId,
|
|
2573
|
+
traceName: reasoningRunName,
|
|
2574
|
+
traceMetadata,
|
|
2575
|
+
tags: reasoningTags,
|
|
2576
|
+
},
|
|
2577
|
+
() =>
|
|
2578
|
+
model.invoke(
|
|
2579
|
+
[
|
|
2580
|
+
new SystemMessage(prompt ?? REASONING_LABEL_PROMPT),
|
|
2581
|
+
new HumanMessage(userPrompt),
|
|
2582
|
+
],
|
|
2583
|
+
runtimeConfig
|
|
2584
|
+
)
|
|
2585
|
+
);
|
|
2586
|
+
const extractResult = (response: unknown): t.ReasoningLabelResult => {
|
|
2587
|
+
const result = response as {
|
|
2588
|
+
content?: unknown;
|
|
2589
|
+
usage_metadata?: UsageMetadata;
|
|
2590
|
+
} | null;
|
|
2591
|
+
const content = result?.content;
|
|
2592
|
+
let text = '';
|
|
2593
|
+
if (typeof content === 'string') {
|
|
2594
|
+
text = content;
|
|
2595
|
+
} else if (Array.isArray(content)) {
|
|
2596
|
+
text = content
|
|
2597
|
+
.map((block) =>
|
|
2598
|
+
typeof block === 'string'
|
|
2599
|
+
? block
|
|
2600
|
+
: ((block as { text?: string }).text ?? '')
|
|
2601
|
+
)
|
|
2602
|
+
.join('');
|
|
2603
|
+
}
|
|
2604
|
+
const label = normalizeReasoningLabel(text);
|
|
2605
|
+
return {
|
|
2606
|
+
...(label === '' ? {} : { label }),
|
|
2607
|
+
...(result?.usage_metadata == null
|
|
2608
|
+
? {}
|
|
2609
|
+
: { usage: result.usage_metadata }),
|
|
2610
|
+
};
|
|
2611
|
+
};
|
|
2612
|
+
|
|
2613
|
+
try {
|
|
2614
|
+
const response = await withLangfuseRuntimeScope(
|
|
2615
|
+
reasoningRuntimeScope,
|
|
2616
|
+
() => invokeLabel(invokeConfig)
|
|
2617
|
+
);
|
|
2618
|
+
return extractResult(response);
|
|
2619
|
+
} finally {
|
|
2620
|
+
await disposeLangfuseHandler(reasoningLangfuseHandler);
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2357
2624
|
/**
|
|
2358
2625
|
* Generates one parent summary for two or more logical activities. The
|
|
2359
2626
|
* summary model is traced as a dedicated activity-phase chain root in the
|
package/src/types/index.ts
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
+
import type { UsageMetadata } from '@langchain/core/messages';
|
|
3
|
+
import type { ClientOptions } from '@/types/llm';
|
|
4
|
+
import type { Providers } from '@/common';
|
|
5
|
+
|
|
6
|
+
/** Lifecycle state of the visible reasoning snapshot being labeled. */
|
|
7
|
+
export type ReasoningLabelStatus = 'streaming' | 'complete';
|
|
8
|
+
|
|
9
|
+
/** Result of one reasoning-label revision. */
|
|
10
|
+
export type ReasoningLabelResult = {
|
|
11
|
+
label?: string;
|
|
12
|
+
/** Provider-reported usage for host-side billing after a durable commit. */
|
|
13
|
+
usage?: UsageMetadata;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** Options for `Run.generateReasoningLabel`. */
|
|
17
|
+
export type RunReasoningLabelOptions = {
|
|
18
|
+
provider: Providers;
|
|
19
|
+
clientOptions?: ClientOptions;
|
|
20
|
+
/**
|
|
21
|
+
* Complete user-visible reasoning accumulated for this step so far. Hidden
|
|
22
|
+
* chain-of-thought must never be supplied through this API.
|
|
23
|
+
*/
|
|
24
|
+
visibleReasoning: string;
|
|
25
|
+
/** Stable run-step identity shared by every revision of this label. */
|
|
26
|
+
reasoningStepId: string;
|
|
27
|
+
/** Monotonically increasing host revision for this reasoning step. */
|
|
28
|
+
revision: number;
|
|
29
|
+
/** Whether the snapshot can still grow. Default `streaming`. */
|
|
30
|
+
status?: ReasoningLabelStatus;
|
|
31
|
+
/**
|
|
32
|
+
* Last durably visible label for this step. The model repeats it exactly
|
|
33
|
+
* when the reasoning direction has not materially changed, allowing hosts
|
|
34
|
+
* to avoid redundant UI updates.
|
|
35
|
+
*/
|
|
36
|
+
previousLabel?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Agent that emitted the reasoning. Selects its Langfuse overlay and
|
|
39
|
+
* redaction policy. Unknown agents and omitted multi-agent ownership fail
|
|
40
|
+
* closed before tracing or generation.
|
|
41
|
+
*/
|
|
42
|
+
agentId?: string;
|
|
43
|
+
/** Override for the default reasoning-label system prompt. */
|
|
44
|
+
prompt?: string;
|
|
45
|
+
/** Maximum reasoning characters retained in the prompt. Default 6000. */
|
|
46
|
+
charLimit?: number;
|
|
47
|
+
/** LangChain runnable config carrier (signal, callbacks, thread/user ids). */
|
|
48
|
+
chainOptions?: Partial<RunnableConfig> & {
|
|
49
|
+
configurable?: Record<string, unknown>;
|
|
50
|
+
};
|
|
51
|
+
/** Deterministic seed for this reasoning-label revision trace. */
|
|
52
|
+
traceSeed?: string;
|
|
53
|
+
/** Stable source run identifier recorded on the observation. */
|
|
54
|
+
sourceRunId?: string;
|
|
55
|
+
/** Source Langfuse trace id for linking this detached label trace. */
|
|
56
|
+
sourceTraceId?: string;
|
|
57
|
+
/** Host response/message identifier recorded on the observation. */
|
|
58
|
+
responseId?: string;
|
|
59
|
+
};
|