@inflexa-ai/harness 0.45.1 → 0.46.2

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 (790) hide show
  1. package/README.md +6 -3
  2. package/dist/agents/conversation-agent.d.ts +9 -3
  3. package/dist/agents/conversation-agent.js +34 -33
  4. package/dist/agents/report-session-agent.d.ts +15 -15
  5. package/dist/agents/report-session-agent.js +23 -15
  6. package/dist/agents/sandbox/index.d.ts +1 -1
  7. package/dist/agents/sandbox/index.js +1 -1
  8. package/dist/agents/sandbox/shared.d.ts +12 -14
  9. package/dist/agents/sandbox/shared.js +18 -12
  10. package/dist/agents/sandbox/types.d.ts +4 -4
  11. package/dist/agents/sandbox/validate-skills.d.ts +2 -2
  12. package/dist/agents/sandbox/validate-skills.js +3 -1
  13. package/dist/agents/sandbox-catalog.d.ts +2 -2
  14. package/dist/agents/sandbox-catalog.js +3 -3
  15. package/dist/agents/system-prompt.d.ts +2 -2
  16. package/dist/app/chat-turn-workflow.d.ts +114 -0
  17. package/dist/app/chat-turn-workflow.js +306 -0
  18. package/dist/app/chat-turn.d.ts +85 -57
  19. package/dist/app/chat-turn.js +123 -100
  20. package/dist/app/data-profile-orientation.js +10 -8
  21. package/dist/app/data-profile-view.d.ts +4 -4
  22. package/dist/app/data-profile-view.js +9 -8
  23. package/dist/app/in-process-turn.d.ts +42 -0
  24. package/dist/app/in-process-turn.js +139 -0
  25. package/dist/app/message-assembly.d.ts +10 -4
  26. package/dist/app/message-assembly.js +13 -8
  27. package/dist/app/report-session-runtime.d.ts +4 -4
  28. package/dist/app/report-session-runtime.js +36 -21
  29. package/dist/app/spawn-report-session.d.ts +33 -28
  30. package/dist/app/spawn-report-session.js +25 -40
  31. package/dist/app/synthesize-run.d.ts +22 -16
  32. package/dist/app/synthesize-run.js +41 -35
  33. package/dist/app/work.d.ts +96 -0
  34. package/dist/app/work.js +147 -0
  35. package/dist/auth/local-auth-context.d.ts +1 -3
  36. package/dist/auth/local-auth-context.js +1 -3
  37. package/dist/auth/local-run-authorizer.d.ts +1 -1
  38. package/dist/auth/local-run-authorizer.js +5 -3
  39. package/dist/auth/types.d.ts +26 -26
  40. package/dist/billing/cached-resolver.d.ts +4 -4
  41. package/dist/billing/run-charge.d.ts +5 -8
  42. package/dist/billing/run-charge.js +2 -2
  43. package/dist/billing/usage-recorder.d.ts +9 -9
  44. package/dist/citations/aggregate.js +1 -1
  45. package/dist/citations/clients/arxiv.d.ts +2 -2
  46. package/dist/citations/clients/arxiv.js +12 -4
  47. package/dist/citations/clients/common.js +4 -2
  48. package/dist/citations/clients/crossref.d.ts +2 -2
  49. package/dist/citations/clients/crossref.js +37 -37
  50. package/dist/citations/clients/doi-registry.js +15 -16
  51. package/dist/citations/clients/pubmed.d.ts +2 -2
  52. package/dist/citations/clients/pubmed.js +20 -13
  53. package/dist/citations/clients/semantic-scholar.d.ts +2 -2
  54. package/dist/citations/clients/semantic-scholar.js +9 -9
  55. package/dist/citations/compare.js +2 -2
  56. package/dist/citations/match.d.ts +2 -2
  57. package/dist/citations/match.js +12 -7
  58. package/dist/citations/normalize.js +35 -26
  59. package/dist/citations/plan.js +6 -2
  60. package/dist/citations/resolve.d.ts +6 -6
  61. package/dist/citations/resolve.js +34 -25
  62. package/dist/citations/types.d.ts +77 -77
  63. package/dist/config/environment-stores.d.ts +6 -6
  64. package/dist/config/resource-limits.js +1 -3
  65. package/dist/contracts/analogy-report.d.ts +7 -7
  66. package/dist/contracts/analogy-report.js +2 -2
  67. package/dist/contracts/chat-events.d.ts +38 -24
  68. package/dist/contracts/chat-frame.d.ts +15 -5
  69. package/dist/contracts/chat-frame.js +64 -41
  70. package/dist/contracts/chat-parts.d.ts +130 -67
  71. package/dist/contracts/chat-parts.js +1 -0
  72. package/dist/contracts/content-url.js +16 -2
  73. package/dist/contracts/data-profile.d.ts +38 -38
  74. package/dist/contracts/index.d.ts +2 -2
  75. package/dist/contracts/index.js +1 -1
  76. package/dist/contracts/message.d.ts +6 -6
  77. package/dist/contracts/organ-system.d.ts +11 -11
  78. package/dist/contracts/part-registry.d.ts +5 -4
  79. package/dist/contracts/part-registry.js +5 -0
  80. package/dist/contracts/profile-vocabulary.d.ts +11 -10
  81. package/dist/contracts/profile-vocabulary.js +10 -3
  82. package/dist/contracts/report-blocks.d.ts +329 -329
  83. package/dist/contracts/report-reference.d.ts +105 -81
  84. package/dist/contracts/report-reference.js +30 -13
  85. package/dist/contracts/schemas/chat-events.d.ts +30 -16
  86. package/dist/contracts/schemas/chat-events.js +15 -6
  87. package/dist/contracts/schemas/chat-parts.d.ts +175 -102
  88. package/dist/contracts/schemas/chat-parts.js +33 -7
  89. package/dist/contracts/severity.d.ts +1 -1
  90. package/dist/contracts/structure-source.d.ts +3 -3
  91. package/dist/contracts/structure-source.js +6 -2
  92. package/dist/contracts/subagent-activity.d.ts +2 -2
  93. package/dist/contracts/subagent-activity.js +5 -3
  94. package/dist/contracts/usage.d.ts +2 -2
  95. package/dist/data/safety-panel-schema.d.ts +25 -25
  96. package/dist/data/safety-panel-schema.js +13 -4
  97. package/dist/execution/artifact-metadata.d.ts +23 -15
  98. package/dist/execution/artifact-metadata.js +33 -10
  99. package/dist/execution/artifact-record.d.ts +2 -2
  100. package/dist/execution/artifact-registration.d.ts +5 -5
  101. package/dist/execution/artifact-registry.d.ts +8 -8
  102. package/dist/execution/dbos-run-launcher.d.ts +24 -4
  103. package/dist/execution/dbos-run-launcher.js +58 -4
  104. package/dist/execution/dbos-workflow-purger.d.ts +5 -6
  105. package/dist/execution/dbos-workflow-purger.js +8 -7
  106. package/dist/execution/input-signature.d.ts +2 -2
  107. package/dist/execution/post-step-pipeline.d.ts +9 -9
  108. package/dist/execution/post-step-pipeline.js +1 -1
  109. package/dist/execution/post-step.js +2 -2
  110. package/dist/execution/reconcile-manifest.d.ts +4 -4
  111. package/dist/execution/reconcile-manifest.js +3 -2
  112. package/dist/execution/run-authorizer.d.ts +46 -37
  113. package/dist/execution/run-authorizer.js +8 -8
  114. package/dist/execution/run-canceler.d.ts +7 -7
  115. package/dist/execution/run-canceler.js +14 -7
  116. package/dist/execution/run-end-record.d.ts +2 -3
  117. package/dist/execution/run-event-parts.d.ts +0 -8
  118. package/dist/execution/run-event-parts.js +29 -24
  119. package/dist/execution/run-event-stream.d.ts +8 -8
  120. package/dist/execution/run-event-stream.js +3 -4
  121. package/dist/execution/run-launcher.d.ts +4 -4
  122. package/dist/execution/run-synthesis.d.ts +49 -48
  123. package/dist/execution/run-synthesis.js +96 -255
  124. package/dist/execution/staged-input.d.ts +2 -2
  125. package/dist/execution/step-summary.d.ts +6 -6
  126. package/dist/execution/step-summary.js +4 -8
  127. package/dist/execution/topo-sort.js +4 -3
  128. package/dist/execution/workflow-purger.d.ts +2 -2
  129. package/dist/index.d.ts +17 -20
  130. package/dist/index.js +25 -36
  131. package/dist/input-sanitization.js +9 -2
  132. package/dist/input-scan/clustering.d.ts +6 -6
  133. package/dist/input-scan/clustering.js +11 -5
  134. package/dist/input-scan/companions.js +3 -2
  135. package/dist/input-scan/detect-sets.d.ts +2 -2
  136. package/dist/input-scan/detect-sets.js +25 -21
  137. package/dist/input-scan/enrich.d.ts +6 -6
  138. package/dist/input-scan/enrich.js +29 -12
  139. package/dist/input-scan/formats.d.ts +2 -2
  140. package/dist/input-scan/formats.js +8 -2
  141. package/dist/input-scan/markers.d.ts +2 -2
  142. package/dist/input-scan/markers.js +14 -5
  143. package/dist/input-scan/menu.d.ts +10 -10
  144. package/dist/input-scan/menu.js +0 -0
  145. package/dist/input-scan/quarantine.d.ts +2 -2
  146. package/dist/input-scan/quarantine.js +23 -18
  147. package/dist/input-scan/readout-budget.d.ts +2 -2
  148. package/dist/input-scan/readout-budget.js +1 -1
  149. package/dist/input-scan/readout.d.ts +2 -2
  150. package/dist/input-scan/readout.js +47 -34
  151. package/dist/input-scan/scan.d.ts +2 -2
  152. package/dist/input-scan/scan.js +7 -5
  153. package/dist/input-scan/set-types.d.ts +28 -28
  154. package/dist/input-scan/shapes.d.ts +4 -4
  155. package/dist/input-scan/shapes.js +0 -0
  156. package/dist/input-scan/templates.d.ts +10 -10
  157. package/dist/input-scan/templates.js +30 -22
  158. package/dist/input-scan/tokens.d.ts +6 -4
  159. package/dist/input-scan/tokens.js +100 -38
  160. package/dist/input-scan/types.d.ts +22 -22
  161. package/dist/lib/async-utils.d.ts +3 -7
  162. package/dist/lib/async-utils.js +5 -9
  163. package/dist/lib/cache.js +1 -1
  164. package/dist/lib/chrome.d.ts +46 -6
  165. package/dist/lib/console-logger.js +2 -2
  166. package/dist/lib/db-result.d.ts +22 -6
  167. package/dist/lib/db-result.js +9 -13
  168. package/dist/lib/eyes.d.ts +4 -4
  169. package/dist/lib/eyes.js +1 -1
  170. package/dist/lib/fs-helpers.js +18 -6
  171. package/dist/lib/fs-result.d.ts +1 -0
  172. package/dist/lib/fs-result.js +5 -6
  173. package/dist/lib/hooks.d.ts +32 -7
  174. package/dist/lib/hooks.js +22 -3
  175. package/dist/lib/host-concurrency.js +3 -2
  176. package/dist/lib/logger.d.ts +2 -2
  177. package/dist/lib/logger.js +2 -1
  178. package/dist/lib/metrics.d.ts +1 -1
  179. package/dist/lib/null-proto.d.ts +6 -0
  180. package/dist/lib/null-proto.js +17 -0
  181. package/dist/lib/otel-spans.d.ts +1 -1
  182. package/dist/lib/otel-spans.js +9 -5
  183. package/dist/lib/otel.d.ts +4 -2
  184. package/dist/lib/otel.js +10 -2
  185. package/dist/lib/page-capture.d.ts +8 -8
  186. package/dist/lib/page-capture.js +9 -4
  187. package/dist/lib/parse-json.d.ts +5 -0
  188. package/dist/lib/parse-json.js +12 -0
  189. package/dist/lib/present.d.ts +12 -0
  190. package/dist/lib/present.js +39 -0
  191. package/dist/lib/rate-limit.d.ts +4 -4
  192. package/dist/lib/rate-limit.js +12 -13
  193. package/dist/lib/regulatory-corpus/fetch-fda-guidance.d.ts +4 -4
  194. package/dist/lib/regulatory-corpus/fetch-fda-guidance.js +4 -10
  195. package/dist/lib/regulatory-corpus/fetch-ich.d.ts +4 -4
  196. package/dist/lib/regulatory-corpus/fetch-ich.js +18 -14
  197. package/dist/lib/regulatory-corpus/normalize-whitespace.d.ts +6 -0
  198. package/dist/lib/regulatory-corpus/normalize-whitespace.js +41 -0
  199. package/dist/lib/regulatory-corpus.d.ts +10 -10
  200. package/dist/lib/regulatory-corpus.js +3 -1
  201. package/dist/lib/result.d.ts +10 -11
  202. package/dist/lib/result.js +15 -13
  203. package/dist/lib/storage.d.ts +2 -2
  204. package/dist/lib/test/async-iterable.d.ts +9 -0
  205. package/dist/lib/test/async-iterable.js +28 -0
  206. package/dist/lib/test/request-url.d.ts +5 -0
  207. package/dist/lib/test/request-url.js +7 -0
  208. package/dist/lib/test/result-assert.d.ts +12 -0
  209. package/dist/lib/test/result-assert.js +17 -0
  210. package/dist/lib/test/text-shapes.d.ts +24 -0
  211. package/dist/lib/test/text-shapes.js +63 -0
  212. package/dist/lib/text.d.ts +22 -0
  213. package/dist/lib/text.js +68 -0
  214. package/dist/lib/thrown.d.ts +18 -0
  215. package/dist/lib/thrown.js +30 -0
  216. package/dist/lib/unknown-array.d.ts +6 -0
  217. package/dist/lib/unknown-array.js +8 -0
  218. package/dist/lib/unknown-containers.d.ts +14 -0
  219. package/dist/lib/unknown-containers.js +17 -0
  220. package/dist/lib/unknown-text.d.ts +8 -0
  221. package/dist/lib/unknown-text.js +28 -0
  222. package/dist/lib/zod-issue-shape.d.ts +1 -1
  223. package/dist/lib/zod-issue-shape.js +31 -31
  224. package/dist/lib/zod-issues.d.ts +3 -3
  225. package/dist/lib/zod-issues.js +30 -17
  226. package/dist/literature/sources/arxiv.d.ts +6 -6
  227. package/dist/literature/sources/arxiv.js +92 -35
  228. package/dist/literature/sources/http.d.ts +2 -2
  229. package/dist/literature/sources/http.js +16 -15
  230. package/dist/literature/sources/pubmed.d.ts +16 -16
  231. package/dist/literature/sources/pubmed.js +96 -61
  232. package/dist/literature/sources/semantic-scholar.d.ts +8 -8
  233. package/dist/literature/sources/semantic-scholar.js +22 -13
  234. package/dist/loop/accounting.d.ts +63 -0
  235. package/dist/loop/accounting.js +141 -0
  236. package/dist/loop/call-policy.d.ts +73 -0
  237. package/dist/loop/call-policy.js +109 -0
  238. package/dist/loop/chat-stream.d.ts +62 -0
  239. package/dist/loop/chat-stream.js +237 -0
  240. package/dist/loop/compaction.d.ts +9 -9
  241. package/dist/loop/compaction.js +1 -1
  242. package/dist/loop/metrics.d.ts +12 -15
  243. package/dist/loop/metrics.js +14 -26
  244. package/dist/loop/run-loop.d.ts +233 -0
  245. package/dist/loop/run-loop.js +770 -0
  246. package/dist/loop/sub-agent.d.ts +61 -0
  247. package/dist/loop/sub-agent.js +160 -0
  248. package/dist/loop/tool-adapter.d.ts +98 -0
  249. package/dist/loop/tool-adapter.js +364 -0
  250. package/dist/loop/tool-detail.d.ts +1 -1
  251. package/dist/loop/tool-detail.js +6 -5
  252. package/dist/loop/tool-outcome.d.ts +1 -1
  253. package/dist/loop/tool-output.d.ts +4 -4
  254. package/dist/loop/tool-output.js +2 -2
  255. package/dist/loop/turn-credentials.d.ts +39 -0
  256. package/dist/loop/turn-credentials.js +90 -0
  257. package/dist/loop/types.d.ts +29 -38
  258. package/dist/loop/types.js +2 -7
  259. package/dist/memory/ai-sdk-message-storage.d.ts +5 -5
  260. package/dist/memory/ai-sdk-message-storage.js +13 -11
  261. package/dist/memory/card-builders.d.ts +14 -14
  262. package/dist/memory/card-builders.js +19 -15
  263. package/dist/memory/conversation-display-recorder.d.ts +22 -4
  264. package/dist/memory/conversation-display-recorder.js +43 -24
  265. package/dist/memory/conversation-display-replay.js +3 -2
  266. package/dist/memory/conversation-display-storage.d.ts +15 -7
  267. package/dist/memory/conversation-display-storage.js +141 -36
  268. package/dist/memory/conversation-view.d.ts +4 -4
  269. package/dist/memory/conversation-view.js +5 -4
  270. package/dist/memory/count-tokens.js +10 -8
  271. package/dist/memory/derive-thread-title.d.ts +0 -13
  272. package/dist/memory/derive-thread-title.js +2 -1
  273. package/dist/memory/message-backfill.d.ts +12 -5
  274. package/dist/memory/message-backfill.js +5 -3
  275. package/dist/memory/thread-history.d.ts +36 -21
  276. package/dist/memory/thread-history.js +78 -54
  277. package/dist/memory/thread-store.d.ts +26 -17
  278. package/dist/memory/thread-store.js +15 -9
  279. package/dist/memory/tool-call-integrity.d.ts +2 -2
  280. package/dist/memory/tool-call-integrity.js +4 -3
  281. package/dist/memory/working-memory.d.ts +16 -12
  282. package/dist/memory/working-memory.js +72 -61
  283. package/dist/prompts/briefing.d.ts +12 -12
  284. package/dist/prompts/briefing.js +1 -1
  285. package/dist/prompts/synthesis-agent.d.ts +1 -1
  286. package/dist/prompts/synthesis-agent.js +6 -14
  287. package/dist/provenance/collector.d.ts +6 -6
  288. package/dist/provenance/collector.js +15 -8
  289. package/dist/provenance/exec-frame.d.ts +2 -2
  290. package/dist/provenance/exec-frame.js +6 -1
  291. package/dist/provenance/seam.d.ts +1 -4
  292. package/dist/provenance/types.d.ts +6 -6
  293. package/dist/providers/ai-sdk.d.ts +113 -62
  294. package/dist/providers/ai-sdk.js +283 -518
  295. package/dist/providers/embedding.d.ts +2 -2
  296. package/dist/providers/embedding.js +1 -1
  297. package/dist/providers/errors.d.ts +22 -2
  298. package/dist/providers/errors.js +98 -50
  299. package/dist/providers/prompt-cache.d.ts +8 -8
  300. package/dist/providers/prompt-cache.js +13 -11
  301. package/dist/providers/reasoning.d.ts +2 -2
  302. package/dist/providers/reasoning.js +2 -2
  303. package/dist/providers/request-headers.js +12 -3
  304. package/dist/providers/types.d.ts +55 -94
  305. package/dist/reference-data/catalog.d.ts +2 -15
  306. package/dist/reference-data/catalog.js +25 -8
  307. package/dist/reference-data/receipt.d.ts +2 -2
  308. package/dist/report-model/assert-rules.js +1 -1
  309. package/dist/report-model/authoring-grammar.d.ts +211 -233
  310. package/dist/report-model/block-walk.d.ts +10 -10
  311. package/dist/report-model/block-walk.js +2 -0
  312. package/dist/report-model/draft-finish.d.ts +8 -8
  313. package/dist/report-model/draft-finish.js +1 -1
  314. package/dist/report-model/draft-hash.js +8 -7
  315. package/dist/report-model/draft-operations.d.ts +22 -10
  316. package/dist/report-model/draft-operations.js +48 -30
  317. package/dist/report-model/draft-read.d.ts +19 -7
  318. package/dist/report-model/draft-read.js +16 -6
  319. package/dist/report-model/draft.d.ts +844 -2
  320. package/dist/report-model/draft.js +3 -1
  321. package/dist/report-model/fixture-resolver.js +39 -16
  322. package/dist/report-model/pin-snapshot.d.ts +2 -2
  323. package/dist/report-model/pin-snapshot.js +15 -15
  324. package/dist/report-model/production-resolver.d.ts +18 -18
  325. package/dist/report-model/production-resolver.js +50 -42
  326. package/dist/report-model/reference-resolver.d.ts +26 -10
  327. package/dist/report-model/reference-resolver.js +68 -5
  328. package/dist/report-model/reference-stamp.js +30 -38
  329. package/dist/report-model/structural-validation.js +12 -4
  330. package/dist/report-model/validate.d.ts +7 -7
  331. package/dist/report-model/validate.js +6 -6
  332. package/dist/report-render/assets.d.ts +2 -2
  333. package/dist/report-render/assets.js +27 -3
  334. package/dist/report-render/chart-export.d.ts +10 -2
  335. package/dist/report-render/chart-export.js +37 -11
  336. package/dist/report-render/chart-presets.d.ts +8 -8
  337. package/dist/report-render/chart-presets.js +3 -3
  338. package/dist/report-render/chart-renderers.d.ts +23 -16
  339. package/dist/report-render/chart-renderers.js +74 -53
  340. package/dist/report-render/chart-toolbox.d.ts +2 -2
  341. package/dist/report-render/chart-toolbox.js +7 -6
  342. package/dist/report-render/chart.d.ts +15 -16
  343. package/dist/report-render/chart.js +369 -252
  344. package/dist/report-render/design.d.ts +36 -297
  345. package/dist/report-render/design.js +0 -12
  346. package/dist/report-render/figures/common.d.ts +12 -12
  347. package/dist/report-render/figures/common.js +42 -31
  348. package/dist/report-render/figures/dendrogram.d.ts +3 -3
  349. package/dist/report-render/figures/dendrogram.js +10 -10
  350. package/dist/report-render/figures/dense.js +15 -8
  351. package/dist/report-render/figures/dotplot.js +46 -33
  352. package/dist/report-render/figures/embedding.js +52 -43
  353. package/dist/report-render/figures/equal-units.d.ts +10 -10
  354. package/dist/report-render/figures/equal-units.js +27 -27
  355. package/dist/report-render/figures/forest.js +9 -7
  356. package/dist/report-render/figures/gsea.js +21 -11
  357. package/dist/report-render/figures/heatmap.js +13 -9
  358. package/dist/report-render/figures/index.d.ts +10 -10
  359. package/dist/report-render/figures/index.js +4 -2
  360. package/dist/report-render/figures/km.js +10 -9
  361. package/dist/report-render/figures/label-room.d.ts +12 -12
  362. package/dist/report-render/figures/label-room.js +7 -2
  363. package/dist/report-render/figures/locuszoom.d.ts +2 -2
  364. package/dist/report-render/figures/locuszoom.js +59 -31
  365. package/dist/report-render/figures/lollipop.js +3 -2
  366. package/dist/report-render/figures/ma.js +8 -4
  367. package/dist/report-render/figures/manhattan.d.ts +1 -2
  368. package/dist/report-render/figures/manhattan.js +52 -34
  369. package/dist/report-render/figures/oncoprint.js +4 -5
  370. package/dist/report-render/figures/pca.js +25 -11
  371. package/dist/report-render/figures/qq.js +20 -9
  372. package/dist/report-render/figures/roc.js +1 -1
  373. package/dist/report-render/figures/sankey.d.ts +2 -2
  374. package/dist/report-render/figures/sankey.js +11 -10
  375. package/dist/report-render/figures/upset.d.ts +6 -6
  376. package/dist/report-render/figures/upset.js +7 -4
  377. package/dist/report-render/figures/volcano.js +12 -10
  378. package/dist/report-render/hybrid-svg.d.ts +4 -4
  379. package/dist/report-render/hybrid-svg.js +7 -5
  380. package/dist/report-render/number-format.d.ts +4 -4
  381. package/dist/report-render/number-format.js +62 -27
  382. package/dist/report-render/page.js +2 -1
  383. package/dist/report-render/provenance-data.d.ts +2 -2
  384. package/dist/report-render/references.d.ts +4 -4
  385. package/dist/report-render/render.d.ts +2 -2
  386. package/dist/report-render/render.js +10 -11
  387. package/dist/report-render/script-json.js +1 -1
  388. package/dist/report-render/table-data.d.ts +6 -6
  389. package/dist/report-render/test/options.d.ts +49 -0
  390. package/dist/report-render/test/options.js +143 -0
  391. package/dist/report-render/test/page-function.d.ts +19 -0
  392. package/dist/report-render/test/page-function.js +33 -0
  393. package/dist/report-render/types.d.ts +10 -10
  394. package/dist/report-render/value-bridge.d.ts +4 -4
  395. package/dist/report-render/value-bridge.js +27 -14
  396. package/dist/report-render/views/chart-view.d.ts +2 -2
  397. package/dist/report-render/views/chart-view.js +2 -2
  398. package/dist/report-render/views/lineage.d.ts +6 -6
  399. package/dist/report-render/views/lineage.js +2 -0
  400. package/dist/report-render/views/page-view.d.ts +2 -2
  401. package/dist/report-render/views/page-view.js +1 -0
  402. package/dist/report-render/views/prose.js +25 -8
  403. package/dist/report-render/views/references-view.js +12 -1
  404. package/dist/report-render/views/values.js +1 -1
  405. package/dist/runtime/assemble.d.ts +53 -26
  406. package/dist/runtime/assemble.js +103 -56
  407. package/dist/runtime/boot.d.ts +8 -7
  408. package/dist/runtime/boot.js +1 -1
  409. package/dist/runtime/connection-budget.d.ts +6 -6
  410. package/dist/runtime/connection-budget.js +1 -1
  411. package/dist/runtime/dbos.d.ts +29 -19
  412. package/dist/runtime/dbos.js +35 -20
  413. package/dist/runtime/result-serialization.js +18 -5
  414. package/dist/runtime/shutdown.d.ts +2 -2
  415. package/dist/sandbox/client.d.ts +7 -3
  416. package/dist/sandbox/cpu-files.d.ts +2 -2
  417. package/dist/sandbox/cpu-files.js +21 -4
  418. package/dist/sandbox/create-sandbox.d.ts +7 -8
  419. package/dist/sandbox/create-sandbox.js +6 -12
  420. package/dist/sandbox/docker-client.d.ts +48 -3
  421. package/dist/sandbox/docker-client.js +10 -6
  422. package/dist/sandbox/estimate-data-profile-resources.js +2 -7
  423. package/dist/sandbox/exec-outcome.d.ts +2 -2
  424. package/dist/sandbox/exec-outcome.js +1 -1
  425. package/dist/sandbox/exec.d.ts +10 -6
  426. package/dist/sandbox/exec.js +27 -12
  427. package/dist/sandbox/execution-id.js +14 -6
  428. package/dist/sandbox/farm.d.ts +2 -2
  429. package/dist/sandbox/farm.js +22 -27
  430. package/dist/sandbox/identity.d.ts +7 -0
  431. package/dist/sandbox/identity.js +14 -3
  432. package/dist/sandbox/image-packages.js +15 -27
  433. package/dist/sandbox/k8s-client.d.ts +35 -8
  434. package/dist/sandbox/k8s-client.js +6 -5
  435. package/dist/sandbox/labels.js +1 -0
  436. package/dist/sandbox/liveness.js +3 -1
  437. package/dist/sandbox/mount-plan.d.ts +10 -10
  438. package/dist/sandbox/mount-plan.js +13 -14
  439. package/dist/sandbox/notification-sweep.d.ts +4 -4
  440. package/dist/sandbox/notification-sweep.js +4 -7
  441. package/dist/sandbox/package-identity.d.ts +6 -13
  442. package/dist/sandbox/package-identity.js +46 -28
  443. package/dist/sandbox/reaper.d.ts +10 -10
  444. package/dist/sandbox/reaper.js +4 -6
  445. package/dist/sandbox/sandbox-error.d.ts +2 -9
  446. package/dist/sandbox/sandbox-error.js +21 -8
  447. package/dist/sandbox/sandbox-step-translate.d.ts +8 -5
  448. package/dist/sandbox/sandbox-step-translate.js +22 -8
  449. package/dist/sandbox/step-sandbox.d.ts +47 -0
  450. package/dist/sandbox/step-sandbox.js +53 -0
  451. package/dist/sandbox/types.d.ts +18 -19
  452. package/dist/sandbox/types.js +1 -1
  453. package/dist/schemas/artifact-manifest.d.ts +4 -4
  454. package/dist/schemas/data-profile-schemas.d.ts +343 -298
  455. package/dist/schemas/file-metadata.js +2 -4
  456. package/dist/schemas/plan-schemas.d.ts +31 -31
  457. package/dist/schemas/run-synthesis.d.ts +95 -26
  458. package/dist/schemas/run-synthesis.js +3 -1
  459. package/dist/schemas/validate-plan.d.ts +4 -4
  460. package/dist/schemas/validate-plan.js +17 -5
  461. package/dist/schemas/workflow-state.d.ts +19 -19
  462. package/dist/schemas/workflow-state.js +2 -2
  463. package/dist/state/active-turns.d.ts +36 -0
  464. package/dist/state/active-turns.js +67 -0
  465. package/dist/state/analyses-metrics.d.ts +8 -8
  466. package/dist/state/analyses-metrics.js +4 -4
  467. package/dist/state/analyses.d.ts +0 -14
  468. package/dist/state/analyses.js +0 -32
  469. package/dist/state/artifacts.d.ts +32 -19
  470. package/dist/state/artifacts.js +28 -5
  471. package/dist/state/data-profile.d.ts +2 -2
  472. package/dist/state/db.d.ts +12 -2
  473. package/dist/state/db.js +5 -0
  474. package/dist/state/edit-intents.d.ts +4 -0
  475. package/dist/state/edit-intents.js +71 -0
  476. package/dist/state/index.d.ts +4 -4
  477. package/dist/state/index.js +2 -2
  478. package/dist/state/init.d.ts +2 -1
  479. package/dist/state/init.js +5 -2
  480. package/dist/state/migrations/20260927120000_baseline.js +3 -1
  481. package/dist/state/migrations/20261026120000_add_the_edit_intents.d.ts +7 -0
  482. package/dist/state/migrations/20261026120000_add_the_edit_intents.js +21 -0
  483. package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.d.ts +7 -0
  484. package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.js +16 -0
  485. package/dist/state/migrations/20261027120100_store_the_authoring_results.d.ts +8 -0
  486. package/dist/state/migrations/20261027120100_store_the_authoring_results.js +20 -0
  487. package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.d.ts +7 -0
  488. package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.js +12 -0
  489. package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.d.ts +7 -0
  490. package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.js +11 -0
  491. package/dist/state/migrations/20261028120000_record_the_paused_work.d.ts +7 -0
  492. package/dist/state/migrations/20261028120000_record_the_paused_work.js +25 -0
  493. package/dist/state/migrations/20261028120100_end_the_suspended_runs.d.ts +8 -0
  494. package/dist/state/migrations/20261028120100_end_the_suspended_runs.js +13 -0
  495. package/dist/state/migrations/20261029120000_reference_the_run_mandate.d.ts +7 -0
  496. package/dist/state/migrations/20261029120000_reference_the_run_mandate.js +23 -0
  497. package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.d.ts +7 -0
  498. package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.js +11 -0
  499. package/dist/state/migrations/index.js +18 -0
  500. package/dist/state/paused-work.d.ts +52 -0
  501. package/dist/state/paused-work.js +105 -0
  502. package/dist/state/plans.d.ts +27 -8
  503. package/dist/state/plans.js +14 -11
  504. package/dist/state/purge-analysis.d.ts +6 -6
  505. package/dist/state/purge-analysis.js +10 -2
  506. package/dist/state/report-session-state.d.ts +43 -18
  507. package/dist/state/report-session-state.js +43 -4
  508. package/dist/state/report-versions.d.ts +16 -11
  509. package/dist/state/report-versions.js +5 -3
  510. package/dist/state/runs.d.ts +30 -19
  511. package/dist/state/runs.js +43 -51
  512. package/dist/state/schema.d.ts +18 -21
  513. package/dist/state/schema.js +4 -5
  514. package/dist/state/snapshot-parse.d.ts +2 -2
  515. package/dist/state/snapshot-parse.js +14 -8
  516. package/dist/state/step-executions.d.ts +20 -8
  517. package/dist/state/step-executions.js +6 -4
  518. package/dist/state/tool-outputs.d.ts +2 -2
  519. package/dist/state/tool-outputs.js +2 -1
  520. package/dist/state/vector-store.d.ts +16 -16
  521. package/dist/state/vector-store.js +11 -7
  522. package/dist/tasks/data-profile-absorb.d.ts +3 -3
  523. package/dist/tasks/data-profile-absorb.js +21 -16
  524. package/dist/tasks/data-profile-activity.d.ts +5 -5
  525. package/dist/tasks/data-profile-activity.js +5 -5
  526. package/dist/tasks/data-profile-index.d.ts +4 -4
  527. package/dist/tasks/data-profile-index.js +32 -17
  528. package/dist/tasks/data-profile-resolve.d.ts +8 -8
  529. package/dist/tasks/data-profile-resolve.js +88 -62
  530. package/dist/tasks/data-profile.d.ts +40 -31
  531. package/dist/tasks/data-profile.js +138 -95
  532. package/dist/tasks/extract-values.d.ts +26 -79
  533. package/dist/tasks/extract-values.js +48 -108
  534. package/dist/tasks/refresh-regulatory-corpus.d.ts +4 -20
  535. package/dist/tasks/refresh-regulatory-corpus.js +12 -8
  536. package/dist/tasks/regulatory-corpus-boot-refresh.d.ts +2 -2
  537. package/dist/tasks/regulatory-corpus-boot-refresh.js +12 -10
  538. package/dist/testing.d.ts +62 -0
  539. package/dist/testing.js +101 -0
  540. package/dist/tools/ad-hoc-router.d.ts +9 -9
  541. package/dist/tools/ad-hoc-router.js +65 -52
  542. package/dist/tools/analysis-invocation.d.ts +7 -0
  543. package/dist/tools/analysis-invocation.js +29 -5
  544. package/dist/tools/approval/contract.d.ts +8 -52
  545. package/dist/tools/approval/contract.js +7 -36
  546. package/dist/tools/approval/gateway.d.ts +27 -28
  547. package/dist/tools/approval/gateway.js +33 -130
  548. package/dist/tools/approval/queries.d.ts +6 -11
  549. package/dist/tools/approval/queries.js +43 -29
  550. package/dist/tools/approval/uuidv7.js +2 -2
  551. package/dist/tools/bio/chembl.d.ts +3 -3
  552. package/dist/tools/bio/chembl.js +10 -0
  553. package/dist/tools/bio/comptox.d.ts +25 -8
  554. package/dist/tools/bio/comptox.js +4 -2
  555. package/dist/tools/bio/drug-gene-interactions.d.ts +27 -17
  556. package/dist/tools/bio/drug-gene-interactions.js +11 -8
  557. package/dist/tools/bio/gene-disease-evidence.d.ts +61 -15
  558. package/dist/tools/bio/gene-disease-evidence.js +10 -6
  559. package/dist/tools/bio/gene-preclinical-profile.d.ts +11 -11
  560. package/dist/tools/bio/keys.d.ts +2 -2
  561. package/dist/tools/bio/keys.js +3 -3
  562. package/dist/tools/bio/lookup-annotation.d.ts +5 -5
  563. package/dist/tools/bio/lookup-annotation.js +3 -0
  564. package/dist/tools/bio/opentargets.d.ts +1 -1
  565. package/dist/tools/bio/opentargets.js +6 -0
  566. package/dist/tools/bio/pubchem.d.ts +2 -2
  567. package/dist/tools/bio/pubchem.js +6 -0
  568. package/dist/tools/bio/pubmed.d.ts +26 -16
  569. package/dist/tools/bio/pubmed.js +9 -3
  570. package/dist/tools/bio/search-clinical-trials.d.ts +4 -4
  571. package/dist/tools/bio/search-clinical-trials.js +5 -1
  572. package/dist/tools/bio/search-faers.d.ts +2 -2
  573. package/dist/tools/bio/search-faers.js +1 -1
  574. package/dist/tools/bio/search-gene.d.ts +2 -2
  575. package/dist/tools/bio/search-gene.js +1 -0
  576. package/dist/tools/bio/search-geo-datasets.d.ts +4 -4
  577. package/dist/tools/bio/search-geo-datasets.js +5 -5
  578. package/dist/tools/bio/search-interactions.d.ts +1 -1
  579. package/dist/tools/bio/search-patents.d.ts +28 -22
  580. package/dist/tools/bio/search-patents.js +20 -17
  581. package/dist/tools/bio/search-protein.d.ts +2 -2
  582. package/dist/tools/bio/search-protein.js +1 -1
  583. package/dist/tools/bio/search-regulatory-approvals.d.ts +64 -18
  584. package/dist/tools/bio/search-regulatory-approvals.js +21 -16
  585. package/dist/tools/bio/target-safety.d.ts +8 -8
  586. package/dist/tools/bio/target-safety.js +11 -6
  587. package/dist/tools/capability-data.d.ts +9 -5
  588. package/dist/tools/capability-data.js +2 -1
  589. package/dist/tools/define-tool.d.ts +55 -46
  590. package/dist/tools/define-tool.js +39 -27
  591. package/dist/tools/display/normalize-echart-spec.d.ts +2 -2
  592. package/dist/tools/display/normalize-echart-spec.js +51 -27
  593. package/dist/tools/display/show-user.d.ts +2 -2
  594. package/dist/tools/display/show-user.js +1 -1
  595. package/dist/tools/execute-analysis.d.ts +19 -10
  596. package/dist/tools/execute-analysis.js +83 -62
  597. package/dist/tools/knowledge/check.d.ts +166 -44
  598. package/dist/tools/knowledge/check.js +5 -3
  599. package/dist/tools/knowledge/client.d.ts +31 -62
  600. package/dist/tools/knowledge/client.js +44 -27
  601. package/dist/tools/knowledge/environment.d.ts +6 -6
  602. package/dist/tools/knowledge/environment.js +18 -7
  603. package/dist/tools/knowledge/index.d.ts +2 -2
  604. package/dist/tools/knowledge/index.js +9 -9
  605. package/dist/tools/knowledge/local-slots.d.ts +4 -4
  606. package/dist/tools/knowledge/local-slots.js +11 -4
  607. package/dist/tools/knowledge/pin.d.ts +2 -2
  608. package/dist/tools/knowledge/recommend.d.ts +20 -45
  609. package/dist/tools/knowledge/recommend.js +27 -19
  610. package/dist/tools/knowledge/situation.d.ts +40 -40
  611. package/dist/tools/knowledge/situation.js +2 -9
  612. package/dist/tools/knowledge/skeleton.d.ts +4 -4
  613. package/dist/tools/knowledge/skeleton.js +10 -11
  614. package/dist/tools/knowledge/template.d.ts +20 -18
  615. package/dist/tools/knowledge/template.js +38 -32
  616. package/dist/tools/lib/alphafold-client.js +2 -1
  617. package/dist/tools/lib/amass-client.d.ts +28 -28
  618. package/dist/tools/lib/amass-client.js +20 -10
  619. package/dist/tools/lib/api-utils.d.ts +13 -3
  620. package/dist/tools/lib/api-utils.js +17 -3
  621. package/dist/tools/lib/bgee-client.d.ts +6 -6
  622. package/dist/tools/lib/bgee-client.js +16 -10
  623. package/dist/tools/lib/cbioportal-client.d.ts +4 -4
  624. package/dist/tools/lib/cbioportal-client.js +9 -8
  625. package/dist/tools/lib/chembl-client.d.ts +14 -14
  626. package/dist/tools/lib/chembl-client.js +11 -4
  627. package/dist/tools/lib/clinical-benchmarks-client.d.ts +4 -4
  628. package/dist/tools/lib/clinical-benchmarks-client.js +4 -7
  629. package/dist/tools/lib/clinical-trials-client.d.ts +18 -18
  630. package/dist/tools/lib/clinical-trials-client.js +10 -10
  631. package/dist/tools/lib/clinvar-client.d.ts +2 -2
  632. package/dist/tools/lib/clinvar-client.js +6 -6
  633. package/dist/tools/lib/ctx-ops.d.ts +23 -23
  634. package/dist/tools/lib/ctx-ops.js +13 -10
  635. package/dist/tools/lib/dgidb-client.d.ts +6 -6
  636. package/dist/tools/lib/dgidb-client.js +10 -12
  637. package/dist/tools/lib/disgenet-client.d.ts +4 -4
  638. package/dist/tools/lib/ema-client.d.ts +2 -2
  639. package/dist/tools/lib/ensembl-client.d.ts +4 -4
  640. package/dist/tools/lib/ensembl-client.js +5 -4
  641. package/dist/tools/lib/gwas-catalog-client.d.ts +4 -4
  642. package/dist/tools/lib/gwas-catalog-client.js +17 -17
  643. package/dist/tools/lib/html-text.d.ts +6 -0
  644. package/dist/tools/lib/html-text.js +9 -0
  645. package/dist/tools/lib/identifier-resolver.d.ts +4 -4
  646. package/dist/tools/lib/identifier-resolver.js +7 -3
  647. package/dist/tools/lib/impc-client.d.ts +8 -8
  648. package/dist/tools/lib/impc-client.js +46 -35
  649. package/dist/tools/lib/iuphar-client.d.ts +2 -2
  650. package/dist/tools/lib/iuphar-client.js +7 -16
  651. package/dist/tools/lib/monarch-client.d.ts +4 -4
  652. package/dist/tools/lib/openfda-client.d.ts +22 -22
  653. package/dist/tools/lib/openfda-client.js +23 -22
  654. package/dist/tools/lib/opentargets-client.d.ts +12 -12
  655. package/dist/tools/lib/pathway-client.d.ts +4 -4
  656. package/dist/tools/lib/pathway-client.js +15 -19
  657. package/dist/tools/lib/pharmgkb-client.d.ts +2 -2
  658. package/dist/tools/lib/pharmgkb-client.js +1 -1
  659. package/dist/tools/lib/protein-family-modality.d.ts +2 -2
  660. package/dist/tools/lib/protein-family-modality.js +0 -2
  661. package/dist/tools/lib/protein-family-normalize.js +7 -0
  662. package/dist/tools/lib/pubchem-client.d.ts +2 -2
  663. package/dist/tools/lib/pubchem-client.js +1 -0
  664. package/dist/tools/lib/pubchem-ops.d.ts +4 -4
  665. package/dist/tools/lib/pubchem-ops.js +8 -0
  666. package/dist/tools/lib/pubmed-client.d.ts +9 -9
  667. package/dist/tools/lib/pubmed-client.js +1 -1
  668. package/dist/tools/lib/string-client.d.ts +6 -6
  669. package/dist/tools/lib/uniprot-client.d.ts +8 -8
  670. package/dist/tools/lib/uniprot-client.js +5 -1
  671. package/dist/tools/memory/update-working-memory.d.ts +16 -13
  672. package/dist/tools/memory/update-working-memory.js +21 -3
  673. package/dist/tools/read-tool-output.js +8 -2
  674. package/dist/tools/registry.d.ts +2 -2
  675. package/dist/tools/report-authoring/authoring-tools.d.ts +54 -23
  676. package/dist/tools/report-authoring/authoring-tools.js +128 -62
  677. package/dist/tools/report-session/derive-table.d.ts +19 -59
  678. package/dist/tools/report-session/derive-table.js +120 -122
  679. package/dist/tools/report-session/examine-page.d.ts +6 -6
  680. package/dist/tools/report-session/examine-page.js +14 -12
  681. package/dist/tools/report-session/list-artifacts.d.ts +6 -6
  682. package/dist/tools/report-session/list-artifacts.js +5 -5
  683. package/dist/tools/report-session/page-faults.d.ts +6 -6
  684. package/dist/tools/report-session/page-faults.js +3 -1
  685. package/dist/tools/report-session/preview-report.d.ts +4 -3
  686. package/dist/tools/report-session/preview-report.js +26 -7
  687. package/dist/tools/report-session/record-version.d.ts +9 -4
  688. package/dist/tools/report-session/record-version.js +16 -9
  689. package/dist/tools/report-session/session-page-publisher.d.ts +6 -6
  690. package/dist/tools/research/generate-analogy-report.d.ts +14 -7
  691. package/dist/tools/research/generate-analogy-report.js +80 -76
  692. package/dist/tools/research/generate-plan.d.ts +16 -16
  693. package/dist/tools/research/generate-plan.js +410 -374
  694. package/dist/tools/research/guarded-address.js +3 -2
  695. package/dist/tools/research/inspect-data-profile.d.ts +27 -20
  696. package/dist/tools/research/inspect-data-profile.js +26 -25
  697. package/dist/tools/research/inspect-run.d.ts +54 -27
  698. package/dist/tools/research/inspect-run.js +50 -40
  699. package/dist/tools/research/literature-reviewer.d.ts +8 -7
  700. package/dist/tools/research/literature-reviewer.js +29 -28
  701. package/dist/tools/research/search-arxiv.d.ts +1 -1
  702. package/dist/tools/research/search-arxiv.js +1 -1
  703. package/dist/tools/research/search-github-repos.d.ts +10 -7
  704. package/dist/tools/research/search-github-repos.js +25 -22
  705. package/dist/tools/research/search-semantic-scholar.js +1 -1
  706. package/dist/tools/research/searxng-engine.d.ts +2 -2
  707. package/dist/tools/research/searxng-engine.js +6 -4
  708. package/dist/tools/research/web-fetch.d.ts +24 -21
  709. package/dist/tools/research/web-fetch.js +65 -74
  710. package/dist/tools/research/web-search.d.ts +26 -17
  711. package/dist/tools/research/web-search.js +26 -21
  712. package/dist/tools/sandbox/link-packages.d.ts +11 -7
  713. package/dist/tools/sandbox/link-packages.js +11 -8
  714. package/dist/tools/sandbox/list-available-packages.d.ts +17 -8
  715. package/dist/tools/sandbox/list-available-packages.js +31 -25
  716. package/dist/tools/sandbox/list-available-refs.d.ts +17 -14
  717. package/dist/tools/sandbox/list-available-refs.js +61 -36
  718. package/dist/tools/sandbox/report-blocker.d.ts +30 -37
  719. package/dist/tools/sandbox/report-blocker.js +23 -73
  720. package/dist/tools/sandbox/skills.d.ts +16 -12
  721. package/dist/tools/sandbox/skills.js +16 -12
  722. package/dist/tools/sandbox/submit-file-metadata.d.ts +12 -9
  723. package/dist/tools/sandbox/submit-file-metadata.js +18 -21
  724. package/dist/tools/start-report-session.d.ts +13 -5
  725. package/dist/tools/start-report-session.js +35 -8
  726. package/dist/tools/terminal-text.d.ts +5 -2
  727. package/dist/tools/terminal-text.js +35 -3
  728. package/dist/tools/workspace/decision-record.d.ts +4 -4
  729. package/dist/tools/workspace/decision-record.js +23 -13
  730. package/dist/tools/workspace/edit-file.d.ts +59 -20
  731. package/dist/tools/workspace/edit-file.js +81 -16
  732. package/dist/tools/workspace/execute-command.d.ts +15 -13
  733. package/dist/tools/workspace/execute-command.js +11 -9
  734. package/dist/tools/workspace/file-stat.d.ts +6 -3
  735. package/dist/tools/workspace/grep.d.ts +10 -7
  736. package/dist/tools/workspace/grep.js +9 -3
  737. package/dist/tools/workspace/list-files.d.ts +6 -3
  738. package/dist/tools/workspace/mutator.d.ts +28 -15
  739. package/dist/tools/workspace/mutator.js +107 -53
  740. package/dist/tools/workspace/read-file.d.ts +8 -5
  741. package/dist/tools/workspace/result-bounds.d.ts +5 -5
  742. package/dist/tools/workspace/result-bounds.js +4 -2
  743. package/dist/tools/workspace/run-exec.d.ts +2 -2
  744. package/dist/tools/workspace/run-exec.js +3 -3
  745. package/dist/tools/workspace/scan-inputs.d.ts +8 -5
  746. package/dist/tools/workspace/scan-inputs.js +17 -5
  747. package/dist/tools/workspace/show-file.d.ts +1 -1
  748. package/dist/tools/workspace/show-file.js +2 -1
  749. package/dist/tools/workspace/show-plan.d.ts +8 -5
  750. package/dist/tools/workspace/show-plan.js +9 -8
  751. package/dist/tools/workspace/workspace-search.d.ts +41 -13
  752. package/dist/tools/workspace/workspace-search.js +27 -14
  753. package/dist/tools/workspace/write-file.d.ts +9 -7
  754. package/dist/workflows/execute-analysis-scheduler.d.ts +9 -9
  755. package/dist/workflows/execute-analysis-scheduler.js +6 -3
  756. package/dist/workflows/execute-analysis.d.ts +46 -62
  757. package/dist/workflows/execute-analysis.js +137 -219
  758. package/dist/workflows/pause.d.ts +71 -0
  759. package/dist/workflows/pause.js +173 -0
  760. package/dist/workflows/sandbox-step.d.ts +38 -61
  761. package/dist/workflows/sandbox-step.js +99 -106
  762. package/dist/workflows/test/sql-writes.d.ts +21 -0
  763. package/dist/workflows/test/sql-writes.js +36 -0
  764. package/dist/workspace/filesystem.d.ts +6 -6
  765. package/dist/workspace/filesystem.js +10 -8
  766. package/dist/workspace/paths.d.ts +1 -1
  767. package/dist/workspace/paths.js +15 -4
  768. package/dist/workspace/search-config.d.ts +2 -2
  769. package/dist/workspace/search-config.js +1 -1
  770. package/package.json +21 -22
  771. package/dist/loop/call-guard.d.ts +0 -50
  772. package/dist/loop/call-guard.js +0 -90
  773. package/dist/loop/continue-agent.d.ts +0 -40
  774. package/dist/loop/continue-agent.js +0 -38
  775. package/dist/loop/genai-spans.d.ts +0 -47
  776. package/dist/loop/genai-spans.js +0 -134
  777. package/dist/loop/run-agent.d.ts +0 -245
  778. package/dist/loop/run-agent.js +0 -1124
  779. package/dist/loop/run-step.d.ts +0 -29
  780. package/dist/loop/run-step.js +0 -34
  781. package/dist/loop/run-to-terminal.d.ts +0 -66
  782. package/dist/loop/run-to-terminal.js +0 -93
  783. package/dist/loop/tool-mask.d.ts +0 -23
  784. package/dist/loop/tool-mask.js +0 -46
  785. package/dist/providers/streaming-chat.d.ts +0 -32
  786. package/dist/providers/streaming-chat.js +0 -91
  787. package/dist/tasks/derive-table-exec.d.ts +0 -54
  788. package/dist/tasks/derive-table-exec.js +0 -86
  789. package/dist/workflows/suspension.d.ts +0 -32
  790. package/dist/workflows/suspension.js +0 -38
