@librechat/agents 3.6.3 → 3.6.5

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 (72) hide show
  1. package/dist/cjs/graphs/Graph.cjs +44 -19
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/hooks/HookRegistry.cjs +7 -1
  4. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  5. package/dist/cjs/hooks/index.cjs +1 -1
  6. package/dist/cjs/langchain/index.cjs +12 -0
  7. package/dist/cjs/langchain/messages.cjs +12 -0
  8. package/dist/cjs/langfuseConfig.cjs +16 -0
  9. package/dist/cjs/langfuseConfig.cjs.map +1 -1
  10. package/dist/cjs/langfuseSpanRegistry.cjs +16 -4
  11. package/dist/cjs/langfuseSpanRegistry.cjs.map +1 -1
  12. package/dist/cjs/main.cjs +15 -1
  13. package/dist/cjs/run.cjs +4 -0
  14. package/dist/cjs/run.cjs.map +1 -1
  15. package/dist/cjs/tools/SubagentTool.cjs +14 -4
  16. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  17. package/dist/cjs/tools/ToolNode.cjs +1 -1
  18. package/dist/cjs/tools/subagent/InMemorySubagentTaskStore.cjs +403 -0
  19. package/dist/cjs/tools/subagent/InMemorySubagentTaskStore.cjs.map +1 -0
  20. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +201 -61
  21. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  22. package/dist/cjs/tools/subagent/index.cjs +1 -0
  23. package/dist/esm/graphs/Graph.mjs +44 -19
  24. package/dist/esm/graphs/Graph.mjs.map +1 -1
  25. package/dist/esm/hooks/HookRegistry.mjs +7 -1
  26. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  27. package/dist/esm/hooks/index.mjs +1 -1
  28. package/dist/esm/langchain/index.mjs +2 -2
  29. package/dist/esm/langchain/messages.mjs +2 -2
  30. package/dist/esm/langfuseConfig.mjs +16 -0
  31. package/dist/esm/langfuseConfig.mjs.map +1 -1
  32. package/dist/esm/langfuseSpanRegistry.mjs +16 -4
  33. package/dist/esm/langfuseSpanRegistry.mjs.map +1 -1
  34. package/dist/esm/main.mjs +4 -3
  35. package/dist/esm/run.mjs +4 -0
  36. package/dist/esm/run.mjs.map +1 -1
  37. package/dist/esm/tools/SubagentTool.mjs +14 -4
  38. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  39. package/dist/esm/tools/ToolNode.mjs +1 -1
  40. package/dist/esm/tools/subagent/InMemorySubagentTaskStore.mjs +403 -0
  41. package/dist/esm/tools/subagent/InMemorySubagentTaskStore.mjs.map +1 -0
  42. package/dist/esm/tools/subagent/SubagentExecutor.mjs +201 -61
  43. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  44. package/dist/esm/tools/subagent/index.mjs +1 -0
  45. package/dist/types/graphs/Graph.d.ts +6 -3
  46. package/dist/types/hooks/HookRegistry.d.ts +8 -0
  47. package/dist/types/langchain/messages.d.ts +2 -2
  48. package/dist/types/langfuseSpanRegistry.d.ts +9 -4
  49. package/dist/types/run.d.ts +1 -0
  50. package/dist/types/tools/SubagentTool.d.ts +5 -2
  51. package/dist/types/tools/subagent/InMemorySubagentTaskStore.d.ts +45 -0
  52. package/dist/types/tools/subagent/SubagentExecutor.d.ts +30 -3
  53. package/dist/types/tools/subagent/index.d.ts +2 -0
  54. package/dist/types/types/graph.d.ts +22 -4
  55. package/dist/types/types/index.d.ts +1 -0
  56. package/dist/types/types/run.d.ts +6 -0
  57. package/dist/types/types/subagentTasks.d.ts +172 -0
  58. package/package.json +1 -1
  59. package/src/graphs/Graph.ts +75 -30
  60. package/src/hooks/HookRegistry.ts +18 -0
  61. package/src/langchain/messages.ts +3 -0
  62. package/src/langfuseConfig.ts +43 -0
  63. package/src/langfuseSpanRegistry.ts +42 -4
  64. package/src/run.ts +4 -0
  65. package/src/tools/SubagentTool.ts +37 -3
  66. package/src/tools/subagent/InMemorySubagentTaskStore.ts +632 -0
  67. package/src/tools/subagent/SubagentExecutor.ts +411 -74
  68. package/src/tools/subagent/index.ts +2 -0
  69. package/src/types/graph.ts +22 -4
  70. package/src/types/index.ts +1 -0
  71. package/src/types/run.ts +6 -0
  72. package/src/types/subagentTasks.ts +162 -0
