@librechat/agents 4.0.2 → 4.0.3

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 (156) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +3 -2
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/decisions/structuredChat.cjs +2 -8
  4. package/dist/cjs/decisions/structuredChat.cjs.map +1 -1
  5. package/dist/cjs/decisions/structuredOutput.cjs +18 -0
  6. package/dist/cjs/decisions/structuredOutput.cjs.map +1 -0
  7. package/dist/cjs/graphs/Graph.cjs +25 -9
  8. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  9. package/dist/cjs/llm/google/index.cjs +1 -1
  10. package/dist/cjs/llm/invoke.cjs +34 -12
  11. package/dist/cjs/llm/invoke.cjs.map +1 -1
  12. package/dist/cjs/llm/openai/index.cjs +7 -0
  13. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  14. package/dist/cjs/llm/providerTextBoundary.cjs +355 -0
  15. package/dist/cjs/llm/providerTextBoundary.cjs.map +1 -0
  16. package/dist/cjs/llm/providerTextChunk.cjs +14 -0
  17. package/dist/cjs/llm/providerTextChunk.cjs.map +1 -0
  18. package/dist/cjs/llm/providerTextControls.cjs +236 -0
  19. package/dist/cjs/llm/providerTextControls.cjs.map +1 -0
  20. package/dist/cjs/llm/stream/smoother.cjs +2 -1
  21. package/dist/cjs/llm/stream/smoother.cjs.map +1 -1
  22. package/dist/cjs/main.cjs +10 -1
  23. package/dist/cjs/protection/providerText.cjs +224 -0
  24. package/dist/cjs/protection/providerText.cjs.map +1 -0
  25. package/dist/cjs/protection/providerTextInput.cjs +25 -0
  26. package/dist/cjs/protection/providerTextInput.cjs.map +1 -0
  27. package/dist/cjs/run.cjs +7 -1
  28. package/dist/cjs/run.cjs.map +1 -1
  29. package/dist/cjs/stream.cjs +42 -14
  30. package/dist/cjs/stream.cjs.map +1 -1
  31. package/dist/cjs/summarization/node.cjs +26 -8
  32. package/dist/cjs/summarization/node.cjs.map +1 -1
  33. package/dist/cjs/tools/SubagentTool.cjs +11 -3
  34. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  35. package/dist/cjs/tools/ToolNode.cjs +6 -5
  36. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  37. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +2 -2
  38. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
  39. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +66 -16
  40. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  41. package/dist/cjs/tools/subagent/SubagentReplay.cjs +4 -2
  42. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
  43. package/dist/cjs/tools/subagent/childGraphConfig.cjs +3 -1
  44. package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -1
  45. package/dist/cjs/tools/subagent/diagnostics.cjs +48 -5
  46. package/dist/cjs/tools/subagent/diagnostics.cjs.map +1 -1
  47. package/dist/cjs/tools/subagent/hostArgs.cjs +214 -0
  48. package/dist/cjs/tools/subagent/hostArgs.cjs.map +1 -0
  49. package/dist/cjs/tools/subagent/index.cjs +1 -0
  50. package/dist/cjs/tools/toolErrorContent.cjs +1 -1
  51. package/dist/esm/agents/AgentContext.mjs +3 -2
  52. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  53. package/dist/esm/decisions/structuredChat.mjs +2 -8
  54. package/dist/esm/decisions/structuredChat.mjs.map +1 -1
  55. package/dist/esm/decisions/structuredOutput.mjs +18 -0
  56. package/dist/esm/decisions/structuredOutput.mjs.map +1 -0
  57. package/dist/esm/graphs/Graph.mjs +25 -9
  58. package/dist/esm/graphs/Graph.mjs.map +1 -1
  59. package/dist/esm/llm/google/index.mjs +1 -1
  60. package/dist/esm/llm/invoke.mjs +34 -12
  61. package/dist/esm/llm/invoke.mjs.map +1 -1
  62. package/dist/esm/llm/openai/index.mjs +7 -0
  63. package/dist/esm/llm/openai/index.mjs.map +1 -1
  64. package/dist/esm/llm/providerTextBoundary.mjs +355 -0
  65. package/dist/esm/llm/providerTextBoundary.mjs.map +1 -0
  66. package/dist/esm/llm/providerTextChunk.mjs +13 -0
  67. package/dist/esm/llm/providerTextChunk.mjs.map +1 -0
  68. package/dist/esm/llm/providerTextControls.mjs +230 -0
  69. package/dist/esm/llm/providerTextControls.mjs.map +1 -0
  70. package/dist/esm/llm/stream/smoother.mjs +2 -1
  71. package/dist/esm/llm/stream/smoother.mjs.map +1 -1
  72. package/dist/esm/main.mjs +5 -3
  73. package/dist/esm/protection/providerText.mjs +218 -0
  74. package/dist/esm/protection/providerText.mjs.map +1 -0
  75. package/dist/esm/protection/providerTextInput.mjs +24 -0
  76. package/dist/esm/protection/providerTextInput.mjs.map +1 -0
  77. package/dist/esm/run.mjs +7 -1
  78. package/dist/esm/run.mjs.map +1 -1
  79. package/dist/esm/stream.mjs +42 -14
  80. package/dist/esm/stream.mjs.map +1 -1
  81. package/dist/esm/summarization/node.mjs +26 -8
  82. package/dist/esm/summarization/node.mjs.map +1 -1
  83. package/dist/esm/tools/SubagentTool.mjs +11 -3
  84. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  85. package/dist/esm/tools/ToolNode.mjs +6 -5
  86. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  87. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +2 -2
  88. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
  89. package/dist/esm/tools/subagent/SubagentExecutor.mjs +66 -16
  90. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  91. package/dist/esm/tools/subagent/SubagentReplay.mjs +4 -2
  92. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
  93. package/dist/esm/tools/subagent/childGraphConfig.mjs +3 -1
  94. package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -1
  95. package/dist/esm/tools/subagent/diagnostics.mjs +46 -6
  96. package/dist/esm/tools/subagent/diagnostics.mjs.map +1 -1
  97. package/dist/esm/tools/subagent/hostArgs.mjs +207 -0
  98. package/dist/esm/tools/subagent/hostArgs.mjs.map +1 -0
  99. package/dist/esm/tools/subagent/index.mjs +1 -0
  100. package/dist/esm/tools/toolErrorContent.mjs +1 -1
  101. package/dist/types/decisions/structuredChat.d.ts +3 -2
  102. package/dist/types/decisions/structuredOutput.d.ts +4 -0
  103. package/dist/types/graphs/Graph.d.ts +6 -3
  104. package/dist/types/index.d.ts +2 -0
  105. package/dist/types/llm/invoke.d.ts +4 -1
  106. package/dist/types/llm/providerTextBoundary.d.ts +4 -0
  107. package/dist/types/llm/providerTextChunk.d.ts +7 -0
  108. package/dist/types/llm/providerTextControls.d.ts +18 -0
  109. package/dist/types/protection/providerText.d.ts +77 -0
  110. package/dist/types/protection/providerTextInput.d.ts +3 -0
  111. package/dist/types/run.d.ts +1 -0
  112. package/dist/types/tools/BashExecutor.d.ts +4 -0
  113. package/dist/types/tools/CodeExecutor.d.ts +4 -0
  114. package/dist/types/tools/ReadFile.d.ts +4 -0
  115. package/dist/types/tools/SkillTool.d.ts +4 -0
  116. package/dist/types/tools/SubagentTool.d.ts +2 -0
  117. package/dist/types/tools/ToolSearch.d.ts +4 -0
  118. package/dist/types/tools/search/schema.d.ts +4 -0
  119. package/dist/types/tools/subagent/SubagentExecutionRegistry.d.ts +2 -0
  120. package/dist/types/tools/subagent/SubagentExecutor.d.ts +10 -2
  121. package/dist/types/tools/subagent/SubagentReplay.d.ts +3 -1
  122. package/dist/types/tools/subagent/diagnostics.d.ts +27 -3
  123. package/dist/types/tools/subagent/hostArgs.d.ts +57 -0
  124. package/dist/types/tools/subagent/index.d.ts +3 -2
  125. package/dist/types/types/graph.d.ts +36 -0
  126. package/dist/types/types/run.d.ts +4 -2
  127. package/dist/types/types/tools.d.ts +2 -0
  128. package/package.json +4 -4
  129. package/src/agents/AgentContext.ts +3 -2
  130. package/src/decisions/structuredChat.ts +9 -15
  131. package/src/decisions/structuredOutput.ts +25 -0
  132. package/src/graphs/Graph.ts +53 -9
  133. package/src/index.ts +7 -0
  134. package/src/llm/invoke.ts +48 -7
  135. package/src/llm/openai/index.ts +8 -0
  136. package/src/llm/providerTextBoundary.ts +446 -0
  137. package/src/llm/providerTextChunk.ts +15 -0
  138. package/src/llm/providerTextControls.ts +173 -0
  139. package/src/llm/stream/smoother.ts +4 -2
  140. package/src/protection/providerText.ts +325 -0
  141. package/src/protection/providerTextInput.ts +21 -0
  142. package/src/run.ts +9 -0
  143. package/src/stream.ts +33 -7
  144. package/src/summarization/node.ts +32 -14
  145. package/src/tools/SubagentTool.ts +14 -3
  146. package/src/tools/ToolNode.ts +7 -3
  147. package/src/tools/subagent/SubagentExecutionRegistry.ts +6 -2
  148. package/src/tools/subagent/SubagentExecutor.ts +145 -18
  149. package/src/tools/subagent/SubagentReplay.ts +10 -3
  150. package/src/tools/subagent/childGraphConfig.ts +12 -1
  151. package/src/tools/subagent/diagnostics.ts +98 -6
  152. package/src/tools/subagent/hostArgs.ts +413 -0
  153. package/src/tools/subagent/index.ts +9 -0
  154. package/src/types/graph.ts +41 -0
  155. package/src/types/run.ts +4 -2
  156. package/src/types/tools.ts +6 -1
