@librechat/agents 4.0.1 → 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 (245) 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/deadline.cjs +52 -0
  4. package/dist/cjs/decisions/deadline.cjs.map +1 -0
  5. package/dist/cjs/decisions/dialect.cjs +88 -0
  6. package/dist/cjs/decisions/dialect.cjs.map +1 -0
  7. package/dist/cjs/decisions/http.cjs +77 -0
  8. package/dist/cjs/decisions/http.cjs.map +1 -0
  9. package/dist/cjs/decisions/index.cjs +7 -0
  10. package/dist/cjs/decisions/presets.cjs +82 -0
  11. package/dist/cjs/decisions/presets.cjs.map +1 -0
  12. package/dist/cjs/decisions/questions.cjs +70 -0
  13. package/dist/cjs/decisions/questions.cjs.map +1 -0
  14. package/dist/cjs/decisions/structuredChat.cjs +172 -0
  15. package/dist/cjs/decisions/structuredChat.cjs.map +1 -0
  16. package/dist/cjs/decisions/structuredOutput.cjs +18 -0
  17. package/dist/cjs/decisions/structuredOutput.cjs.map +1 -0
  18. package/dist/cjs/decisions/traceMarker.cjs +6 -0
  19. package/dist/cjs/decisions/traceMarker.cjs.map +1 -0
  20. package/dist/cjs/decisions/transport.cjs +166 -0
  21. package/dist/cjs/decisions/transport.cjs.map +1 -0
  22. package/dist/cjs/decisions/types.cjs +44 -0
  23. package/dist/cjs/decisions/types.cjs.map +1 -0
  24. package/dist/cjs/graphs/Graph.cjs +28 -9
  25. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  26. package/dist/cjs/langfuseToolOutputTracing.cjs +6 -1
  27. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  28. package/dist/cjs/llm/google/index.cjs +1 -1
  29. package/dist/cjs/llm/invoke.cjs +34 -12
  30. package/dist/cjs/llm/invoke.cjs.map +1 -1
  31. package/dist/cjs/llm/openai/index.cjs +7 -0
  32. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  33. package/dist/cjs/llm/providerTextBoundary.cjs +355 -0
  34. package/dist/cjs/llm/providerTextBoundary.cjs.map +1 -0
  35. package/dist/cjs/llm/providerTextChunk.cjs +14 -0
  36. package/dist/cjs/llm/providerTextChunk.cjs.map +1 -0
  37. package/dist/cjs/llm/providerTextControls.cjs +236 -0
  38. package/dist/cjs/llm/providerTextControls.cjs.map +1 -0
  39. package/dist/cjs/llm/stream/smoother.cjs +2 -1
  40. package/dist/cjs/llm/stream/smoother.cjs.map +1 -1
  41. package/dist/cjs/main.cjs +49 -1
  42. package/dist/cjs/protection/providerText.cjs +224 -0
  43. package/dist/cjs/protection/providerText.cjs.map +1 -0
  44. package/dist/cjs/protection/providerTextInput.cjs +25 -0
  45. package/dist/cjs/protection/providerTextInput.cjs.map +1 -0
  46. package/dist/cjs/rerank/index.cjs +2 -0
  47. package/dist/cjs/rerank/search.cjs +45 -0
  48. package/dist/cjs/rerank/search.cjs.map +1 -0
  49. package/dist/cjs/rerank/systemone.cjs +70 -0
  50. package/dist/cjs/rerank/systemone.cjs.map +1 -0
  51. package/dist/cjs/run.cjs +11 -1
  52. package/dist/cjs/run.cjs.map +1 -1
  53. package/dist/cjs/stream.cjs +42 -14
  54. package/dist/cjs/stream.cjs.map +1 -1
  55. package/dist/cjs/summarization/node.cjs +26 -8
  56. package/dist/cjs/summarization/node.cjs.map +1 -1
  57. package/dist/cjs/tools/SubagentTool.cjs +11 -3
  58. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  59. package/dist/cjs/tools/ToolNode.cjs +6 -5
  60. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  61. package/dist/cjs/tools/search/rerankers.cjs +1 -0
  62. package/dist/cjs/tools/search/search.cjs +3 -3
  63. package/dist/cjs/tools/search/search.cjs.map +1 -1
  64. package/dist/cjs/tools/search/tool.cjs +4 -3
  65. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  66. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +13 -2
  67. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
  68. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +149 -26
  69. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  70. package/dist/cjs/tools/subagent/SubagentReplay.cjs +4 -2
  71. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
  72. package/dist/cjs/tools/subagent/childGraphConfig.cjs +3 -1
  73. package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -1
  74. package/dist/cjs/tools/subagent/diagnostics.cjs +88 -2
  75. package/dist/cjs/tools/subagent/diagnostics.cjs.map +1 -1
  76. package/dist/cjs/tools/subagent/hostArgs.cjs +214 -0
  77. package/dist/cjs/tools/subagent/hostArgs.cjs.map +1 -0
  78. package/dist/cjs/tools/subagent/index.cjs +2 -0
  79. package/dist/cjs/tools/toolErrorContent.cjs +1 -1
  80. package/dist/esm/agents/AgentContext.mjs +3 -2
  81. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  82. package/dist/esm/decisions/deadline.mjs +52 -0
  83. package/dist/esm/decisions/deadline.mjs.map +1 -0
  84. package/dist/esm/decisions/dialect.mjs +87 -0
  85. package/dist/esm/decisions/dialect.mjs.map +1 -0
  86. package/dist/esm/decisions/http.mjs +75 -0
  87. package/dist/esm/decisions/http.mjs.map +1 -0
  88. package/dist/esm/decisions/index.mjs +8 -0
  89. package/dist/esm/decisions/presets.mjs +77 -0
  90. package/dist/esm/decisions/presets.mjs.map +1 -0
  91. package/dist/esm/decisions/questions.mjs +67 -0
  92. package/dist/esm/decisions/questions.mjs.map +1 -0
  93. package/dist/esm/decisions/structuredChat.mjs +172 -0
  94. package/dist/esm/decisions/structuredChat.mjs.map +1 -0
  95. package/dist/esm/decisions/structuredOutput.mjs +18 -0
  96. package/dist/esm/decisions/structuredOutput.mjs.map +1 -0
  97. package/dist/esm/decisions/traceMarker.mjs +6 -0
  98. package/dist/esm/decisions/traceMarker.mjs.map +1 -0
  99. package/dist/esm/decisions/transport.mjs +164 -0
  100. package/dist/esm/decisions/transport.mjs.map +1 -0
  101. package/dist/esm/decisions/types.mjs +39 -0
  102. package/dist/esm/decisions/types.mjs.map +1 -0
  103. package/dist/esm/graphs/Graph.mjs +28 -9
  104. package/dist/esm/graphs/Graph.mjs.map +1 -1
  105. package/dist/esm/langfuseToolOutputTracing.mjs +6 -1
  106. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  107. package/dist/esm/llm/google/index.mjs +1 -1
  108. package/dist/esm/llm/invoke.mjs +34 -12
  109. package/dist/esm/llm/invoke.mjs.map +1 -1
  110. package/dist/esm/llm/openai/index.mjs +7 -0
  111. package/dist/esm/llm/openai/index.mjs.map +1 -1
  112. package/dist/esm/llm/providerTextBoundary.mjs +355 -0
  113. package/dist/esm/llm/providerTextBoundary.mjs.map +1 -0
  114. package/dist/esm/llm/providerTextChunk.mjs +13 -0
  115. package/dist/esm/llm/providerTextChunk.mjs.map +1 -0
  116. package/dist/esm/llm/providerTextControls.mjs +230 -0
  117. package/dist/esm/llm/providerTextControls.mjs.map +1 -0
  118. package/dist/esm/llm/stream/smoother.mjs +2 -1
  119. package/dist/esm/llm/stream/smoother.mjs.map +1 -1
  120. package/dist/esm/main.mjs +16 -2
  121. package/dist/esm/protection/providerText.mjs +218 -0
  122. package/dist/esm/protection/providerText.mjs.map +1 -0
  123. package/dist/esm/protection/providerTextInput.mjs +24 -0
  124. package/dist/esm/protection/providerTextInput.mjs.map +1 -0
  125. package/dist/esm/rerank/index.mjs +3 -0
  126. package/dist/esm/rerank/search.mjs +45 -0
  127. package/dist/esm/rerank/search.mjs.map +1 -0
  128. package/dist/esm/rerank/systemone.mjs +70 -0
  129. package/dist/esm/rerank/systemone.mjs.map +1 -0
  130. package/dist/esm/run.mjs +11 -1
  131. package/dist/esm/run.mjs.map +1 -1
  132. package/dist/esm/stream.mjs +42 -14
  133. package/dist/esm/stream.mjs.map +1 -1
  134. package/dist/esm/summarization/node.mjs +26 -8
  135. package/dist/esm/summarization/node.mjs.map +1 -1
  136. package/dist/esm/tools/SubagentTool.mjs +11 -3
  137. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  138. package/dist/esm/tools/ToolNode.mjs +6 -5
  139. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  140. package/dist/esm/tools/search/rerankers.mjs +1 -1
  141. package/dist/esm/tools/search/search.mjs +3 -3
  142. package/dist/esm/tools/search/search.mjs.map +1 -1
  143. package/dist/esm/tools/search/tool.mjs +4 -3
  144. package/dist/esm/tools/search/tool.mjs.map +1 -1
  145. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +13 -2
  146. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
  147. package/dist/esm/tools/subagent/SubagentExecutor.mjs +149 -26
  148. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  149. package/dist/esm/tools/subagent/SubagentReplay.mjs +4 -2
  150. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
  151. package/dist/esm/tools/subagent/childGraphConfig.mjs +3 -1
  152. package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -1
  153. package/dist/esm/tools/subagent/diagnostics.mjs +84 -3
  154. package/dist/esm/tools/subagent/diagnostics.mjs.map +1 -1
  155. package/dist/esm/tools/subagent/hostArgs.mjs +207 -0
  156. package/dist/esm/tools/subagent/hostArgs.mjs.map +1 -0
  157. package/dist/esm/tools/subagent/index.mjs +2 -0
  158. package/dist/esm/tools/toolErrorContent.mjs +1 -1
  159. package/dist/types/decisions/deadline.d.ts +3 -0
  160. package/dist/types/decisions/dialect.d.ts +11 -0
  161. package/dist/types/decisions/http.d.ts +22 -0
  162. package/dist/types/decisions/index.d.ts +10 -0
  163. package/dist/types/decisions/presets.d.ts +17 -0
  164. package/dist/types/decisions/questions.d.ts +8 -0
  165. package/dist/types/decisions/structuredChat.d.ts +17 -0
  166. package/dist/types/decisions/structuredOutput.d.ts +4 -0
  167. package/dist/types/decisions/traceMarker.d.ts +2 -0
  168. package/dist/types/decisions/transport.d.ts +29 -0
  169. package/dist/types/decisions/types.d.ts +119 -0
  170. package/dist/types/graphs/Graph.d.ts +7 -3
  171. package/dist/types/index.d.ts +4 -0
  172. package/dist/types/llm/invoke.d.ts +4 -1
  173. package/dist/types/llm/providerTextBoundary.d.ts +4 -0
  174. package/dist/types/llm/providerTextChunk.d.ts +7 -0
  175. package/dist/types/llm/providerTextControls.d.ts +18 -0
  176. package/dist/types/protection/providerText.d.ts +77 -0
  177. package/dist/types/protection/providerTextInput.d.ts +3 -0
  178. package/dist/types/rerank/index.d.ts +4 -0
  179. package/dist/types/rerank/search.d.ts +7 -0
  180. package/dist/types/rerank/systemone.d.ts +13 -0
  181. package/dist/types/rerank/types.d.ts +24 -0
  182. package/dist/types/run.d.ts +2 -0
  183. package/dist/types/tools/BashExecutor.d.ts +4 -0
  184. package/dist/types/tools/CodeExecutor.d.ts +4 -0
  185. package/dist/types/tools/ReadFile.d.ts +4 -0
  186. package/dist/types/tools/SkillTool.d.ts +4 -0
  187. package/dist/types/tools/SubagentTool.d.ts +2 -0
  188. package/dist/types/tools/ToolSearch.d.ts +4 -0
  189. package/dist/types/tools/search/schema.d.ts +4 -0
  190. package/dist/types/tools/search/types.d.ts +3 -1
  191. package/dist/types/tools/subagent/SubagentExecutionRegistry.d.ts +6 -0
  192. package/dist/types/tools/subagent/SubagentExecutor.d.ts +22 -1
  193. package/dist/types/tools/subagent/SubagentReplay.d.ts +3 -1
  194. package/dist/types/tools/subagent/diagnostics.d.ts +56 -8
  195. package/dist/types/tools/subagent/hostArgs.d.ts +57 -0
  196. package/dist/types/tools/subagent/index.d.ts +3 -0
  197. package/dist/types/types/graph.d.ts +39 -0
  198. package/dist/types/types/run.d.ts +6 -2
  199. package/dist/types/types/tools.d.ts +2 -0
  200. package/package.json +4 -4
  201. package/src/agents/AgentContext.ts +3 -2
  202. package/src/decisions/deadline.ts +92 -0
  203. package/src/decisions/dialect.ts +200 -0
  204. package/src/decisions/http.ts +175 -0
  205. package/src/decisions/index.ts +14 -0
  206. package/src/decisions/presets.ts +111 -0
  207. package/src/decisions/questions.ts +128 -0
  208. package/src/decisions/structuredChat.ts +358 -0
  209. package/src/decisions/structuredOutput.ts +25 -0
  210. package/src/decisions/traceMarker.ts +2 -0
  211. package/src/decisions/transport.ts +335 -0
  212. package/src/decisions/types.ts +193 -0
  213. package/src/graphs/Graph.ts +57 -9
  214. package/src/index.ts +9 -0
  215. package/src/langfuseToolOutputTracing.ts +8 -1
  216. package/src/llm/invoke.ts +48 -7
  217. package/src/llm/openai/index.ts +8 -0
  218. package/src/llm/providerTextBoundary.ts +446 -0
  219. package/src/llm/providerTextChunk.ts +15 -0
  220. package/src/llm/providerTextControls.ts +173 -0
  221. package/src/llm/stream/smoother.ts +4 -2
  222. package/src/protection/providerText.ts +325 -0
  223. package/src/protection/providerTextInput.ts +21 -0
  224. package/src/rerank/index.ts +4 -0
  225. package/src/rerank/search.ts +85 -0
  226. package/src/rerank/systemone.ts +140 -0
  227. package/src/rerank/types.ts +28 -0
  228. package/src/run.ts +13 -0
  229. package/src/stream.ts +33 -7
  230. package/src/summarization/node.ts +32 -14
  231. package/src/tools/SubagentTool.ts +14 -3
  232. package/src/tools/ToolNode.ts +7 -3
  233. package/src/tools/search/search.ts +4 -4
  234. package/src/tools/search/tool.ts +27 -25
  235. package/src/tools/search/types.ts +4 -1
  236. package/src/tools/subagent/SubagentExecutionRegistry.ts +27 -2
  237. package/src/tools/subagent/SubagentExecutor.ts +323 -28
  238. package/src/tools/subagent/SubagentReplay.ts +10 -3
  239. package/src/tools/subagent/childGraphConfig.ts +12 -1
  240. package/src/tools/subagent/diagnostics.ts +180 -9
  241. package/src/tools/subagent/hostArgs.ts +413 -0
  242. package/src/tools/subagent/index.ts +20 -0
  243. package/src/types/graph.ts +44 -0
  244. package/src/types/run.ts +6 -2
  245. package/src/types/tools.ts +6 -1
