@librechat/agents 3.5.1 → 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.
Files changed (106) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +5 -2
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +148 -22
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/graphs/MultiAgentGraph.cjs +2 -1
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/main.cjs +4 -0
  8. package/dist/cjs/prompts/activityLabel.cjs +1 -0
  9. package/dist/cjs/prompts/reasoningLabel.cjs +60 -0
  10. package/dist/cjs/prompts/reasoningLabel.cjs.map +1 -0
  11. package/dist/cjs/run.cjs +161 -11
  12. package/dist/cjs/run.cjs.map +1 -1
  13. package/dist/cjs/stream.cjs +8 -6
  14. package/dist/cjs/stream.cjs.map +1 -1
  15. package/dist/cjs/tools/BashExecutor.cjs +8 -7
  16. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  17. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +5 -4
  18. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  19. package/dist/cjs/tools/CodeExecutor.cjs +26 -7
  20. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  21. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +7 -6
  22. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  23. package/dist/cjs/tools/ToolNode.cjs +33 -10
  24. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  25. package/dist/cjs/tools/ToolSearch.cjs +1 -1
  26. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  27. package/dist/cjs/tools/runStepResume.cjs +51 -0
  28. package/dist/cjs/tools/runStepResume.cjs.map +1 -0
  29. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +15 -43
  30. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  31. package/dist/cjs/tools/subagent/SubagentReplay.cjs +6 -1
  32. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
  33. package/dist/cjs/utils/toolSessions.cjs +63 -0
  34. package/dist/cjs/utils/toolSessions.cjs.map +1 -0
  35. package/dist/esm/agents/AgentContext.mjs +5 -2
  36. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  37. package/dist/esm/graphs/Graph.mjs +148 -22
  38. package/dist/esm/graphs/Graph.mjs.map +1 -1
  39. package/dist/esm/graphs/MultiAgentGraph.mjs +2 -1
  40. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  41. package/dist/esm/main.mjs +2 -2
  42. package/dist/esm/prompts/activityLabel.mjs +1 -1
  43. package/dist/esm/prompts/reasoningLabel.mjs +57 -0
  44. package/dist/esm/prompts/reasoningLabel.mjs.map +1 -0
  45. package/dist/esm/run.mjs +161 -11
  46. package/dist/esm/run.mjs.map +1 -1
  47. package/dist/esm/stream.mjs +8 -6
  48. package/dist/esm/stream.mjs.map +1 -1
  49. package/dist/esm/tools/BashExecutor.mjs +9 -8
  50. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  51. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +6 -5
  52. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  53. package/dist/esm/tools/CodeExecutor.mjs +23 -8
  54. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  55. package/dist/esm/tools/ProgrammaticToolCalling.mjs +8 -7
  56. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  57. package/dist/esm/tools/ToolNode.mjs +33 -10
  58. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  59. package/dist/esm/tools/ToolSearch.mjs +2 -2
  60. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  61. package/dist/esm/tools/runStepResume.mjs +48 -0
  62. package/dist/esm/tools/runStepResume.mjs.map +1 -0
  63. package/dist/esm/tools/subagent/SubagentExecutor.mjs +15 -43
  64. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  65. package/dist/esm/tools/subagent/SubagentReplay.mjs +6 -1
  66. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
  67. package/dist/esm/utils/toolSessions.mjs +62 -0
  68. package/dist/esm/utils/toolSessions.mjs.map +1 -0
  69. package/dist/types/agents/AgentContext.d.ts +4 -1
  70. package/dist/types/graphs/Graph.d.ts +11 -3
  71. package/dist/types/prompts/reasoningLabel.d.ts +17 -0
  72. package/dist/types/run.d.ts +8 -0
  73. package/dist/types/tools/CodeExecutor.d.ts +4 -0
  74. package/dist/types/tools/ProgrammaticToolCalling.d.ts +1 -1
  75. package/dist/types/tools/ToolNode.d.ts +3 -1
  76. package/dist/types/tools/runStepResume.d.ts +5 -0
  77. package/dist/types/tools/subagent/SubagentExecutor.d.ts +25 -0
  78. package/dist/types/tools/subagent/SubagentReplay.d.ts +2 -1
  79. package/dist/types/types/graph.d.ts +10 -1
  80. package/dist/types/types/index.d.ts +1 -0
  81. package/dist/types/types/reasoningLabel.d.ts +56 -0
  82. package/dist/types/types/stream.d.ts +18 -0
  83. package/dist/types/types/tools.d.ts +36 -16
  84. package/dist/types/utils/toolSessions.d.ts +18 -0
  85. package/package.json +1 -1
  86. package/src/agents/AgentContext.ts +7 -0
  87. package/src/graphs/Graph.ts +192 -13
  88. package/src/graphs/MultiAgentGraph.ts +1 -0
  89. package/src/prompts/reasoningLabel.ts +118 -0
  90. package/src/run.ts +330 -12
  91. package/src/stream.ts +28 -9
  92. package/src/tools/BashExecutor.ts +31 -13
  93. package/src/tools/BashProgrammaticToolCalling.ts +19 -9
  94. package/src/tools/CodeExecutor.ts +57 -16
  95. package/src/tools/ProgrammaticToolCalling.ts +26 -12
  96. package/src/tools/ToolNode.ts +58 -8
  97. package/src/tools/ToolSearch.ts +2 -2
  98. package/src/tools/runStepResume.ts +121 -0
  99. package/src/tools/subagent/SubagentExecutor.ts +67 -65
  100. package/src/tools/subagent/SubagentReplay.ts +22 -1
  101. package/src/types/graph.ts +10 -0
  102. package/src/types/index.ts +1 -0
  103. package/src/types/reasoningLabel.ts +59 -0
  104. package/src/types/stream.ts +17 -0
  105. package/src/types/tools.ts +50 -21
  106. package/src/utils/toolSessions.ts +113 -0
