@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
@@ -17,3 +17,5 @@ export type {
17
17
  SubagentExecutorOptions,
18
18
  ChildGraphFactory,
19
19
  } from './SubagentExecutor';
20
+ export { InMemorySubagentTaskStore } from './InMemorySubagentTaskStore';
21
+ export type { InMemorySubagentTaskStoreOptions } from './InMemorySubagentTaskStore';
@@ -40,6 +40,7 @@ import type {
40
40
  TokenBudgetBreakdown,
41
41
  } from '@/types/run';
42
42
  import type { Providers, Callback, GraphNodeKeys } from '@/common';
43
+ import type { SubagentTaskConfig } from '@/types/subagentTasks';
43
44
  import type { StandardGraph, MultiAgentGraph } from '@/graphs';
44
45
  import type { ClientOptions } from '@/types/llm';
45
46
 
@@ -352,6 +353,12 @@ export type StandardGraphInput = {
352
353
  * they already flow through the registry's `CHAT_MODEL_END` handler.
353
354
  */
354
355
  subagentUsageSink?: SubagentUsageSink;
356
+ /**
357
+ * Optional host-owned process-local task namespace for detached subagents.
358
+ * Presence enables `run_in_background` on the subagent tool. Child graphs
359
+ * do not inherit it, keeping background nesting disabled for the MVP.
360
+ */
361
+ subagentTasks?: SubagentTaskConfig;
355
362
  /**
356
363
  * True when this graph IS a subagent child run (set by `SubagentExecutor`
357
364
  * when it constructs the child graph). Drives the hook-input `agentId`
@@ -363,10 +370,10 @@ export type StandardGraphInput = {
363
370
  */
364
371
  subagentScope?: boolean;
365
372
  /**
366
- * Cooperative preemption, forwarded from `RunConfig.preemption`. Only ever
367
- * set on the top-level graph: a steer targets the conversation, so subagent
368
- * children must run to completion and `buildChildInputs` does not propagate
369
- * this field.
373
+ * Cooperative preemption, forwarded from `RunConfig.preemption`. Ordinary
374
+ * child graphs do not inherit it. Detached subagent tasks may receive their
375
+ * own internal parent-control source so an interrupt can reuse the same
376
+ * provider-safe sealing path without targeting the top-level conversation.
370
377
  */
371
378
  preemption?: StreamPreemption;
372
379
  /**
@@ -780,6 +787,17 @@ export interface LangfuseConfig {
780
787
  * payloads. Defaults to the Langfuse SDK behavior.
781
788
  */
782
789
  mediaUploadEnabled?: boolean;
790
+ /**
791
+ * Extra HTTP headers sent on every Langfuse export request (OTLP trace
792
+ * export and media uploads), for self-hosted instances behind an
793
+ * authenticating proxy or gateway.
794
+ *
795
+ * Deployment-level only: one exporter is shared by every span routed to a
796
+ * destination, so these cannot carry per-request or per-user identity.
797
+ * Headers participate in destination identity — see
798
+ * `getLangfuseDestinationKey`.
799
+ */
800
+ additionalHeaders?: Record<string, string>;
783
801
  metadata?: Record<string, string | number | boolean | null | undefined>;
784
802
  /**
785
803
  * Internal OTLP span attributes to attach to Langfuse observations before
@@ -6,6 +6,7 @@ export * from './messages';
6
6
  export * from './run';
7
7
  export * from './skill';
8
8
  export * from './stream';
9
+ export * from './subagentTasks';
9
10
  export * from './tools';
10
11
  export * from './summarize';
11
12
  export * from './activityLabel';
package/src/types/run.ts CHANGED
@@ -10,6 +10,7 @@ import type {
10
10
  ToolOutputReferencesConfig,
11
11
  EagerEventToolExecutionConfig,
12
12
  } from '@/types/tools';
13
+ import type { SubagentTaskConfig } from '@/types/subagentTasks';
13
14
  import type { HumanInTheLoopConfig } from '@/types/hitl';
14
15
  import type { HookRegistry } from '@/hooks';
15
16
  import type * as s from '@/types/stream';
@@ -234,6 +235,11 @@ export type RunConfig = {
234
235
  * the registered `CHAT_MODEL_END` handler as usual.
235
236
  */
236
237
  subagentUsageSink?: g.SubagentUsageSink;
238
+ /**
239
+ * Trusted process-local task namespace for detached subagent execution.
240
+ * Omit to preserve foreground-only subagent behavior.
241
+ */
242
+ subagentTasks?: SubagentTaskConfig;
237
243
  /**
238
244
  * Pre-constructed hook registry for this run. Hooks fire at lifecycle
239
245
  * points in `processStream` (RunStart, UserPromptSubmit, Stop,
@@ -0,0 +1,162 @@
1
+ import type { BaseMessage } from '@langchain/core/messages';
2
+ import type { SubagentUpdateEvent } from './graph';
3
+ import type { InjectedMessage } from './tools';
4
+
5
+ /** Terminal and in-flight states for a detached subagent task. */
6
+ export type SubagentTaskStatus =
7
+ | 'running'
8
+ | 'completed'
9
+ | 'error'
10
+ | 'cancelled';
11
+
12
+ /** Where a pending parent message may enter the child run. */
13
+ export type SubagentTaskBoundary = 'preempt' | 'tool' | 'turn';
14
+
15
+ /** Parent-to-child control operations accepted while a task is running. */
16
+ export type SubagentTaskControlCommand =
17
+ | { action: 'steer' | 'queue' | 'interrupt'; message: string }
18
+ | { action: 'cancel' }
19
+ | { action: 'cancel_message'; controlId: string };
20
+
21
+ /** Small, payload-free progress view safe to retain between parent turns. */
22
+ export interface SubagentTaskProgress {
23
+ phase: SubagentUpdateEvent['phase'];
24
+ at: number;
25
+ eventCount: number;
26
+ label?: string;
27
+ }
28
+ /** Read-only task metadata. Results are exposed only through `claim`. */
29
+ export interface SubagentTaskSnapshot {
30
+ /** Handle for this child-thread execution lease within its trusted scope. */
31
+ taskId: string;
32
+ /**
33
+ * Stable logical thread identity shared by fresh execution leases. Required
34
+ * from stores that advertise `supportsThreadContinuation`; optional for
35
+ * legacy/process-local stores that do not expose a durable conversation.
36
+ */
37
+ threadId?: string;
38
+ subagentType: string;
39
+ status: SubagentTaskStatus;
40
+ createdAt: number;
41
+ updatedAt: number;
42
+ resultAvailable: boolean;
43
+ resultClaimed: boolean;
44
+ pendingControls: number;
45
+ progress?: SubagentTaskProgress;
46
+ error?: string;
47
+ }
48
+
49
+ export type SubagentTaskClaim =
50
+ | { status: 'running'; task: SubagentTaskSnapshot }
51
+ | { status: 'completed'; task: SubagentTaskSnapshot; result: string }
52
+ | { status: 'error'; task: SubagentTaskSnapshot; error: string }
53
+ | { status: 'cancelled'; task: SubagentTaskSnapshot; error: string }
54
+ | { status: 'claimed'; task: SubagentTaskSnapshot }
55
+ | { status: 'not_found' };
56
+
57
+ export type SubagentTaskControlResult =
58
+ | {
59
+ status: 'accepted';
60
+ task: SubagentTaskSnapshot;
61
+ controlId?: string;
62
+ }
63
+ | { status: 'cancelled'; task: SubagentTaskSnapshot }
64
+ | { status: 'not_running'; task: SubagentTaskSnapshot }
65
+ | { status: 'not_found' }
66
+ | { status: 'control_not_found'; task: SubagentTaskSnapshot }
67
+ | { status: 'invalid'; message: string };
68
+
69
+ /**
70
+ * Child-side view supplied to one detached execution. It intentionally owns
71
+ * only cancellation, bounded message drains, and payload-free progress — no
72
+ * request/response object or host transport can leak into retained task state.
73
+ */
74
+ export interface SubagentTaskRuntime {
75
+ readonly taskId: string;
76
+ readonly signal: AbortSignal;
77
+ shouldPreempt(): boolean;
78
+ drain(boundary: SubagentTaskBoundary): InjectedMessage[];
79
+ closeTurn(): { closed: boolean; messages: InjectedMessage[] };
80
+ reportProgress(event: SubagentUpdateEvent): void;
81
+ }
82
+
83
+ export interface SubagentTaskStartRequest {
84
+ scopeId: string;
85
+ idempotencyKey: string;
86
+ /** Host/SDK-owned parent run identity for durable lineage. */
87
+ parentRunId: string;
88
+ /** Executing parent agent, when the graph has a stable agent identity. */
89
+ parentAgentId?: string;
90
+ /** Provider tool-call identity that created this execution lease. */
91
+ parentToolCallId: string;
92
+ /**
93
+ * Untrusted child-thread selector supplied by the parent model. A
94
+ * continuation-capable store MUST validate ownership, scope, lineage, and
95
+ * `subagentType` before loading any saved messages.
96
+ */
97
+ threadId?: string;
98
+ /** Untrusted new user-turn text for host persistence and audit. */
99
+ input: string;
100
+ /** Stable hash of model-writable inputs used to reject conflicting replays. */
101
+ requestFingerprint?: string;
102
+ /** Execution shape selected from the host-provided subagent catalog. */
103
+ subagentKind: SubagentUpdateEvent['subagentKind'];
104
+ subagentType: string;
105
+ /**
106
+ * Starts one ephemeral execution lease. The canonical child transcript is
107
+ * returned so a host-owned store may persist it for a later fresh run;
108
+ * retaining a graph/checkpoint after terminal completion is unnecessary.
109
+ */
110
+ run(
111
+ runtime: SubagentTaskRuntime,
112
+ initialMessages?: BaseMessage[]
113
+ ): Promise<{
114
+ content: string;
115
+ messages?: BaseMessage[];
116
+ }>;
117
+ }
118
+
119
+ export type SubagentTaskStartResult =
120
+ | {
121
+ accepted: true;
122
+ isNew: boolean;
123
+ task: SubagentTaskSnapshot;
124
+ }
125
+ | { accepted: false; reason: 'capacity' }
126
+ | { accepted: false; reason: 'thread_unavailable' }
127
+ | {
128
+ accepted: false;
129
+ reason: 'conflict';
130
+ task: SubagentTaskSnapshot;
131
+ };
132
+
133
+ /**
134
+ * Host-replaceable store contract used by the SDK's subagent tool. The store
135
+ * should normally outlive individual `Run` instances. Durable hosts may
136
+ * persist the transcript returned by `run` under the task/thread
137
+ * lineage and start a fresh execution for a later turn.
138
+ */
139
+ export interface SubagentTaskStore {
140
+ /**
141
+ * True only when `start` authorizes an existing `threadId`, loads its
142
+ * saved transcript, and supplies that transcript to `run`. The flag exposes
143
+ * the model-facing continuation field, so a store must fail closed for an
144
+ * unknown or unauthorized id rather than starting an empty child.
145
+ */
146
+ readonly supportsThreadContinuation?: boolean;
147
+ start(request: SubagentTaskStartRequest): SubagentTaskStartResult;
148
+ get(scopeId: string, taskId: string): SubagentTaskSnapshot | undefined;
149
+ list(scopeId: string): SubagentTaskSnapshot[];
150
+ claim(scopeId: string, taskId: string): SubagentTaskClaim;
151
+ control(
152
+ scopeId: string,
153
+ taskId: string,
154
+ command: SubagentTaskControlCommand
155
+ ): SubagentTaskControlResult;
156
+ }
157
+
158
+ /** Trusted, host-selected task namespace. It is never model-writable. */
159
+ export interface SubagentTaskConfig {
160
+ store: SubagentTaskStore;
161
+ scopeId: string;
162
+ }