@@ -0,0 +1,207 @@
1
+ import { createHash } from "crypto";
2
+ //#region src/tools/subagent/hostArgs.ts
3
+ const SUBAGENT_HOST_ARG_LIMITS = Object.freeze({
4
+ argsPerSubagent: 8,
5
+ distinctArgs: 16,
6
+ enumValues: 64,
7
+ mergedEnumValues: 256,
8
+ valueLength: 256,
9
+ descriptionLength: 1024
10
+ });
11
+ const HOST_ARG_NAME_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
12
+ const FREE_FORM_SCHEMA_PATTERN = "^[^\\u0000-\\u001f\\u007f]*$";
13
+ const RESERVED_HOST_ARG_NAMES = new Set([
14
+ "intent",
15
+ "description",
16
+ "subagent_type",
17
+ "run_in_background",
18
+ "subagent_thread_id"
19
+ ]);
20
+ function isSubagentHostArgName(name) {
21
+ return HOST_ARG_NAME_PATTERN.test(name) && !RESERVED_HOST_ARG_NAMES.has(name);
22
+ }
23
+ function countCodePoints(value) {
24
+ let count = 0;
25
+ for (const _ of value) count += 1;
26
+ return count;
27
+ }
28
+ function hasControlCharacter(value) {
29
+ for (let i = 0; i < value.length; i++) {
30
+ const code = value.charCodeAt(i);
31
+ if (code < 32 || code === 127) return true;
32
+ }
33
+ return false;
34
+ }
35
+ function isBoundedText(value, maxLength) {
36
+ return typeof value === "string" && value.trim().length > 0 && countCodePoints(value) <= maxLength && !hasControlCharacter(value);
37
+ }
38
+ function getFreeFormMaxLength(spec) {
39
+ return spec.maxLength ?? SUBAGENT_HOST_ARG_LIMITS.valueLength;
40
+ }
41
+ function validateEnum(label, values) {
42
+ if (!Array.isArray(values) || values.length === 0 || values.length > SUBAGENT_HOST_ARG_LIMITS.enumValues) throw new Error(`${label} enum must list 1-${SUBAGENT_HOST_ARG_LIMITS.enumValues} values.`);
43
+ const seen = /* @__PURE__ */ new Set();
44
+ for (const value of values) {
45
+ if (!isBoundedText(value, SUBAGENT_HOST_ARG_LIMITS.valueLength)) throw new Error(`${label} enum values must be non-blank strings of at most ${SUBAGENT_HOST_ARG_LIMITS.valueLength} characters without control characters.`);
46
+ if (seen.has(value)) throw new Error(`${label} enum values must be unique.`);
47
+ seen.add(value);
48
+ }
49
+ }
50
+ function validateFreeForm(label, spec) {
51
+ const maxLength = getFreeFormMaxLength(spec);
52
+ if (!Number.isSafeInteger(maxLength) || maxLength < 1 || maxLength > SUBAGENT_HOST_ARG_LIMITS.valueLength) throw new Error(`${label} maxLength must be an integer from 1 to ${SUBAGENT_HOST_ARG_LIMITS.valueLength}.`);
53
+ }
54
+ function validateSpec(type, name, spec) {
55
+ const label = `Subagent "${type}" host argument "${name}"`;
56
+ if (!isSubagentHostArgName(name)) throw new Error(`${label} must match ${HOST_ARG_NAME_PATTERN.source} and must not reuse a built-in subagent argument name.`);
57
+ if (spec == null) throw new Error(`${label} must be an object.`);
58
+ if (spec.pattern !== void 0) throw new Error(`${label} cannot declare a pattern; validate the format in the resolver.`);
59
+ if (typeof spec.description !== "string" || spec.description.trim().length === 0 || spec.description.length > SUBAGENT_HOST_ARG_LIMITS.descriptionLength) throw new Error(`${label} needs a description of at most ${SUBAGENT_HOST_ARG_LIMITS.descriptionLength} characters.`);
60
+ if (spec.enum == null) {
61
+ validateFreeForm(label, spec);
62
+ return;
63
+ }
64
+ if (spec.maxLength != null) throw new Error(`${label} cannot combine enum with maxLength.`);
65
+ validateEnum(label, spec.enum);
66
+ }
67
+ function getSubagentHostArgSpecs(config) {
68
+ const { hostArgs } = config;
69
+ if (hostArgs == null) return [];
70
+ if (typeof hostArgs !== "object" || Array.isArray(hostArgs)) throw new Error(`Subagent "${config.type}" hostArgs must be an object.`);
71
+ const entries = Object.entries(hostArgs);
72
+ if (entries.length > SUBAGENT_HOST_ARG_LIMITS.argsPerSubagent) throw new Error(`Subagent "${config.type}" declares more than ${SUBAGENT_HOST_ARG_LIMITS.argsPerSubagent} host arguments.`);
73
+ for (const [name, spec] of entries) validateSpec(config.type, name, spec);
74
+ return entries;
75
+ }
76
+ function collectSubagentHostArgNames(configs) {
77
+ const names = /* @__PURE__ */ new Set();
78
+ for (const config of configs) for (const [name] of getSubagentHostArgSpecs(config)) names.add(name);
79
+ if (names.size > SUBAGENT_HOST_ARG_LIMITS.distinctArgs) throw new Error(`Subagents declare more than ${SUBAGENT_HOST_ARG_LIMITS.distinctArgs} distinct host arguments.`);
80
+ return names;
81
+ }
82
+ function mergeSpec(merged, name, spec) {
83
+ let entry = merged.get(name);
84
+ if (entry == null) {
85
+ entry = {
86
+ description: spec.description,
87
+ values: [],
88
+ seenValues: /* @__PURE__ */ new Set(),
89
+ freeForm: false,
90
+ maxLength: 0
91
+ };
92
+ merged.set(name, entry);
93
+ }
94
+ if (spec.enum == null) {
95
+ entry.freeForm = true;
96
+ entry.maxLength = Math.max(entry.maxLength, getFreeFormMaxLength(spec));
97
+ return;
98
+ }
99
+ for (const value of spec.enum) {
100
+ entry.maxLength = Math.max(entry.maxLength, countCodePoints(value));
101
+ if (!entry.seenValues.has(value)) {
102
+ entry.seenValues.add(value);
103
+ entry.values.push(value);
104
+ }
105
+ }
106
+ if (entry.values.length > SUBAGENT_HOST_ARG_LIMITS.mergedEnumValues) throw new Error(`Subagent host argument "${name}" lists more than ${SUBAGENT_HOST_ARG_LIMITS.mergedEnumValues} distinct values across subagents.`);
107
+ }
108
+ function toPropertySchema(entry) {
109
+ if (!entry.freeForm) return {
110
+ type: "string",
111
+ description: entry.description,
112
+ enum: entry.values
113
+ };
114
+ return {
115
+ type: "string",
116
+ description: entry.description,
117
+ maxLength: entry.maxLength,
118
+ pattern: FREE_FORM_SCHEMA_PATTERN
119
+ };
120
+ }
121
+ function summarizeSpecs(entries) {
122
+ return entries.map(([name, spec]) => `${name}: ${spec.enum == null ? `any text up to ${getFreeFormMaxLength(spec)} characters` : spec.enum.join(" | ")}`).join("; ");
123
+ }
124
+ function buildSubagentHostArgProperties(configs) {
125
+ const merged = /* @__PURE__ */ new Map();
126
+ const summaries = /* @__PURE__ */ new Map();
127
+ for (const config of configs) {
128
+ const entries = getSubagentHostArgSpecs(config);
129
+ if (entries.length === 0) continue;
130
+ for (const [name, spec] of entries) mergeSpec(merged, name, spec);
131
+ summaries.set(config.type, summarizeSpecs(entries));
132
+ }
133
+ if (merged.size > SUBAGENT_HOST_ARG_LIMITS.distinctArgs) throw new Error(`Subagents declare more than ${SUBAGENT_HOST_ARG_LIMITS.distinctArgs} distinct host arguments.`);
134
+ const properties = {};
135
+ for (const [name, entry] of merged) properties[name] = toPropertySchema(entry);
136
+ return {
137
+ properties,
138
+ summaries
139
+ };
140
+ }
141
+ function pickSubagentHostArgInput(input, names) {
142
+ if (names.size === 0) return { ok: true };
143
+ const values = input;
144
+ const picked = {};
145
+ let count = 0;
146
+ for (const name of names) {
147
+ if (!Object.prototype.hasOwnProperty.call(values, name)) continue;
148
+ const value = values[name];
149
+ if (value == null) continue;
150
+ if (typeof value !== "string") return {
151
+ ok: false,
152
+ message: `Error: "${name}" must be a string.`
153
+ };
154
+ if (value.trim() === "") continue;
155
+ picked[name] = value;
156
+ count += 1;
157
+ }
158
+ return count === 0 ? { ok: true } : {
159
+ ok: true,
160
+ hostArgs: picked
161
+ };
162
+ }
163
+ function checkValue(type, name, spec, value) {
164
+ const omit = `Omit "${name}" to let the host choose.`;
165
+ if (spec.enum != null) return spec.enum.includes(value) ? void 0 : `Error: "${name}" for subagent "${type}" must be one of: ${spec.enum.join(", ")}. ${omit}`;
166
+ const maxLength = getFreeFormMaxLength(spec);
167
+ return isBoundedText(value, maxLength) ? void 0 : `Error: "${name}" for subagent "${type}" must be at most ${maxLength} characters without control characters. ${omit}`;
168
+ }
169
+ function resolveSubagentHostArgs(config, hostArgs) {
170
+ if (hostArgs == null) return { ok: true };
171
+ const names = Object.keys(hostArgs).sort();
172
+ if (names.length === 0) return { ok: true };
173
+ const specs = new Map(getSubagentHostArgSpecs(config));
174
+ const resolved = {};
175
+ for (const name of names) {
176
+ const spec = specs.get(name);
177
+ if (spec == null) return {
178
+ ok: false,
179
+ message: isSubagentHostArgName(name) ? `Error: Subagent "${config.type}" does not accept "${name}". Omit it for this subagent type.` : `Error: Subagent "${config.type}" received an unsupported argument.`
180
+ };
181
+ const value = hostArgs[name];
182
+ if (typeof value !== "string") return {
183
+ ok: false,
184
+ message: `Error: "${name}" must be a string.`
185
+ };
186
+ const error = checkValue(config.type, name, spec, value);
187
+ if (error != null) return {
188
+ ok: false,
189
+ message: error
190
+ };
191
+ resolved[name] = value;
192
+ }
193
+ return {
194
+ ok: true,
195
+ hostArgs: Object.freeze(resolved)
196
+ };
197
+ }
198
+ function getSubagentHostArgsDigest(hostArgs) {
199
+ if (hostArgs == null) return;
200
+ const entries = Object.entries(hostArgs).sort(([left], [right]) => left < right ? -1 : 1);
201
+ if (entries.length === 0) return;
202
+ return createHash("sha256").update(JSON.stringify(entries)).digest("hex");
203
+ }
204
+ //#endregion
205
+ export { SUBAGENT_HOST_ARG_LIMITS, buildSubagentHostArgProperties, collectSubagentHostArgNames, getSubagentHostArgSpecs, getSubagentHostArgsDigest, isSubagentHostArgName, pickSubagentHostArgInput, resolveSubagentHostArgs };
206
+
207
+ //# sourceMappingURL=hostArgs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostArgs.mjs","names":[],"sources":["../../../../src/tools/subagent/hostArgs.ts"],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import "./hostArgs.mjs";
2
+ import "./diagnostics.mjs";
1
3
  import "./childGraphConfig.mjs";