@@ -126,6 +126,8 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
126
126
  private programmaticCache?;
127
127
  /** Reference to Graph's sessions map for automatic session injection */
128
128
  private sessions?;
129
+ /** Partition within `sessions` owned by this agent's execution profile. */
130
+ private codeSessionKey;
129
131
  /** When true, dispatches ON_TOOL_EXECUTE events instead of invoking tools directly */
130
132
  private eventDrivenMode;
131
133
  /** Opt-in stream-layer prestart config for event-driven tools. */
@@ -211,7 +213,7 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
211
213
  * other's in-flight state.
212
214
  */
213
215
  private anonBatchCounter;
214
- constructor({ tools, toolMap, name, tags, trace, runLangfuse, agentLangfuse, errorHandler, toolCallStepIds, handleToolErrors, loadRuntimeTools, toolRegistry, sessions, eventDrivenMode, eagerEventToolExecution, eagerEventToolExecutions, eagerEventToolUsageCount, eagerEventToolSuppressions, agentId, executingAgentId, directToolNames, interruptingToolNames, codeSessionToolNames, maxContextTokens, maxToolResultChars, hookRegistry, humanInTheLoop, toolOutputReferences, toolOutputRegistry, toolExecution, fileCheckpointer, getBreakerSignal, getRunScope, }: t.ToolNodeConstructorParams);
216
+ constructor({ tools, toolMap, name, tags, trace, runLangfuse, agentLangfuse, errorHandler, toolCallStepIds, handleToolErrors, loadRuntimeTools, toolRegistry, sessions, codeSessionKey, eventDrivenMode, eagerEventToolExecution, eagerEventToolExecutions, eagerEventToolUsageCount, eagerEventToolSuppressions, agentId, executingAgentId, directToolNames, interruptingToolNames, codeSessionToolNames, maxContextTokens, maxToolResultChars, hookRegistry, humanInTheLoop, toolOutputReferences, toolOutputRegistry, toolExecution, fileCheckpointer, getBreakerSignal, getRunScope, restoreRunStepResumeState, createRunStepResumeState, }: t.ToolNodeConstructorParams);
215
217
  invoke(input: any, options?: Partial<RunnableConfig>): Promise<any>;