@@ -1,5 +1,7 @@
1
- import { createHash } from "node:crypto";
2
- import { streamText, wrapLanguageModel, } from "ai";
1
+ import { errorOf, errorNameOf } from "../lib/thrown.js";
2
+ import { textOf } from "../lib/unknown-text.js";
3
+ import { createHash, randomUUID } from "node:crypto";
4
+ import { wrapLanguageModel } from "ai";
3
5
  import { createAnthropic } from "@ai-sdk/anthropic";
4
6
  // Any `providerOptions.anthropic.thinking` bypasses this table's thinking
5
7
  // selection (see `thinkingWithBinding`).
@@ -10,11 +12,12 @@ import { OpenTelemetry } from "@ai-sdk/otel";
10
12
  import { APICallError } from "@ai-sdk/provider";
11
13
  import { retryWithExponentialBackoff } from "@ai-sdk/provider-utils";
12
14
  import { trace } from "@opentelemetry/api";
13
- import { ResultAsync, err, ok } from "neverthrow";
14
15
  import { scopeWorkloadId } from "../auth/types.js";
15
16
  import { createNoopLogger } from "../lib/console-logger.js";
16
- import { passThroughTracer } from "../lib/otel-spans.js";
17
- import { DEFAULT_SUSPEND_ON, classifyProviderError, RequestTimeoutError, toProviderError } from "./errors.js";
17
+ import { ResultError } from "../lib/result.js";
18
+ import { isUnknownArray } from "../lib/unknown-array.js";
19
+ import { parseUnknownRecord } from "../lib/unknown-containers.js";
20
+ import { DEFAULT_SUSPEND_ON, classifyProviderError, extractStatus, RequestTimeoutError, toProviderError, } from "./errors.js";
18
21
  import { DEFAULT_REASONING } from "./reasoning.js";