2
4
  import "./SubagentExecutor.mjs";
3
5
  import "./InMemorySubagentTaskStore.mjs";
@@ -1,6 +1,6 @@
1
1
  import { truncateToolResultContent } from "../utils/truncation.mjs";
2
- import { StreamLimitExceededError } from "../llm/streamLimits.mjs";
3
2
  import { PreparedSubagentError } from "./preparedSubagents.mjs";
3
+ import { StreamLimitExceededError } from "../llm/streamLimits.mjs";
4
4
  //#region src/tools/toolErrorContent.ts
5
5
  const STOPPED_RUN_TOOL_ERROR = "STOP. The user doesn't want to proceed with this tool use. The run was stopped; the tool may not have completed, and its effects should not be assumed. STOP what you are doing and wait for the user to tell you how to proceed.";
6
6
  function isStoppedRunToolError(message, signal, error) {
@@ -0,0 +1,3 @@
1
+ export type AwaitWithinDeadline = <T>(task: Promise<T>) => Promise<T>;
2
+ /** Bounds even non-cooperative credential minters, fetches, body reads, and model calls. */
3
+ export declare function withDecisionDeadline<T>(provider: string, timeoutMs: number, callerSignal: AbortSignal | undefined, operation: (signal: AbortSignal, waitFor: AwaitWithinDeadline) => Promise<T>): Promise<T>;
@@ -0,0 +1,11 @@
1
+ import type { DecisionAnswer, DecisionDialect, DecisionQuestion } from './types';
2
+ interface WireQuestion {
3
+ type: string;
4
+ instructions: DecisionQuestion['instructions'];
5
+ criteria?: DecisionQuestion['criteria'];
6
+ }
7
+ /** System One calls a yes/no question a `noul`; both dialects use a `{true, false}` criterion. */
8
+ export declare function toWireQuestion(question: DecisionQuestion, dialect: DecisionDialect): WireQuestion;
9
+ /** A validated answer, or `null` for one that cannot safely be read. */
10
+ export declare function readAnswer(answer: unknown, dialect: DecisionDialect, question?: DecisionQuestion): DecisionAnswer | null;
11
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { DecisionModel, DecisionAnswer, DecisionResult, DecisionDialect, DecisionCredential, DecisionQuestion } from './types';
2
+ import type { DecisionFetch } from './transport';
3
+ export declare const HTTP_PROVIDER_ID = "http";
4
+ export interface HttpDecisionModelOptions {
5
+ providerId?: string;
6
+ apiKey?: DecisionCredential;
7
+ requiresAuth?: boolean;
8
+ /** Full URL, not a base path. */
9
+ endpoint: string;
10
+ model?: string;
11
+ dialect?: DecisionDialect;
12
+ requestKey?: string;
13
+ responseKey?: string;
14
+ timeoutMs?: number;
15
+ maxRetries?: number;
16
+ fetch?: DecisionFetch;
17
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
18
+ onAnswered?: (label: string, ms: number) => void;
19
+ }
20
+ export declare function parseEnvelope(body: string, providerId: string, readOne: (answer: unknown, question?: DecisionQuestion) => DecisionAnswer | null, responseKey?: string, expected?: Record<string, DecisionQuestion>): DecisionResult;
21
+ /** Jev and Laya use the same System One HTTP dialect, but may report different confidence metrics. */
22
+ export declare function createHttpDecisionModel(options: HttpDecisionModelOptions): DecisionModel;
@@ -0,0 +1,10 @@
1
+ export * from './types';
2
+ export * from './questions';
3
+ export * from './presets';
4
+ export { createHttpDecisionModel, parseEnvelope, HTTP_PROVIDER_ID, } from './http';
5
+ export { createStructuredChatDecisionModel } from './structuredChat';
6
+ export type { HttpDecisionModelOptions } from './http';
7
+ export type { StructuredChatDecisionModelOptions } from './structuredChat';
8
+ export { toWireQuestion, readAnswer } from './dialect';
9
+ export { createTransport } from './transport';
10
+ export type { DecisionFetch, Transport, TransportOptions } from './transport';
@@ -0,0 +1,17 @@
1
+ import type { DecisionModel, DecisionCredential, DecisionProviderSettings } from './types';
2
+ import type { DecisionFetch } from './transport';
3
+ export declare const DEFAULT_API_KEY_ENV = "DECISION_API_KEY";
4
+ /**
5
+ * Known HTTP hosts as settings, not new decision model implementations. Jev and Laya speak the
6
+ * same wire protocol, but their confidence measures and checkpoint calibration differ.
7
+ */
8
+ export declare const DECISION_PRESETS: Readonly<Record<string, Readonly<DecisionProviderSettings>>>;
9
+ export declare function decisionPreset(name: string | undefined): DecisionProviderSettings | null;
10
+ /** Caller settings win except that required preset authentication cannot be weakened. */
11
+ export declare function mergeDecisionSettings(preset: DecisionProviderSettings | null, configured: DecisionProviderSettings | undefined): DecisionProviderSettings;
12
+ export declare function decisionProviderNames(): string[];
13
+ export declare function createDecisionModel(settings: DecisionProviderSettings, apiKey?: DecisionCredential, options?: {
14
+ fetch?: DecisionFetch;
15
+ providerId?: string;
16
+ onAnswered?: (label: string, ms: number) => void;
17
+ }): DecisionModel;
@@ -0,0 +1,8 @@
1
+ import type { BooleanCriteria, BooleanQuestion, ChoiceQuestion, ScoreQuestion, DecisionText, DecisionQuestion } from './types';
2
+ export declare function validateDecisionQuestions(questions: Record<string, DecisionQuestion>, provider: string): Array<[string, DecisionQuestion]>;
3
+ /** A yes/no question; `criteria` describes what counts as yes (a string) or both sides. */
4
+ export declare function booleanQuestion(instructions: DecisionText, criteria?: BooleanCriteria | string): BooleanQuestion;
5
+ /** Pick one of the named options; a `null` description means the name speaks for itself. */
6
+ export declare function choiceQuestion(instructions: DecisionText, criteria: Record<string, DecisionText | null>): ChoiceQuestion;
7
+ /** Rate against an ordered rubric, level 0 first. */
8
+ export declare function scoreQuestion(instructions: DecisionText, levels: DecisionText[]): ScoreQuestion;
@@ -0,0 +1,17 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { DecisionModel, DecisionResult } from './types';
3
+ import type { DecisionOutputMethod } from './structuredOutput';
4
+ export declare function readChatUsage(raw: unknown): DecisionResult['usage'];
5
+ export interface StructuredChatDecisionModelOptions {
6
+ /** An already configured chat model whose chosen method enforces strict schemas. */
7
+ model: BaseChatModel;
8
+ modelId: string;
9
+ providerId?: string;
10
+ /** Verified OpenAI/Azure strict modes or Anthropic strict tools; other paths fail closed. */
11
+ method: DecisionOutputMethod;
12
+ timeoutMs?: number;
13
+ maxQuestions?: number;
14
+ onAnswered?: (label: string, ms: number) => void;
15
+ }
16
+ /** Strict provider schema or strict tool calling, without an agent loop or fabricated probabilities. */
17
+ export declare function createStructuredChatDecisionModel(options: StructuredChatDecisionModelOptions): DecisionModel;
@@ -0,0 +1,4 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ export type DecisionOutputMethod = 'jsonSchema' | 'functionCalling';
3
+ /** Binds only verified enforcement paths; a model profile alone is not a strict-output guarantee. */
4
+ export declare function withDecisionStructuredOutput(model: BaseChatModel, schema: Record<string, unknown>, method: DecisionOutputMethod): ReturnType<BaseChatModel['withStructuredOutput']>;
@@ -0,0 +1,2 @@
1
+ /** Marks a JSON decision prompt so trace redaction can safely inspect its nested state. */
2
+ export declare const DECISION_PROMPT_PREFIX = "librechat-decision-state:";
@@ -0,0 +1,29 @@
1
+ import type { DecisionCredential } from './types';
2
+ export type DecisionFetch = (input: string, init: {
3
+ method: string;
4
+ headers: Record<string, string>;
5
+ body: string;
6
+ signal: AbortSignal;
7
+ redirect: 'error';
8
+ }) => Promise<Pick<Response, 'ok' | 'status' | 'headers' | 'body'>>;
9
+ export interface TransportOptions {
10
+ providerId: string;
11
+ apiKey?: DecisionCredential;
12
+ requiresAuth?: boolean;
13
+ /** Full URL, not a base path. */
14
+ endpoint: string;
15
+ timeoutMs?: number;
16
+ maxRetries?: number;
17
+ fetch?: DecisionFetch;
18
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
19
+ /** Called only after the response parses, with no state, answers, or credentials. */
20
+ onAnswered?: (label: string, ms: number) => void;
21
+ }
22
+ export type Transport = <T>(prepare: () => {
23
+ payload: string;
24
+ parse: (body: string) => T;
25
+ }, signal: AbortSignal | undefined, label: string, timeoutOverrideMs?: number) => Promise<T>;
26
+ export declare function failureForStatus(status: number): 'unauthorized' | 'rate_limited' | 'server_error' | 'bad_request';
27
+ export declare function retryAfterMs(header: string | null): number | undefined;
28
+ /** One immutable transport; every call owns its signal, deadline, and credentials. */
29
+ export declare function createTransport(options: TransportOptions): Transport;
@@ -0,0 +1,119 @@
1
+ /** Typed decisions over content, independent of the model that makes them. */
2
+ export type DecisionJson = string | number | boolean | null | DecisionJson[] | {
3
+ [key: string]: DecisionJson;
4
+ };
5
+ export type DecisionText = string | DecisionJson[] | {
6
+ [key: string]: DecisionJson;
7
+ };
8
+ export type DecisionState = DecisionText;
9
+ export interface BooleanCriteria {
10
+ true?: DecisionText;
11
+ false?: DecisionText;
12
+ }
13
+ /** A string criterion describes the yes side of a yes/no question. */
14
+ export interface BooleanQuestion {
15
+ type: 'boolean';
16
+ instructions: DecisionText;
17
+ criteria?: BooleanCriteria | string;
18
+ }
19
+ export interface ChoiceQuestion {
20
+ type: 'choice';
21
+ instructions: DecisionText;
22
+ criteria: Record<string, DecisionText | null>;
23
+ }
24
+ /** The measured answer is an expected level, which may fall between two rubric levels. */
25
+ export interface ScoreQuestion {
26
+ type: 'score';
27
+ instructions: DecisionText;
28
+ criteria: DecisionText[];
29
+ }
30
+ export type DecisionQuestion = BooleanQuestion | ChoiceQuestion | ScoreQuestion;
31
+ /** `null` is an unmeasured decision, not a probability of zero. */
32
+ export type BooleanAnswer = {
33
+ type: 'boolean';
34
+ probability: number;
35
+ decision?: never;
36
+ } | {
37
+ type: 'boolean';
38
+ probability: null;
39
+ decision: boolean;
40
+ };
41
+ export interface ChoiceAnswer {
42
+ type: 'choice';
43
+ choice: string;
44
+ /** Backend-specific concentration measure; Jev and Laya use different definitions. */
45
+ confidence: number | null;
46
+ /** `null` when no distribution was measured; never substitute an empty distribution. */
47
+ probabilities: Record<string, number> | null;
48
+ }
49
+ export interface ScoreAnswer {
50
+ type: 'score';
51
+ /** Expected value over rubric levels, not an LLM's selection of one level. */
52
+ score: number;
53
+ /** Backend-specific concentration measure; do not transfer thresholds between checkpoints. */
54
+ confidence: number | null;
55
+ probabilities: Record<string, number> | null;
56
+ }
57
+ export type DecisionAnswer = BooleanAnswer | ChoiceAnswer | ScoreAnswer;
58
+ /** Unknown counts are omitted, never inferred from an answer or replaced by zero. */
59
+ export interface DecisionUsage {
60
+ inputTokens?: number;
61
+ outputTokens?: number;
62
+ }
63
+ export interface DecisionRequest {
64
+ state: DecisionState;
65
+ questions: Record<string, DecisionQuestion>;
66
+ signal?: AbortSignal;
67
+ label?: string;
68
+ /** Overrides the provider's timeout for this request alone. */
69
+ timeoutMs?: number;
70
+ }
71
+ export interface DecisionResult {
72
+ model: string;
73
+ /** A requested answer can be omitted; callers must handle `undefined` explicitly. */
74
+ answers: Record<string, DecisionAnswer | undefined>;
75
+ usage: DecisionUsage | null;
76
+ }
77
+ export interface DecisionModel {
78
+ readonly id: string;
79
+ readonly model: string;
80
+ decide(request: DecisionRequest): Promise<DecisionResult>;
81
+ }
82
+ export type DecisionDialect = 'port' | 'systemone';
83
+ /** A bearer key, or a per-request token minter; a 401 requests one fresh token for that call. */
84
+ export type DecisionCredential = string | ((options: {
85
+ refresh: boolean;
86
+ signal?: AbortSignal;
87
+ }) => Promise<string>);
88
+ export interface DecisionProviderSettings {
89
+ /** Full URL of the decision endpoint, not a base path. */
90
+ baseURL?: string;
91
+ model?: string;
92
+ dialect?: DecisionDialect;
93
+ requestKey?: string;
94
+ responseKey?: string;
95
+ timeoutMs?: number;
96
+ maxRetries?: number;
97
+ /** Auth is required by default; self-hosted Laya can be unauthenticated. */
98
+ requiresAuth?: boolean;
99
+ apiKeyEnv?: string;
100
+ }
101
+ export type DecisionFailure = 'timeout' | 'aborted' | 'rate_limited' | 'unauthorized' | 'bad_request' | 'server_error' | 'network' | 'unsupported_question' | 'unsupported_mode' | 'malformed_response';
102
+ export declare class DecisionError extends Error {
103
+ readonly failure: DecisionFailure;
104
+ readonly provider: string;
105
+ readonly status?: number;
106
+ retryAfterMs?: number;
107
+ constructor(failure: DecisionFailure, message: string, options?: {
108
+ provider?: string;
109
+ status?: number;
110
+ });
111
+ }
112
+ /** A JSON boundary guard; never trust a parsed response's declared TypeScript type. */
113
+ export declare function isDecisionObject(value: unknown): value is {
114
+ [key: string]: unknown;
115
+ };
116
+ export declare function readDecisionUsage(raw: unknown): DecisionUsage | null;
117
+ export declare function isBooleanAnswer(answer: DecisionAnswer | undefined): answer is BooleanAnswer;
118
+ export declare function isChoiceAnswer(answer: DecisionAnswer | undefined): answer is ChoiceAnswer;
119
+ export declare function isScoreAnswer(answer: DecisionAnswer | undefined): answer is ScoreAnswer;
@@ -11,6 +11,7 @@ import type { HookRegistry } from '@/hooks';
11
11
  import type * as t from '@/types';
12
12
  import { StreamLimitExceededError } from '@/llm/streamLimits';
13
13
  import { SubagentExecutor } from '@/tools/subagent';
14
+ import { ProviderTextProtectionError } from '@/protection/providerText';
14
15
  import { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
15
16
  import { PreparedSubagents, PreparedSubagentError } from '@/tools/preparedSubagents';
16
17
  import { ToolNode as CustomToolNode } from '@/tools/ToolNode';
@@ -305,6 +306,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
305
306
  /** See {@link t.StandardGraphInput.subagentExecutionContext}. */
306
307
  readonly subagentExecutionContext?: t.SubagentExecutionContext;
307
308
  private readonly subagentContext?;
309
+ private readonly onSubagentResolutionFailure?;
308
310
  /** See {@link t.StandardGraphInput.preemption}. */
309
311
  preemption?: t.StreamPreemption;
310
312
  /**
@@ -313,6 +315,8 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
313
315
  * these on every streamed chunk event.
314
316
  */
315
317
  streamLimits: ResolvedStreamLimits;
318
+ /** Default-off mandatory provider prose release. */
319
+ providerTextProtection?: t.StandardGraphInput['providerTextProtection'];
316
320
  /**
317
321
  * Cumulative streamed argument bytes per in-flight tool call, keyed by
318
322
  * generation key + chunk index (see `resolveGenerationKey`). Per-run
@@ -351,12 +355,12 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
351
355
  * `StreamLimitState.activeStreamLimitGenerations`). Lazily created by the
352
356
  * attempt lease; spans resets on purpose. */
353
357
  activeStreamLimitGenerations?: Set<string>;
354
- /** The stream-limit error behind an already-fired breaker, whether this
358
+ /** The safety error behind an already-fired breaker, whether this
355
359
  * graph's own controller tripped or a parent run's breaker arrived through
356
360
  * the composed constructor signal (child graphs own separate controllers).
357
361
  * Providers can translate either abort into a generic error, and recovery
358
362
  * paths must not run in that state. */
359
- protected resolveTrippedBreakerReason(breakerSignal?: AbortSignal): StreamLimitExceededError | PreparedSubagentError | undefined;
363
+ protected resolveTrippedBreakerReason(breakerSignal?: AbortSignal): StreamLimitExceededError | PreparedSubagentError | ProviderTextProtectionError | undefined;
360
364
  /**
361
365
  * Seals charged against `preemption.maxSeals`. Per-turn: cleared by both
362
366
  * reset paths so a fresh turn gets a fresh budget, while a HITL resume —
@@ -441,7 +445,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
441
445
  * from a discard.
442
446
  */
443
447
  private preemptRestartPending;
444
- constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, fadingTier, fadingTiers, subagentUsageSink, subagentTasks, subagentScope, subagentExecutionContext, subagentContext, preemption, streamLimits, toolExecution, clientDelegatedToolNames, }: t.StandardGraphInput, dependencies?: GraphFactoryDependencies);
448
+ constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, fadingTier, fadingTiers, subagentUsageSink, subagentTasks, subagentScope, subagentExecutionContext, subagentContext, onSubagentResolutionFailure, preemption, streamLimits, providerTextProtection, toolExecution, clientDelegatedToolNames, }: t.StandardGraphInput, dependencies?: GraphFactoryDependencies);
445
449
  /**
446
450
  * A compaction applies its remove-all inside the agent subgraph, so the
447
451
  * subgraph's result carries only the retained tail, and an outer reducer
@@ -59,3 +59,7 @@ export { canSealPreempt } from './llm/preempt';
59
59
  export { isThinkingEnabled, getMaxOutputTokensKey } from './llm/request';
60
60
  export { DEFAULT_MAX_TOOL_CALL_ARG_BYTES, StreamLimitExceededError, resolveStreamLimits, } from './llm/streamLimits';
61
61
  export type { StreamedToolCallArgTally, ResolvedStreamLimits, StreamLimitState, StreamLimitKind, } from './llm/streamLimits';
62
+ export * from './decisions';
63
+ export * from './rerank';
64
+ export { PROVIDER_TEXT_PROTECTION_VERSION, ProviderTextProtectionError } from './protection/providerText';
65
+ export type { ProviderTextProtection, ProviderTextProtectionResult, ProviderTextProtectionErrorCode, } from './protection/providerText';
@@ -3,6 +3,7 @@ import type { RunnableConfig } from '@langchain/core/runnables';
3
3
  import type { BaseMessage } from '@langchain/core/messages';
4
4
  import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
5
5
  import type { PreparedProviderRequest } from '@/llm/prepareProviderRequest';
6
+ import type { ProviderTextProtection } from '@/protection/providerText';
6
7
  import type { ContextOverflowContext } from '@/utils/errors';
7
8
  import type { StreamLimitState } from '@/llm/streamLimits';
8
9
  import type * as t from '@/types';
@@ -59,6 +60,7 @@ export type OnChunk = (chunk: AIMessageChunk, metadata?: Record<string, unknown>
59
60
  */