216
218
  /**
217
219
  * Returns the run-scoped tool output registry, or `undefined` when
@@ -0,0 +1,5 @@
1
+ import type { RunStepResumeState } from '@/types';
2
+ export declare function isRunStepResumeState(value: unknown): value is RunStepResumeState;
3
+ export declare function attachRunStepResumeState(payload: unknown, state: RunStepResumeState): object;
4
+ export declare function getRunStepResumeState(payload: unknown): RunStepResumeState | undefined;
5
+ export declare function stripRunStepResumeState(payload: unknown): unknown;
@@ -207,6 +207,31 @@ export declare class SubagentExecutor {
207
207
  resetCheckpointThreadIds(): void;
208
208
  private getGraphChildCheckpointThreadIds;
209
209
  private clearChildGraph;
210
+ /**
211
+ * Terminal sweep for a child graph's run steps. `Run.processStream` sweeps
212
+ * only the graph it owns, and a child executes through `workflow.invoke()`
213
+ * outside that loop — so without this, a child's last message step (no
214
+ * successor step ever opens to close it) and every step of an aborted child
215
+ * stay `in_progress` forever, leaving hosts with unmatched starts.
216
+ *
217
+ * Must run BEFORE `forwarding.drain()`: closures reach the parent only as
218
+ * child custom events through the forwarder, which stops relaying once
219
+ * drained.
220
+ *
221
+ * Deliberately not called on the interrupt path, mirroring the parent's
222
+ * `isAwaitingResume` guard: an in-process resume continues into these same
223
+ * steps, so closing them would strand the resumed run. A resume that
224
+ * crosses a process boundary is a known gap either way — the child rebuilds
225
+ * from `SubagentGraphResumeState`, which carries tool-call identity but not
226
+ * `contentData`, so pre-interrupt steps are unreachable from the new graph
227
+ * and stay open. That is the child-level instance of the same cross-process
228
+ * orphan the parent graph has, and it needs persisted lifecycle state to
229
+ * fix rather than a sweep here.
230
+ *
231
+ * `at` is the moment execution actually ended, threaded through so
232
+ * observational work between then and the sweep cannot inflate the stamps.
233
+ */
234
+ private closeChildRunSteps;
210
235
  clearHeavyState(): void;
211
236
  private getResumeCheckpointMarker;
212
237
  getSettledToolOutput(call: ToolCall, config: RunnableConfig): Promise<SettledSubagentToolOutput | undefined>;
@@ -2,7 +2,7 @@ import type { ToolCall, ToolMessage } from '@langchain/core/messages/tool';
2
2
  import type { RunnableConfig } from '@langchain/core/runnables';
3
3
  import type { ToolOutputReferenceState } from '@/tools/toolOutputReferences';
4
4
  import type { ToolApprovalReplaySnapshot } from '@/hooks';
5
- import type { ToolSessionContext } from '@/types';
5
+ import type { RunStepResumeState, ToolSessionContext } from '@/types';
6
6
  export declare const SUBAGENT_RESUME_MANIFEST_CONFIG_KEY = "__librechat_subagent_resume_manifest";
7
7
  export declare const SUBAGENT_RESUME_ATTEMPT_CONFIG_KEY = "__librechat_subagent_resume_attempt";
8
8
  export declare const SUBAGENT_PARENT_BATCH_CONFIG_KEY = "__librechat_subagent_parent_batch";
@@ -43,6 +43,7 @@ export interface SubagentGraphResumeState {
43
43
  toolNodes: SubagentToolNodeResumeState[];
44
44
  eagerToolUsage: SubagentEagerToolUsageState[];
45
45
  eagerToolSuppressions: string[];
46
+ runStepState?: RunStepResumeState;
46
47
  toolOutputReferences?: ToolOutputReferenceState;
47
48
  }
48
49
  /** Private checkpoint payload linking a parent pause to an exact child state. */