19
22
  import { headersRefusalError, requestHeadersFor } from "./request-headers.js";
20
23
  /**
@@ -55,14 +58,15 @@ export const DEFAULT_MAX_OUTPUT_TOKENS = 64_000;
55
58
  * provider over a boot shares one sink.
56
59
  */
57
60
  function routeSdkWarningsTo(logger) {
58
- const g = globalThis;
59
- if (g.AI_SDK_LOG_WARNINGS !== undefined)
61
+ // The SDK names a global that no declaration of `globalThis` describes, so the install reads and
62
+ // writes the key reflectively.
63
+ if (Reflect.get(globalThis, "AI_SDK_LOG_WARNINGS") !== undefined)
60
64
  return;
61
- g.AI_SDK_LOG_WARNINGS = (options) => {
65
+ Reflect.set(globalThis, "AI_SDK_LOG_WARNINGS", (options) => {
62
66
  for (const warning of options.warnings) {
63
67
  logger.warn("ai sdk warning", { provider: options.provider, model: options.model, warning });
64
68
  }
65
- };
69
+ });
66
70
  }
67
71
  function workloadOf(session) {
68
72
  return `${session.scope.kind}:${scopeWorkloadId(session.scope)}`;
@@ -108,55 +112,49 @@ function thinkingWithBinding(reasoning, mode) {
108
112
  * because the AI SDK has no part for a model hop, and it drops the block from the
109
113
  * content it returns (`anthropic-messages-language-model`, the `content_block_start`
110
114
  * case). Thus the turn the harness holds is not the turn the API produced, and every
111
- * signed thinking block of that turn is rejected from the next request on. This reader
112
- * is what lets {@link settleFallbackReply} see the hop the content no longer shows.
115
+ * signed thinking block of that turn is rejected from the next request on.
116
+ *
117
+ * The API holds the whole turn against the signature of each of its thinking blocks, so
118
+ * echoing that turn earns `thinking ... blocks in the latest assistant message cannot be
119
+ * modified`, which is a 400 that no retry can pass. A thinking block is optional on the
120
+ * way back, thus the loop records the reply of a hop with no thinking block, and the next
121
+ * request continues. The cost is the reasoning of this one turn and the cache write that
122
+ * its new prefix pays for.
123
+ *
124
+ * The response metadata of the package carries `message_start.message.model`, and that
125
+ * field keeps the REQUESTED model across a hop. The iteration names the model that
126
+ * answered, thus it wins for the usage record.
113
127
  */
114
- function fallbackModelOf(metadata) {
128
+ export function fallbackModelOf(metadata) {
115
129
  const entries = metadata?.["anthropic"]?.["iterations"];
116
- if (!Array.isArray(entries))
130
+ if (!isUnknownArray(entries))
117
131
  return undefined;
118
132
  for (const entry of entries) {
119
- if (typeof entry !== "object" || entry === null)
133
+ const record = parseUnknownRecord(entry);
134
+ if (record === undefined || !("type" in record))
120
135
  continue;
121
- const fields = entry;
122
- if (fields["type"] !== "fallback_message")
136
+ if (record["type"] !== "fallback_message")
123
137
  continue;
124
- return typeof fields["model"] === "string" ? fields["model"] : "";
138
+ return "model" in record && typeof record["model"] === "string" ? record["model"] : "";
125
139
  }
126
140
  return undefined;
127
141
  }
128
- /**
129
- * The assistant message with no thinking block, and with `""` for content when it held
130
- * nothing else. An empty message reaches no wire: `sanitizeMessages` drops it.
131
- */
132
- function withoutThinking(message) {
133
- if (typeof message.content === "string")
134
- return message;
135
- const content = message.content.filter((part) => part.type !== "reasoning" && part.type !== "reasoning-file");
136
- if (content.length === message.content.length)
137
- return message;
138
- return content.length === 0 ? { ...message, content: "" } : { ...message, content };
139
- }
140
142
  /** Reads `providerMetadata.anthropic.inputTransformations`; empty for another vendor. */
141
143
  function inputTransformationsOf(metadata) {
142
144
  const entries = metadata?.["anthropic"]?.["inputTransformations"];
143
- if (!Array.isArray(entries))
145
+ if (!isUnknownArray(entries))
144
146
  return [];
145
147
  return entries.map((entry) => {
146
- const fields = typeof entry === "object" && entry !== null ? entry : {};
148
+ const record = parseUnknownRecord(entry);
147
149
  const text = (key) => {
148
- const value = fields[key];
150
+ const value = record?.[key];
149
151
  return typeof value === "string" ? value : undefined;
150
152
  };
151
153
  return { type: text("type"), path: text("path"), reason: text("reason") };
152
154
  });
153
155
  }
154
156
  function isAbortError(value) {
155
- if (value instanceof DOMException && value.name === "AbortError")
156
- return true;
157
- if (value instanceof Error && value.name === "AbortError")
158
- return true;
159
- return false;
157
+ return errorNameOf(value) === "AbortError";
160
158
  }
161
159
  /**
162
160
  * Locate an `APICallError` on the throwable itself or one hop down its `cause`.
@@ -167,7 +165,9 @@ function isAbortError(value) {
167
165
  function apiCallErrorOf(error) {
168
166
  if (APICallError.isInstance(error))
169
167
  return error;
170
- const cause = error?.cause;
168
+ if (error === null || typeof error !== "object" || !("cause" in error))
169
+ return undefined;
170
+ const cause = error.cause;
171
171
  if (APICallError.isInstance(cause))
172
172
  return cause;
173
173
  return undefined;
@@ -282,8 +282,9 @@ export function failureOf(e, workload, suspendOn) {
282
282
  * timeout. Without this guard the envelope would loop an expiry that the caller
283
283
  * itself declared.
284
284
  */
285
- export function createRetry(signal, logger, maxRetries, suspendOn, hookCall) {
285
+ export function createRetry(signal, logger, maxRetries, suspendOn, hookCall, onRetry) {
286
286
  let retryCount = 0;
287
+ const requestId = randomUUID();
287
288
  return retryWithExponentialBackoff({
288
289
  maxRetries,
289
290
  initialDelayInMs: RETRY_INITIAL_DELAY_MS,
@@ -294,6 +295,8 @@ export function createRetry(signal, logger, maxRetries, suspendOn, hookCall) {
294
295
  const delayMs = computeRetryDelayMs(error, exponentialBackoffDelay);
295
296
  retryCount += 1;
296
297
  logger.debug("retrying provider call", { attempt: retryCount, delayMs, ...logger.errorFields(error) });
298
+ const status = extractStatus(error);
299
+ onRetry?.({ requestId, attempt: retryCount, maxRetries, delayMs, status: status !== undefined && status >= 400 ? status : undefined });
297
300
  return delayMs;
298
301
  },
299
302
  createRetryError: ({ message, errors }) => {
@@ -315,9 +318,7 @@ export function createRetry(signal, logger, maxRetries, suspendOn, hookCall) {
315
318
  * `@ai-sdk/openai-compatible` maps `prompt_tokens_details.cached_tokens` →
316
319
  * `cacheReadTokens` (it never reports a write — that family caches
317
320
  * server-side, with no billed write step). Reading the neutral field is
318
- * therefore both correct and vendor-agnostic; the raw vendor payload remains
319
- * available under `providerMetadata.anthropic.usage` for debugging, in the
320
- * vendor's own snake_case.
321
+ * therefore both correct and vendor-agnostic.
321
322
  *
322
323
  * `inputTokens` is the total billed prefix, cache reads included.
323
324
  *
@@ -325,134 +326,24 @@ export function createRetry(signal, logger, maxRetries, suspendOn, hookCall) {
325
326
  * count and is copied verbatim: providers disagree on whether reasoning tokens
326
327
  * are already inside the output total, so the harness reconciles nothing.
327
328
  */
328
- function toChatUsage(usage) {
329
+ export function toChatUsage(usage) {
329
330
  if (usage === undefined)
330
331
  return undefined;
331
332
  return {
332
333
  inputTokens: usage.inputTokens,
333
334
  outputTokens: usage.outputTokens,
334
- cacheCreationInputTokens: usage.inputTokenDetails?.cacheWriteTokens,
335
- cacheReadInputTokens: usage.inputTokenDetails?.cacheReadTokens,
336
- reasoningTokens: usage.outputTokenDetails?.reasoningTokens,
335
+ cacheCreationInputTokens: usage.inputTokenDetails.cacheWriteTokens,
336
+ cacheReadInputTokens: usage.inputTokenDetails.cacheReadTokens,
337
+ reasoningTokens: usage.outputTokenDetails.reasoningTokens,
337
338
  };
338
339
  }
339
- /** The id of the model bound into this provider — a bare id string is its own id. */
340
- function requestedModelIdOf(model) {
341
- return typeof model === "string" ? model : model.modelId;
342
- }
343
- /** The provider id of the model bound into this provider, as the AI SDK names it — a bare id string names no provider. */
344
- function providerIdOf(model) {
345
- return typeof model === "string" ? undefined : model.provider;
346
- }
347
- /**
348
- * Capture the served model id at the raw model boundary, because that is the
349
- * only place it is still distinguishable from the requested one: `streamText`
350
- * coalesces an unreported response model id to the bound model's own id, so
351
- * reading `result.response.modelId` would silently republish the requested id
352
- * as an endpoint's claim. A middleware sees the provider's
353
- * result before that fallback applies, so "reported nothing" stays absent.
354
- *
355
- * Built per call, never per provider: one provider instance serves concurrent
356
- * calls, and a shared mutable slot would hand one call another's answer. A bare
357
- * model-id string has no wire result to observe, so it captures nothing.
358
- */
359
- function captureServedModelId(model) {
360
- if (typeof model === "string")
361
- return { model, servedModelId: () => undefined };
362
- let served;
363
- const wrapped = wrapLanguageModel({
364
- model,
365
- middleware: {
366
- wrapGenerate: async ({ doGenerate }) => {
367
- const result = await doGenerate();
368
- served = result.response?.modelId;
369
- return result;
370
- },
371
- wrapStream: async ({ doStream }) => {
372
- const result = await doStream();
373
- return {
374
- ...result,
375
- stream: result.stream.pipeThrough(new TransformStream({
376
- transform(chunk, controller) {
377
- if (chunk.type === "response-metadata" && chunk.modelId !== undefined)
378
- served = chunk.modelId;
379
- controller.enqueue(chunk);
380
- },
381
- })),
382
- };
383
- },
384
- },
385
- });
386
- return { model: wrapped, servedModelId: () => served };
387
- }
388
- function responseFromMessages(input) {
389
- const { messages, fallbackText, finishReason, rawFinishReason, requestedModelId, servedModelId, provider } = input;
390
- const usage = toChatUsage(input.usage);
391
- const message = [...messages].reverse().find((m) => m.role === "assistant");
392
- if (message === undefined) {
393
- return { message: { role: "assistant", content: fallbackText }, finishReason, rawFinishReason, usage, requestedModelId, servedModelId, provider };
394
- }
395
- return { message, finishReason, rawFinishReason, usage, requestedModelId, servedModelId, provider };
396
- }
397
- /**
398
- * Drop empty text parts — and messages left with no content at all — before
399
- * the wire call. The Anthropic Messages API rejects any request containing an
400
- * empty text block, and the SDK's own response assembly legitimately produces
401
- * them: a turn that goes straight to tool calls yields an assistant message
402
- * carrying a ""-text part, which the agent loop then echoes back as history
403
- * on its next request. Filtering once at the outbound boundary covers every
404
- * source at once — loop echo, stored thread history, legacy backfill, and the
405
- * empty-string fallback in `responseFromMessages`.
406
- */
407
- function sanitizeMessages(messages) {
408
- const out = [];
409
- for (const m of messages) {
410
- if (typeof m.content === "string") {
411
- if (m.content !== "")
412
- out.push(m);
413
- continue;
414
- }
415
- const parts = m.content.filter((p) => p.type !== "text" || p.text !== "");
416
- // The filtered parts are a subset of this message's own content, so the
417
- // message remains valid for its role — the cast only re-associates the
418
- // narrowed array with the union member TS can no longer correlate.
419
- if (parts.length > 0)
420
- out.push({ ...m, content: parts });
421
- }
422
- return out;
423
- }
424
- /**
425
- * Advance the SDK stream to the next text delta.
426
- *
427
- * The full stream carries one part for each event of a turn, and only a text
428
- * part reaches the consumer of the harness. Thus the pull skips each other part.
429
- * The `abort` part stops the pull, because the SDK closes the stream directly
430
- * after it. Thus a timeout can never end the stream in silence with the text
431
- * that arrived before it.
432
- */
433
- async function pullNextDelta(iterator) {
434
- for (let next = await iterator.next(); next.done !== true; next = await iterator.next()) {
435
- const part = next.value;
436
- if (part.type === "text-delta")
437
- return { kind: "delta", text: part.text };
438
- if (part.type === "abort")
439
- return { kind: "aborted", reason: part.reason };
440
- // The SDK reports a wire failure as a part, not as a rejection, and it
441
- // then closes the stream. Skipping it would turn a failed call into an
442
- // empty assistant turn that the loop reads as a real answer.
443
- if (part.type === "error")
444
- return { kind: "failed", error: part.error };
445
- }
446
- return { kind: "end" };
447
- }
448
340
  /**
449
341
  * The HTTP status that each Anthropic stream error type stands for.
450
342
  *
451
343
  * A provider names a mid-stream failure in the payload, not in the status line:
452
344
  * a stream that carries `overloaded_error` reports the condition that a 529
453
345
  * names on the non-streaming wire. The classifier reads the status alone, thus
454
- * the part has to reach it as an error that names one, or the same condition
455
- * would classify one way on `chat` and another way on `chatStream`.
346
+ * the part has to reach it as an error that names one.
456
347
  */
457
348
  const STREAM_ERROR_STATUS = {
458
349
  invalid_request_error: 400,
@@ -466,20 +357,20 @@ const STREAM_ERROR_STATUS = {
466
357
  overloaded_error: 529,
467
358
  };
468
359
  /**
469
- * The failure that an `error` part of the SDK stream stands for.
360
+ * The failure that an `error` part of the model stream stands for.
470
361
  *
471
362
  * The part carries whatever the provider put on the wire, and that is often a
472
363
  * bare object rather than an `Error`. Left as it is, it reaches the message as
473
364
  * `[object Object]` and reaches the classifier with no status at all.
474
365
  */
475
366
  function streamPartFailure(error) {
476
- if (error instanceof Error)
477
- return error;
367
+ const thrownError = errorOf(error);
368
+ if (thrownError !== undefined)
369
+ return thrownError;
478
370
  if (typeof error !== "object" || error === null)
479
- return new Error(String(error));
480
- const reported = error;
481
- const type = typeof reported.type === "string" ? reported.type : undefined;
482
- const message = typeof reported.message === "string" ? reported.message : undefined;
371
+ return new Error(textOf(error));
372
+ const type = "type" in error && typeof error.type === "string" ? error.type : undefined;
373
+ const message = "message" in error && typeof error.message === "string" ? error.message : undefined;
483
374
  const failure = new Error(message ?? type ?? "The provider reported a stream error.", { cause: error });
484
375
  const status = type === undefined ? undefined : STREAM_ERROR_STATUS[type];
485
376
  // `extractStatus` walks the chain for this field, thus the named condition
@@ -489,344 +380,215 @@ function streamPartFailure(error) {
489
380
  return failure;
490
381
  }
491
382
  /**
492
- * The failure that an `abort` part of the SDK stream stands for.
493
- *
494
- * The part carries a message only, thus the caller signal is the one thing that
495
- * separates a cancellation from a timeout. When the caller signal is aborted,
496
- * the reason of that signal rides out, and the cancellation path applies
497
- * unchanged. Otherwise the SDK chunk bound stopped the stream, and the sentinel
498
- * names the configured value for the classifier.
383
+ * A part that the reader of a reply can see. A retry after one would show the
384
+ * reader the start of the reply again, thus a live call retries only before the
385
+ * first one. The same parts reset the silent-interval bound: a part that carries
386
+ * no content does not prove that the model writes.
499
387
  */
500
- function abortedStreamFailure(signal, reason, requestTimeoutMs) {
501
- if (signal?.aborted === true)
502
- return signal.reason;
503
- if (requestTimeoutMs !== undefined)
504
- return new RequestTimeoutError(requestTimeoutMs);
505
- return new Error(reason ?? "The provider aborted the stream.");
388
+ function isOutputPart(part) {
389
+ return part.type !== "stream-start" && part.type !== "response-metadata" && part.type !== "raw";
506
390
  }
507
- /** The `gen_ai.operation.name` of the operation span and of the step span that the AI SDK opens around each `chat` span. */
508
- function isSdkWrapperSpan(operation) {
509
- return operation === "invoke_agent" || operation === "agent_step";
391
+ /**
392
+ * A reader of one model stream under the silent-interval bound. The bound runs
393
+ * from the start of the read, and each output part resets it. A part with no
394
+ * content leaves the bound as it was.
395
+ */
396
+ function boundedReader(stream, timeoutMs) {
397
+ const reader = stream.getReader();
398
+ let deadline = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
399
+ return {
400
+ async read() {
401
+ if (deadline === undefined || timeoutMs === undefined) {
402
+ const next = await reader.read();
403
+ return next.done ? { done: true } : { done: false, value: next.value };
404
+ }
405
+ const remaining = Math.max(deadline - performance.now(), 0);
406
+ let timer;
407
+ const expiry = new Promise((_resolve, reject) => {
408
+ // oxlint-disable-next-line eslint-js/no-restricted-syntax -- a guard, not a wait: it rejects the read of a silent stream at the bound, unrefs so an armed guard never holds a short-lived process, and the finally clears it.
409
+ timer = setTimeout(() => reject(new RequestTimeoutError(timeoutMs)), remaining);
410
+ timer.unref();
411
+ });
412
+ try {
413
+ const next = await Promise.race([reader.read(), expiry]);
414
+ if (next.done)
415
+ return { done: true };
416
+ if (isOutputPart(next.value))
417
+ deadline = performance.now() + timeoutMs;
418
+ return { done: false, value: next.value };
419
+ }
420
+ catch (e) {
421
+ void reader.cancel(e).catch(() => undefined);
422
+ throw e;
423
+ }
424
+ finally {
425
+ clearTimeout(timer);
426
+ }
427
+ },
428
+ cancel(reason) {
429
+ void reader.cancel(reason).catch(() => undefined);
430
+ },
431
+ };
432
+ }
433
+ /**
434
+ * The retry envelope of a model call, as a model middleware.
435
+ *
436
+ * Each attempt resolves the request headers of the host first: a host header can
437
+ * be time-limited, and the retry window can last minutes. A live call retries
438
+ * until its first output part, because a reader already saw each part after it.
439
+ * A call with no live reader takes the whole reply inside the attempt, thus a
440
+ * failure at any point of the stream runs the whole attempt again.
441
+ *
442
+ * After the last attempt, the failure leaves as a `ResultError` that carries the
443
+ * classified `ProviderError`. An abort and a rejection of the headers hook leave
444
+ * unchanged.
445
+ */
446
+ function retryEnvelope(options) {
447
+ const { session, live, logger, maxRetries, suspendOn, requestTimeoutMs, onRetry } = options;
448
+ const workload = workloadOf(session);
449
+ /** The one record of a call that the envelope gave up on: the reply carries the failure, and the operator sees this. */
450
+ const failed = (thrown) => {
451
+ const failure = failureOf(thrown, workload, suspendOn);
452
+ logger.error("provider call failed", { workload, kind: failure.type, retryable: failure.retryable, ...logger.errorFields(thrown) });
453
+ return new ResultError(failure);
454
+ };
455
+ const observeFinish = (part) => {
456
+ if (part.type !== "finish")
457
+ return;
458
+ for (const drop of inputTransformationsOf(part.providerMetadata)) {
459
+ logger.warn("thinking block dropped", { workload, type: drop.type, path: drop.path, reason: drop.reason });
460
+ }
461
+ const servedBy = fallbackModelOf(part.providerMetadata);
462
+ if (servedBy !== undefined) {
463
+ logger.warn("reply served by a fallback model, thus the harness drops the thinking of that turn", {
464
+ workload,
465
+ servedBy: servedBy === "" ? undefined : servedBy,
466
+ });
467
+ }
468
+ };
469
+ return {
470
+ specificationVersion: "v4",
471
+ wrapStream: async ({ params, model }) => {
472
+ const signal = params.abortSignal;
473
+ const hookCall = { unsettled: false };
474
+ const retry = createRetry(signal, logger, maxRetries, suspendOn, hookCall, onRetry);
475
+ let opened;
476
+ try {
477
+ opened = await retry(async () => {
478
+ const headers = await headersForAttempt(options.resolveRequestHeaders, session, hookCall);
479
+ const { stream, ...rest } = await model.doStream({ ...params, headers: { ...params.headers, ...headers } });
480
+ const reader = boundedReader(stream, requestTimeoutMs);
481
+ const head = [];
482
+ for (let next = await reader.read(); !next.done; next = await reader.read()) {
483
+ const part = next.value;
484
+ // The provider reports a wire failure as a part, and then it closes the stream.
485
+ if (part.type === "error") {
486
+ reader.cancel();
487
+ throw streamPartFailure(part.error);
488
+ }
489
+ head.push(part);
490
+ if (live && isOutputPart(part))
491
+ return { rest, head, tail: reader };
492
+ }
493
+ return { rest, head };
494
+ });
495
+ }
496
+ catch (e) {
497
+ if (isAbortError(e) || signal?.aborted === true || hookCall.unsettled)
498
+ throw e;
499
+ throw failed(e);
500
+ }
501
+ const { rest, head, tail } = opened;
502
+ const stream = new ReadableStream({
503
+ start(controller) {
504
+ for (const part of head) {
505
+ observeFinish(part);
506
+ controller.enqueue(part);
507
+ }
508
+ if (tail === undefined)
509
+ controller.close();
510
+ },
511
+ async pull(controller) {
512
+ if (tail === undefined)
513
+ return;
514
+ try {
515
+ const next = await tail.read();
516
+ if (next.done) {
517
+ controller.close();
518
+ return;
519
+ }
520
+ const part = next.value;
521
+ if (part.type === "error") {
522
+ tail.cancel();
523
+ controller.enqueue({ type: "error", error: failed(streamPartFailure(part.error)) });
524
+ controller.close();
525
+ return;
526
+ }
527
+ observeFinish(part);
528
+ controller.enqueue(part);
529
+ }
530
+ catch (e) {
531
+ // Past the first output part, a failure ends the reply with no retry: the reader saw its start.
532
+ if (isAbortError(e) || signal?.aborted === true) {
533
+ controller.error(e);
534
+ return;
535
+ }
536
+ controller.enqueue({ type: "error", error: failed(e) });
537
+ controller.close();
538
+ }
539
+ },
540
+ cancel(reason) {
541
+ tail?.cancel(reason);
542
+ },
543
+ });
544
+ return { ...rest, stream };
545
+ },
546
+ };
510
547
  }
511
548
  export function createAiSdkProvider(deps) {
512
549
  const capabilities = {
513
550
  toolCalling: deps.capabilities?.toolCalling ?? true,
514
551
  // Propagate a picture flag only when the caller states it. An absent
515
- // flag stays absent, thus the loop degrades to the next placement for a
516
- // wire that carries no picture there.
517
- ...(deps.capabilities?.imageToolResults !== undefined ? { imageToolResults: deps.capabilities.imageToolResults } : {}),
518
- ...(deps.capabilities?.imageUserMessages !== undefined ? { imageUserMessages: deps.capabilities.imageUserMessages } : {}),
519
- ...(deps.capabilities?.contextWindow !== undefined ? { contextWindow: deps.capabilities.contextWindow } : {}),
552
+ // flag stays absent, thus the loop drops a picture for a wire that
553
+ // carries none in a tool result.
554
+ imageToolResults: deps.capabilities?.imageToolResults,
555
+ contextWindow: deps.capabilities?.contextWindow,
520
556
  };
521
557
  const logger = (deps.logger ?? createNoopLogger()).named("providers.ai-sdk");
522
558
  const maxOutputTokens = deps.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
523
559
  // The sentinel hands the SDK no ceiling, thus the request carries none and the
524
- // server enforces the cap of the model. One binding feeds the call and the
525
- // stream, thus the two cannot disagree about the ceiling of a request.
560
+ // server enforces the cap of the model.
526
561
  const outputCeiling = maxOutputTokens === "provider-maximum" ? {} : { maxOutputTokens };
527
562
  const maxRetries = deps.maxRetries ?? RETRY_MAX_RETRIES;
528
563
  const suspendOn = deps.suspendOn ?? DEFAULT_SUSPEND_ON;
529
564
  const requestTimeoutMs = deps.requestTimeoutMs;
530
- const requestedModelId = requestedModelIdOf(deps.model);
531
- const providerId = providerIdOf(deps.model);
532
- const effortOf = (req) => req.reasoning ?? deps.reasoning ?? DEFAULT_REASONING;
533
- // Each model call emits OpenTelemetry GenAI spans through the AI SDK, with no
534
- // prompt or completion text on them. The integration rides on each call
535
- // instead of the global registry, so the harness never traces the embedder's
536
- // own AI SDK calls. Of the SDK spans only `chat` is written. The operation
537
- // span and the step span around it repeat what `chat` and the span of the
538
- // caller (the loop's `invoke_agent`) say already. Thus they pass through, and
539
- // `chat` attaches to the span of the caller.
540
- const tracer = passThroughTracer(trace.getTracer("gen_ai"), (_name, options) => isSdkWrapperSpan(options.attributes?.["gen_ai.operation.name"]));
541
- const telemetry = { integrations: new OpenTelemetry({ tracer }), recordInputs: false, recordOutputs: false };
565
+ // Each model call and each tool call emits OpenTelemetry GenAI spans through the
566
+ // AI SDK, with no prompt or completion text on them. The integration rides on each
567
+ // call instead of the global registry, so the harness never traces the embedder's
568
+ // own AI SDK calls.
569
+ const telemetry = { integrations: new OpenTelemetry({ tracer: trace.getTracer("gen_ai") }), recordInputs: false, recordOutputs: false };
542
570
  routeSdkWarningsTo(logger);
543
- /**
544
- * Record a call that the envelope gave up on.
545
- *
546
- * The envelope reports one attempt at `debug`, thus a deployment that runs
547
- * at `info` keeps no trace of a call that exhausted its retries: the reply
548
- * carries the failure to the user and the operator sees nothing. This is the
549
- * one record that names the outcome.
550
- */
551
- function logFailure(session, failure, thrown) {
552
- logger.error("provider call failed", {
553
- workload: workloadOf(session),
554
- kind: failure.type,
555
- retryable: failure.retryable,
556
- ...logger.errorFields(thrown),
557
- });
558
- }
559
- /**
560
- * Logs each dropped thinking block; the drop does not fail the call.
561
- * `reason` is `prefix_binding_mismatch` or `model_binding_mismatch`.
562
- */
563
- function logDroppedThinkingBlocks(session, metadata) {
564
- for (const drop of inputTransformationsOf(metadata)) {
565
- logger.warn("thinking block dropped", { workload: workloadOf(session), type: drop.type, path: drop.path, reason: drop.reason });
566
- }
567
- }
568
- /**
569
- * The reply as the harness must hold it when a fallback model served it: with no
570
- * thinking block, and with the model that answered named.
571
- *
572
- * A reply that carries a fallback hop ({@link fallbackModelOf}) reaches the harness
573
- * already short of the `fallback` content block the API put in the turn. The API holds
574
- * the whole turn against the signature of each of its thinking blocks, so echoing that
575
- * turn earns `thinking ... blocks in the latest assistant message cannot be modified`,
576
- * which is a 400 that no retry can pass. The conversation is then dead: the loop sends
577
- * its history on every request, and nothing downstream can repair a turn.
578
- *
579
- * A thinking block is optional on the way back, thus the reply without them is a valid
580
- * turn, and the next request continues. The cost is the reasoning of this one turn and
581
- * the cache write that its new prefix pays for. A reply of nothing but thinking carries
582
- * no part at all, and `sanitizeMessages` drops such a message from the next request.
583
- *
584
- * `servedModelId` needs the same correction. {@link captureServedModelId} reads the id
585
- * the response metadata of the package carries, which is `message_start.message.model`,
586
- * and that field keeps the REQUESTED model across a hop. Published as it stands, it
587
- * makes the usage ledger of an embedder attribute the tokens to the model that refused
588
- * the work. The iteration names the model that answered, thus it wins. An iteration that
589
- * names no model changes nothing: there is no better id to publish, and the record above
590
- * is then the only account of the hop.
591
- */
592
- function settleFallbackReply(session, response, metadata) {
593
- const servedBy = fallbackModelOf(metadata);
594
- if (servedBy === undefined)
595
- return response;
596
- logger.warn("reply served by a fallback model, thus the harness drops the thinking of that turn", {
597
- workload: workloadOf(session),
598
- ...(servedBy === "" ? {} : { servedBy }),
571
+ function bind(call) {
572
+ const reasoning = call.reasoning ?? deps.reasoning ?? DEFAULT_REASONING;
573
+ const model = wrapLanguageModel({
574
+ model: deps.model,
575
+ middleware: retryEnvelope({
576
+ session: call.session,
577
+ live: call.live,
578
+ logger,
579
+ maxRetries,
580
+ suspendOn,
581
+ requestTimeoutMs,
582
+ resolveRequestHeaders: deps.resolveRequestHeaders,
583
+ onRetry: call.onRetry,
584
+ }),
599
585
  });
600
- return {
601
- ...response,
602
- message: withoutThinking(response.message),
603
- ...(servedBy === "" ? {} : { servedModelId: servedBy }),
604
- };
605
- }
606
- function chat(req, session, signal) {
607
- const reasoning = effortOf(req);
608
- const providerOptions = deps.providerOptionsFor?.({ session, reasoning });
609
- const run = async () => {
610
- const hookCall = { unsettled: false };
611
- const retry = createRetry(signal, logger, maxRetries, suspendOn, hookCall);
612
- const capture = captureServedModelId(deps.model);
613
- try {
614
- const collected = await retry(async () => {
615
- // The hook runs before each attempt: a host header can be
616
- // time-limited, and the retry window can last minutes.
617
- const headers = await headersForAttempt(deps.resolveRequestHeaders, session, hookCall);
618
- // The call streams on the wire and collapses below.
619
- //
620
- // A non-streaming turn sends no header until the model completes,
621
- // thus the `headersTimeout` of the host HTTP client bounds the whole
622
- // generation. No option of the SDK lifts that bound, because it sits
623
- // under the fetch. Node defaults the field to 300s, and a turn near
624
- // 18k output tokens reaches it, while `DEFAULT_MAX_OUTPUT_TOKENS`
625
- // asks for up to 64k. A cut turn then costs twice: the envelope
626
- // starts the same generation again from zero.
627
- //
628
- // Anthropic states the rule for its own SDKs: a large `max_tokens`
629
- // makes streaming necessary, to prevent an HTTP timeout. Thus a
630
- // ceiling this size streams whether or not a consumer wants the
631
- // deltas, and `chatStream` stays the seam that forwards them.
632
- const result = streamText({
633
- model: capture.model,
634
- system: req.system,
635
- messages: sanitizeMessages(req.messages),
636
- tools: req.tools,
637
- toolChoice: req.toolChoice ?? "auto",
638
- ...outputCeiling,
639
- stopWhen: [],
640
- // The harness envelope owns retries; leaving the SDK default in
641
- // place would multiply attempts (10 outer × 3 inner).
642
- maxRetries: 0,
643
- headers,
644
- abortSignal: signal,
645
- telemetry,
646
- // `firstChunkMs` bounds the wait for the first content chunk,
647
- // and `chunkMs` bounds each later gap. Thus each silent interval
648
- // carries the one configured bound, and a turn that writes
649
- // steadily runs as long as it needs.
650
- ...(requestTimeoutMs !== undefined ? { timeout: { firstChunkMs: requestTimeoutMs, chunkMs: requestTimeoutMs } } : {}),
651
- providerOptions,
652
- reasoning,
653
- });
654
- // The drain sits inside the retried closure, thus a failure at any
655
- // point of the stream re-runs the whole attempt and the envelope
656
- // keeps its whole-call scope. No delta reaches a consumer here —
657
- // `chatStream` is the seam that forwards them.
658
- const iterator = result.fullStream[Symbol.asyncIterator]();
659
- let text = "";
660
- for (let pull = await pullNextDelta(iterator); pull.kind !== "end"; pull = await pullNextDelta(iterator)) {
661
- // A caller abort rides out as the reason of its own signal, thus
662
- // it stays a cancellation and reaches the caller as a throw.
663
- if (pull.kind === "aborted")
664
- throw abortedStreamFailure(signal, pull.reason, requestTimeoutMs);
665
- if (pull.kind === "failed")
666
- throw streamPartFailure(pull.error);
667
- text += pull.text;
668
- }
669
- // These promises settle only once the stream is fully drained, thus
670
- // the loop above must reach its end before this point.
671
- return {
672
- messages: await result.responseMessages,
673
- fallbackText: text,
674
- finishReason: await result.finishReason,
675
- rawFinishReason: await result.rawFinishReason,
676
- usage: await result.usage,
677
- providerMetadata: (await result.finalStep).providerMetadata,
678
- };
679
- });
680
- // Logged past the envelope, thus only the attempt that succeeded
681
- // reports its drops.
682
- const { providerMetadata: metadata, ...reply } = collected;
683
- logDroppedThinkingBlocks(session, metadata);
684
- return ok(settleFallbackReply(session, responseFromMessages({
685
- ...reply,
686
- requestedModelId,
687
- // Read after the drain: the metadata chunk that carries the
688
- // served id reaches the capture only as the stream is consumed.
689
- servedModelId: capture.servedModelId(),
690
- provider: providerId,
691
- }), metadata));
692
- }
693
- catch (e) {
694
- if (isAbortError(e) || signal?.aborted || hookCall.unsettled)
695
- throw e;
696
- const failure = failureOf(e, workloadOf(session), suspendOn);
697
- logFailure(session, failure, e);
698
- return err(failure);
699
- }
700
- };
701
- return new ResultAsync(run());
702
- }
703
- async function* chatStream(req, session, signal) {
704
- const reasoning = effortOf(req);
705
- const providerOptions = deps.providerOptionsFor?.({ session, reasoning });
706
- const hookCall = { unsettled: false };
707
- const retry = createRetry(signal, logger, maxRetries, suspendOn, hookCall);
708
- const capture = captureServedModelId(deps.model);
709
- try {
710
- // Retry covers only stream establishment: streamText defers wire errors
711
- // to consumption, so a failure is not visible until the stream is read.
712
- // The retried closure resolves to one of two outcomes — the stream is
713
- // live with a first delta in hand, or it finished without yielding any
714
- // text — and a delta is only ever yielded OUTSIDE the closure, so a
715
- // retried attempt can never re-emit a delta the consumer already saw.
716
- const opened = await retry(async () => {
717
- const headers = await headersForAttempt(deps.resolveRequestHeaders, session, hookCall);
718
- const result = streamText({
719
- model: capture.model,
720
- system: req.system,
721
- messages: sanitizeMessages(req.messages),
722
- tools: req.tools,
723
- toolChoice: req.toolChoice ?? "auto",
724
- ...outputCeiling,
725
- stopWhen: [],
726
- maxRetries: 0,
727
- headers,
728
- abortSignal: signal,
729
- telemetry,
730
- // The fetch guard bounds the wait until the headers. Past the
731
- // headers the SDK owns two bounds: `firstChunkMs` covers the wait
732
- // for the first content chunk, and `chunkMs` covers each later
733
- // gap. The two take the same value, thus each silent interval of
734
- // the stream has the one configured bound. A chunk that carries
735
- // no content, for example a keep-alive comment, produces no part,
736
- // thus it feeds neither bound.
737
- ...(requestTimeoutMs !== undefined ? { timeout: { firstChunkMs: requestTimeoutMs, chunkMs: requestTimeoutMs } } : {}),
738
- providerOptions,
739
- reasoning,
740
- });
741
- const iterator = result.fullStream[Symbol.asyncIterator]();
742
- const first = await pullNextDelta(iterator);
743
- // The chunk bound can stop the stream before any content arrives. The
744
- // throw carries the sentinel, thus the envelope gives the attempt a
745
- // fresh window under the retry policy of a connection error.
746
- if (first.kind === "aborted")
747
- throw abortedStreamFailure(signal, first.reason, requestTimeoutMs);
748
- if (first.kind === "failed")
749
- throw streamPartFailure(first.error);
750
- if (first.kind === "end") {
751
- // A doStream promise rejection — the shape a real connection
752
- // failure takes — does NOT surface at this first pull: streamText
753
- // resolves it `{ done: true }` and defers the rejection to the
754
- // deferred result promises. Awaiting them here brings that failure
755
- // inside the retry envelope so a text-less establishment error is
756
- // retried; a genuine text-less turn resolves them, and the terminal
757
- // event is built from these already-resolved values without a
758
- // second await. (These promises only settle once the stream is
759
- // fully drained, so they can be awaited here only because the pull
760
- // already reported the stream done.)
761
- return {
762
- kind: "completed",
763
- messages: await result.responseMessages,
764
- finishReason: await result.finishReason,
765
- rawFinishReason: await result.rawFinishReason,
766
- usage: await result.usage,
767
- providerMetadata: (await result.finalStep).providerMetadata,
768
- };
769
- }
770
- return { kind: "streaming", result, iterator, firstDelta: first.text };
771
- });
772
- if (opened.kind === "completed") {
773
- logDroppedThinkingBlocks(session, opened.providerMetadata);
774
- const response = settleFallbackReply(session, responseFromMessages({
775
- messages: opened.messages,
776
- fallbackText: "",
777
- finishReason: opened.finishReason,
778
- rawFinishReason: opened.rawFinishReason,
779
- usage: opened.usage,
780
- requestedModelId,
781
- servedModelId: capture.servedModelId(),
782
- provider: providerId,
783
- }), opened.providerMetadata);
784
- yield { type: "done", response };
785
- return;
786
- }
787
- const { result, iterator, firstDelta } = opened;
788
- let text = firstDelta;
789
- yield { type: "text-delta", text: firstDelta };
790
- // Drain the same iterator: past the first delta, errors propagate
791
- // unchanged (no retry, no re-emit).
792
- for (let pull = await pullNextDelta(iterator); pull.kind !== "end"; pull = await pullNextDelta(iterator)) {
793
- // A mid-stream abort ends the turn with an error, never with the
794
- // partial text that arrived before it. The catch below builds the
795
- // terminal `ProviderError` from the throwable.
796
- if (pull.kind === "aborted")
797
- throw abortedStreamFailure(signal, pull.reason, requestTimeoutMs);
798
- if (pull.kind === "failed")
799
- throw streamPartFailure(pull.error);
800
- text += pull.text;
801
- yield { type: "text-delta", text: pull.text };
802
- }
803
- const metadata = (await result.finalStep).providerMetadata;
804
- const response = settleFallbackReply(session, responseFromMessages({
805
- messages: await result.responseMessages,
806
- fallbackText: text,
807
- finishReason: await result.finishReason,
808
- rawFinishReason: await result.rawFinishReason,
809
- usage: await result.usage,
810
- requestedModelId,
811
- // Read after the drain: the metadata chunk carrying the served id
812
- // reaches the capture only as the stream is consumed.
813
- servedModelId: capture.servedModelId(),
814
- provider: providerId,
815
- }), metadata);
816
- logDroppedThinkingBlocks(session, metadata);
817
- yield { type: "done", response };
818
- }
819
- catch (e) {
820
- if (isAbortError(e) || signal?.aborted || hookCall.unsettled)
821
- throw e;
822
- const failure = failureOf(e, workloadOf(session), suspendOn);
823
- logFailure(session, failure, e);
824
- throw failure;
825
- }
586
+ const providerOptions = deps.providerOptionsFor?.({ session: call.session, reasoning });
587
+ return { model, settings: { ...outputCeiling, reasoning, providerOptions }, telemetry };
826
588
  }
827
589
  // The provider advertises the guard limit on its own instance, thus a
828
590
  // consumer that scales a deadline reads it from the provider in its deps.
829
- return { capabilities, chat, chatStream, ...(requestTimeoutMs !== undefined ? { requestTimeoutMs } : {}) };
591
+ return { capabilities, bind, requestTimeoutMs };
830
592
  }
831
593
  /**
832
594
  * Wrap a fetch so that the wait until the response starts does not exceed
@@ -837,24 +599,23 @@ export function createAiSdkProvider(deps) {
837
599
  * signal through `AbortSignal.any`. Thus the caller signal keeps its normal
838
600
  * effect, and a caller abort stays a cancellation.
839
601
  *
840
- * The guard bounds the response start only. The SDK bounds each later gap of a
841
- * streamed body with its own `chunkMs` setting, thus no timer of the wrapper
842
- * survives the headers. Thus a stream with steady content does not trip the
843
- * guard, whatever its total length. One fetch call is one attempt, because the
844
- * SDK retries are off, thus the window is per attempt.
602
+ * The guard bounds the response start only. The retry envelope bounds each later
603
+ * gap of a streamed body, thus no timer of the wrapper survives the headers. One
604
+ * fetch call is one attempt, because the SDK retries are off, thus the window is
605
+ * per attempt.
845
606
  *
846
607
  * When the field is absent, `createConfiguredAiSdkProvider` installs no wrapper,
847
608
  * and the behavior stays byte-identical.
848
609
  */
849
610
  export function wrapFetchWithRequestTimeout(fetchImpl, requestTimeoutMs) {
850
- return async (input, init) => {
611
+ return Object.assign(async (input, init) => {
851
612
  const controller = new AbortController();
852
613
  const callerSignal = init?.signal ?? undefined;
614
+ // oxlint-disable-next-line eslint-js/no-restricted-syntax -- a guard, not a wait: it aborts the controller of the in-flight fetch at the deadline, unrefs so an armed guard never holds a short-lived process, and the finally clears it.
853
615
  const timer = setTimeout(() => controller.abort(new RequestTimeoutError(requestTimeoutMs)), requestTimeoutMs);
854
616
  // The harness runs on Node, where a timer has `unref`. Unref the guard
855
617
  // timer, thus an armed guard does not keep a short-lived process alive.
856
- // The DOM type of `setTimeout` declares no `unref`, thus guard the call.
857
- timer.unref?.();
618
+ timer.unref();
858
619
  const clear = () => {
859
620
  clearTimeout(timer);
860
621
  // The harness runs on Node, where a caller signal can outlive one fetch
@@ -874,7 +635,7 @@ export function wrapFetchWithRequestTimeout(fetchImpl, requestTimeoutMs) {
874
635
  // is inert there. A probe on Bun 1.4.2 proved both results: the cut fired
875
636
  // at 360 seconds, because Bun pads the timer to its minute wheel, and a
876
637
  // request with the key completed after 420 seconds. The `RequestInit` type
877
- // declares no such member, thus the cast.
638
+ // declares no such member, thus the wider annotation.
878
639
  const forwarded = { ...init, signal, timeout: false };
879
640
  try {
880
641
  return await fetchImpl(input, forwarded);
@@ -882,7 +643,10 @@ export function wrapFetchWithRequestTimeout(fetchImpl, requestTimeoutMs) {
882
643
  finally {
883
644
  clear();
884
645
  }
885
- };
646
+ },
647
+ // `typeof fetch` is a callable with the `preconnect` member of the Bun declaration, so the
648
+ // wrapper carries the member of the fetch it wraps.
649
+ { preconnect: fetchImpl.preconnect });
886
650
  }
887
651
  /**
888
652
  * Bind one explicit `store` directive onto each call of a model.
@@ -898,7 +662,7 @@ function withStoreDirective(model, store) {
898
662
  return wrapLanguageModel({
899
663
  model,
900
664
  middleware: {
901
- transformParams: async ({ params }) => ({
665
+ transformParams: ({ params }) => Promise.resolve({
902
666
  ...params,
903
667
  providerOptions: { ...params.providerOptions, openai: { ...params.providerOptions?.openai, store } },
904
668
  }),
@@ -907,22 +671,21 @@ function withStoreDirective(model, store) {
907
671
  }
908
672
  export function hostPolicyOf(deps) {
909
673
  return {
910
- ...(deps.resolveRequestHeaders !== undefined ? { resolveRequestHeaders: deps.resolveRequestHeaders } : {}),
911
- ...(deps.suspendOn !== undefined ? { suspendOn: deps.suspendOn } : {}),
674
+ resolveRequestHeaders: deps.resolveRequestHeaders,
675
+ suspendOn: deps.suspendOn,
912
676
  };
913
677
  }
914
678
  /**
915
679
  * Realize an `AiSdkProviderConfig` into a `ChatProvider` bound to that config's
916
- * connection and model. The model is closed into the returned provider here (it
917
- * is never passed per `ChatRequest`), so N models require N provider
918
- * instances over one shared connection configuration — one instance serves the
919
- * single model it was built with.
680
+ * connection and model. The model is closed into the returned provider here, so
681
+ * N models require N provider instances over one shared connection
682
+ * configuration — one instance serves the single model it was built with.
920
683
  *
921
684
  * When the config sets `requestTimeoutMs`, the provider wraps the effective fetch
922
- * (`config.fetch ?? globalThis.fetch`) with the response-start guard, it hands
923
- * the value to the stream call as the SDK chunk bound, and it advertises the
924
- * value on the returned instance. When the field is absent, it installs no
925
- * wrapper, it hands the SDK no bound, and it advertises no value.
685
+ * (`config.fetch ?? globalThis.fetch`) with the response-start guard, the retry
686
+ * envelope bounds each later silent interval with the same value, and the
687
+ * provider advertises the value on the returned instance. When the field is
688
+ * absent, it installs no wrapper, it bounds nothing, and it advertises no value.
926
689
  */
927
690
  export function createConfiguredAiSdkProvider(deps) {
928
691
  const config = deps.config;
@@ -950,16 +713,16 @@ export function createConfiguredAiSdkProvider(deps) {
950
713
  ...hostPolicyOf(deps),
951
714
  capabilities: { ...pictureDefault, ...config.capabilities },
952
715
  logger: deps.logger,
953
- ...(config.maxOutputTokens !== undefined ? { maxOutputTokens: config.maxOutputTokens } : {}),
954
- ...(config.maxRetries !== undefined ? { maxRetries: config.maxRetries } : {}),
955
- ...(requestTimeoutMs !== undefined ? { requestTimeoutMs } : {}),
956
- ...(config.reasoning !== undefined ? { reasoning: config.reasoning } : {}),
716
+ maxOutputTokens: config.maxOutputTokens,
717
+ maxRetries: config.maxRetries,
718
+ requestTimeoutMs,
719
+ reasoning: config.reasoning,
957
720
  // The package sends the key as `metadata.user_id`, and the binding as
958
721
  // `thinking.block_binding`.
959
722
  providerOptionsFor: ({ session, reasoning }) => ({
960
723
  anthropic: {
961
724
  metadata: { userId: sessionKeyDigestOf(session) },
962
- ...(binding !== undefined ? { thinking: thinkingWithBinding(reasoning, binding) } : {}),
725
+ thinking: binding === undefined ? undefined : thinkingWithBinding(reasoning, binding),
963
726
  },
964
727
  }),
965
728
  });
@@ -992,9 +755,9 @@ export function createConfiguredAiSdkProvider(deps) {
992
755
  // unset config sends no ceiling, and the server holds the reply at the
993
756
  // cap of the model.
994
757
  maxOutputTokens: config.maxOutputTokens ?? "provider-maximum",
995
- ...(config.maxRetries !== undefined ? { maxRetries: config.maxRetries } : {}),
996
- ...(requestTimeoutMs !== undefined ? { requestTimeoutMs } : {}),
997
- ...(config.reasoning !== undefined ? { reasoning: config.reasoning } : {}),
758
+ maxRetries: config.maxRetries,
759
+ requestTimeoutMs,
760
+ reasoning: config.reasoning,
998
761
  // The package sends the key as `prompt_cache_key`. The store
999
762
  // directive merges into the same namespace, and it keeps this key.
1000
763
  providerOptionsFor: ({ session }) => ({ openai: { promptCacheKey: sessionKeyDigestOf(session) } }),
@@ -1005,10 +768,12 @@ export function createConfiguredAiSdkProvider(deps) {
1005
768
  baseURL: config.baseURL,
1006
769
  apiKey: config.apiKey,
1007
770
  fetch: effectiveFetch,
1008
- // Each call of the provider streams, `chat` included. Without this flag
1009
- // the package asks for no usage on a stream, and the call reports none.
771
+ // Each call of the provider streams. Without this flag the package asks for
772
+ // no usage on a stream, and the call reports none.
1010
773
  includeUsage: true,
774
+ supportsMultiPartToolContent: config.supportsMultiPartToolContent,
1011
775
  });
776
+ const pictureDefault = config.supportsMultiPartToolContent === true ? { imageToolResults: true } : {};
1012
777
  // The compatible wire has no standard field for a session key, thus this arm
1013
778
  // gives no provider options of its own.
1014
779
  return createAiSdkProvider({
@@ -1016,11 +781,11 @@ export function createConfiguredAiSdkProvider(deps) {
1016
781
  // the seam needs no middleware to carry the depth into its namespace.
1017
782
  model: provider.chatModel(config.model),
1018
783
  ...hostPolicyOf(deps),
1019
- capabilities: config.capabilities,
784
+ capabilities: { ...pictureDefault, ...config.capabilities },
1020
785
  logger: deps.logger,
1021
- ...(config.maxOutputTokens !== undefined ? { maxOutputTokens: config.maxOutputTokens } : {}),
1022
- ...(config.maxRetries !== undefined ? { maxRetries: config.maxRetries } : {}),
1023
- ...(requestTimeoutMs !== undefined ? { requestTimeoutMs } : {}),
1024
- ...(config.reasoning !== undefined ? { reasoning: config.reasoning } : {}),
786
+ maxOutputTokens: config.maxOutputTokens,
787
+ maxRetries: config.maxRetries,
788
+ requestTimeoutMs,
789
+ reasoning: config.reasoning,
1025
790
  });
1026
791
  }