@librechat/agents 3.2.68 → 3.3.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.
Files changed (159) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +117 -3
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/common/enum.cjs +4 -0
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/graphs/Graph.cjs +243 -49
  6. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  7. package/dist/cjs/graphs/MultiAgentGraph.cjs +103 -28
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  9. package/dist/cjs/langfuseToolOutputTracing.cjs +4 -0
  10. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/index.cjs +11 -2
  12. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  13. package/dist/cjs/llm/contextOverflowRecovery.cjs +132 -0
  14. package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -0
  15. package/dist/cjs/llm/google/index.cjs +1 -1
  16. package/dist/cjs/llm/invoke.cjs +60 -3
  17. package/dist/cjs/llm/invoke.cjs.map +1 -1
  18. package/dist/cjs/llm/openai/index.cjs +1 -1
  19. package/dist/cjs/main.cjs +21 -7
  20. package/dist/cjs/messages/format.cjs +136 -4
  21. package/dist/cjs/messages/format.cjs.map +1 -1
  22. package/dist/cjs/messages/prune.cjs +16 -5
  23. package/dist/cjs/messages/prune.cjs.map +1 -1
  24. package/dist/cjs/messages/recency.cjs +2 -0
  25. package/dist/cjs/messages/recency.cjs.map +1 -1
  26. package/dist/cjs/prompts/activityLabel.cjs +101 -0
  27. package/dist/cjs/prompts/activityLabel.cjs.map +1 -0
  28. package/dist/cjs/run.cjs +177 -3
  29. package/dist/cjs/run.cjs.map +1 -1
  30. package/dist/cjs/stream.cjs +205 -49
  31. package/dist/cjs/stream.cjs.map +1 -1
  32. package/dist/cjs/summarization/node.cjs +55 -7
  33. package/dist/cjs/summarization/node.cjs.map +1 -1
  34. package/dist/cjs/tools/BashExecutor.cjs +2 -2
  35. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  36. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +2 -2
  37. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  38. package/dist/cjs/tools/CodeExecutor.cjs +69 -8
  39. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  40. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +19 -15
  41. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  42. package/dist/cjs/tools/ToolNode.cjs +32 -3
  43. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  44. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
  45. package/dist/cjs/utils/errors.cjs +317 -52
  46. package/dist/cjs/utils/errors.cjs.map +1 -1
  47. package/dist/esm/agents/AgentContext.mjs +118 -4
  48. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  49. package/dist/esm/common/enum.mjs +4 -0
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/graphs/Graph.mjs +242 -48
  52. package/dist/esm/graphs/Graph.mjs.map +1 -1
  53. package/dist/esm/graphs/MultiAgentGraph.mjs +103 -28
  54. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  55. package/dist/esm/langfuseToolOutputTracing.mjs +4 -1
  56. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  57. package/dist/esm/llm/bedrock/index.mjs +11 -2
  58. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  59. package/dist/esm/llm/contextOverflowRecovery.mjs +130 -0
  60. package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -0
  61. package/dist/esm/llm/google/index.mjs +1 -1
  62. package/dist/esm/llm/invoke.mjs +59 -4
  63. package/dist/esm/llm/invoke.mjs.map +1 -1
  64. package/dist/esm/llm/openai/index.mjs +1 -1
  65. package/dist/esm/main.mjs +10 -10
  66. package/dist/esm/messages/format.mjs +136 -5
  67. package/dist/esm/messages/format.mjs.map +1 -1
  68. package/dist/esm/messages/prune.mjs +14 -6
  69. package/dist/esm/messages/prune.mjs.map +1 -1
  70. package/dist/esm/messages/recency.mjs +2 -1
  71. package/dist/esm/messages/recency.mjs.map +1 -1
  72. package/dist/esm/prompts/activityLabel.mjs +100 -0
  73. package/dist/esm/prompts/activityLabel.mjs.map +1 -0
  74. package/dist/esm/run.mjs +178 -4
  75. package/dist/esm/run.mjs.map +1 -1
  76. package/dist/esm/stream.mjs +205 -49
  77. package/dist/esm/stream.mjs.map +1 -1
  78. package/dist/esm/summarization/node.mjs +55 -7
  79. package/dist/esm/summarization/node.mjs.map +1 -1
  80. package/dist/esm/tools/BashExecutor.mjs +3 -3
  81. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  82. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +3 -3
  83. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  84. package/dist/esm/tools/CodeExecutor.mjs +62 -9
  85. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  86. package/dist/esm/tools/ProgrammaticToolCalling.mjs +20 -16
  87. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  88. package/dist/esm/tools/ToolNode.mjs +32 -3
  89. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  90. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
  91. package/dist/esm/utils/errors.mjs +317 -53
  92. package/dist/esm/utils/errors.mjs.map +1 -1
  93. package/dist/types/agents/AgentContext.d.ts +62 -3
  94. package/dist/types/common/enum.d.ts +5 -1
  95. package/dist/types/graphs/Graph.d.ts +16 -2
  96. package/dist/types/graphs/MultiAgentGraph.d.ts +1 -0
  97. package/dist/types/langfuseToolOutputTracing.d.ts +4 -0
  98. package/dist/types/llm/contextOverflowRecovery.d.ts +85 -0
  99. package/dist/types/llm/invoke.d.ts +35 -6
  100. package/dist/types/messages/format.d.ts +22 -0
  101. package/dist/types/messages/prune.d.ts +10 -2
  102. package/dist/types/messages/recency.d.ts +1 -0
  103. package/dist/types/prompts/activityLabel.d.ts +31 -0
  104. package/dist/types/run.d.ts +16 -0
  105. package/dist/types/tools/CodeExecutor.d.ts +14 -1
  106. package/dist/types/types/activityLabel.d.ts +53 -0
  107. package/dist/types/types/index.d.ts +1 -0
  108. package/dist/types/types/llm.d.ts +7 -4
  109. package/dist/types/types/stream.d.ts +7 -4
  110. package/dist/types/types/summarize.d.ts +22 -0
  111. package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +40 -0
  112. package/dist/types/utils/errors.d.ts +65 -16
  113. package/dist/types/utils/redactSecrets.d.ts +3 -0
  114. package/package.json +7 -8
  115. package/src/agents/AgentContext.ts +188 -7
  116. package/src/agents/__tests__/AgentContext.overflow.test.ts +205 -0
  117. package/src/common/enum.ts +4 -0
  118. package/src/graphs/Graph.ts +409 -58
  119. package/src/graphs/MultiAgentGraph.ts +184 -46
  120. package/src/graphs/__tests__/Graph.contextOverflow.test.ts +631 -0
  121. package/src/langfuseToolOutputTracing.ts +4 -1
  122. package/src/llm/__tests__/contextOverflowRecovery.test.ts +401 -0
  123. package/src/llm/__tests__/fallbackOverflow.test.ts +287 -0
  124. package/src/llm/bedrock/index.ts +25 -12
  125. package/src/llm/contextOverflowRecovery.ts +292 -0
  126. package/src/llm/invoke.ts +119 -4
  127. package/src/messages/foldToollessToolBlocks.test.ts +438 -0
  128. package/src/messages/format.ts +233 -5
  129. package/src/messages/prune.ts +24 -11
  130. package/src/messages/recency.ts +3 -1
  131. package/src/prompts/activityLabel.ts +177 -0
  132. package/src/run.ts +322 -3
  133. package/src/scripts/context-overflow-probe.ts +997 -0
  134. package/src/specs/activity-label-prompt.test.ts +128 -0
  135. package/src/specs/activity-label-trace-seed.test.ts +47 -0
  136. package/src/specs/agent-handoffs.test.ts +903 -1
  137. package/src/specs/bedrock-toolless.live.test.ts +123 -0
  138. package/src/specs/context-overflow-recovery.live.test.ts +213 -0
  139. package/src/splitStream.test.ts +882 -0
  140. package/src/stream.ts +315 -51
  141. package/src/summarization/__tests__/aggregator.test.ts +83 -0
  142. package/src/summarization/__tests__/node.test.ts +139 -0
  143. package/src/summarization/node.ts +99 -14
  144. package/src/tools/BashExecutor.ts +4 -2
  145. package/src/tools/BashProgrammaticToolCalling.ts +4 -7
  146. package/src/tools/CodeExecutor.ts +119 -8
  147. package/src/tools/ProgrammaticToolCalling.ts +29 -27
  148. package/src/tools/ToolNode.ts +50 -8
  149. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +297 -3
  150. package/src/types/activityLabel.ts +55 -0
  151. package/src/types/index.ts +1 -0
  152. package/src/types/llm.ts +8 -1
  153. package/src/types/stream.ts +7 -4
  154. package/src/types/summarize.ts +22 -0
  155. package/src/utils/__tests__/errors.test.ts +270 -0
  156. package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +336 -0
  157. package/src/utils/__tests__/redactSecrets.test.ts +56 -0
  158. package/src/utils/errors.ts +484 -66
  159. package/src/utils/redactSecrets.ts +61 -0