@@ -0,0 +1,77 @@
1
+ export declare const PROVIDER_TEXT_PROTECTION_VERSION = 1;
2
+ export type ProviderTextProtectionErrorCode = 'blocked' | 'unavailable' | 'timeout' | 'overflow' | 'cancelled' | 'unsupported' | 'incompatible';
3
+ export type ProviderTextProtectionResult = {
4
+ readonly version: 1;
5
+ readonly ok: true;
6
+ readonly value: {
7
+ readonly content: string;
8
+ readonly replacements: number;
9
+ readonly categories: readonly {
10
+ readonly category: string;
11
+ readonly count: number;
12
+ }[];
13
+ };
14
+ } | {
15
+ readonly version: 1;
16
+ readonly ok: false;
17
+ readonly error: {
18
+ readonly code: ProviderTextProtectionErrorCode;
19
+ };
20
+ };
21
+ /** Trusted host adapter. Classification must reject code, JSON and ambiguous text. */
22
+ export interface ProviderTextProtection {
23
+ readonly version: 1;
24
+ readonly timeoutMs: number;
25
+ readonly maxAttemptBytes: number;
26
+ /** Shared across all attempts using this policy, including child graphs. */
27
+ readonly maxBufferedBytes: number;
28
+ readonly classify: (content: string) => 'prose' | 'unsupported';
29
+ readonly inspect: (input: {
30
+ readonly version: 1;
31
+ readonly content: string;
32
+ readonly target: {
33
+ readonly source: 'message';
34
+ readonly field: 'text';
35
+ readonly provenance: 'model';
36
+ };
37
+ readonly signal: AbortSignal;
38
+ }) => ProviderTextProtectionResult | Promise<ProviderTextProtectionResult>;
39
+ }
40
+ export declare class ProviderTextProtectionError extends Error {
41
+ readonly code: ProviderTextProtectionErrorCode;
42
+ constructor(code: ProviderTextProtectionErrorCode);
43
+ }
44
+ /** Internal control flow, never a host policy decision or public capability. */
45
+ export declare function createProviderTextRestartCancellation(): ProviderTextProtectionError;
46
+ export declare function isProviderTextRestartCancellation(error: unknown): boolean;
47
+ /** Provider smoothing must stay lazy while the release boundary owns raw text. */
48
+ export declare function isProtectedProviderTextSignal(signal?: AbortSignal): boolean;
49
+ export declare function validateProviderTextProtection(policy: ProviderTextProtection): void;
50
+ /** A lease stays charged while a cancellation-ignoring producer/handler still owns raw text. */
51
+ export declare class ProviderTextAttempt {
52
+ private readonly policy;
53
+ private readonly parent?;
54
+ private readonly controller;
55
+ private readonly budget;
56
+ private readonly deadline;
57
+ private bytes;
58
+ private textLength;
59
+ private readonly fragments;
60
+ private readonly pending;
61
+ private readonly timer;
62
+ private readonly abort;
63
+ private finished;
64
+ constructor(policy: ProviderTextProtection, parent?: AbortSignal | undefined);
65
+ get signal(): AbortSignal;
66
+ check(): void;
67
+ private charge;
68
+ append(text: string, cumulativeReplay?: boolean): void;
69
+ /** Compare buffered fragments without allocating an uncharged joined copy. */
70
+ private hasCandidatePrefix;
71
+ matchesText(text: string): boolean;
72
+ retain(bytes: number): void;
73
+ observeChunk(): void;
74
+ wait<T>(work: Promise<T>): Promise<T>;
75
+ release(): Promise<string>;
76
+ finish(): void;
77
+ }
@@ -0,0 +1,3 @@
1
+ /** Internal provenance for the SDK's pure instruction transform, not a host capability. */
2
+ export declare function markProviderTextInput<T extends object>(input: T): T;
3
+ export declare function isProviderTextInput(input: object): boolean;
@@ -21,6 +21,7 @@ export declare class Run<_T extends t.BaseGraphState> {
21
21
  private subagentUsageSink?;
22
22
  private preemption?;
23
23
  private maxStopContinuations;
24
+ private providerTextProtection?;
24
25
  private streamLimits?;
25
26
  private subagentTasks?;
26
27
  private subagentContext?;
@@ -11,6 +11,8 @@ export declare const BashExecutionToolSchema: {
11
11
  readonly properties?: Record<string, t.JsonSchemaType>;
12
12
  readonly required?: string[];
13
13
  readonly description?: string;
14
+ readonly pattern?: string;
15
+ readonly maxLength?: number;
14
16
  readonly additionalProperties?: boolean | t.JsonSchemaType;
15
17
  };
16
18
  readonly command: {
@@ -89,6 +91,8 @@ export declare const BashExecutionToolDefinition: {
89
91
  readonly properties?: Record<string, t.JsonSchemaType>;
90
92
  readonly required?: string[];
91
93
  readonly description?: string;
94
+ readonly pattern?: string;
95
+ readonly maxLength?: number;
92
96
  readonly additionalProperties?: boolean | t.JsonSchemaType;
93
97
  };
94
98
  readonly command: {
@@ -23,6 +23,8 @@ export declare const CodeExecutionToolSchema: {
23
23
  readonly properties?: Record<string, t.JsonSchemaType>;
24
24
  readonly required?: string[];
25
25
  readonly description?: string;
26
+ readonly pattern?: string;
27
+ readonly maxLength?: number;
26
28
  readonly additionalProperties?: boolean | t.JsonSchemaType;
27
29
  };
28
30
  readonly lang: {
@@ -107,6 +109,8 @@ export declare const CodeExecutionToolDefinition: {
107
109
  readonly properties?: Record<string, t.JsonSchemaType>;
108
110
  readonly required?: string[];
109
111
  readonly description?: string;
112
+ readonly pattern?: string;
113
+ readonly maxLength?: number;
110
114
  readonly additionalProperties?: boolean | t.JsonSchemaType;
111
115
  };
112
116
  readonly lang: {
@@ -11,6 +11,8 @@ export declare const ReadFileToolSchema: {
11
11
  readonly properties?: Record<string, import("..").JsonSchemaType>;
12
12
  readonly required?: string[];
13
13
  readonly description?: string;
14
+ readonly pattern?: string;
15
+ readonly maxLength?: number;
14
16
  readonly additionalProperties?: boolean | import("..").JsonSchemaType;
15
17
  };
16
18
  readonly path: {
@@ -33,6 +35,8 @@ export declare const ReadFileToolDefinition: {
33
35
  readonly properties?: Record<string, import("..").JsonSchemaType>;
34
36
  readonly required?: string[];
35
37
  readonly description?: string;
38
+ readonly pattern?: string;
39
+ readonly maxLength?: number;
36
40
  readonly additionalProperties?: boolean | import("..").JsonSchemaType;
37
41
  };
38
42
  readonly path: {
@@ -16,6 +16,8 @@ export declare const SkillToolSchema: {
16
16
  readonly properties?: Record<string, import("..").JsonSchemaType>;
17
17
  readonly required?: string[];
18
18
  readonly description?: string;
19
+ readonly pattern?: string;
20
+ readonly maxLength?: number;
19
21
  readonly additionalProperties?: boolean | import("..").JsonSchemaType;
20
22
  };
21
23
  readonly skillName: {
@@ -42,6 +44,8 @@ export declare const SkillToolDefinition: {
42
44
  readonly properties?: Record<string, import("..").JsonSchemaType>;
43
45
  readonly required?: string[];
44
46
  readonly description?: string;
47
+ readonly pattern?: string;
48
+ readonly maxLength?: number;
45
49
  readonly additionalProperties?: boolean | import("..").JsonSchemaType;
46
50
  };
47
51
  readonly skillName: {
@@ -13,6 +13,8 @@ export declare const SubagentToolSchema: {
13
13
  readonly properties?: Record<string, JsonSchemaType>;
14
14
  readonly required?: string[];
15
15
  readonly description?: string;
16
+ readonly pattern?: string;
17
+ readonly maxLength?: number;
16
18
  readonly additionalProperties?: boolean | JsonSchemaType;
17
19
  };
18
20
  readonly description: {
@@ -13,6 +13,8 @@ export declare const ToolSearchToolSchema: {
13
13
  readonly properties?: Record<string, t.JsonSchemaType>;
14
14
  readonly required?: string[];
15
15
  readonly description?: string;
16
+ readonly pattern?: string;
17
+ readonly maxLength?: number;
16
18
  readonly additionalProperties?: boolean | t.JsonSchemaType;
17
19
  };
18
20
  readonly query: {
@@ -64,6 +66,8 @@ export declare const ToolSearchToolDefinition: {
64
66
  readonly properties?: Record<string, t.JsonSchemaType>;
65
67
  readonly required?: string[];
66
68
  readonly description?: string;
69
+ readonly pattern?: string;
70
+ readonly maxLength?: number;
67
71
  readonly additionalProperties?: boolean | t.JsonSchemaType;
68
72
  };
69
73
  readonly query: {
@@ -43,6 +43,8 @@ export declare const WebSearchToolSchema: {
43
43
  readonly properties?: Record<string, import("../..").JsonSchemaType>;
44
44
  readonly required?: string[];
45
45
  readonly description?: string;
46
+ readonly pattern?: string;
47
+ readonly maxLength?: number;
46
48
  readonly additionalProperties?: boolean | import("../..").JsonSchemaType;
47
49
  };
48
50
  readonly query: {
@@ -88,6 +90,8 @@ export declare const WebSearchToolDefinition: {
88
90
  readonly properties?: Record<string, import("../..").JsonSchemaType>;
89
91
  readonly required?: string[];
90
92
  readonly description?: string;
93
+ readonly pattern?: string;
94
+ readonly maxLength?: number;
91
95
  readonly additionalProperties?: boolean | import("../..").JsonSchemaType;
92
96
  };
93
97
  readonly query: {
@@ -44,6 +44,8 @@ export type SubagentInvocationBinding = Readonly<{
44
44
  description: string;
45
45
  subagentType: string;
46
46
  configId?: string;
47
+ /** Value-free identity of the call's validated host arguments. */
48
+ hostArgsDigest?: string;
47
49
  }>;
48
50
  export type SubagentSettlementBinding = Readonly<{
49
51
  definitionAuthority: 'provisional' | 'effective';
@@ -1,9 +1,9 @@
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, SubagentContextAdapter, SubagentContextResult, SubagentTaskConfig, SubagentTaskRuntime, SubagentUsageSink, TokenCounter } from '@/types';
4
+ import type { MultiAgentGraphState, HumanInTheLoopConfig, StandardGraphInput, ExecutableSubagentConfigEntry, SubagentExecutionContext, SubagentContextAdapter, SubagentContextResult, SubagentTaskConfig, SubagentTaskRuntime, SubagentHostArgs, SubagentUsageSink, TokenCounter } from '@/types';
5
+ import type { SubagentResolutionPhase, SubagentResolutionCause, SubagentHostArgumentFailure, SubagentResolutionFailureHandler } from './diagnostics';
5
6
  import type { SubagentResumeManifest, SettledSubagentToolOutput } from './SubagentReplay';
6
- import type { SubagentResolutionPhase, SubagentResolutionCause, SubagentResolutionFailureHandler } from './diagnostics';
7
7
  import type { GraphFactory } from '@/graphs/graphFactory';
8
8
  import type { StandardGraph } from '@/graphs/Graph';
9
9
  import { HookRegistry } from '@/hooks';
@@ -71,6 +71,11 @@ export type SubagentExecuteParams = {
71
71
  taskRuntime?: SubagentTaskRuntime;
72
72
  /** Host-restored child transcript for a fresh continuation run. @internal */
73
73
  initialMessages?: BaseMessage[];
74
+ /**
75
+ * Values for the selected subagent's declared `hostArgs`. Checked against
76
+ * the declaration before an execution opens, then bound to it.
77
+ */
78
+ hostArgs?: SubagentHostArgs;
74
79
  };
75
80
  export type SubagentExecuteResult = SubagentContextResult & {
76
81
  /** Tagged internal failure; foreground callers retain the legacy content. */
@@ -79,6 +84,7 @@ export type SubagentExecuteResult = SubagentContextResult & {
79
84
  resolutionFailure?: {
80
85
  phase: SubagentResolutionPhase;
81
86
  cause: SubagentResolutionCause;
87
+ hostArgument?: SubagentHostArgumentFailure;
82
88
  };
83
89
  /** Completed child work whose host projection must be retried without re-execution. */
84
90
  retryableDelivery?: true;
@@ -120,6 +126,7 @@ export type SubagentExecutorOptions = {
120
126
  * graph's own resolved limits; without this the child would silently
121
127
  * revert to the defaults.
122
128
  */
129
+ providerTextProtection?: StandardGraphInput['providerTextProtection'];
123
130
  streamLimits?: StandardGraphInput['streamLimits'];
124
131
  humanInTheLoop?: HumanInTheLoopConfig;
125
132
  /** Shared durable saver used to recover outer tool lifecycle results before
@@ -187,6 +194,7 @@ export declare class SubagentExecutor {
187
194
  private readonly executionContext;
188
195
  private readonly langfuse?;
189
196
  private readonly tokenCounter?;
197
+ private readonly providerTextProtection?;
190
198
  private readonly streamLimits?;
191
199
  private readonly humanInTheLoop?;
192
200
  private readonly checkpointer?;
@@ -1,8 +1,8 @@
1
1
  import type { ToolCall, ToolMessage } from '@langchain/core/messages/tool';
2
2
  import type { RunnableConfig } from '@langchain/core/runnables';
3
+ import type { FadingTier, FadingTiers, RunStepResumeState, ToolSessionContext } from '@/types';
3
4
  import type { ToolOutputReferenceState } from '@/tools/toolOutputReferences';
4
5
  import type { ToolApprovalReplaySnapshot } from '@/hooks';
5
- import type { FadingTier, FadingTiers, 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";
@@ -56,6 +56,8 @@ export interface SubagentResumeExecution {
56
56
  subagentType?: string;
57
57
  /** Lazy child revision bound when this execution first resolved. */
58
58
  configId?: string;
59
+ /** SHA-256 identity of the host arguments bound to this execution; never the values. */
60
+ hostArgsDigest?: string;
59
61
  approvalExecutionScope: string;
60
62
  checkpoints: SubagentCheckpointReference[];
61
63
  graphState: SubagentGraphResumeState;
@@ -1,14 +1,33 @@
1
+ import type { SubagentHostArgs } from '@/types/graph';
1
2
  import { SubagentSettlementBindingError, SubagentDefinitionBindingError, SubagentInvocationBindingError, SubagentExecutionInvalidatedError } from './SubagentExecutionRegistry';
2
3
  import { describeCodeApiError } from '@/tools/diagnostics';
3
4
  /** Which step of child start-up failed: execution identity, then host config resolution. */
4
5
  export type SubagentResolutionPhase = 'identity' | 'config';
5
- declare const SUBAGENT_ERROR_TYPES: readonly [readonly ["SubagentExecutionInvalidatedError", typeof SubagentExecutionInvalidatedError], readonly ["SubagentDefinitionBindingError", typeof SubagentDefinitionBindingError], readonly ["SubagentInvocationBindingError", typeof SubagentInvocationBindingError], readonly ["SubagentSettlementBindingError", typeof SubagentSettlementBindingError]];
6
+ /** Why a host resolver refused a declared host argument value. */
7
+ export type SubagentHostArgumentRejection = 'unavailable' | 'not_allowed';
8
+ /**
9
+ * Thrown by a lazy resolver to refuse one declared host argument value. The
10
+ * parent model receives a fixed message naming the argument; the value and
11
+ * any error text stay private.
12
+ */
13
+ export declare class SubagentHostArgumentError extends Error {
14
+ readonly argument: string;
15
+ readonly rejection: SubagentHostArgumentRejection;
16
+ constructor(argument: string, rejection: SubagentHostArgumentRejection);
17
+ }
18
+ /** Safe host-argument refusal retained across the detached delivery boundary. */
19
+ export type SubagentHostArgumentFailure = {
20
+ argument: string;
21
+ rejection: SubagentHostArgumentRejection;
22
+ };
23
+ declare const SUBAGENT_ERROR_TYPES: readonly [readonly ["SubagentHostArgumentError", typeof SubagentHostArgumentError], readonly ["SubagentExecutionInvalidatedError", typeof SubagentExecutionInvalidatedError], readonly ["SubagentDefinitionBindingError", typeof SubagentDefinitionBindingError], readonly ["SubagentInvocationBindingError", typeof SubagentInvocationBindingError], readonly ["SubagentSettlementBindingError", typeof SubagentSettlementBindingError]];
6
24
  type SubagentErrorLabel = (typeof SUBAGENT_ERROR_TYPES)[number][0] | ReturnType<typeof describeCodeApiError>['type'];
7
25
  declare const SUBAGENT_RESOLUTION_MESSAGES: {
8
26
  readonly workspace_unavailable: "Subagent error: Workspace unavailable. Retry later or choose another workspace.";
9
27
  readonly agent_unavailable: "Subagent error: Agent not found or not accessible.";
10
28
  readonly model_unavailable: "Subagent error: Model or provider unavailable.";
11
29
  readonly configuration_changed: "Subagent error: Subagent configuration changed. Start a new execution.";
30
+ readonly host_argument_rejected: "Subagent error: A requested subagent argument is not available. Omit it to let the host choose, or pass a different value.";
12
31
  readonly unknown: "Subagent error: Unable to initialize the selected subagent.";
13
32
  };
14
33
  /** Host classifications accepted at the public failure boundary. */
@@ -34,11 +53,16 @@ export type SubagentResolutionDiagnostic = {
34
53
  /** The original error is private. Return a classification, never error text. */
35
54
  export type SubagentResolutionFailureHandler = (detail: Readonly<SubagentResolutionDiagnostic>, error: unknown) => SubagentResolutionCause | void;
36
55
  export declare function getSubagentResolutionFailureMessage(cause: SubagentResolutionCause): SubagentResolutionDiagnostic['message'];
56
+ /** Returns a resolver's typed host-argument refusal when its name is safe to show. */
57
+ export declare function getSubagentHostArgumentFailure(error: unknown, suppliedHostArgs: SubagentHostArgs | undefined): SubagentHostArgumentFailure | undefined;
58
+ /** Model-facing message for a refused host argument. */
59
+ export declare function getSubagentHostArgumentFailureMessage(failure: SubagentHostArgumentFailure): string;
37
60
  /** Safe typed failure retained when detached execution crosses the host boundary. */
38
61
  export declare class SubagentResolutionError extends Error {
39
62
  readonly phase: SubagentResolutionPhase;
40
63
  readonly resolutionCause: SubagentResolutionCause;
41
- constructor(phase: SubagentResolutionPhase, cause: SubagentResolutionCause);
64
+ readonly hostArgument?: SubagentHostArgumentFailure;
65
+ constructor(phase: SubagentResolutionPhase, cause: SubagentResolutionCause, hostArgument?: SubagentHostArgumentFailure);
42
66
  }
43
- export declare function logSubagentResolutionFailure(phase: SubagentResolutionPhase, subagentType: string, signal: AbortSignal, error: unknown, context?: SubagentResolutionContext, onResolutionFailure?: SubagentResolutionFailureHandler): SubagentResolutionDiagnostic;
67
+ export declare function logSubagentResolutionFailure(phase: SubagentResolutionPhase, subagentType: string, signal: AbortSignal, error: unknown, context?: SubagentResolutionContext, onResolutionFailure?: SubagentResolutionFailureHandler, suppliedHostArgs?: SubagentHostArgs): SubagentResolutionDiagnostic;
44
68
  export {};
@@ -0,0 +1,57 @@
1
+ import type { SubagentHostArgs, SubagentHostArgSpec, SubagentHostArgSpecs } from '@/types/graph';
2
+ import type { JsonSchemaType } from '@/types/tools';
3
+ /** Bounds on host-declared subagent call arguments and their values. */
4
+ export declare const SUBAGENT_HOST_ARG_LIMITS: Readonly<{
5
+ argsPerSubagent: 8;
6
+ distinctArgs: 16;
7
+ enumValues: 64;
8
+ mergedEnumValues: 256;
9
+ valueLength: 256;
10
+ descriptionLength: 1024;
11
+ }>;
12
+ /** Any subagent entry that may declare host arguments. */
13
+ export type SubagentHostArgDeclaration = {
14
+ type: string;
15
+ hostArgs?: SubagentHostArgSpecs;
16
+ };
17
+ export type SubagentHostArgsResult = {
18
+ ok: true;
19
+ hostArgs?: SubagentHostArgs;
20
+ } | {
21
+ ok: false;
22
+ message: string;
23
+ };
24
+ type HostArgEntry = readonly [string, SubagentHostArgSpec];
25
+ /** A name a host may declare: lowercase snake case, not a built-in subagent argument. */
26
+ export declare function isSubagentHostArgName(name: string): boolean;
27
+ /**
28
+ * Returns a subagent's validated host argument declarations in declaration
29
+ * order. Throws on a malformed or oversized declaration.
30
+ */
31
+ export declare function getSubagentHostArgSpecs(config: SubagentHostArgDeclaration): readonly HostArgEntry[];
32
+ /** Every host argument name declared by at least one subagent. */
33
+ export declare function collectSubagentHostArgNames(configs: readonly SubagentHostArgDeclaration[]): ReadonlySet<string>;
34
+ /**
35
+ * Builds one optional tool property per declared host argument plus a
36
+ * per-type summary of the values each subagent accepts. The first
37
+ * declaration's description wins; enums are unioned across subagents.
38
+ */
39
+ export declare function buildSubagentHostArgProperties(configs: readonly SubagentHostArgDeclaration[]): {
40
+ properties: Record<string, JsonSchemaType>;
41
+ summaries: ReadonlyMap<string, string>;
42
+ };
43
+ /**
44
+ * Reads the declared host argument properties from raw tool input. Missing,
45
+ * null, and blank values count as omitted; other non-string values are
46
+ * rejected rather than coerced.
47
+ */
48
+ export declare function pickSubagentHostArgInput(input: object, names: ReadonlySet<string>): SubagentHostArgsResult;
49
+ /**
50
+ * Checks call values against the selected subagent's declarations and
51
+ * returns them frozen in canonical key order. Rejects arguments the selected
52
+ * subagent does not declare, including ones declared by a sibling.
53
+ */
54
+ export declare function resolveSubagentHostArgs(config: SubagentHostArgDeclaration, hostArgs: SubagentHostArgs | undefined): SubagentHostArgsResult;
55
+ /** Opaque, value-free identity of a call's host arguments for replay records. */
56
+ export declare function getSubagentHostArgsDigest(hostArgs: SubagentHostArgs | undefined): string | undefined;
57
+ export {};
@@ -2,5 +2,6 @@ export { DEFAULT_SUBAGENT_DESCRIPTION, SubagentExecutor, filterSubagentResult, f
2
2
  export type { SubagentExecuteParams, SubagentExecuteResult, SubagentExecutorOptions, ChildGraphFactory, } from './SubagentExecutor';
3
3
  export { InMemorySubagentTaskStore } from './InMemorySubagentTaskStore';
4
4
  export type { InMemorySubagentTaskStoreOptions } from './InMemorySubagentTaskStore';
5
- export { SubagentResolutionError, getSubagentResolutionFailureMessage, } from './diagnostics';
6
- export type { SubagentResolutionPhase, SubagentResolutionCause, SubagentResolutionContext, SubagentResolutionDiagnostic, SubagentResolutionFailureHandler, } from './diagnostics';
5
+ export { SubagentResolutionError, SubagentHostArgumentError, getSubagentResolutionFailureMessage, getSubagentHostArgumentFailureMessage, } from './diagnostics';
6
+ export { SUBAGENT_HOST_ARG_LIMITS, buildSubagentHostArgProperties, resolveSubagentHostArgs, } from './hostArgs';
7
+ export type { SubagentHostArgumentFailure, SubagentHostArgumentRejection, SubagentResolutionPhase, SubagentResolutionCause, SubagentResolutionContext, SubagentResolutionDiagnostic, SubagentResolutionFailureHandler, } from './diagnostics';
@@ -1,3 +1,4 @@
1
+ import type { ProviderTextProtection } from '@/protection/providerText';
1
2
  import type { BaseMessage, AIMessageChunk, SystemMessage, UsageMetadata } from '@langchain/core/messages';
2
3
  import type { BindToolsInput } from '@langchain/core/language_models/chat_models';
3
4
  import type { START, StateGraph, StateGraphArgs } from '@langchain/langgraph';
@@ -287,6 +288,7 @@ export type ModelEndData = (StreamEventData & {
287
288
  }) | undefined;
288
289
  export type GraphTools = GenericTool[] | BindToolsInput[] | GoogleAIToolType[];
289
290
  export type StandardGraphInput = {
291
+ providerTextProtection?: ProviderTextProtection;
290
292
  runId?: string;
291
293
  signal?: AbortSignal;
292
294
  agents: AgentInputs[];
@@ -436,6 +438,26 @@ export interface SubagentResolveConfigurable {
436
438
  user?: Readonly<SubagentResolveUserContext>;
437
439
  user_id?: string;
438
440
  }
441
+ /**
442
+ * Optional string argument a host lets the parent model pass on a subagent
443
+ * call, such as where the child should run. The SDK checks the declared shape
444
+ * before resolution; the host still authorizes the value in its resolver.
445
+ */
446
+ export interface SubagentHostArgSpec {
447
+ /** Model-facing explanation of the argument and when to pass it. */
448
+ description: string;
449
+ /**
450
+ * Values this subagent accepts. Omit to accept a bounded free-form string,
451
+ * whose format the resolver must check.
452
+ */
453
+ enum?: readonly string[];
454
+ /** Maximum length of a free-form value (at most 256). */
455
+ maxLength?: number;
456
+ }
457
+ /** Host argument declarations keyed by tool-call property name. */
458
+ export type SubagentHostArgSpecs = Readonly<Record<string, SubagentHostArgSpec>>;
459
+ /** Validated host argument values from one subagent call. */
460
+ export type SubagentHostArgs = Readonly<Record<string, string>>;
439
461
  /** Runtime context supplied when a host lazily resolves a selected subagent. */
440
462
  export interface SubagentResolveContext {
441
463
  /** Stable subagent identity selected by the model. */
@@ -454,6 +476,13 @@ export interface SubagentResolveContext {
454
476
  signal: AbortSignal;
455
477
  /** Stable, sanitized host context from the parent tool invocation. */
456
478
  configurable?: Readonly<SubagentResolveConfigurable>;
479
+ /**
480
+ * Values the parent passed for this subagent's declared `hostArgs`, already
481
+ * checked against the declaration. Omitted when the call passed none. Bound
482
+ * to the execution: a reconstruction with different values is rejected
483
+ * before the resolver runs.
484
+ */
485
+ hostArgs?: SubagentHostArgs;
457
486
  }
458
487
  /** Host contract for resolving a selected subagent's full graph inputs. */
459
488
  export type SubagentAgentInputsResolver = (context: SubagentResolveContext) => Promise<AgentInputs>;
@@ -480,6 +509,12 @@ export interface SubagentConfig extends SubagentConfigBase {
480
509
  * `(context.executionId, context.descriptor.configId)`.
481
510
  */
482
511
  resolveAgentInputs?: SubagentAgentInputsResolver;
512
+ /**
513
+ * Optional per-call arguments the parent model may pass for this subagent,
514
+ * delivered to `resolveAgentInputs` as `context.hostArgs`. Only lazy
515
+ * configs accept them. Declaring none leaves the tool schema unchanged.
516
+ */
517
+ hostArgs?: SubagentHostArgSpecs;
483
518
  /** When true, reuse the parent's AgentInputs (context isolation without separate config). */
484
519
  self?: boolean;
485
520
  }
@@ -494,6 +529,7 @@ export interface GraphSubagentConfig extends SubagentConfigBase {
494
529
  kind: 'graph';
495
530
  configId?: never;
496
531
  resolveAgentInputs?: never;
532
+ hostArgs?: never;
497
533
  allowNested?: false;
498
534
  agents: AgentInputs[];
499
535
  /**
@@ -24,8 +24,9 @@ export type LegacyGraphConfig = BaseGraphConfig & {
24
24
  } & Omit<g.StandardGraphInput,
25
25
  /** `streamLimits` is excluded because legacy graphs receive limits only
26
26
  * via the top-level `RunConfig.streamLimits`; accepting the field here
27
- * would type-check but be silently ignored by `createLegacyGraph`. */
28
- 'provider' | 'clientOptions' | 'agents' | 'streamLimits'> & Omit<g.AgentInputs, 'provider' | 'clientOptions' | 'agentId'>;
27
+ * would type-check but be silently ignored by `createLegacyGraph`.
28
+ * Required provider-text protection also belongs only to RunConfig. */
29
+ 'provider' | 'clientOptions' | 'agents' | 'streamLimits' | 'providerTextProtection'> & Omit<g.AgentInputs, 'provider' | 'clientOptions' | 'agentId'>;
29
30
  export type SupervisedGraphConfig = BaseGraphConfig & {
30
31
  type: 'supervised';
31
32
  /** Enable supervised router; when false, fall back to standard loop */
@@ -317,6 +318,7 @@ export type RunConfig = {
317
318
  * tool-call argument byte cap is ON by default, the per-turn event cap is
318
319
  * opt-in. See {@link StreamLimits}.
319
320
  */
321
+ providerTextProtection?: g.StandardGraphInput['providerTextProtection'];
320
322
  streamLimits?: StreamLimits;
321
323
  returnContent?: boolean;
322
324
  tokenCounter?: TokenCounter;
@@ -502,6 +502,8 @@ export type JsonSchemaType = {
502
502
  properties?: Record<string, JsonSchemaType>;
503
503
  required?: string[];
504
504
  description?: string;
505
+ pattern?: string;
506
+ maxLength?: number;
505
507
  additionalProperties?: boolean | JsonSchemaType;
506
508
  };
507
509
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "4.0.2",
3
+ "version": "4.0.3",
4
4
  "reova": {
5
5
  "enabled": true,
6
6
  "endpoint": "https://telemetry.reo.dev/data"
@@ -329,7 +329,7 @@
329
329
  "uuid": "^11.1.1"
330
330
  },
331
331
  "peerDependencies": {
332
- "@anthropic-ai/sandbox-runtime": "^0.0.67"
332
+ "@anthropic-ai/sandbox-runtime": "^0.0.78"
333
333
  },
334
334
  "peerDependenciesMeta": {
335
335
  "@anthropic-ai/sandbox-runtime": {
@@ -337,7 +337,7 @@
337
337
  }
338
338
  },
339
339
  "devDependencies": {
340
- "@anthropic-ai/sandbox-runtime": "^0.0.67",
340
+ "@anthropic-ai/sandbox-runtime": "0.0.78",
341
341
  "@anthropic-ai/vertex-sdk": "^0.12.0",
342
342
  "@eslint/js": "^10.0.1",
343
343
  "@langchain/langgraph-checkpoint-mongodb": "^1.4.1",
@@ -360,7 +360,7 @@
360
360
  "mongodb-memory-server-core": "^11.2.0",
361
361
  "prettier": "^3.6.2",
362
362
  "ts-jest": "^29.4.12",
363
- "tsc-alias": "^1.8.10",
363
+ "tsc-alias": "^1.9.7",
364
364
  "tsdown": "^0.22.2",
365
365
  "tslib": "^2.6.3",
366
366
  "tsx": "^4.23.12",
@@ -58,6 +58,7 @@ import {
58
58
  import { isTokenCounterCacheCompatible } from '@/llm/tokenCounterCacheCompatibility';
59
59
  import { snapshotCompactionSemanticIndex } from '@/summarization/semanticIndex';
60
60
  import { createExactTokenCountCache } from '@/llm/contextPressureMeter';
61
+ import { markProviderTextInput } from '@/protection/providerTextInput';
61
62
  import { buildSummaryCarrierText } from '@/summarization/shared';
62
63
  import { createSchemaOnlyTools } from '@/tools/schema';
63
64
  import { apportionTokenCounts } from '@/utils/tokens';
@@ -960,7 +961,7 @@ export class AgentContext {
960
961
  : 0;
961
962
  }
962
963
 
963
- return RunnableLambda.from((messages: BaseMessage[]) => {
964
+ return markProviderTextInput(RunnableLambda.from((messages: BaseMessage[]) => {
964
965
  const prefix: BaseMessage[] = systemMessage ? [systemMessage] : [];
965
966
 
966
967
  // Build the non-system portion (summary + conversation), then apply
@@ -998,7 +999,7 @@ export class AgentContext {
998
999
  );
999
1000
  }
1000
1001
  return [...prefix, ...body];
1001
- }).withConfig({ runName: 'prompt' });
1002
+ })).withConfig({ runName: 'prompt' });
1002
1003
  }
1003
1004
 
1004
1005
  private buildSummaryHumanMessage(
@@ -6,7 +6,9 @@ import type {
6
6
  DecisionResult,
7
7
  DecisionRequest,
8
8
  } from './types';
9
+ import type { DecisionOutputMethod } from './structuredOutput';
9
10
  import { DecisionError, isDecisionObject, readDecisionUsage } from './types';
11
+ import { withDecisionStructuredOutput } from './structuredOutput';
10
12
  import { failureForStatus, retryAfterMs } from './transport';
11
13
  import { validateDecisionQuestions } from './questions';
12
14
  import { DECISION_PROMPT_PREFIX } from './traceMarker';
@@ -86,8 +88,8 @@ export interface StructuredChatDecisionModelOptions {
86
88
  model: BaseChatModel;
87
89
  modelId: string;
88
90
  providerId?: string;
89
- /** Verified OpenAI strict modes or Anthropic strict tool calling; other adapters fail closed. */
90
- method: 'jsonSchema' | 'functionCalling';
91
+ /** Verified OpenAI/Azure strict modes or Anthropic strict tools; other paths fail closed. */
92
+ method: DecisionOutputMethod;
91
93
  timeoutMs?: number;
92
94
  maxQuestions?: number;
93
95
  onAnswered?: (label: string, ms: number) => void;
@@ -299,19 +301,11 @@ export function createStructuredChatDecisionModel(
299
301
  }
300
302
  let structured: ReturnType<typeof model.withStructuredOutput>;
301
303
  try {
302
- const adapter = model._llmType();
303
- if (
304
- adapter !== 'openai' &&
305
- (adapter !== 'anthropic' || method !== 'functionCalling')
306
- ) {
307
- throw new Error('unverified strict decision model adapter');
308
- }
309
- structured = model.withStructuredOutput(decisionSchema(entries), {
310
- name: 'DecideQuestions',
311
- method,
312
- strict: true,
313
- includeRaw: true,
314
- });
304
+ structured = withDecisionStructuredOutput(
305
+ model,
306
+ decisionSchema(entries),
307
+ method
308
+ );
315
309
  } catch {
316
310
  throw new DecisionError(
317
311
  'unsupported_mode',