60
61
  interface AttemptInvokeCommonParams {
61
62
  context?: InvokeContext;
63
+ providerTextProtection?: ProviderTextProtection;
62
64
  onChunk?: OnChunk;
63
65
  /**
64
66
  * The agent lane this attempt belongs to, as the model node names it. Only
@@ -123,7 +125,7 @@ export declare function getFallbackOverflowCandidates(error: unknown): FallbackO
123
125
  * behind a later unrelated error would surface a dead end instead. Ordinary
124
126
  * failures still throw last-error-wins.
125
127
  */
126
- export declare function tryFallbackProviders({ fallbacks, tools, messages, config, primaryError, context, onChunk, streamLimitState, preemptAgentId, overflowContext, prepareProviderRequest: prepareFallbackRequest, prepareProviderMessages, }: {
128
+ export declare function tryFallbackProviders({ fallbacks, tools, messages, config, primaryError, context, onChunk, streamLimitState, providerTextProtection, preemptAgentId, overflowContext, prepareProviderRequest: prepareFallbackRequest, prepareProviderMessages, }: {
127
129
  fallbacks: t.FallbackConfig[];
128
130
  tools?: t.GraphTools;
129
131
  messages: BaseMessage[];
@@ -134,6 +136,7 @@ export declare function tryFallbackProviders({ fallbacks, tools, messages, confi
134
136
  /** Accounting-lease owner forwarded to each fallback attempt (see
135
137
  * `AttemptInvokeParams.streamLimitState`). */
136
138
  streamLimitState?: StreamLimitState;
139
+ providerTextProtection?: ProviderTextProtection;
137
140
  /** Forwarded so a fallback-served attempt records a discarded turn in the
138
141
  * SAME lane the primary would have (see
139
142
  * `AttemptInvokeParams.preemptAgentId`). Dropping it here would leave the
@@ -0,0 +1,4 @@
1
+ import type { ProviderTextProtection } from '@/protection/providerText';
2
+ import type { ChatModel, ProviderName } from '@/types';
3
+ /** Clone only known runnable shells. Never mutate a shared provider or its callback configuration. */
4
+ export declare function withProviderTextBoundary(model: ChatModel, policy: ProviderTextProtection, provider?: ProviderName): ChatModel;
@@ -0,0 +1,7 @@
1
+ import { AIMessageChunk } from '@langchain/core/messages';
2
+ import type { AIMessageChunkFields } from '@langchain/core/messages';
3
+ type ChunkConstructor = new (fields: AIMessageChunkFields) => AIMessageChunk;
4
+ /** Internal certification for SDK-owned aggregation semantics, not arbitrary provider subclasses. */
5
+ export declare function registerProviderTextChunkConstructor(constructor: ChunkConstructor): void;
6
+ export declare function createProviderTextChunk(source: object, fields: AIMessageChunkFields): AIMessageChunk;
7
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { AIMessageChunk } from '@langchain/core/messages';
2
+ import type { ProviderTextAttempt } from '@/protection/providerText';
3
+ export declare const GEMINI_SIGNATURES = "__gemini_function_call_thought_signatures__";
4
+ export declare const RESPONSES_POSITIONS = "__openai_responses_replay_positions__";
5
+ export declare function keys(value: unknown, allowed: readonly string[]): value is Record<string, unknown>;
6
+ export declare function stringMap(value: unknown): boolean;
7
+ export declare function safetyRatings(value: unknown): boolean;
8
+ export declare function replayPositions(value: unknown): boolean;
9
+ /** One certified prose output. Unknown structured outputs and alternate aliases stay gated. */
10
+ export declare class ResponsesTextProjection {
11
+ private readonly attempt;
12
+ private metadata?;
13
+ private hasOutputAlias;
14
+ private output?;
15
+ constructor(attempt: ProviderTextAttempt);
16
+ strip(metadata: AIMessageChunk['response_metadata']): AIMessageChunk['response_metadata'];
17
+ canonical(content: string): AIMessageChunk['response_metadata'] | undefined;
18
+ }