@@ -5,7 +5,7 @@ import type { RunnableConfig, Runnable } from '@langchain/core/runnables';
5
5
  import type { ChatGenerationChunk } from '@langchain/core/outputs';
6
6
  import type { GoogleAIToolType } from '@langchain/google-common';
7
7
  import type { SummarizationNodeInput, SummarizeCompleteEvent, SummarizationConfig, SummarizeStartEvent, SummarizeDeltaEvent } from '@/types/summarize';
8
- import type { RunStep, RunStepDeltaEvent, RunStepClosedEvent, MessageDeltaEvent, ReasoningDeltaEvent } from '@/types/stream';
8
+ import type { RunStep, RunStepDeltaEvent, RunStepResumeState, RunStepClosedEvent, MessageDeltaEvent, ReasoningDeltaEvent } from '@/types/stream';
9
9
  import type { ToolMap, ToolSessionMap, ToolEndEvent, GenericTool, LCTool, ToolExecuteBatchRequest } from '@/types/tools';
10
10
  import type { TokenCounter, StreamLimits, StreamPreemption, TokenBudgetBreakdown } from '@/types/run';
11
11
  import type { Providers, Callback, GraphNodeKeys } from '@/common';
@@ -28,6 +28,7 @@ export type SystemCallbacks = {
28
28
  };
29
29
  export type BaseGraphState = {
30
30
  messages: BaseMessage[];
31
+ runStepState?: RunStepResumeState;
31
32
  };