@@ -9,7 +9,7 @@ import { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
9
9
  import { AgentContext } from '@/agents/AgentContext';
10
10
  import { HandlerRegistry } from '@/events';
11
11
  export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphState, _TNodeName extends string = string> {
12
- abstract resetValues(): void;
12
+ abstract resetValues(keepContent?: boolean, checkpointScope?: string): void;
13
13
  abstract initializeTools({ currentTools, currentToolMap, }: {
14
14
  currentTools?: t.GraphTools;
15
15
  currentToolMap?: t.ToolMap;
@@ -173,9 +173,13 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
173
173
  overrideModel?: t.ChatModel;
174
174
  /** Optional compile options passed into workflow.compile() */
175
175
  compileOptions?: t.CompileOptions | undefined;
176
+ /** Whether the workflow was actually compiled with a checkpointer. */
177
+ hasCompiledCheckpointer: boolean;
176
178
  messages: BaseMessage[];
177
179
  /** Cached run messages preserved before clearHeavyState() so getRunMessages() works after cleanup. */
178
180
  private cachedRunMessages?;
181
+ /** Checkpoint scope whose messages match index-keyed tool snapshots. */
182
+ private originalToolContentCheckpointScope?;
179
183
  runId: string | undefined;
180
184
  /**
181
185
  * Boundary between historical messages (loaded from conversation state)
@@ -200,7 +204,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
200
204
  /** See {@link t.StandardGraphInput.subagentScope}. */
201
205
  subagentScope: boolean;
202
206
  constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, subagentUsageSink, subagentScope, }: t.StandardGraphInput);
203
- resetValues(keepContent?: boolean): void;
207
+ resetValues(keepContent?: boolean, checkpointScope?: string): void;
204
208
  clearHeavyState(): void;
205
209
  getRunStep(stepId: string): t.RunStep | undefined;
206
210
  getAgentContext(metadata: Record<string, unknown> | undefined): AgentContext;
@@ -242,6 +246,15 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
242
246
  overrideTestModel(responses: string[], sleep?: number, toolCalls?: ToolCall[]): void;
243
247
  getUsageMetadata(finalMessage?: BaseMessage): Partial<UsageMetadata> | undefined;
244
248
  cleanupSignalListener(currentModel?: t.ChatModel): void;
249
+ /**
250
+ * Applies a context-overflow recovery plan and hands control to the
251
+ * summarize node, which compacts and then routes straight back here for a
252
+ * retry against the corrected budget.
253
+ *
254
+ * Returning the detour rather than rethrowing is the whole point: the
255
+ * caller never sees the provider's rejection, only a slightly longer turn.
256
+ */
257
+ private beginOverflowRecovery;
245
258
  createCallModel(agentId?: string): (state: t.AgentSubgraphState, config?: RunnableConfig) => Promise<Partial<t.AgentSubgraphState>>;
246
259
  createAgentNode(agentId: string): t.CompiledAgentWorfklow;
247
260
  createWorkflow(): t.CompiledStateWorkflow;
@@ -259,6 +272,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
259
272
  * @returns undefined for StandardGraph (no parallel groups), or group number for MultiAgentGraph
260
273
  */
261
274
  protected getParallelGroupIdForAgent(_agentId: string): number | undefined;
275
+ protected resolveParallelGroupId(agentId: string, metadata?: Record<string, unknown>): number | undefined;
262
276
  /**
263
277
  * Dispatches a run step to the client, returns the step ID
264
278
  */
@@ -19,6 +19,7 @@ export declare class MultiAgentGraph extends StandardGraph {
19
19
  private startingNodes;
20
20
  private directEdges;
21
21
  private handoffEdges;
22
+ private handoffPromptLabels;
22
23
  /**
23
24
  * Map of agentId to parallel group info.
24
25
  * Contains groupId (incrementing number reflecting execution order) for agents in parallel groups.
@@ -4,6 +4,10 @@ import type { ResolvedLangfuseToolOutputTracingConfig } from '@/langfuseRuntimeC
4
4
  import type * as t from '@/types';
5
5
  import { LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT, resolveLangfuseConfig } from '@/langfuseConfig';
6
6
  export { LANGFUSE_TOOL_OUTPUT_REDACTION_TEXT, resolveLangfuseConfig };
7
+ /** Whether a tool's outputs are excluded from tracing (global disable or
8
+ * `redactedToolNames` match). Exported for the activity-label prompt
9
+ * builder, whose prompt becomes Langfuse generation input. */
10
+ export declare function shouldRedactTool(toolName: string | undefined, config: ResolvedLangfuseToolOutputTracingConfig): boolean;
7
11
  export declare function classifyLangfuseToolNodeSpan(span: ReadableSpan): void;
8
12
  export declare function redactLangfuseSpanToolOutputs(span: ReadableSpan, config: ResolvedLangfuseToolOutputTracingConfig): void;
9
13
  export declare function createLangfuseSpanProcessor(params?: LangfuseSpanProcessorParams, runLangfuse?: t.LangfuseConfig, agentLangfuse?: t.LangfuseConfig): SpanProcessor;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Recovery policy for provider context-overflow rejections.
3
+ *
4
+ * Detection (`@/utils/errors`) answers "was this an overflow, and what did
5
+ * the provider disclose?". This module answers the follow-up: "what budget
6
+ * should the retry target?" — deliberately kept as pure functions so the
7
+ * policy can be reasoned about and tested without a graph.
8
+ *
9
+ * On units: `maxContextTokens` is a **provider-space** budget. The pruner
10
+ * converts it into its own raw estimate space by dividing by the
11
+ * `calibrationRatio` it learns from reported usage. A provider-reported
12
+ * ceiling is therefore applied verbatim — converting it here as well would
13
+ * apply the same correction twice and prune toward roughly `limit / ratio²`,
14
+ * silently discarding far more history than the overflow called for.
15
+ *
16
+ * `observedCalibrationRatio` is returned separately so the caller can seed
17
+ * the pruner's conversion without folding the same correction into the
18
+ * provider-space budget.
19
+ */
20
+ import type { ContextOverflowInfo } from '@/utils/errors';
21
+ import type { Providers } from '@/common';
22
+ /** Bound on forced-compaction retries per agent, per run. */
23
+ export declare const DEFAULT_MAX_OVERFLOW_RECOVERIES = 2;
24
+ export interface OverflowRecoveryPlan {
25
+ /** Budget the retry should target, in provider token units when known. */
26
+ budgetTokens?: number;
27
+ /** What the provider disclosed. Carried through for logging. */
28
+ info: ContextOverflowInfo;
29
+ /**
30
+ * Provider-reported message tokens divided by our own message estimate,
31
+ * when both are known. Greater than 1 means we under-count relative to this
32
+ * provider.
33
+ *
34
+ * Returned separately so the graph can seed the pruner's calibration;
35
+ * applying it to this plan's budget as well would double-count. Fixed
36
+ * instruction overhead is removed before deriving it from
37
+ * `info.promptTokens`, never `info.requestedTokens`, since several providers
38
+ * fold the completion allowance into the latter.
39
+ */
40
+ observedCalibrationRatio?: number;
41
+ }
42
+ export interface OverflowRecoveryParams {
43
+ error: unknown;
44
+ provider: Providers;
45
+ /** Budget in force when the rejected prompt was built. */
46
+ maxContextTokens?: number;
47
+ /** Our own estimate of the prompt we actually sent. */
48
+ estimatedPromptTokens?: number;
49
+ /** Provider/local calibration already applied to the prompt estimate. */
50
+ calibrationRatio?: number;
51
+ /**
52
+ * System prompt plus tool schemas — the part of the budget compaction
53
+ * cannot touch. A corrected budget at or below this leaves no room for
54
+ * messages, and the summarize node refuses to run, so recovery is declined
55
+ * rather than entered.
56
+ */
57
+ instructionTokens?: number;
58
+ /** Whether a model-backed summary can compact messages without a pruner. */
59
+ canSummarize?: boolean;
60
+ /**
61
+ * Completion allowance the caller configured. Providers count it against
62
+ * the same ceiling, so it has to come off the top when the error itself did
63
+ * not break the total down.
64
+ */
65
+ configuredCompletionTokens?: number;
66
+ /** Recoveries already attempted for this agent in this run. */
67
+ attemptsSoFar: number;
68
+ maxAttempts?: number;
69
+ }
70
+ /**
71
+ * Converts a provider-space retry budget into the units consumed by a pruner
72
+ * calibrated for another provider while preserving the same raw-token limit.
73
+ */
74
+ export declare function translateRecoveryBudget(budgetTokens: number | undefined, sourceCalibrationRatio: number | undefined, targetCalibrationRatio: number | undefined): number | undefined;
75
+ /** Applies the conservative shrink used when no provider-space ceiling is usable. */
76
+ export declare function getBlindRecoveryBudget(maxContextTokens: number | undefined): number | undefined;
77
+ /**
78
+ * Decides whether a failed model call is a recoverable context overflow and,
79
+ * if so, what budget the retry should be re-pruned against.
80
+ *
81
+ * Returns `null` when the error is something compaction cannot fix, or when
82
+ * the per-run recovery budget is spent — in both cases the caller should let
83
+ * its normal failure handling proceed.
84
+ */
85
+ export declare function planContextOverflowRecovery({ error, provider, maxContextTokens, estimatedPromptTokens, calibrationRatio, instructionTokens, canSummarize, configuredCompletionTokens, attemptsSoFar, maxAttempts, }: OverflowRecoveryParams): OverflowRecoveryPlan | null;
@@ -2,6 +2,7 @@ import { AIMessageChunk } from '@langchain/core/messages';
2
2
  import type { RunnableConfig } from '@langchain/core/runnables';
3
3
  import type { BaseMessage } from '@langchain/core/messages';
4
4
  import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
5
+ import type { ContextOverflowContext } from '@/utils/errors';
5
6
  import type * as t from '@/types';
6
7
  import { Providers } from '@/common';
7
8
  import { ChatModelStreamHandler } from '@/stream';
@@ -56,19 +57,47 @@ export declare function attemptInvoke({ model, messages, provider, context, onCh
56
57
  context?: InvokeContext;
57
58
  onChunk?: OnChunk;
58
59
  }, config?: RunnableConfig): Promise<Partial<t.BaseGraphState>>;
60
+ /**
61
+ * Identifies which fallback produced an error, so a caller planning a
62
+ * recovery can reason about the client that actually failed rather than the
63
+ * primary's configuration — their context windows and output allowances
64
+ * differ, which is the whole reason a fallback exists.
65
+ */
66
+ export interface FallbackErrorContext {
67
+ provider: Providers;
68
+ clientOptions?: t.ClientOptions;
69
+ maxContextTokens?: number;
70
+ }
71
+ export interface FallbackOverflowCandidate {
72
+ error: unknown;
73
+ context: FallbackErrorContext;
74
+ }
75
+ /** Reads back the fallback attribution attached by `tryFallbackProviders`. */
76
+ export declare function getFallbackErrorContext(error: unknown): FallbackErrorContext | undefined;
77
+ /** Returns every fallback overflow retained from an exhausted provider chain. */
78
+ export declare function getFallbackOverflowCandidates(error: unknown): FallbackOverflowCandidate[];
59
79
  /**
60
80
  * Attempts each fallback provider in order until one succeeds.
61
- * Throws the last error if all fallbacks fail.
81
+ *
82
+ * When every fallback fails, a context overflow among them is thrown in
83
+ * preference to whichever failure happened to come last. An overflow is the
84
+ * one failure the caller can act on — it compacts and retries — and losing it
85
+ * behind a later unrelated error would surface a dead end instead. Ordinary
86
+ * failures still throw last-error-wins.
62
87
  */
63
- export declare function tryFallbackProviders({ fallbacks, tools, messages, config, primaryError, context, onChunk, }: {
64
- fallbacks: Array<{
65
- provider: Providers;
66
- clientOptions?: t.ClientOptions;
67
- }>;
88
+ export declare function tryFallbackProviders({ fallbacks, tools, messages, config, primaryError, context, onChunk, overflowContext, }: {
89
+ fallbacks: t.FallbackConfig[];
68
90
  tools?: t.GraphTools;
69
91
  messages: BaseMessage[];
70
92
  config?: RunnableConfig;
71
93
  primaryError: unknown;
72
94
  context?: InvokeContext;
73
95
  onChunk?: OnChunk;
96
+ /**
97
+ * Prompt-size corroboration for signatures that are not self-describing.
98
+ * Vertex AI's overflow is a bare `400` with no reason, so without this a
99
+ * fallback that overflows is indistinguishable from any other 400 and would
100
+ * be dropped in favour of whichever failure came last.
101
+ */
102
+ overflowContext?: ContextOverflowContext;
74
103
  }): Promise<Partial<t.BaseGraphState> | undefined>;
@@ -178,4 +178,26 @@ export declare function shiftIndexTokenCountMap(indexTokenCountMap: Record<numbe
178
178
  * @returns The messages array with tool sequences converted to buffer strings if necessary
179
179
  */
180
180
  export declare function ensureThinkingBlockInMessages(messages: BaseMessage[], _provider: Providers, config?: RunnableConfig, runStartIndex?: number): BaseMessage[];
181
+ /**
182
+ * Folds tool_use / tool_result content into plain text for an agent that binds
183
+ * no tools.
184
+ *
185
+ * In a multi-agent graph, a tool-less destination still inherits the prior
186
+ * agent's conversation history, which can contain toolUse/toolResult blocks.
187
+ * Because it binds no tools, the model is invoked with no tool schema — and
188
+ * Bedrock's Converse API rejects any request that carries toolUse/toolResult
189
+ * blocks without a top-level toolConfig ("The toolConfig field must be defined
190
+ * when using toolUse and toolResult content blocks"). Adding a dummy toolConfig
191
+ * is not an option: AWS requires at least one tool, and it would expose a
192
+ * capability the destination was intentionally denied.
193
+ *
194
+ * Each tool-call turn plus its trailing tool results (ToolMessages or
195
+ * `tool_result` content blocks) is collapsed into a single `[Previous tool
196
+ * interaction]` HumanMessage that preserves the tool name, arguments and result
197
+ * as text (image blocks are kept as-is). Runs in a single pass: non-tool
198
+ * messages pass through, `result` is allocated lazily on the first fold, and the
199
+ * original array is returned unchanged when it holds no tool content (the common
200
+ * fresh-tool-less-agent case).
201
+ */
202
+ export declare function foldToolBlocksForToollessAgent(messages: BaseMessage[], config?: RunnableConfig): BaseMessage[];
181
203
  export {};
@@ -15,6 +15,13 @@ export declare const ORIGINAL_CONTENT_MAX_CHARS = 2000000;
15
15
  * recency carry-over bypasses that cap unless re-applied here.
16
16
  */
17
17
  export declare function enforceOriginalContentCap(map: Map<number, string>): void;
18
+ /** Minimum cumulative calibration ratio — provider can't count fewer tokens
19
+ * than our raw estimate (within reason). Prevents divide-by-zero edge cases. */
20
+ export declare const CALIBRATION_RATIO_MIN = 0.5;
21
+ /** Maximum cumulative calibration ratio — sanity cap for the running ratio. */
22
+ export declare const CALIBRATION_RATIO_MAX = 5;
23
+ /** Keeps provider/local token calibration within the shared safe range. */
24
+ export declare function clampCalibrationRatio(ratio: number): number;
18
25
  export type PruneMessagesFactoryParams = {
19
26
  provider?: Providers;
20
27
  maxTokens: number;
@@ -172,8 +179,8 @@ export declare function maskConsumedToolResults(params: {
172
179
  /** When provided, original (pre-masking) content is stored here keyed by
173
180
  * message index — only for entries that actually get truncated. */
174
181
  originalContentStore?: Map<number, string>;
175
- /** Called after storing content with the char length of the stored entry. */
176
- onContentStored?: (charLength: number) => void;
182
+ /** Called after storing a newly captured entry. */
183
+ onContentStored?: (index: number, content: string) => void;
177
184
  }): number;
178
185
  /**
179
186
  * Pre-flight truncation: truncates oversized ToolMessage content before the
@@ -219,6 +226,7 @@ export declare function createPruneMessages(factoryParams: PruneMessagesFactoryP
219
226
  remainingContextTokens?: number;
220
227
  contextPressure?: number;
221
228
  originalToolContent?: Map<number, string>;
229
+ newOriginalToolContent?: Map<number, string>;
222
230
  calibrationRatio?: number;
223
231
  resolvedInstructionOverhead?: number;
224
232
  /** Usable budget this call: maxTokens minus output reserve */
@@ -1,4 +1,5 @@
1
1
  import type { BaseMessage } from '@langchain/core/messages';
2
+ export declare const DEFAULT_RETAIN_RECENT_TURNS = 2;
2
3
  /**
3
4
  * Configuration for splitting a message list into a head (to be summarized)
4
5
  * and a tail (to be preserved verbatim).
@@ -0,0 +1,31 @@
1
+ import type { ResolvedLangfuseToolOutputTracingConfig } from '@/langfuseRuntimeContext';
2
+ import type { ActivityLabelToolEntry } from '@/types/activityLabel';
3
+ /**
4
+ * Default system prompt for fast-model activity labeling.
5
+ *
6
+ * Style synthesized from Claude Code's tool-use summary prompt (git-subject
7
+ * register, past tense, distinctive nouns) and claude.ai's observed group
8
+ * headers (5–9 words describing a mixed reasoning + tool block, e.g.
9
+ * "Synthesized version data and curated comparative framework").
10
+ */
11
+ export declare const ACTIVITY_LABEL_PROMPT = "Write a short label describing what this block of agent activity accomplished. It appears as the header of a collapsed activity group in a chat UI.\n\nRules:\n- 5 to 9 words, past-tense verb first\n- Name the most distinctive subject (file, API, topic); drop articles and filler\n- Describe outcomes, not mechanics; if something failed, say so plainly\n- Output only the label \u2014 no quotes, no punctuation at the end, no preamble\n\nExamples:\n- Searched Node.js release notes and changelogs\n- Compared runtime versions across official sources\n- Fixed failing auth middleware tests\n- Read project config and dependency manifests\n- Attempted database migration, hit permission errors";
12
+ /** Truncates a serialized value for the label prompt. */
13
+ export declare function truncateForLabel(value: string, maxLength: number): string;
14
+ export type BuildActivityLabelPromptParams = {
15
+ entries: ActivityLabelToolEntry[];
16
+ charLimit: number;
17
+ thinkingExcerpts?: string[];
18
+ lastAssistantText?: string;
19
+ /**
20
+ * Resolved tool-output tracing policy. The label prompt becomes Langfuse
21
+ * generation input, so outputs/errors excluded from tracing (global
22
+ * disable or `redactedToolNames`) must never appear in it — the same
23
+ * redaction the span processor applies to structured tool observations.
24
+ */
25
+ redaction?: ResolvedLangfuseToolOutputTracingConfig;
26
+ };
27
+ /**
28
+ * Builds the user prompt for a fast-model activity label. Pure — exported
29
+ * for direct testing of redaction and truncation behavior.
30
+ */
31
+ export declare function buildActivityLabelPrompt({ entries, charLimit, thinkingExcerpts, lastAssistantText, redaction, }: BuildActivityLabelPromptParams): string;
@@ -39,6 +39,10 @@ export declare class Run<_T extends t.BaseGraphState> {
39
39
  * lets callers assert the type they expect.
40
40
  */
41
41
  private _interrupt;
42
+ /** Per-run sequence for batch-unique activity-label trace-seed fallbacks. */
43
+ private activityLabelSeq;
44
+ /** Distinguishes sibling forks started from the same explicit checkpoint. */
45
+ private checkpointForkSeq;
42
46
  private _haltedReason;
43
47
  private constructor();
44
48
  private createLegacyGraph;
@@ -207,4 +211,16 @@ export declare class Run<_T extends t.BaseGraphState> {
207
211
  language?: string;
208
212
  title?: string;
209
213
  }>;
214
+ /**
215
+ * Generates a short activity label for a completed tool/reasoning block
216
+ * using a fast model. Mirrors `generateTitle`'s Langfuse wiring so the
217
+ * call is traced under the conversation's session (sessionId from
218
+ * `chainOptions.configurable.thread_id`) with its own tags — never as an
219
+ * orphan trace. The payload contains no human messages by design: intent
220
+ * comes from `lastAssistantText`, content from reasoning excerpts and
221
+ * tool entries.
222
+ */
223
+ generateActivityLabel({ provider, clientOptions, entries, thinkingExcerpts, lastAssistantText, prompt, charLimit, chainOptions, traceSeed, agentId, }: t.RunActivityLabelOptions): Promise<{
224
+ label?: string;
225
+ }>;
210
226
  }
@@ -32,8 +32,21 @@ export declare const CodeExecutionToolSchema: {
32
32
  };
33
33
  readonly required: readonly ["lang", "code"];
34
34
  };
35
+ export declare const CODE_API_UNAVAILABLE_ERROR_MESSAGE = "Code execution is temporarily unavailable. Please retry.";
36
+ export declare const CODE_API_AUTHORIZATION_ERROR_MESSAGE = "Code execution is not authorized. Verify access before trying again.";
37
+ export declare const CODE_API_EXECUTION_FAILED_ERROR_MESSAGE = "Code execution failed.";
38
+ export declare const CODE_API_INVALID_REQUEST_ERROR_MESSAGE = "The code execution request was rejected. Please check the tool input and try again.";
39
+ export declare const CODE_API_RATE_LIMITED_ERROR_MESSAGE = "Code execution is temporarily rate-limited. Please retry shortly.";
40
+ export declare class CodeApiRequestError extends Error {
41
+ constructor(message?: string);
42
+ }
43
+ export declare function normalizeCodeApiRequestError(error: unknown): CodeApiRequestError;
44
+ export declare function buildCodeApiExecutionErrorMessage(response: {
45
+ error?: unknown;
46
+ stderr?: unknown;
47
+ }): string;
35
48
  export declare function resolveCodeApiAuthHeaders(authHeaders?: t.CodeApiAuthHeaders): Promise<t.CodeApiAuthHeaderMap>;
36
- export declare function buildCodeApiHttpErrorMessage(method: string, endpoint: string, response: {
49
+ export declare function buildCodeApiHttpErrorMessage(_method: string, _endpoint: string, response: {
37
50
  status: number;
38
51
  text: () => Promise<string>;
39
52
  }): Promise<string>;
@@ -0,0 +1,53 @@
1
+ import type { RunnableConfig } from '@langchain/core/runnables';
2
+ import type { ClientOptions } from '@/types/llm';
3
+ import type { Providers } from '@/common';
4
+ /** One tool call's contribution to the label payload (host-assembled). */
5
+ export type ActivityLabelToolEntry = {
6
+ toolName: string;
7
+ toolInput: unknown;
8
+ toolOutput?: unknown;
9
+ error?: string;
10
+ status: 'success' | 'error';
11
+ };
12
+ /**
13
+ * Options for `Run.generateActivityLabel`. The payload deliberately contains
14
+ * NO human messages: intent context comes from the assistant's own last text
15
+ * (Claude Code's pattern) and the block's reasoning excerpts (claude.ai's
16
+ * pattern) — user text stays out of this low-scrutiny pathway entirely.
17
+ *
18
+ * This SDK defines NO activity-label graph event and never dispatches one.
19
+ * Label lifecycle streaming is entirely host-owned: a host claims its own
20
+ * content slots and emits on its own transport, with a payload shape only
21
+ * it defines. The SDK surface here is exactly this method plus the
22
+ * `activity_label` content type's formatter exclusions.
23
+ */
24
+ export type RunActivityLabelOptions = {
25
+ provider: Providers;
26
+ clientOptions?: ClientOptions;
27
+ /**
28
+ * Agent that executed the labeled batch. Selects that agent's Langfuse
29
+ * overlay (trace metadata AND tool-output redaction policy) instead of
30
+ * the graph default — a stricter per-agent policy must not be bypassed
31
+ * by labeling work the default agent never performed.
32
+ */
33
+ agentId?: string;
34
+ entries: ActivityLabelToolEntry[];
35
+ /** Truncated reasoning excerpts from the block being labeled. */
36
+ thinkingExcerpts?: string[];
37
+ /** Assistant's last text before the block (~200 chars), as intent context. */
38
+ lastAssistantText?: string;
39
+ /** Override for the default label system prompt. */
40
+ prompt?: string;
41
+ /** Per-entry serialization cap for the prompt. Default 600. */
42
+ charLimit?: number;
43
+ /** LangChain runnable config carrier (signal, callbacks, thread/user ids). */
44
+ chainOptions?: Partial<RunnableConfig> & {
45
+ configurable?: Record<string, unknown>;
46
+ };
47
+ /**
48
+ * Seed for deterministic Langfuse trace ids (e.g. `${runId}-${slotIndex}`)
49
+ * so each batch's label gets a distinct, reproducible trace. When omitted,
50
+ * a per-run sequence keeps batches from collapsing into one trace.
51
+ */
52
+ traceSeed?: string;
53
+ };
@@ -7,3 +7,4 @@ export * from './skill';
7
7
  export * from './stream';
8
8
  export * from './tools';
9
9
  export * from './summarize';
10
+ export * from './activityLabel';
@@ -103,12 +103,15 @@ export type SharedLLMConfig = {
103
103
  provider: Providers;
104
104
  _lc_stream_delay?: number;
105
105
  };
106
+ export interface FallbackConfig {
107
+ provider: Providers;
108
+ clientOptions?: ClientOptions;
109
+ /** Context window used to corroborate ambiguous fallback overflow errors. */
110
+ maxContextTokens?: number;
111
+ }
106
112
  export type LLMConfig = SharedLLMConfig & ClientOptions & {
107
113
  /** Optional provider fallbacks in order of attempt */
108
- fallbacks?: Array<{
109
- provider: Providers;
110
- clientOptions?: ClientOptions;
111
- }>;
114
+ fallbacks?: FallbackConfig[];
112
115
  };
113
116
  export type ProviderOptionsMap = {
114
117
  [Providers.AZURE]: AzureClientOptions;
@@ -40,13 +40,14 @@ export type RunStep = {
40
40
  runId?: string;
41
41
  agentId?: string;
42
42
  /**
43
- * Group ID - incrementing number (1, 2, 3...) reflecting execution order.
44
- * Agents with the same groupId run in parallel and should be rendered together.
45
- * undefined means the agent runs sequentially (not part of any parallel group).
43
+ * Opaque positive safe-integer identifier for parallel execution.
44
+ * Agents with the same groupId should be rendered together.
45
+ * Consumers must use content indexes, not groupId ordering, for execution order.
46
+ * undefined means the agent runs sequentially (not part of a parallel group).
46
47
  *
47
48
  * Example for: researcher -> [analyst1, analyst2, analyst3] -> summarizer
48
49
  * - researcher: undefined (sequential)
49
- * - analyst1, analyst2, analyst3: 1 (first parallel group)
50
+ * - analyst1, analyst2, analyst3: the same groupId (parallel group)
50
51
  * - summarizer: undefined (sequential)
51
52
  */
52
53
  groupId?: number;
@@ -138,6 +139,8 @@ export interface ExtendedMessageContent {
138
139
  type?: string;
139
140
  text?: string;
140
141
  input?: string;
142
+ /** Tool-call arguments on a v1 standard-content `tool_call` block. */
143
+ args?: ToolCallPart['args'];
141
144
  index?: string | number;
142
145
  id?: string;
143
146
  name?: string;
@@ -54,6 +54,28 @@ export interface SummarizeResult {
54
54
  export interface SummarizationNodeInput {
55
55
  remainingContextTokens: number;
56
56
  agentId: string;
57
+ /**
58
+ * Why the detour was requested.
59
+ *
60
+ * - `trigger` (default): the configured summarization trigger fired during
61
+ * the pre-call budget check.
62
+ * - `overflow`: the provider rejected the prompt as too large and the run
63
+ * is compacting to recover. When summarization is not enabled, this
64
+ * variant performs no model call — the corrected budget alone is what the
65
+ * retry needs.
66
+ */
67
+ reason?: 'trigger' | 'overflow';
68
+ /**
69
+ * Whether an overflow recovery may spend a summarization model call.
70
+ *
71
+ * The first recovery deliberately does not: re-pruning against the
72
+ * corrected budget raises context pressure, which drives the pruner's
73
+ * existing tool-output compression and masking. That is cheaper, needs no
74
+ * model call, and cannot lose message content the way a summary can. Only
75
+ * when deterministic compression proves insufficient does the next attempt
76
+ * allow the summarizer to run.
77
+ */
78
+ allowSummarization?: boolean;
57
79
  }
58
80
  export interface SummarizeStartEvent {
59
81
  agentId: string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Provider error signatures captured from live over-limit requests.
3
+ *
4
+ * Every entry below was produced by `src/scripts/context-overflow-probe.ts`
5
+ * sending a prompt past the model's context window and recording what came
6
+ * back. Account identifiers and request ids have been replaced with
7
+ * placeholders; the wording, status codes, and nesting are verbatim.
8
+ *
9
+ * Treat these as evidence, not examples: if a provider changes its wording,
10
+ * re-run the probe and update the fixture rather than loosening the matcher.
11
+ */
12
+ import { Providers } from '@/common';
13
+ export interface OverflowSignature {
14
+ provider: Providers;
15
+ model: string;
16
+ /** Class the SDK actually threw, for reference in review. */
17
+ thrownAs: string;
18
+ /**
19
+ * Stand-in for the thrown error carrying exactly the fields the classifier
20
+ * reads. Nested bodies are kept as the strings the SDKs attach.
21
+ */
22
+ error: Record<string, unknown>;
23
+ expected: {
24
+ kind: 'context_window' | 'request_too_large';
25
+ limitTokens?: number;
26
+ requestedTokens?: number;
27
+ };
28
+ /** Set when the signature is only decidable with caller-side corroboration. */
29
+ requiresContextPressure?: boolean;
30
+ }
31
+ export declare const OVERFLOW_SIGNATURES: readonly OverflowSignature[];
32
+ /**
33
+ * Errors that mention limits, sizes, or tokens but are NOT fixed by
34
+ * compaction. The first two were captured live alongside the signatures
35
+ * above; the rest are the adjacent failures a loose matcher would swallow.
36
+ */
37
+ export declare const NON_OVERFLOW_SIGNATURES: readonly {
38
+ label: string;
39
+ error: Record<string, unknown>;
40
+ }[];