@@ -79,6 +79,14 @@ export declare class HookRegistry {
79
79
  clearSession(sessionId: string): void;
80
80
  /** Copies session-scoped policy into a rebuilt or branched Run. */
81
81
  copySession(sourceSessionId: string, targetSessionId: string): void;
82
+ /**
83
+ * Takes an isolated policy snapshot for work that may outlive the source
84
+ * run. Global and source-session matchers become global to the returned
85
+ * task-local registry, so parent cleanup and one-shot hook consumption
86
+ * cannot mutate the detached child (or vice versa). Runtime halt signals
87
+ * and pending approvals are intentionally not copied.
88
+ */
89
+ forkSession(sourceSessionId: string): HookRegistry;
82
90
  getPendingToolApproval(sessionId: string, key: ToolApprovalReplayKey): AggregatedHookResult | undefined;
83
91
  setPendingToolApproval(sessionId: string, key: ToolApprovalReplayKey, result: AggregatedHookResult): void;
84
92
  clearPendingToolApproval(sessionId: string, key: ToolApprovalReplayKey): void;
@@ -1,2 +1,2 @@
1
- export { AIMessage, AIMessageChunk, BaseMessage, BaseMessageChunk, HumanMessage, SystemMessage, ToolMessage, getBufferString, isAIMessage, isBaseMessage, isToolMessage, } from '@langchain/core/messages';
2
- export type { BaseMessageFields, MessageContent, MessageContentText, MessageContentImageUrl, UsageMetadata, } from '@langchain/core/messages';
1
+ export { AIMessage, AIMessageChunk, BaseMessage, BaseMessageChunk, HumanMessage, SystemMessage, ToolMessage, getBufferString, isAIMessage, isBaseMessage, isToolMessage, mapChatMessagesToStoredMessages, mapStoredMessagesToChatMessages, } from '@langchain/core/messages';
2
+ export type { BaseMessageFields, MessageContent, MessageContentText, MessageContentImageUrl, StoredMessage, UsageMetadata, } from '@langchain/core/messages';
@@ -6,10 +6,15 @@ export declare function getLangfuseManagedSpanDestination(span: Span): string |
6
6
  export declare function getLangfuseSpanProcessorParams(langfuse?: t.LangfuseConfig): LangfuseSpanProcessorParams | undefined;
7
7
  /**
8
8
  * Identity of an export destination (project credentials + endpoint +
9
- * environment) only. Processor-level policies like `toolOutputTracing` are
10
- * deliberately excluded: two spans exporting to the same project under
11
- * different redaction settings still share a destination and may parent one
12
- * another.
9
+ * environment + custom headers) only. Processor-level policies like
10
+ * `toolOutputTracing` are deliberately excluded: two spans exporting to the
11
+ * same project under different redaction settings still share a destination
12
+ * and may parent one another.
13
+ *
14
+ * Custom headers are included because a gateway may route on them, making two
15
+ * otherwise-identical configs different projects. Treating them as part of the
16
+ * destination keeps a run from inheriting a parent span bound elsewhere, and
17
+ * keeps a rotated proxy credential from reusing the stale exporter.
13
18
  */
14
19
  export declare function getLangfuseDestinationKey(params: LangfuseSpanProcessorParams): string;
15
20
  /** The export destination a run with this config resolves to, or `undefined`
@@ -20,6 +20,7 @@ export declare class Run<_T extends t.BaseGraphState> {
20
20
  private subagentUsageSink?;
21
21
  private preemption?;
22
22
  private streamLimits?;
23
+ private subagentTasks?;
23
24
  private indexTokenCountMap?;
24
25
  calibrationRatio: number;
25
26
  graphRunnable?: t.CompiledStateWorkflow;
@@ -2,7 +2,7 @@ import type { JsonSchemaType, LCTool } from '@/types/tools';
2
2
  import type { SubagentConfig } from '@/types';
3
3
  import { Constants } from '@/common';
4
4
  export declare const SubagentToolName = Constants.SUBAGENT;
5
- export declare const SubagentToolDescription = "Delegate a task to a specialized subagent or bounded agent team that runs in an isolated context window. The delegated execution returns only its designated final text result \u2014 all intermediate tool calls, reasoning, and context stay isolated.\n\nWHEN TO USE:\n- The task is self-contained and can be described in a single prompt.\n- You want to offload verbose or exploratory work without bloating your own context.\n- A specialized subagent is available for the task domain.\n\nWHAT HAPPENS:\n- A fresh agent or configured agent graph is created with the task description as its only input.\n- The delegated agent or team runs to completion using isolated tools and context.\n- Only the single agent's final response or the graph's designated result-agent response is returned to you.\n\nCONSTRAINTS:\n- subagent_type must match one of the available types listed below.\n- The subagent cannot see your conversation history.";
5
+ export declare const SubagentToolDescription = "Delegate a task to a specialized subagent or bounded agent team that runs in an isolated context window. The delegated execution returns only its designated final text result \u2014 all intermediate tool calls, reasoning, and context stay isolated.\n\nWHEN TO USE:\n- The task is self-contained and can be described in a single prompt.\n- You want to offload verbose or exploratory work without bloating your own context.\n- A specialized subagent is available for the task domain.\n\nWHAT HAPPENS:\n- A fresh agent or configured agent graph is created with the task description as its only input, unless the host enables child-thread continuation and you provide a saved thread id.\n- The delegated agent or team runs to completion using isolated tools and context.\n- Only the single agent's final response or the graph's designated result-agent response is returned to you.\n\nCONSTRAINTS:\n- subagent_type must match one of the available types listed below.\n- The subagent cannot see your conversation history.";
6
6
  export declare const SubagentToolSchema: {
7
7
  readonly type: "object";
8
8
  readonly properties: {
@@ -32,7 +32,10 @@ export declare const SubagentToolDefinition: LCTool;
32
32
  * Used by `Graph.createAgentNode()` when constructing the runtime tool instance.
33
33
  * Extends `SubagentToolSchema` by populating `subagent_type.enum` dynamically.
34
34
  */
35
- export declare function buildSubagentToolParams(configs: SubagentConfig[]): {
35
+ export declare function buildSubagentToolParams(configs: SubagentConfig[], options?: {
36
+ background?: boolean;
37
+ threadContinuation?: boolean;
38
+ }): {
36
39
  name: string;
37
40
  schema: JsonSchemaType;
38
41
  description: string;
@@ -0,0 +1,45 @@
1
+ import type { SubagentTaskClaim, SubagentTaskControlCommand, SubagentTaskControlResult, SubagentTaskSnapshot, SubagentTaskStartRequest, SubagentTaskStartResult, SubagentTaskStore } from '@/types';
2
+ export interface InMemorySubagentTaskStoreOptions {
3
+ completedTtlMs?: number;
4
+ maxControlMessageChars?: number;
5
+ maxControlsPerTask?: number;
6
+ maxErrorChars?: number;
7
+ maxResultChars?: number;
8
+ maxRunningPerScope?: number;
9
+ maxRunningTotal?: number;
10
+ maxTasksPerScope?: number;
11
+ maxTasksTotal?: number;
12
+ taskTimeoutMs?: number;
13
+ }
14
+ /**
15
+ * Bounded process-local task ownership for detached subagents. Terminal tasks
16
+ * keep only a bounded claimable result: the child graph, checkpoint, and full
17
+ * transcript are released. Hosts that need later child-chat continuation may
18
+ * replace this store and persist the canonical messages returned by `run`.
19
+ * This default deliberately makes no restart or cross-replica durability
20
+ * claim.
21
+ */
22
+ export declare class InMemorySubagentTaskStore implements SubagentTaskStore {
23
+ private readonly buckets;
24
+ private readonly options;
25
+ private runningTasks;
26
+ private totalTasks;
27
+ constructor(options?: InMemorySubagentTaskStoreOptions);
28
+ start(request: SubagentTaskStartRequest): SubagentTaskStartResult;
29
+ get(scopeId: string, taskId: string): SubagentTaskSnapshot | undefined;
30
+ list(scopeId: string): SubagentTaskSnapshot[];
31
+ claim(scopeId: string, taskId: string): SubagentTaskClaim;
32
+ control(scopeId: string, taskId: string, command: SubagentTaskControlCommand): SubagentTaskControlResult;
33
+ private getBucket;
34
+ private find;
35
+ private makeRoom;
36
+ private makeGlobalRoom;
37
+ private sweepBucket;
38
+ private removeTask;
39
+ private dropEmptyBucket;
40
+ private scheduleExpiry;
41
+ private clearTaskExpiry;
42
+ private clearTaskTimeout;
43
+ private finishWithError;
44
+ private createRuntime;
45
+ }
@@ -1,17 +1,19 @@
1
1
  import { BaseMessage } from '@langchain/core/messages';
2
2
  import type { RunnableConfig } from '@langchain/core/runnables';
3
3
  import type { ToolCall } from '@langchain/core/messages/tool';
4
- import type { MultiAgentGraphState, HumanInTheLoopConfig, StandardGraphInput, ExecutableSubagentConfigEntry, SubagentExecutionContext, SubagentUsageSink, TokenCounter } from '@/types';
4
+ import type { MultiAgentGraphState, HumanInTheLoopConfig, StandardGraphInput, ExecutableSubagentConfigEntry, SubagentExecutionContext, SubagentTaskConfig, SubagentTaskRuntime, SubagentUsageSink, TokenCounter } from '@/types';
5
5
  import type { SubagentResumeManifest, SettledSubagentToolOutput } from './SubagentReplay';
6
- import type { HookRegistry } from '@/hooks';
7
6
  import type { GraphFactory } from '@/graphs/graphFactory';
8
7
  import type { StandardGraph } from '@/graphs/Graph';
9
- import type { HandlerRegistry } from '@/events';
8
+ import { HookRegistry } from '@/hooks';
9
+ import { HandlerRegistry } from '@/events';
10
10
  export { buildChildInputs, isGraphSubagentConfig, normalizeSubagentConfigs, normalizeSubagentConfigEntries, resolveSubagentConfigs, resolveSubagentConfigEntries, } from './childGraphConfig';
11
11
  export declare const DEFAULT_SUBAGENT_DESCRIPTION = "No task description provided";
12
12
  export type SubagentExecuteParams = {
13
13
  description: string;
14
14
  subagentType: string;
15
+ /** Saved logical child thread selected by the parent model. */
16
+ subagentThreadId?: string;
15
17
  threadId?: string;
16
18
  /** Signal attached to this specific parent tool invocation. */
17
19
  signal?: AbortSignal;
@@ -62,10 +64,18 @@ export type SubagentExecuteParams = {
62
64
  * rather than sharing parent's host context.
63
65
  */
64
66
  parentConfigurable?: Record<string, unknown>;
67
+ /** Dedicated hook session used by a detached task. @internal */
68
+ hookSessionId?: string;
69
+ /** Process-local task controls consumed by the child graph. @internal */
70
+ taskRuntime?: SubagentTaskRuntime;
71
+ /** Host-restored child transcript for a fresh continuation run. @internal */
72
+ initialMessages?: BaseMessage[];
65
73
  };
66
74
  export type SubagentExecuteResult = {
67
75
  content: string;
68
76
  messages: BaseMessage[];
77
+ /** Tagged internal failure; foreground callers retain the legacy content. */
78
+ error?: string;
69
79
  };
70
80
  /**
71
81
  * Factory that constructs a child graph for subagent execution. Injected
@@ -121,6 +131,11 @@ export type SubagentExecutorOptions = {
121
131
  /** Preferred polymorphic child constructor. The legacy standard-only
122
132
  * factory remains required for source compatibility. */
123
133
  createChildGraphByKind?: GraphFactory;
134
+ /**
135
+ * Captures a child-graph factory and its run-scoped host dependencies
136
+ * synchronously, before a detached task can outlive parent cleanup.
137
+ */
138
+ createDetachedChildGraphFactory?: (parentHandlerRegistry: HandlerRegistry) => GraphFactory;
124
139
  /**
125
140
  * Parent's event handler registry. When provided, child-graph events are
126
141
  * forwarded through this registry so hosts can:
@@ -143,6 +158,8 @@ export type SubagentExecutorOptions = {
143
158
  * nested subagents report through the same sink.
144
159
  */
145
160
  usageSink?: SubagentUsageSink;
161
+ /** Host-owned process-local task namespace for detached execution. */
162
+ taskConfig?: SubagentTaskConfig;
146
163
  };
147
164
  export declare class SubagentExecutor {
148
165
  private readonly configs;
@@ -167,7 +184,9 @@ export declare class SubagentExecutor {
167
184
  private readonly maxDepth;
168
185
  private readonly createChildGraph;
169
186
  private readonly createChildGraphByKind?;
187
+ private readonly createDetachedChildGraphFactory?;
170
188
  private readonly usageSink?;
189
+ private readonly taskConfig?;
171
190
  private readonly executions;
172
191
  private replayCheckpointWorkflow?;
173
192
  private readonly resolveParentHandlerRegistry?;
@@ -181,6 +200,14 @@ export declare class SubagentExecutor {
181
200
  private composeChildSignal;
182
201
  /** Snapshot of the parent's registry at the moment a subagent is dispatched. */
183
202
  private getParentHandlerRegistry;
203
+ /**
204
+ * Starts one independently-owned executor behind the configured task store.
205
+ * The parent ToolNode receives the handle synchronously; the detached clone
206
+ * is not registered on the parent graph, so end-of-turn cleanup cannot
207
+ * invalidate or clear a child that intentionally outlives that turn.
208
+ */
209
+ executeInBackground(params: SubagentExecuteParams): string;
210
+ private executeDetached;
184
211
  private bindExecutionDefinition;
185
212
  /** Resolve one lazy descriptor per stable child execution. Concurrent
186
213
  * duplicate dispatches share the same in-flight resolution; HITL re-entry
@@ -1,2 +1,4 @@
1
1
  export { DEFAULT_SUBAGENT_DESCRIPTION, SubagentExecutor, filterSubagentResult, filterGraphSubagentResult, isGraphSubagentConfig, normalizeSubagentConfigs, normalizeSubagentConfigEntries, resolveSubagentConfigs, resolveSubagentConfigEntries, buildChildInputs, summarizeEvent, } from './SubagentExecutor';
2
2
  export type { SubagentExecuteParams, SubagentExecuteResult, SubagentExecutorOptions, ChildGraphFactory, } from './SubagentExecutor';
3
+ export { InMemorySubagentTaskStore } from './InMemorySubagentTaskStore';
4
+ export type { InMemorySubagentTaskStoreOptions } from './InMemorySubagentTaskStore';
@@ -9,6 +9,7 @@ import type { RunStep, RunStepDeltaEvent, RunStepResumeState, RunStepClosedEvent
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';
12
+ import type { SubagentTaskConfig } from '@/types/subagentTasks';
12
13
  import type { StandardGraph, MultiAgentGraph } from '@/graphs';
13
14
  import type { ClientOptions } from '@/types/llm';
14
15
  /** Interface for bound model with stream and invoke methods */
@@ -239,6 +240,12 @@ export type StandardGraphInput = {
239
240
  * they already flow through the registry's `CHAT_MODEL_END` handler.
240
241
  */
241
242
  subagentUsageSink?: SubagentUsageSink;
243
+ /**
244
+ * Optional host-owned process-local task namespace for detached subagents.
245
+ * Presence enables `run_in_background` on the subagent tool. Child graphs
246
+ * do not inherit it, keeping background nesting disabled for the MVP.
247
+ */
248
+ subagentTasks?: SubagentTaskConfig;
242
249
  /**
243
250
  * True when this graph IS a subagent child run (set by `SubagentExecutor`
244
251
  * when it constructs the child graph). Drives the hook-input `agentId`
@@ -250,10 +257,10 @@ export type StandardGraphInput = {
250
257
  */
251
258
  subagentScope?: boolean;
252
259
  /**
253
- * Cooperative preemption, forwarded from `RunConfig.preemption`. Only ever
254
- * set on the top-level graph: a steer targets the conversation, so subagent
255
- * children must run to completion and `buildChildInputs` does not propagate
256
- * this field.
260
+ * Cooperative preemption, forwarded from `RunConfig.preemption`. Ordinary
261
+ * child graphs do not inherit it. Detached subagent tasks may receive their
262
+ * own internal parent-control source so an interrupt can reuse the same
263
+ * provider-safe sealing path without targeting the top-level conversation.
257
264
  */
258
265
  preemption?: StreamPreemption;
259
266
  /**
@@ -608,6 +615,17 @@ export interface LangfuseConfig {
608
615
  * payloads. Defaults to the Langfuse SDK behavior.
609
616
  */
610
617
  mediaUploadEnabled?: boolean;
618
+ /**
619
+ * Extra HTTP headers sent on every Langfuse export request (OTLP trace
620
+ * export and media uploads), for self-hosted instances behind an
621
+ * authenticating proxy or gateway.
622
+ *
623
+ * Deployment-level only: one exporter is shared by every span routed to a
624
+ * destination, so these cannot carry per-request or per-user identity.
625
+ * Headers participate in destination identity — see
626
+ * `getLangfuseDestinationKey`.
627
+ */
628
+ additionalHeaders?: Record<string, string>;
611
629
  metadata?: Record<string, string | number | boolean | null | undefined>;
612
630
  /**
613
631
  * Internal OTLP span attributes to attach to Langfuse observations before
@@ -5,6 +5,7 @@ export * from './messages';
5
5
  export * from './run';
6
6
  export * from './skill';
7
7
  export * from './stream';
8
+ export * from './subagentTasks';
8
9
  export * from './tools';
9
10
  export * from './summarize';
10
11
  export * from './activityLabel';
@@ -4,6 +4,7 @@ import type { BaseMessage } from '@langchain/core/messages';
4
4
  import type { StructuredTool } from '@langchain/core/tools';
5
5
  import type * as z from 'zod';
6
6
  import type { ToolSessionMap, ToolExecutionConfig, ToolOutputReferencesConfig, EagerEventToolExecutionConfig } from '@/types/tools';
7
+ import type { SubagentTaskConfig } from '@/types/subagentTasks';
7
8
  import type { HumanInTheLoopConfig } from '@/types/hitl';
8
9
  import type { HookRegistry } from '@/hooks';
9
10
  import type * as s from '@/types/stream';
@@ -215,6 +216,11 @@ export type RunConfig = {
215
216
  * the registered `CHAT_MODEL_END` handler as usual.
216
217
  */
217
218
  subagentUsageSink?: g.SubagentUsageSink;
219
+ /**
220
+ * Trusted process-local task namespace for detached subagent execution.
221
+ * Omit to preserve foreground-only subagent behavior.
222
+ */
223
+ subagentTasks?: SubagentTaskConfig;
218
224
  /**
219
225
  * Pre-constructed hook registry for this run. Hooks fire at lifecycle
220
226
  * points in `processStream` (RunStart, UserPromptSubmit, Stop,
@@ -0,0 +1,172 @@
1
+ import type { BaseMessage } from '@langchain/core/messages';
2
+ import type { SubagentUpdateEvent } from './graph';
3
+ import type { InjectedMessage } from './tools';
4
+ /** Terminal and in-flight states for a detached subagent task. */
5
+ export type SubagentTaskStatus = 'running' | 'completed' | 'error' | 'cancelled';
6
+ /** Where a pending parent message may enter the child run. */
7
+ export type SubagentTaskBoundary = 'preempt' | 'tool' | 'turn';
8
+ /** Parent-to-child control operations accepted while a task is running. */
9
+ export type SubagentTaskControlCommand = {
10
+ action: 'steer' | 'queue' | 'interrupt';
11
+ message: string;
12
+ } | {
13
+ action: 'cancel';
14
+ } | {
15
+ action: 'cancel_message';
16
+ controlId: string;
17
+ };
18
+ /** Small, payload-free progress view safe to retain between parent turns. */
19
+ export interface SubagentTaskProgress {
20
+ phase: SubagentUpdateEvent['phase'];
21
+ at: number;
22
+ eventCount: number;
23
+ label?: string;
24
+ }
25
+ /** Read-only task metadata. Results are exposed only through `claim`. */
26
+ export interface SubagentTaskSnapshot {
27
+ /** Handle for this child-thread execution lease within its trusted scope. */
28
+ taskId: string;
29
+ /**
30
+ * Stable logical thread identity shared by fresh execution leases. Required
31
+ * from stores that advertise `supportsThreadContinuation`; optional for
32
+ * legacy/process-local stores that do not expose a durable conversation.
33
+ */
34
+ threadId?: string;
35
+ subagentType: string;
36
+ status: SubagentTaskStatus;
37
+ createdAt: number;
38
+ updatedAt: number;
39
+ resultAvailable: boolean;
40
+ resultClaimed: boolean;
41
+ pendingControls: number;
42
+ progress?: SubagentTaskProgress;
43
+ error?: string;
44
+ }
45
+ export type SubagentTaskClaim = {
46
+ status: 'running';
47
+ task: SubagentTaskSnapshot;
48
+ } | {
49
+ status: 'completed';
50
+ task: SubagentTaskSnapshot;
51
+ result: string;
52
+ } | {
53
+ status: 'error';
54
+ task: SubagentTaskSnapshot;
55
+ error: string;
56
+ } | {
57
+ status: 'cancelled';
58
+ task: SubagentTaskSnapshot;
59
+ error: string;
60
+ } | {
61
+ status: 'claimed';
62
+ task: SubagentTaskSnapshot;
63
+ } | {
64
+ status: 'not_found';
65
+ };
66
+ export type SubagentTaskControlResult = {
67
+ status: 'accepted';
68
+ task: SubagentTaskSnapshot;
69
+ controlId?: string;
70
+ } | {
71
+ status: 'cancelled';
72
+ task: SubagentTaskSnapshot;
73
+ } | {
74
+ status: 'not_running';
75
+ task: SubagentTaskSnapshot;
76
+ } | {
77
+ status: 'not_found';
78
+ } | {
79
+ status: 'control_not_found';
80
+ task: SubagentTaskSnapshot;
81
+ } | {
82
+ status: 'invalid';
83
+ message: string;
84
+ };
85
+ /**
86
+ * Child-side view supplied to one detached execution. It intentionally owns
87
+ * only cancellation, bounded message drains, and payload-free progress — no
88
+ * request/response object or host transport can leak into retained task state.
89
+ */
90
+ export interface SubagentTaskRuntime {
91
+ readonly taskId: string;
92
+ readonly signal: AbortSignal;
93
+ shouldPreempt(): boolean;
94
+ drain(boundary: SubagentTaskBoundary): InjectedMessage[];
95
+ closeTurn(): {
96
+ closed: boolean;
97
+ messages: InjectedMessage[];
98
+ };
99
+ reportProgress(event: SubagentUpdateEvent): void;
100
+ }
101
+ export interface SubagentTaskStartRequest {
102
+ scopeId: string;
103
+ idempotencyKey: string;
104
+ /** Host/SDK-owned parent run identity for durable lineage. */
105
+ parentRunId: string;
106
+ /** Executing parent agent, when the graph has a stable agent identity. */
107
+ parentAgentId?: string;
108
+ /** Provider tool-call identity that created this execution lease. */
109
+ parentToolCallId: string;
110
+ /**
111
+ * Untrusted child-thread selector supplied by the parent model. A
112
+ * continuation-capable store MUST validate ownership, scope, lineage, and
113
+ * `subagentType` before loading any saved messages.
114
+ */
115
+ threadId?: string;
116
+ /** Untrusted new user-turn text for host persistence and audit. */
117
+ input: string;
118
+ /** Stable hash of model-writable inputs used to reject conflicting replays. */
119
+ requestFingerprint?: string;
120
+ /** Execution shape selected from the host-provided subagent catalog. */
121
+ subagentKind: SubagentUpdateEvent['subagentKind'];
122
+ subagentType: string;
123
+ /**
124
+ * Starts one ephemeral execution lease. The canonical child transcript is
125
+ * returned so a host-owned store may persist it for a later fresh run;
126
+ * retaining a graph/checkpoint after terminal completion is unnecessary.
127
+ */
128
+ run(runtime: SubagentTaskRuntime, initialMessages?: BaseMessage[]): Promise<{
129
+ content: string;
130
+ messages?: BaseMessage[];
131
+ }>;
132
+ }
133
+ export type SubagentTaskStartResult = {
134
+ accepted: true;
135
+ isNew: boolean;
136
+ task: SubagentTaskSnapshot;
137
+ } | {
138
+ accepted: false;
139
+ reason: 'capacity';
140
+ } | {
141
+ accepted: false;
142
+ reason: 'thread_unavailable';
143
+ } | {
144
+ accepted: false;
145
+ reason: 'conflict';
146
+ task: SubagentTaskSnapshot;
147
+ };
148
+ /**
149
+ * Host-replaceable store contract used by the SDK's subagent tool. The store
150
+ * should normally outlive individual `Run` instances. Durable hosts may
151
+ * persist the transcript returned by `run` under the task/thread
152
+ * lineage and start a fresh execution for a later turn.
153
+ */
154
+ export interface SubagentTaskStore {
155
+ /**
156
+ * True only when `start` authorizes an existing `threadId`, loads its
157
+ * saved transcript, and supplies that transcript to `run`. The flag exposes
158
+ * the model-facing continuation field, so a store must fail closed for an
159
+ * unknown or unauthorized id rather than starting an empty child.
160
+ */
161
+ readonly supportsThreadContinuation?: boolean;
162
+ start(request: SubagentTaskStartRequest): SubagentTaskStartResult;
163
+ get(scopeId: string, taskId: string): SubagentTaskSnapshot | undefined;
164
+ list(scopeId: string): SubagentTaskSnapshot[];
165
+ claim(scopeId: string, taskId: string): SubagentTaskClaim;
166
+ control(scopeId: string, taskId: string, command: SubagentTaskControlCommand): SubagentTaskControlResult;
167
+ }
168
+ /** Trusted, host-selected task namespace. It is never model-writable. */
169
+ export interface SubagentTaskConfig {
170
+ store: SubagentTaskStore;
171
+ scopeId: string;
172
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.6.3",
3
+ "version": "3.6.5",
4
4
  "reova": {
5
5
  "enabled": true,
6
6
  "endpoint": "https://telemetry.reo.dev/data"