32
33
  export type AgentSubgraphState = BaseGraphState & {
33
34
  summarizationRequest?: SummarizationNodeInput;
@@ -628,6 +629,14 @@ export interface LangfuseConfig {
628
629
  }
629
630
  export interface AgentInputs {
630
631
  agentId: string;
632
+ /**
633
+ * Partition key for transient code-session ids and file refs. Agents with
634
+ * the same key share those refs; different execution profiles/scopes must
635
+ * use different keys. Defaults to the legacy shared `execute_code` slot.
636
+ * Non-default partitions also disable speculative eager execution of code
637
+ * tools because their factory may target a durable backend.
638
+ */
639
+ codeSessionKey?: string;
631
640
  /** Human-readable name for the agent (used in handoff context). Defaults to agentId if not provided. */
632
641
  name?: string;
633
642
  toolEnd?: boolean;
@@ -9,3 +9,4 @@ export * from './tools';
9
9
  export * from './summarize';
10
10
  export * from './activityLabel';
11
11
  export * from './assistantPhase';
12
+ export * from './reasoningLabel';
@@ -0,0 +1,56 @@
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
+ /** Lifecycle state of the visible reasoning snapshot being labeled. */
6
+ export type ReasoningLabelStatus = 'streaming' | 'complete';
7
+ /** Result of one reasoning-label revision. */
8
+ export type ReasoningLabelResult = {
9
+ label?: string;
10
+ /** Provider-reported usage for host-side billing after a durable commit. */
11
+ usage?: UsageMetadata;
12
+ };
13
+ /** Options for `Run.generateReasoningLabel`. */
14
+ export type RunReasoningLabelOptions = {
15
+ provider: Providers;
16
+ clientOptions?: ClientOptions;
17
+ /**
18
+ * Complete user-visible reasoning accumulated for this step so far. Hidden
19
+ * chain-of-thought must never be supplied through this API.
20
+ */
21
+ visibleReasoning: string;
22
+ /** Stable run-step identity shared by every revision of this label. */
23
+ reasoningStepId: string;
24
+ /** Monotonically increasing host revision for this reasoning step. */
25
+ revision: number;
26
+ /** Whether the snapshot can still grow. Default `streaming`. */
27
+ status?: ReasoningLabelStatus;
28
+ /**
29
+ * Last durably visible label for this step. The model repeats it exactly
30
+ * when the reasoning direction has not materially changed, allowing hosts
31
+ * to avoid redundant UI updates.
32
+ */
33
+ previousLabel?: string;
34
+ /**
35
+ * Agent that emitted the reasoning. Selects its Langfuse overlay and
36
+ * redaction policy. Unknown agents and omitted multi-agent ownership fail
37
+ * closed before tracing or generation.
38
+ */
39
+ agentId?: string;
40
+ /** Override for the default reasoning-label system prompt. */
41
+ prompt?: string;
42
+ /** Maximum reasoning characters retained in the prompt. Default 6000. */
43
+ charLimit?: number;
44
+ /** LangChain runnable config carrier (signal, callbacks, thread/user ids). */
45
+ chainOptions?: Partial<RunnableConfig> & {
46
+ configurable?: Record<string, unknown>;
47
+ };
48
+ /** Deterministic seed for this reasoning-label revision trace. */
49
+ traceSeed?: string;
50
+ /** Stable source run identifier recorded on the observation. */
51
+ sourceRunId?: string;
52
+ /** Source Langfuse trace id for linking this detached label trace. */
53
+ sourceTraceId?: string;
54
+ /** Host response/message identifier recorded on the observation. */
55
+ responseId?: string;
56
+ };
@@ -75,6 +75,24 @@ export type RunStep = {
75
75
  summary?: SummaryContentBlock;
76
76
  usage?: null | object;
77
77
  };
78
+ /** Minimal durable lifecycle state needed to continue open run steps. */
79
+ export interface RunStepResumeEntry {
80
+ step: RunStep;
81
+ pendingToolCallIds: string[];
82
+ latestCompletionAt?: number;
83
+ openMessageStep: boolean;
84
+ }
85
+ /** SDK-private state persisted in LangGraph checkpoints for process-safe resume. */
86
+ export interface RunStepResumeState {
87
+ version: 1;
88
+ revision: number;
89
+ nextIndex: number;
90
+ toolCallSteps: Array<{
91
+ toolCallId: string;
92
+ stepId: string;
93
+ }>;
94
+ steps: RunStepResumeEntry[];
95
+ }
78
96
  /**
79
97
  * Represents a run step delta i.e. any changed fields on a run step during
80
98
  * streaming.
@@ -1,9 +1,9 @@
1
1
  import type { StructuredToolInterface } from '@langchain/core/tools';
2
- import type { RunnableToolLike } from '@langchain/core/runnables';
2
+ import type { RunnableConfig, RunnableToolLike } from '@langchain/core/runnables';
3
3
  import type { ToolCall } from '@langchain/core/messages/tool';
4
4
  import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
5
5
  import type { RunBreakerScope } from '@/llm/streamLimits';
6
- import type { MessageContentComplex, ToolErrorData } from './stream';
6
+ import type { MessageContentComplex, RunStepResumeState, ToolErrorData } from './stream';
7
7
  import type { HumanInTheLoopConfig } from './hitl';
8
8
  import type { LangfuseConfig } from './graph';
9
9
  import type { HookRegistry } from '@/hooks';
@@ -118,6 +118,8 @@ export type ToolNodeOptions = {
118
118
  toolRegistry?: LCToolRegistry;
119
119
  /** Reference to Graph's sessions map for automatic session injection */
120
120
  sessions?: ToolSessionMap;
121
+ /** Partition within `sessions` used by this agent's code tools. */
122
+ codeSessionKey?: string;
121
123
  /** When true, dispatches ON_TOOL_EXECUTE events instead of invoking tools directly */
122
124
  eventDrivenMode?: boolean;
123
125
  /** Tool definitions for event-driven mode (used for context, not invocation) */
@@ -264,6 +266,10 @@ export type ToolNodeOptions = {
264
266
  * controller.
265
267
  */
266
268
  getRunScope?: () => RunBreakerScope;
269
+ /** SDK-owned checkpoint bridge for open run-step lifecycle state. */
270
+ restoreRunStepResumeState?: (state?: RunStepResumeState, config?: RunnableConfig) => void;
271
+ /** SDK-owned checkpoint snapshot for open run-step lifecycle state. */
272
+ createRunStepResumeState?: () => RunStepResumeState;
267
273
  };
268
274
  export type ToolNodeConstructorParams = ToolRefs & ToolNodeOptions;
269
275
  export type ToolEndEvent = {
@@ -361,6 +367,19 @@ export type CodeEnvFile = (CodeEnvFileBase & {
361
367
  kind: 'user';
362
368
  });
363
369
  export type CodeExecutionToolParams = undefined | {
370
+ /** Trusted Code API endpoint selected by the host for this agent. */
371
+ baseUrl?: string;
372
+ /**
373
+ * Expected Code API execution profile. Sent as a request assertion so
374
+ * endpoint/configuration drift fails closed instead of silently using
375
+ * the wrong sandbox backend.
376
+ */
377
+ executionProfile?: CodeApiExecutionProfile;
378
+ /**
379
+ * Trusted warm-runtime affinity hint selected by the host for this
380
+ * agent invocation. This overrides the legacy ToolNode-injected hint.
381
+ */
382
+ runtimeSessionHint?: string;
364
383
  /** Execution session — see `CodeSessionContext.session_id`. */
365
384
  session_id?: string;
366
385
  user_id?: string;
@@ -368,15 +387,14 @@ export type CodeExecutionToolParams = undefined | {
368
387
  /** Optional host-supplied Code API auth headers. */
369
388
  authHeaders?: CodeApiAuthHeaders;
370
389
  /**
371
- * Advertise best-effort stateful sessions in the tool description
372
- * (variables/files may persist between calls, may reset). Prompt text
373
- * only, and it must be set here because the description is bound to the
374
- * LLM at construction time. Pair it with the run-scoped
375
- * `toolExecution.sandbox.statefulSessions` gate, which drives the wire
376
- * hint — set both from one flag so the prompt and the backend agree.
390
+ * Advertise filesystem-tier stateful sessions in the tool description
391
+ * and allow a trusted runtime affinity hint onto the wire. Resolve this,
392
+ * `baseUrl`, `executionProfile`, and `runtimeSessionHint` together from
393
+ * the executing agent so the prompt and backend agree.
377
394
  */
378
395
  statefulSessions?: boolean;
379
396
  };
397
+ export type CodeApiExecutionProfile = 'default' | 'stateful';
380
398
  export type CodeApiAuthHeaderMap = Record<string, string>;
381
399
  export type CodeApiAuthHeaders = CodeApiAuthHeaderMap | (() => CodeApiAuthHeaderMap | Promise<CodeApiAuthHeaderMap>);
382
400
  export type FileRef = {
@@ -1032,19 +1050,17 @@ export type CloudflareSandboxExecutionConfig = {
1032
1050
  };
1033
1051
  export type SandboxExecutionConfig = {
1034
1052
  /**
1035
- * Opt into best-effort stateful runtime sessions on the remote Code API
1036
- * (its warm per-session MicroVM backend). This gate is run-scoped: it only
1037
- * controls the wire behavior (ToolNode injecting the session hint on
1038
- * execute_code/bash calls). The transport is otherwise unchanged.
1053
+ * Legacy run-scoped opt-in for warm runtime hint injection. New hosts that
1054
+ * need mixed execution profiles should resolve `statefulSessions`,
1055
+ * `baseUrl`, `executionProfile`, and `runtimeSessionHint` on each executing
1056
+ * agent's tool factories instead. Direct executors ignore this injected hint
1057
+ * unless their own factory has `statefulSessions: true`.
1039
1058
  *
1040
1059
  * It does NOT change the model-facing tool description. Tool descriptions are
1041
1060
  * bound to the LLM at construction time (`createCodeExecutionTool` /
1042
1061
  * `createBashExecutionTool`), before this run config is applied inside the
1043
1062
  * graph, so they can only be adjusted via the tools' own `statefulSessions`
1044
- * factory param. Set BOTH from one flag (as LibreChat does): with this on but
1045
- * the factory param off, the backend runs statefully while the model is still
1046
- * told the environment is stateless (non-corrupting — the model just won't
1047
- * exploit persistence).
1063
+ * factory param.
1048
1064
  */
1049
1065
  statefulSessions?: boolean;
1050
1066
  /**
@@ -1193,6 +1209,10 @@ export type BashProgrammaticToolCallingParams = ProgrammaticToolCallingParams;
1193
1209
  export type ProgrammaticToolCallingParams = {
1194
1210
  /** Code API base URL (or use CODE_BASEURL env var) */
1195
1211
  baseUrl?: string;
1212
+ /** Expected Code API execution profile (host-controlled). */
1213
+ executionProfile?: CodeApiExecutionProfile;
1214
+ /** Trusted warm-runtime affinity hint for this agent invocation. */
1215
+ runtimeSessionHint?: string;
1196
1216
  /** Safety limit for round-trips (default: 20) */
1197
1217
  maxRoundTrips?: number;
1198
1218
  /** Maximum per-sandbox-run timeout for PTC's legacy `timeout` field. */
@@ -0,0 +1,18 @@
1
+ import type * as t from '@/types';
2
+ type CodeSessionAgent = Pick<t.AgentInputs, 'codeSessionKey' | 'initialSessions'>;
3
+ /**
4
+ * Seeds a top-level graph while preserving the legacy run-wide session map.
5
+ * A legacy `execute_code` seed is copied into every custom agent partition
6
+ * unless the host already supplied an explicit seed for that partition.
7
+ */
8
+ export declare function seedRunInitialSessions(args: {
9
+ sessions: t.ToolSessionMap;
10
+ initialSessions: t.ToolSessionMap;
11
+ agents: Iterable<Pick<t.AgentInputs, 'codeSessionKey'>>;
12
+ }): void;
13
+ /**
14
+ * Seeds an isolated child graph from each selected agent. Legacy code-session
15
+ * entries are remapped to the owning agent's partition before they are merged.
16
+ */
17
+ export declare function seedAgentInitialSessions(sessions: t.ToolSessionMap, agents: Iterable<CodeSessionAgent>): void;
18
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.5.1",
3
+ "version": "3.6.1",
4
4
  "reova": {
5
5
  "enabled": true,
6
6
  "endpoint": "https://telemetry.reo.dev/data"
@@ -63,6 +63,7 @@ export class AgentContext {
63
63
  ): AgentContext {
64
64
  const {
65
65
  agentId,
66
+ codeSessionKey,
66
67
  name,
67
68
  provider,
68
69
  clientOptions,
@@ -92,6 +93,7 @@ export class AgentContext {
92
93
 
93
94
  const agentContext = new AgentContext({
94
95
  agentId,
96
+ codeSessionKey,
95
97
  name: name ?? agentId,
96
98
  provider,
97
99
  clientOptions,
@@ -167,6 +169,8 @@ export class AgentContext {
167
169
 
168
170
  /** Agent identifier */
169
171
  agentId: string;
172
+ /** Partition for this agent's transient code session and file refs. */
173
+ codeSessionKey?: string;
170
174
  /** Human-readable name for this agent (used in handoff context). Falls back to agentId if not provided. */
171
175
  name?: string;
172
176
  /** Provider for this specific agent */
@@ -370,6 +374,7 @@ export class AgentContext {
370
374
 
371
375
  constructor({
372
376
  agentId,
377
+ codeSessionKey,
373
378
  name,
374
379
  provider,
375
380
  clientOptions,
@@ -394,6 +399,7 @@ export class AgentContext {
394
399
  maxToolResultChars,
395
400
  }: {
396
401
  agentId: string;
402
+ codeSessionKey?: string;
397
403
  name?: string;
398
404
  provider: Providers;
399
405
  clientOptions?: t.ClientOptions;
@@ -418,6 +424,7 @@ export class AgentContext {
418
424
  maxToolResultChars?: number;
419
425
  }) {
420
426
  this.agentId = agentId;
427
+ this.codeSessionKey = codeSessionKey;
421
428
  this.name = name;
422
429
  this.provider = provider;
423
430
  this.clientOptions = clientOptions;