ashlr-plugin 1.36.4

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 (499) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +39 -0
  3. package/.claude-plugin/plugin.json +36 -0
  4. package/.codex/agents/README.md +9 -0
  5. package/.codex/agents/ashlr-explorer.md +36 -0
  6. package/.codex/agents/ashlr-worker.md +38 -0
  7. package/.codex-plugin/plugin.json +45 -0
  8. package/.mcp.json +14 -0
  9. package/LICENSE +21 -0
  10. package/README.md +311 -0
  11. package/agents/ashlr-code.md +69 -0
  12. package/agents/ashlr-explore.md +44 -0
  13. package/agents/ashlr-plan.md +54 -0
  14. package/bench/fixtures/notebook-large.ipynb +660 -0
  15. package/bench/fixtures/notebook-small.ipynb +39 -0
  16. package/bench/fixtures/tasklist-closed.json +62 -0
  17. package/bench/fixtures/tasklist-large-mixed.json +27 -0
  18. package/bench/fixtures/tasklist-sprint-open.json +79 -0
  19. package/bench/fixtures/websearch-bun-runtime.json +32 -0
  20. package/bench/fixtures/websearch-react-hooks-patterns.json +32 -0
  21. package/bench/fixtures/websearch-typescript-generics.json +38 -0
  22. package/bench/refs/node-sdk/.refrev +1 -0
  23. package/bench/refs/node-sdk/README.md +17 -0
  24. package/bench/refs/node-sdk/src/agent/agent.ts +163 -0
  25. package/bench/refs/node-sdk/src/agent/create-agent-ui-stream.ts +83 -0
  26. package/bench/refs/node-sdk/src/agent/tool-loop-agent.ts +238 -0
  27. package/bench/refs/node-sdk/src/embed/embed-many.ts +409 -0
  28. package/bench/refs/node-sdk/src/embed/embed-result.ts +50 -0
  29. package/bench/refs/node-sdk/src/embed/embed.ts +257 -0
  30. package/bench/refs/node-sdk/src/error/invalid-argument-error.ts +34 -0
  31. package/bench/refs/node-sdk/src/error/invalid-tool-input-error.ts +33 -0
  32. package/bench/refs/node-sdk/src/error/no-object-generated-error.ts +70 -0
  33. package/bench/refs/node-sdk/src/generate-image/generate-image-result.ts +42 -0
  34. package/bench/refs/node-sdk/src/generate-image/generate-image.ts +362 -0
  35. package/bench/refs/node-sdk/src/generate-object/generate-object-result.ts +67 -0
  36. package/bench/refs/node-sdk/src/generate-object/generate-object.ts +501 -0
  37. package/bench/refs/node-sdk/src/generate-object/inject-json-instruction.ts +30 -0
  38. package/bench/refs/node-sdk/src/generate-object/output-strategy.ts +415 -0
  39. package/bench/refs/node-sdk/src/generate-object/repair-text.ts +12 -0
  40. package/bench/refs/node-sdk/src/generate-object/stream-object.ts +960 -0
  41. package/bench/refs/node-sdk/src/generate-speech/generate-speech.ts +191 -0
  42. package/bench/refs/node-sdk/src/generate-text/generate-text.ts +1484 -0
  43. package/bench/refs/node-sdk/src/generate-text/stream-text.ts +2708 -0
  44. package/bench/refs/node-sdk/src/generate-text/tool-call.ts +59 -0
  45. package/bench/refs/node-sdk/src/generate-text/tool-result.ts +36 -0
  46. package/bench/refs/node-sdk/src/telemetry/create-telemetry-dispatcher.ts +146 -0
  47. package/bench/refs/node-sdk/src/telemetry/telemetry-registry.ts +15 -0
  48. package/bench/refs/node-sdk/src/telemetry/telemetry.ts +223 -0
  49. package/bench/refs/node-sdk/src/util/async-iterable-stream.ts +94 -0
  50. package/bench/refs/node-sdk/src/util/consume-stream.ts +31 -0
  51. package/bench/refs/node-sdk/src/util/create-stitchable-stream.ts +112 -0
  52. package/bench/refs/node-sdk/src/util/download/download.ts +74 -0
  53. package/bench/refs/node-sdk/src/util/error-handler.ts +1 -0
  54. package/bench/refs/node-sdk/src/util/fix-json.ts +401 -0
  55. package/bench/refs/node-sdk/src/util/merge-objects.ts +79 -0
  56. package/bench/refs/python-lib/.refrev +1 -0
  57. package/bench/refs/python-lib/README.md +18 -0
  58. package/bench/refs/python-lib/pandas/core/_numba/executor.py +249 -0
  59. package/bench/refs/python-lib/pandas/core/_numba/extensions.py +586 -0
  60. package/bench/refs/python-lib/pandas/core/_numba/kernels/mean_.py +198 -0
  61. package/bench/refs/python-lib/pandas/core/_numba/kernels/min_max_.py +178 -0
  62. package/bench/refs/python-lib/pandas/core/_numba/kernels/sum_.py +255 -0
  63. package/bench/refs/python-lib/pandas/core/_numba/kernels/var_.py +251 -0
  64. package/bench/refs/python-lib/pandas/core/accessor.py +520 -0
  65. package/bench/refs/python-lib/pandas/core/api.py +138 -0
  66. package/bench/refs/python-lib/pandas/core/array_algos/masked_accumulations.py +97 -0
  67. package/bench/refs/python-lib/pandas/core/array_algos/masked_reductions.py +252 -0
  68. package/bench/refs/python-lib/pandas/core/array_algos/putmask.py +150 -0
  69. package/bench/refs/python-lib/pandas/core/array_algos/quantile.py +232 -0
  70. package/bench/refs/python-lib/pandas/core/array_algos/replace.py +159 -0
  71. package/bench/refs/python-lib/pandas/core/array_algos/take.py +609 -0
  72. package/bench/refs/python-lib/pandas/core/arraylike.py +534 -0
  73. package/bench/refs/python-lib/pandas/core/arrays/_arrow_string_mixins.py +434 -0
  74. package/bench/refs/python-lib/pandas/core/arrays/_mixins.py +630 -0
  75. package/bench/refs/python-lib/pandas/core/arrays/_ranges.py +276 -0
  76. package/bench/refs/python-lib/pandas/core/arrays/_utils.py +77 -0
  77. package/bench/refs/python-lib/pandas/core/arrays/arrow/accessors.py +521 -0
  78. package/bench/refs/python-lib/pandas/core/arrays/arrow/extension_types.py +174 -0
  79. package/bench/refs/python-lib/pandas/core/arrays/boolean.py +454 -0
  80. package/bench/refs/python-lib/pandas/core/arrays/floating.py +192 -0
  81. package/bench/refs/python-lib/pandas/core/arrays/integer.py +296 -0
  82. package/bench/refs/python-lib/pandas/core/arrays/masked.py +2140 -0
  83. package/bench/refs/python-lib/pandas/core/arrays/numeric.py +305 -0
  84. package/bench/refs/python-lib/pandas/core/arrays/numpy_.py +701 -0
  85. package/bench/refs/python-lib/pandas/core/arrays/period.py +1586 -0
  86. package/bench/refs/python-lib/pandas/core/arrays/sparse/accessor.py +505 -0
  87. package/bench/refs/python-lib/pandas/core/arrays/sparse/scipy_sparse.py +208 -0
  88. package/bench/refs/rust-project/.refrev +1 -0
  89. package/bench/refs/rust-project/README.md +17 -0
  90. package/bench/refs/rust-project/tokio/src/doc/os.rs +68 -0
  91. package/bench/refs/rust-project/tokio/src/fs/dir_builder.rs +129 -0
  92. package/bench/refs/rust-project/tokio/src/fs/file.rs +1113 -0
  93. package/bench/refs/rust-project/tokio/src/fs/mocks.rs +176 -0
  94. package/bench/refs/rust-project/tokio/src/fs/mod.rs +324 -0
  95. package/bench/refs/rust-project/tokio/src/fs/open_options.rs +856 -0
  96. package/bench/refs/rust-project/tokio/src/fs/read.rs +80 -0
  97. package/bench/refs/rust-project/tokio/src/fs/read_dir.rs +357 -0
  98. package/bench/refs/rust-project/tokio/src/fs/write.rs +99 -0
  99. package/bench/refs/rust-project/tokio/src/future/maybe_done.rs +123 -0
  100. package/bench/refs/rust-project/tokio/src/future/try_join.rs +82 -0
  101. package/bench/refs/rust-project/tokio/src/io/async_buf_read.rs +117 -0
  102. package/bench/refs/rust-project/tokio/src/io/async_read.rs +133 -0
  103. package/bench/refs/rust-project/tokio/src/io/async_seek.rs +96 -0
  104. package/bench/refs/rust-project/tokio/src/io/async_write.rs +402 -0
  105. package/bench/refs/rust-project/tokio/src/io/blocking.rs +339 -0
  106. package/bench/refs/rust-project/tokio/src/io/interest.rs +345 -0
  107. package/bench/refs/rust-project/tokio/src/io/join.rs +130 -0
  108. package/bench/refs/rust-project/tokio/src/io/mod.rs +308 -0
  109. package/bench/refs/rust-project/tokio/src/io/poll_evented.rs +319 -0
  110. package/bench/refs/rust-project/tokio/src/io/read_buf.rs +344 -0
  111. package/bench/refs/rust-project/tokio/src/io/ready.rs +322 -0
  112. package/bench/refs/rust-project/tokio/src/io/split.rs +166 -0
  113. package/bench/refs/rust-project/tokio/src/io/stderr.rs +148 -0
  114. package/bench/refs/rust-project/tokio/src/io/stdin.rs +98 -0
  115. package/bench/refs/rust-project/tokio/src/io/stdio_common.rs +222 -0
  116. package/bench/refs/rust-project/tokio/src/io/stdout.rs +197 -0
  117. package/bench/refs/rust-project/tokio/src/io/util/buf_reader.rs +311 -0
  118. package/bench/refs/rust-project/tokio/src/io/util/buf_stream.rs +207 -0
  119. package/bench/refs/rust-project/tokio/src/io/util/buf_writer.rs +310 -0
  120. package/bench/refs/rust-project/tokio/src/io/util/chain.rs +144 -0
  121. package/commands/_spawn-patterns.json +32 -0
  122. package/commands/ashlr-allow.md +21 -0
  123. package/commands/ashlr-benchmark.md +53 -0
  124. package/commands/ashlr-brief.md +97 -0
  125. package/commands/ashlr-budget.md +76 -0
  126. package/commands/ashlr-compact.md +54 -0
  127. package/commands/ashlr-dashboard.md +37 -0
  128. package/commands/ashlr-doctor.md +56 -0
  129. package/commands/ashlr-eco-mode.md +92 -0
  130. package/commands/ashlr-genome-init.md +24 -0
  131. package/commands/ashlr-genome-keygen.md +36 -0
  132. package/commands/ashlr-genome-loop.md +118 -0
  133. package/commands/ashlr-genome-push.md +36 -0
  134. package/commands/ashlr-genome-rewrap.md +48 -0
  135. package/commands/ashlr-genome-team-init.md +67 -0
  136. package/commands/ashlr-handoff.md +23 -0
  137. package/commands/ashlr-help.md +86 -0
  138. package/commands/ashlr-hook-timings.md +30 -0
  139. package/commands/ashlr-leaderboard.md +50 -0
  140. package/commands/ashlr-ollama-setup.md +39 -0
  141. package/commands/ashlr-orchestrate-status.md +72 -0
  142. package/commands/ashlr-orchestrate.md +83 -0
  143. package/commands/ashlr-parallelize.md +63 -0
  144. package/commands/ashlr-report-crash.md +33 -0
  145. package/commands/ashlr-resume.md +72 -0
  146. package/commands/ashlr-savings.md +24 -0
  147. package/commands/ashlr-settings.md +50 -0
  148. package/commands/ashlr-spawn.md +61 -0
  149. package/commands/ashlr-start.md +60 -0
  150. package/commands/ashlr-status.md +64 -0
  151. package/commands/ashlr-team-invite.md +47 -0
  152. package/commands/ashlr-tier.md +122 -0
  153. package/commands/ashlr-tour.md +60 -0
  154. package/commands/ashlr-update.md +155 -0
  155. package/commands/ashlr-upgrade.md +96 -0
  156. package/commands/goal.md +58 -0
  157. package/commands/loop.md +40 -0
  158. package/docs/CNAME +1 -0
  159. package/docs/PRO_TIER.md +104 -0
  160. package/docs/README.md +21 -0
  161. package/docs/architecture.md +415 -0
  162. package/docs/ashlr-pipe.md +161 -0
  163. package/docs/assets/logo.svg +19 -0
  164. package/docs/assets/og.png +0 -0
  165. package/docs/assets/og.svg +41 -0
  166. package/docs/benchmarks-v2.json +355 -0
  167. package/docs/benchmarks.json +102 -0
  168. package/docs/benchmarks.md +211 -0
  169. package/docs/billing.md +185 -0
  170. package/docs/cloud-genome.md +155 -0
  171. package/docs/competitive-wozcode.md +92 -0
  172. package/docs/deploy.md +325 -0
  173. package/docs/email-templates.md +113 -0
  174. package/docs/embed-tuning.md +103 -0
  175. package/docs/genome.md +120 -0
  176. package/docs/github-oauth-onboarding.md +127 -0
  177. package/docs/hero-video-script.md +129 -0
  178. package/docs/index.html +2262 -0
  179. package/docs/install-prompt.md +78 -0
  180. package/docs/install-windows.md +132 -0
  181. package/docs/install.ps1 +171 -0
  182. package/docs/install.sh +146 -0
  183. package/docs/launch/README.md +114 -0
  184. package/docs/launch/hn.md +49 -0
  185. package/docs/launch/reddit.md +45 -0
  186. package/docs/launch/x.md +65 -0
  187. package/docs/launch-post.md +112 -0
  188. package/docs/legal.md +78 -0
  189. package/docs/llm-providers.md +99 -0
  190. package/docs/multi-host-mcp.md +217 -0
  191. package/docs/multi-turn-architecture.md +108 -0
  192. package/docs/operations/deployment.md +108 -0
  193. package/docs/operations/error-monitoring.md +70 -0
  194. package/docs/operations/weekly-digest.md +70 -0
  195. package/docs/operations.md +494 -0
  196. package/docs/platform-support.md +133 -0
  197. package/docs/policy-packs.md +188 -0
  198. package/docs/press-kit/fact-sheet.md +78 -0
  199. package/docs/press-kit/founder-bio.md +3 -0
  200. package/docs/press-kit/logo.svg +33 -0
  201. package/docs/press-kit/screenshots.md +146 -0
  202. package/docs/pricing.md +251 -0
  203. package/docs/pro-backend-architecture.md +523 -0
  204. package/docs/producthunt.md +52 -0
  205. package/docs/router-migration.md +110 -0
  206. package/docs/session-log-schema.md +68 -0
  207. package/docs/social.md +95 -0
  208. package/docs/team-genome.md +528 -0
  209. package/docs/telemetry.md +194 -0
  210. package/docs/test-isolation.md +100 -0
  211. package/docs/upgrade.md +159 -0
  212. package/hooks/_hook-errors.ts +87 -0
  213. package/hooks/_hook-perf-emit.ts +113 -0
  214. package/hooks/_hook-timing-ledger.ts +1133 -0
  215. package/hooks/_nudge-throttle.ts +127 -0
  216. package/hooks/_recent-blocks.ts +127 -0
  217. package/hooks/audit-upload.ts +86 -0
  218. package/hooks/codex-hooks.json +171 -0
  219. package/hooks/commit-attribution.ts +179 -0
  220. package/hooks/edit-batching-nudge.ts +154 -0
  221. package/hooks/genome-scribe-hook.ts +219 -0
  222. package/hooks/hooks.json +294 -0
  223. package/hooks/orient-nudge-hook.ts +242 -0
  224. package/hooks/policy-enforce.ts +214 -0
  225. package/hooks/post-tool-use-embedding.ts +93 -0
  226. package/hooks/post-tool-use-genome.sh +37 -0
  227. package/hooks/post-tool-use-genome.ts +69 -0
  228. package/hooks/posttooluse-correlate.ts +122 -0
  229. package/hooks/posttooluse-dedupe-output.ts +241 -0
  230. package/hooks/posttooluse-genome-refresh.ts +223 -0
  231. package/hooks/posttooluse-native-nudge.ts +205 -0
  232. package/hooks/posttooluse-stale-result.ts +277 -0
  233. package/hooks/pretooluse-bash.ts +63 -0
  234. package/hooks/pretooluse-budget-guard.ts +318 -0
  235. package/hooks/pretooluse-common.ts +985 -0
  236. package/hooks/pretooluse-eco-router.ts +196 -0
  237. package/hooks/pretooluse-edit.sh +93 -0
  238. package/hooks/pretooluse-edit.ts +197 -0
  239. package/hooks/pretooluse-glob.ts +70 -0
  240. package/hooks/pretooluse-grep.sh +85 -0
  241. package/hooks/pretooluse-grep.ts +96 -0
  242. package/hooks/pretooluse-notebookedit.ts +121 -0
  243. package/hooks/pretooluse-read.sh +118 -0
  244. package/hooks/pretooluse-read.ts +118 -0
  245. package/hooks/pretooluse-task.ts +130 -0
  246. package/hooks/pretooluse-webfetch.ts +66 -0
  247. package/hooks/pretooluse-websearch.ts +85 -0
  248. package/hooks/pretooluse-write.ts +128 -0
  249. package/hooks/pulse-emit.ts +197 -0
  250. package/hooks/session-end-consolidate.sh +35 -0
  251. package/hooks/session-end-consolidate.ts +188 -0
  252. package/hooks/session-end-stats-gc.ts +80 -0
  253. package/hooks/session-log-append.sh +94 -0
  254. package/hooks/session-log-append.ts +116 -0
  255. package/hooks/session-start.ts +993 -0
  256. package/hooks/sessionend-hook-health-nudge.ts +451 -0
  257. package/hooks/sessionend-savings-nudge.ts +318 -0
  258. package/hooks/sessionend-status-line-nudge.ts +296 -0
  259. package/hooks/sessionstart-brief.ts +140 -0
  260. package/hooks/sessionstart-cost-refactor.ts +95 -0
  261. package/hooks/sessionstart-efficient.ts +110 -0
  262. package/hooks/sessionstart-genome-author.ts +93 -0
  263. package/hooks/sessionstart-lean-tools.ts +98 -0
  264. package/hooks/sessionstart-search.ts +97 -0
  265. package/hooks/stop-accounting.ts +152 -0
  266. package/hooks/subagent-stop-rollup.ts +162 -0
  267. package/hooks/userpromptsubmit-brief-trigger.ts +156 -0
  268. package/package.json +56 -0
  269. package/ports/README.md +108 -0
  270. package/ports/cursor/mcp.json +11 -0
  271. package/ports/goose/recipe.yaml +26 -0
  272. package/scripts/ashlr-mcp.ts +40 -0
  273. package/scripts/auto-update.ts +177 -0
  274. package/scripts/baseline-scan.ts +831 -0
  275. package/scripts/bench-orchestrate.ts +377 -0
  276. package/scripts/benchmark-refs.ts +292 -0
  277. package/scripts/bootstrap.mjs +100 -0
  278. package/scripts/brief-eval.ts +234 -0
  279. package/scripts/bump-version.ts +82 -0
  280. package/scripts/bun-resolve.d.mts +11 -0
  281. package/scripts/bun-resolve.mjs +59 -0
  282. package/scripts/calibrate-grep.ts +467 -0
  283. package/scripts/capture-grep-workload.ts +260 -0
  284. package/scripts/check-tier.ts +61 -0
  285. package/scripts/check-version-sync.ts +97 -0
  286. package/scripts/cli-orchestrate-status.ts +386 -0
  287. package/scripts/cli-orchestrate.ts +303 -0
  288. package/scripts/cli.ts +478 -0
  289. package/scripts/cloud-smoke-test.ts +313 -0
  290. package/scripts/coach-report.ts +373 -0
  291. package/scripts/context-db-migrate.ts +137 -0
  292. package/scripts/context-status.ts +43 -0
  293. package/scripts/demo-run.ts +255 -0
  294. package/scripts/deploy-smoke.sh +140 -0
  295. package/scripts/doctor.ts +992 -0
  296. package/scripts/embed-file-worker.ts +104 -0
  297. package/scripts/embed-tune.ts +308 -0
  298. package/scripts/errors-report.ts +428 -0
  299. package/scripts/find-test-leak.ts +69 -0
  300. package/scripts/generate-badge.ts +357 -0
  301. package/scripts/genome-auto-consolidate.ts +533 -0
  302. package/scripts/genome-auto-propose.ts +578 -0
  303. package/scripts/genome-cloud-pull.ts +363 -0
  304. package/scripts/genome-cloud-push.ts +382 -0
  305. package/scripts/genome-cloud-sync.ts +587 -0
  306. package/scripts/genome-commit-watcher.ts +295 -0
  307. package/scripts/genome-init.ts +986 -0
  308. package/scripts/genome-key.ts +233 -0
  309. package/scripts/genome-keygen.ts +168 -0
  310. package/scripts/genome-link.ts +59 -0
  311. package/scripts/genome-refresh-worker.ts +364 -0
  312. package/scripts/genome-rewrap.ts +90 -0
  313. package/scripts/genome-synthesizer.ts +679 -0
  314. package/scripts/genome-team-init.ts +312 -0
  315. package/scripts/handoff-pack.ts +438 -0
  316. package/scripts/hook-bootstrap.mjs +75 -0
  317. package/scripts/hook-timing-reader.ts +371 -0
  318. package/scripts/hook-timings-report.ts +554 -0
  319. package/scripts/install-genome-hooks.ts +196 -0
  320. package/scripts/install-onnx-model.ts +154 -0
  321. package/scripts/install-permissions.ts +276 -0
  322. package/scripts/install-status-line.ts +150 -0
  323. package/scripts/mcp-entrypoint.sh +78 -0
  324. package/scripts/mcp-entrypoint.ts +130 -0
  325. package/scripts/mdx-angle-bracket-lint.ts +152 -0
  326. package/scripts/measure-cold-start.ts +126 -0
  327. package/scripts/migrate-stats-to-sqlite.ts +86 -0
  328. package/scripts/ollama-setup.ts +498 -0
  329. package/scripts/onboarding-wizard.ts +1691 -0
  330. package/scripts/orchestrate-emit-telemetry.ts +177 -0
  331. package/scripts/orchestrate-expand.ts +517 -0
  332. package/scripts/orchestrate-run.ts +744 -0
  333. package/scripts/print-legend.ts +50 -0
  334. package/scripts/product-metadata.ts +38 -0
  335. package/scripts/prune-old-memories.ts +208 -0
  336. package/scripts/publish.sh +88 -0
  337. package/scripts/read-calibration.ts +122 -0
  338. package/scripts/report-crash.ts +226 -0
  339. package/scripts/run-benchmark.ts +750 -0
  340. package/scripts/run-root-tests.ts +28 -0
  341. package/scripts/savings-dashboard.ts +1258 -0
  342. package/scripts/savings-report-extras.ts +447 -0
  343. package/scripts/savings-status-line.ts +873 -0
  344. package/scripts/session-event-emit.ts +266 -0
  345. package/scripts/session-greet.ts +686 -0
  346. package/scripts/session-log-report.ts +551 -0
  347. package/scripts/session-resume.ts +614 -0
  348. package/scripts/set-hook-mode.ts +83 -0
  349. package/scripts/smoke-cross-platform.ts +117 -0
  350. package/scripts/smoke-realtime.ts +257 -0
  351. package/scripts/smoke-tools.ts +21 -0
  352. package/scripts/stats-cloud-pull.ts +213 -0
  353. package/scripts/stats-cloud-sync.ts +261 -0
  354. package/scripts/telemetry-flush.ts +160 -0
  355. package/scripts/telemetry-status.ts +266 -0
  356. package/scripts/timing-budget.ts +35 -0
  357. package/scripts/ui-animation.ts +120 -0
  358. package/scripts/ui.ts +431 -0
  359. package/scripts/upgrade-flow.ts +775 -0
  360. package/scripts/weekly-digest.ts +394 -0
  361. package/servers/_accounting.ts +78 -0
  362. package/servers/_ask-router.ts +84 -0
  363. package/servers/_ast-chunker.ts +434 -0
  364. package/servers/_ast-helpers.ts +183 -0
  365. package/servers/_ast-languages.ts +153 -0
  366. package/servers/_ast-refactor/_shared.ts +221 -0
  367. package/servers/_ast-refactor/cross-file-rename.ts +560 -0
  368. package/servers/_ast-refactor/extract-function.ts +357 -0
  369. package/servers/_ast-refactor/file-local-rename.ts +172 -0
  370. package/servers/_ast-refactor.ts +41 -0
  371. package/servers/_ast-skeleton.ts +107 -0
  372. package/servers/_bash-summarizers-registry.ts +1096 -0
  373. package/servers/_crash-dump.ts +210 -0
  374. package/servers/_cwd-clamp.ts +342 -0
  375. package/servers/_edit-log.ts +28 -0
  376. package/servers/_edit-match.ts +236 -0
  377. package/servers/_edit-validate.ts +196 -0
  378. package/servers/_embed-calibration.ts +123 -0
  379. package/servers/_embedding-cache.ts +401 -0
  380. package/servers/_embedding-model.ts +329 -0
  381. package/servers/_events.ts +113 -0
  382. package/servers/_genome-cache.ts +154 -0
  383. package/servers/_genome-commits.ts +172 -0
  384. package/servers/_genome-crypto-v2.ts +242 -0
  385. package/servers/_genome-crypto.ts +259 -0
  386. package/servers/_genome-discoveries.ts +140 -0
  387. package/servers/_genome-embed-populator.ts +216 -0
  388. package/servers/_genome-freshness.ts +134 -0
  389. package/servers/_genome-issues.ts +171 -0
  390. package/servers/_genome-live.ts +263 -0
  391. package/servers/_genome-prs.ts +188 -0
  392. package/servers/_genome-search.ts +479 -0
  393. package/servers/_genome-sync.ts +297 -0
  394. package/servers/_history-tracker.ts +279 -0
  395. package/servers/_http-helpers.ts +151 -0
  396. package/servers/_identity-hash.ts +151 -0
  397. package/servers/_llm-providers/anthropic.ts +132 -0
  398. package/servers/_llm-providers/cloud.ts +195 -0
  399. package/servers/_llm-providers/index.ts +350 -0
  400. package/servers/_llm-providers/local.ts +127 -0
  401. package/servers/_llm-providers/onnx.ts +393 -0
  402. package/servers/_llm-providers/types.ts +27 -0
  403. package/servers/_manifest-v2.ts +447 -0
  404. package/servers/_mcp-host.ts +93 -0
  405. package/servers/_nudge-events.ts +451 -0
  406. package/servers/_orchestrate-executor.ts +316 -0
  407. package/servers/_prefetch.ts +435 -0
  408. package/servers/_pricing.ts +256 -0
  409. package/servers/_pro.ts +381 -0
  410. package/servers/_read-cache.ts +44 -0
  411. package/servers/_router-handlers.ts +46 -0
  412. package/servers/_router.ts +55 -0
  413. package/servers/_run-with-timeout.ts +173 -0
  414. package/servers/_savings-render.ts +214 -0
  415. package/servers/_stats-sqlite.ts +640 -0
  416. package/servers/_stats.ts +1183 -0
  417. package/servers/_status-line-cells.ts +469 -0
  418. package/servers/_streaks.ts +162 -0
  419. package/servers/_summarize.ts +208 -0
  420. package/servers/_task-graph-render.ts +217 -0
  421. package/servers/_task-graph.ts +545 -0
  422. package/servers/_telemetry.ts +719 -0
  423. package/servers/_test-parsers.ts +530 -0
  424. package/servers/_test-watch.ts +626 -0
  425. package/servers/_text-helpers.ts +37 -0
  426. package/servers/_token-measure.ts +160 -0
  427. package/servers/_tool-base.ts +248 -0
  428. package/servers/_weekly-digest.ts +391 -0
  429. package/servers/ask-server-handlers.ts +49 -0
  430. package/servers/ask-server.ts +174 -0
  431. package/servers/bash-server-handlers.ts +138 -0
  432. package/servers/bash-server.ts +1136 -0
  433. package/servers/bench.ts +186 -0
  434. package/servers/diff-semantic-server-handlers.ts +39 -0
  435. package/servers/diff-semantic-server.ts +566 -0
  436. package/servers/diff-server-handlers.ts +317 -0
  437. package/servers/diff-server.ts +20 -0
  438. package/servers/edit-server-handlers.ts +31 -0
  439. package/servers/edit-server.ts +209 -0
  440. package/servers/edit-structural-server-handlers.ts +322 -0
  441. package/servers/efficiency-server-handlers.ts +161 -0
  442. package/servers/efficiency-server.ts +1135 -0
  443. package/servers/flush-server-handlers.ts +21 -0
  444. package/servers/flush-server.ts +19 -0
  445. package/servers/genome-server-handlers.ts +118 -0
  446. package/servers/genome-server.ts +397 -0
  447. package/servers/github-server-handlers.ts +187 -0
  448. package/servers/github-server.ts +856 -0
  449. package/servers/glob-server-handlers.ts +233 -0
  450. package/servers/glob-server.ts +20 -0
  451. package/servers/grep-server-handlers.ts +61 -0
  452. package/servers/grep-server.ts +564 -0
  453. package/servers/http-server-handlers.ts +36 -0
  454. package/servers/http-server.ts +149 -0
  455. package/servers/logs-server-handlers.ts +42 -0
  456. package/servers/logs-server.ts +359 -0
  457. package/servers/ls-server-handlers.ts +166 -0
  458. package/servers/ls-server.ts +20 -0
  459. package/servers/multi-edit-server-handlers.ts +51 -0
  460. package/servers/multi-edit-server.ts +422 -0
  461. package/servers/notebook-edit-server-handlers.ts +34 -0
  462. package/servers/notebook-edit-server.ts +181 -0
  463. package/servers/orient-server-handlers.ts +52 -0
  464. package/servers/orient-server.ts +436 -0
  465. package/servers/pipe-server-handlers.ts +68 -0
  466. package/servers/pipe-server.ts +300 -0
  467. package/servers/read-server-handlers.ts +42 -0
  468. package/servers/read-server.ts +206 -0
  469. package/servers/rename-file-server-handlers.ts +67 -0
  470. package/servers/rename-file-server.ts +699 -0
  471. package/servers/savings-server-handlers.ts +27 -0
  472. package/servers/savings-server.ts +54 -0
  473. package/servers/search-replace-regex-server-handlers.ts +96 -0
  474. package/servers/search-replace-regex-server.ts +751 -0
  475. package/servers/sql-server-handlers.ts +58 -0
  476. package/servers/sql-server.ts +505 -0
  477. package/servers/task-server-handlers.ts +358 -0
  478. package/servers/task-server.ts +24 -0
  479. package/servers/test-server-handlers.ts +351 -0
  480. package/servers/test-server.ts +20 -0
  481. package/servers/tree-server-handlers.ts +503 -0
  482. package/servers/tree-server.ts +20 -0
  483. package/servers/webfetch-server-handlers.ts +166 -0
  484. package/servers/webfetch-server.ts +20 -0
  485. package/servers/websearch-server-handlers.ts +215 -0
  486. package/servers/websearch-server.ts +19 -0
  487. package/servers/write-server-handlers.ts +27 -0
  488. package/servers/write-server.ts +97 -0
  489. package/skills/ashlr-brief/SKILL.md +80 -0
  490. package/skills/ashlr-codex-doctor/SKILL.md +21 -0
  491. package/skills/ashlr-codex-efficient-tools/SKILL.md +17 -0
  492. package/skills/ashlr-codex-genome-refresh/SKILL.md +20 -0
  493. package/skills/ashlr-codex-parallel-explore/SKILL.md +20 -0
  494. package/skills/ashlr-codex-savings/SKILL.md +17 -0
  495. package/skills/ashlr-cost-refactor/SKILL.md +50 -0
  496. package/skills/ashlr-efficient/SKILL.md +64 -0
  497. package/skills/ashlr-genome-author/SKILL.md +43 -0
  498. package/skills/ashlr-lean-tools/SKILL.md +43 -0
  499. package/skills/ashlr-search/SKILL.md +46 -0
@@ -0,0 +1,1484 @@
1
+ import {
2
+ LanguageModelV4Content,
3
+ LanguageModelV4GenerateResult,
4
+ LanguageModelV4ToolCall,
5
+ } from '@ai-sdk/provider';
6
+ import type {
7
+ Arrayable,
8
+ Context,
9
+ InferToolSetContext,
10
+ ToolSet,
11
+ } from '@ai-sdk/provider-utils';
12
+ import {
13
+ asArray,
14
+ createIdGenerator,
15
+ getErrorMessage,
16
+ IdGenerator,
17
+ ProviderOptions,
18
+ withUserAgentSuffix,
19
+ } from '@ai-sdk/provider-utils';
20
+ import { NoOutputGeneratedError } from '../error';
21
+ import { ToolCallNotFoundForApprovalError } from '../error/tool-call-not-found-for-approval-error';
22
+ import { logWarnings } from '../logger/log-warnings';
23
+ import { resolveLanguageModel } from '../model/resolve-model';
24
+ import { ModelMessage } from '../prompt';
25
+ import { convertToLanguageModelPrompt } from '../prompt/convert-to-language-model-prompt';
26
+ import { createToolModelOutput } from '../prompt/create-tool-model-output';
27
+ import { LanguageModelCallOptions } from '../prompt/language-model-call-options';
28
+ import { prepareLanguageModelCallOptions } from '../prompt/prepare-language-model-call-options';
29
+ import { prepareToolChoice } from '../prompt/prepare-tool-choice';
30
+ import { prepareTools } from '../prompt/prepare-tools';
31
+ import { Prompt } from '../prompt/prompt';
32
+ import {
33
+ getStepTimeoutMs,
34
+ getTotalTimeoutMs,
35
+ RequestOptions,
36
+ TimeoutConfiguration,
37
+ } from '../prompt/request-options';
38
+ import { standardizePrompt } from '../prompt/standardize-prompt';
39
+ import { wrapGatewayError } from '../prompt/wrap-gateway-error';
40
+ import { createTelemetryDispatcher } from '../telemetry/create-telemetry-dispatcher';
41
+ import type { Telemetry } from '../telemetry/telemetry';
42
+ import { TelemetryOptions } from '../telemetry/telemetry-options';
43
+ import {
44
+ LanguageModel,
45
+ LanguageModelRequestMetadata,
46
+ ToolChoice,
47
+ } from '../types';
48
+ import {
49
+ addLanguageModelUsage,
50
+ asLanguageModelUsage,
51
+ LanguageModelUsage,
52
+ } from '../types/usage';
53
+ import type { Callback } from '../util/callback';
54
+ import { DownloadFunction } from '../util/download/download-function';
55
+ import { mergeAbortSignals } from '../util/merge-abort-signals';
56
+ import { mergeObjects } from '../util/merge-objects';
57
+ import { notify } from '../util/notify';
58
+ import { prepareRetries } from '../util/prepare-retries';
59
+ import { VERSION } from '../version';
60
+ import { collectToolApprovals } from './collect-tool-approvals';
61
+ import { ContentPart } from './content-part';
62
+ import type {
63
+ GenerateTextEndEvent,
64
+ GenerateTextStartEvent,
65
+ GenerateTextStepEndEvent,
66
+ GenerateTextStepStartEvent,
67
+ } from './core-events';
68
+ import type {
69
+ OnLanguageModelCallEndCallback,
70
+ OnLanguageModelCallStartCallback,
71
+ } from './language-model-events';
72
+ import { executeToolCall } from './execute-tool-call';
73
+ import { filterActiveTools } from './filter-active-tool';
74
+ import { GenerateTextResult } from './generate-text-result';
75
+ import { DefaultGeneratedFile } from './generated-file';
76
+ import { resolveToolApproval } from './resolve-tool-approval';
77
+ import { Output, text } from './output';
78
+ import { InferCompleteOutput } from './output-utils';
79
+ import { parseToolCall } from './parse-tool-call';
80
+ import { PrepareStepFunction } from './prepare-step';
81
+ import { convertToReasoningOutputs } from './reasoning-output';
82
+ import { ResponseMessage } from './response-message';
83
+ import { DefaultStepResult, StepResult } from './step-result';
84
+ import {
85
+ isStepCount,
86
+ isStopConditionMet,
87
+ StopCondition,
88
+ } from './stop-condition';
89
+ import { toResponseMessages } from './to-response-messages';
90
+ import { ToolApprovalConfiguration } from './tool-approval-configuration';
91
+ import { ToolApprovalRequestOutput } from './tool-approval-request-output';
92
+ import { ToolApprovalResponseOutput } from './tool-approval-response-output';
93
+ import { TypedToolCall } from './tool-call';
94
+ import { ToolCallRepairFunction } from './tool-call-repair-function';
95
+ import { TypedToolError } from './tool-error';
96
+ import {
97
+ OnToolExecutionEndCallback,
98
+ OnToolExecutionStartCallback,
99
+ } from './tool-execution-events';
100
+ import { ToolOutput } from './tool-output';
101
+ import { TypedToolResult } from './tool-result';
102
+ import { ToolsContextParameter } from './tools-context-parameter';
103
+
104
+ const originalGenerateId = createIdGenerator({
105
+ prefix: 'aitxt',
106
+ size: 24,
107
+ });
108
+
109
+ const originalGenerateCallId = createIdGenerator({
110
+ prefix: 'call',
111
+ size: 24,
112
+ });
113
+
114
+ /**
115
+ * Callback that is set using the `experimental_onStart` option.
116
+ *
117
+ * Called when the generateText operation begins, before any LLM calls.
118
+ * Use this callback for logging, analytics, or initializing state at the
119
+ * start of a generation.
120
+ *
121
+ * @param event - The event object containing generation configuration.
122
+ */
123
+ export type GenerateTextOnStartCallback<
124
+ TOOLS extends ToolSet = ToolSet,
125
+ RUNTIME_CONTEXT extends Context = Context,
126
+ OUTPUT extends Output = Output,
127
+ > = Callback<GenerateTextStartEvent<TOOLS, RUNTIME_CONTEXT, OUTPUT>>;
128
+
129
+ /**
130
+ * Callback that is set using the `experimental_onStepStart` option.
131
+ *
132
+ * Called when a step (LLM call) begins, before the provider is called.
133
+ * Each step represents a single LLM invocation. Multiple steps occur when
134
+ * using tool calls (the model may be called multiple times in a loop).
135
+ *
136
+ * @param event - The event object containing step configuration.
137
+ */
138
+ export type GenerateTextOnStepStartCallback<
139
+ TOOLS extends ToolSet = ToolSet,
140
+ RUNTIME_CONTEXT extends Context = Context,
141
+ OUTPUT extends Output = Output,
142
+ > = Callback<GenerateTextStepStartEvent<TOOLS, RUNTIME_CONTEXT, OUTPUT>>;
143
+
144
+ /**
145
+ * Callback that is set using the `onStepFinish` option.
146
+ *
147
+ * Called when a step (LLM call) completes. The event includes all step result
148
+ * properties (text, tool calls, usage, etc.) along with additional metadata.
149
+ *
150
+ * @param stepResult - The result of the step.
151
+ */
152
+ export type GenerateTextOnStepFinishCallback<
153
+ TOOLS extends ToolSet = ToolSet,
154
+ RUNTIME_CONTEXT extends Context = Context,
155
+ > = Callback<GenerateTextStepEndEvent<TOOLS, RUNTIME_CONTEXT>>;
156
+
157
+ /**
158
+ * Callback that is set using the `onFinish` option.
159
+ *
160
+ * Called when the entire generation completes (all steps finished).
161
+ * The event includes the final step's result properties along with
162
+ * aggregated data from all steps.
163
+ *
164
+ * @param event - The final result along with aggregated step data.
165
+ */
166
+ export type GenerateTextOnFinishCallback<
167
+ TOOLS extends ToolSet = ToolSet,
168
+ RUNTIME_CONTEXT extends Context = Context,
169
+ > = Callback<GenerateTextEndEvent<TOOLS, RUNTIME_CONTEXT>>;
170
+
171
+ /**
172
+ * Generate a text and call tools for a given prompt using a language model.
173
+ *
174
+ * This function does not stream the output. If you want to stream the output, use `streamText` instead.
175
+ *
176
+ * @param model - The language model to use.
177
+ *
178
+ * @param tools - Tools that are accessible to and can be called by the model. The model needs to support calling tools.
179
+ * @param toolChoice - The tool choice strategy. Default: 'auto'.
180
+ *
181
+ * @param system - A system message that will be part of the prompt.
182
+ * @param prompt - A simple text prompt. You can either use `prompt` or `messages` but not both.
183
+ * @param messages - A list of messages. You can either use `prompt` or `messages` but not both.
184
+ *
185
+ * @param maxOutputTokens - Maximum number of tokens to generate.
186
+ * @param temperature - Temperature setting.
187
+ * The value is passed through to the provider. The range depends on the provider and model.
188
+ * It is recommended to set either `temperature` or `topP`, but not both.
189
+ * @param topP - Nucleus sampling.
190
+ * The value is passed through to the provider. The range depends on the provider and model.
191
+ * It is recommended to set either `temperature` or `topP`, but not both.
192
+ * @param topK - Only sample from the top K options for each subsequent token.
193
+ * Used to remove "long tail" low probability responses.
194
+ * Recommended for advanced use cases only. You usually only need to use temperature.
195
+ * @param presencePenalty - Presence penalty setting.
196
+ * It affects the likelihood of the model to repeat information that is already in the prompt.
197
+ * The value is passed through to the provider. The range depends on the provider and model.
198
+ * @param frequencyPenalty - Frequency penalty setting.
199
+ * It affects the likelihood of the model to repeatedly use the same words or phrases.
200
+ * The value is passed through to the provider. The range depends on the provider and model.
201
+ * @param stopSequences - Stop sequences.
202
+ * If set, the model will stop generating text when one of the stop sequences is generated.
203
+ * @param seed - The seed (integer) to use for random sampling.
204
+ * If set and supported by the model, calls will generate deterministic results.
205
+ *
206
+ * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
207
+ * @param abortSignal - An optional abort signal that can be used to cancel the call.
208
+ * @param timeout - An optional timeout in milliseconds. The call will be aborted if it takes longer than the specified timeout.
209
+ * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
210
+ *
211
+ * @param runtimeContext - User-defined runtime context that flows through the entire generation lifecycle.
212
+ *
213
+ * @param experimental_onStart - Callback invoked when generation begins, before any LLM calls.
214
+ * @param experimental_onStepStart - Callback invoked when each step begins, before the provider is called.
215
+ * Receives step number, messages (in ModelMessage format), tools, and runtimeContext.
216
+ * @param experimental_onToolExecutionStart - Callback invoked before each tool execution begins.
217
+ * Receives tool name, call ID, input, and context.
218
+ * @param experimental_onToolExecutionEnd - Callback invoked after each tool execution completes.
219
+ * Uses a discriminated union: check `success` to determine if `output` or `error` is present.
220
+ * @param onStepFinish - Callback that is called when each step (LLM call) is finished, including intermediate steps.
221
+ * @param onFinish - Callback that is called when all steps are finished and the response is complete.
222
+ *
223
+ * @returns
224
+ * A result object that contains the generated text, the results of the tool calls, and additional information.
225
+ */
226
+ export async function generateText<
227
+ TOOLS extends ToolSet,
228
+ RUNTIME_CONTEXT extends Context = Context,
229
+ OUTPUT extends Output = Output<string, string>,
230
+ >({
231
+ model: modelArg,
232
+ tools,
233
+ toolChoice,
234
+ system,
235
+ prompt,
236
+ messages,
237
+ maxRetries: maxRetriesArg,
238
+ abortSignal,
239
+ timeout,
240
+ headers,
241
+ stopWhen = isStepCount(1),
242
+ output,
243
+ toolApproval,
244
+ experimental_telemetry,
245
+ telemetry = experimental_telemetry,
246
+ providerOptions,
247
+ activeTools,
248
+ prepareStep,
249
+ experimental_repairToolCall: repairToolCall,
250
+ experimental_download: download,
251
+ runtimeContext = {} as RUNTIME_CONTEXT,
252
+ toolsContext = {} as InferToolSetContext<TOOLS>,
253
+ experimental_include: include,
254
+ _internal: {
255
+ generateId = originalGenerateId,
256
+ generateCallId = originalGenerateCallId,
257
+ } = {},
258
+ experimental_onStart: onStart,
259
+ experimental_onStepStart: onStepStart,
260
+ experimental_onLanguageModelCallStart: onLanguageModelCallStart,
261
+ experimental_onLanguageModelCallEnd: onLanguageModelCallEnd,
262
+ experimental_onToolExecutionStart: onToolExecutionStart,
263
+ experimental_onToolExecutionEnd: onToolExecutionEnd,
264
+ onStepFinish,
265
+ onFinish,
266
+ ...settings
267
+ }: LanguageModelCallOptions &
268
+ RequestOptions<TOOLS> &
269
+ Prompt &
270
+ ToolsContextParameter<TOOLS> & {
271
+ /**
272
+ * The language model to use.
273
+ */
274
+ model: LanguageModel;
275
+
276
+ /**
277
+ * The tool choice strategy. Default: 'auto'.
278
+ */
279
+ toolChoice?: ToolChoice<NoInfer<TOOLS>>;
280
+
281
+ /**
282
+ * Condition for stopping the generation when there are tool results in the last step.
283
+ * When the condition is an array, any of the conditions can be met to stop the generation.
284
+ *
285
+ * @default isStepCount(1)
286
+ */
287
+ stopWhen?: Arrayable<StopCondition<NoInfer<TOOLS>, RUNTIME_CONTEXT>>;
288
+
289
+ /**
290
+ * Optional telemetry configuration.
291
+ */
292
+ telemetry?: TelemetryOptions;
293
+
294
+ /**
295
+ * Optional telemetry configuration.
296
+ *
297
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
298
+ */
299
+ experimental_telemetry?: TelemetryOptions;
300
+
301
+ /**
302
+ * Additional provider-specific options. They are passed through
303
+ * to the provider from the AI SDK and enable provider-specific
304
+ * functionality that can be fully encapsulated in the provider.
305
+ */
306
+ providerOptions?: ProviderOptions;
307
+
308
+ /**
309
+ * Runtime context. Treat runtime context as immutable.
310
+ * If you need to mutate runtime context, update it in `prepareStep`.
311
+ */
312
+ runtimeContext?: RUNTIME_CONTEXT;
313
+
314
+ /**
315
+ * Limits the tools that are available for the model to call without
316
+ * changing the tool call and result types in the result.
317
+ */
318
+ activeTools?: Array<keyof NoInfer<TOOLS>>;
319
+
320
+ /**
321
+ * Optional specification for parsing structured outputs from the LLM response.
322
+ */
323
+ output?: OUTPUT;
324
+
325
+ /**
326
+ * Optional tool approval configuration.
327
+ *
328
+ * This configuration takes precedence over tool-defined approval settings.
329
+ */
330
+ toolApproval?: ToolApprovalConfiguration<TOOLS, RUNTIME_CONTEXT>;
331
+
332
+ /**
333
+ * Custom download function to use for URLs.
334
+ *
335
+ * By default, files are downloaded if the model does not support the URL for the given media type.
336
+ */
337
+ experimental_download?: DownloadFunction | undefined;
338
+
339
+ /**
340
+ * Optional function that you can use to provide different settings for a step.
341
+ */
342
+ prepareStep?: PrepareStepFunction<NoInfer<TOOLS>, RUNTIME_CONTEXT>;
343
+
344
+ /**
345
+ * A function that attempts to repair a tool call that failed to parse.
346
+ */
347
+ experimental_repairToolCall?: ToolCallRepairFunction<NoInfer<TOOLS>>;
348
+
349
+ /**
350
+ * Callback that is called when the generateText operation begins,
351
+ * before any LLM calls are made.
352
+ */
353
+ experimental_onStart?: GenerateTextOnStartCallback<
354
+ NoInfer<TOOLS>,
355
+ NoInfer<RUNTIME_CONTEXT>,
356
+ NoInfer<OUTPUT>
357
+ >;
358
+
359
+ /**
360
+ * Callback that is called when a step (LLM call) begins,
361
+ * before the provider is called.
362
+ */
363
+ experimental_onStepStart?: GenerateTextOnStepStartCallback<
364
+ NoInfer<TOOLS>,
365
+ NoInfer<RUNTIME_CONTEXT>,
366
+ NoInfer<OUTPUT>
367
+ >;
368
+
369
+ /**
370
+ * Callback that is called immediately before the provider model call begins.
371
+ */
372
+ experimental_onLanguageModelCallStart?: OnLanguageModelCallStartCallback;
373
+
374
+ /**
375
+ * Callback that is called after the model response has been normalized and parsed,
376
+ * but before any client-side tool execution begins.
377
+ */
378
+ experimental_onLanguageModelCallEnd?: OnLanguageModelCallEndCallback<
379
+ NoInfer<TOOLS>
380
+ >;
381
+
382
+ /**
383
+ * Callback that is called right before a tool's execute function runs.
384
+ */
385
+ experimental_onToolExecutionStart?: OnToolExecutionStartCallback<
386
+ NoInfer<TOOLS>
387
+ >;
388
+
389
+ /**
390
+ * Callback that is called right after a tool's execute function completes (or errors).
391
+ */
392
+ experimental_onToolExecutionEnd?: OnToolExecutionEndCallback<
393
+ NoInfer<TOOLS>
394
+ >;
395
+
396
+ /**
397
+ * Callback that is called when each step (LLM call) is finished, including intermediate steps.
398
+ */
399
+ onStepFinish?: GenerateTextOnStepFinishCallback<
400
+ NoInfer<TOOLS>,
401
+ NoInfer<RUNTIME_CONTEXT>
402
+ >;
403
+
404
+ /**
405
+ * Callback that is called when all steps are finished and the response is complete.
406
+ */
407
+ onFinish?: GenerateTextOnFinishCallback<
408
+ NoInfer<TOOLS>,
409
+ NoInfer<RUNTIME_CONTEXT>
410
+ >;
411
+
412
+ /**
413
+ * Settings for controlling what data is included in step results.
414
+ * Disabling inclusion can help reduce memory usage when processing
415
+ * large payloads like images.
416
+ *
417
+ * By default, all data is included for backwards compatibility.
418
+ */
419
+ experimental_include?: {
420
+ /**
421
+ * Whether to retain the request body in step results.
422
+ * The request body can be large when sending images or files.
423
+ * @default true
424
+ */
425
+ requestBody?: boolean;
426
+
427
+ /**
428
+ * Whether to retain the response body in step results.
429
+ * @default true
430
+ */
431
+ responseBody?: boolean;
432
+ };
433
+
434
+ /**
435
+ * Internal. For test use only. May change without notice.
436
+ */
437
+ _internal?: {
438
+ generateId?: IdGenerator;
439
+ generateCallId?: IdGenerator;
440
+ };
441
+ }): Promise<GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>> {
442
+ const model = resolveLanguageModel(modelArg);
443
+ const stopConditions = asArray(stopWhen);
444
+
445
+ const totalTimeoutMs = getTotalTimeoutMs(timeout);
446
+ const stepTimeoutMs = getStepTimeoutMs(timeout);
447
+ const stepAbortController =
448
+ stepTimeoutMs != null ? new AbortController() : undefined;
449
+ const mergedAbortSignal = mergeAbortSignals(
450
+ abortSignal,
451
+ totalTimeoutMs,
452
+ stepAbortController?.signal,
453
+ );
454
+
455
+ const { maxRetries, retry } = prepareRetries({
456
+ maxRetries: maxRetriesArg,
457
+ abortSignal: mergedAbortSignal,
458
+ });
459
+
460
+ const callSettings = prepareLanguageModelCallOptions(settings);
461
+
462
+ const headersWithUserAgent = withUserAgentSuffix(
463
+ headers ?? {},
464
+ `ai/${VERSION}`,
465
+ );
466
+
467
+ const initialPrompt = await standardizePrompt({
468
+ system,
469
+ prompt,
470
+ messages,
471
+ } as Prompt);
472
+
473
+ const callId = generateCallId();
474
+
475
+ const telemetryDispatcher = createTelemetryDispatcher({
476
+ telemetry,
477
+ });
478
+
479
+ await notify({
480
+ event: {
481
+ callId,
482
+ operationId: 'ai.generateText',
483
+ provider: model.provider,
484
+ modelId: model.modelId,
485
+ system,
486
+ messages: initialPrompt.messages,
487
+ tools,
488
+ toolChoice,
489
+ activeTools,
490
+ maxOutputTokens: callSettings.maxOutputTokens,
491
+ temperature: callSettings.temperature,
492
+ topP: callSettings.topP,
493
+ topK: callSettings.topK,
494
+ presencePenalty: callSettings.presencePenalty,
495
+ frequencyPenalty: callSettings.frequencyPenalty,
496
+ stopSequences: callSettings.stopSequences,
497
+ seed: callSettings.seed,
498
+ reasoning: callSettings.reasoning,
499
+ maxRetries,
500
+ timeout,
501
+ headers: headersWithUserAgent,
502
+ providerOptions,
503
+ stopWhen,
504
+ output,
505
+ runtimeContext,
506
+ toolsContext,
507
+ },
508
+ callbacks: [
509
+ onStart,
510
+ telemetryDispatcher.onStart as
511
+ | undefined
512
+ | GenerateTextOnStartCallback<TOOLS, RUNTIME_CONTEXT, OUTPUT>,
513
+ ],
514
+ });
515
+
516
+ try {
517
+ const initialMessages = initialPrompt.messages;
518
+ const responseMessages: Array<ResponseMessage> = [];
519
+
520
+ const { approvedToolApprovals, deniedToolApprovals } =
521
+ collectToolApprovals<TOOLS>({ messages: initialMessages });
522
+
523
+ const localApprovedToolApprovals = approvedToolApprovals.filter(
524
+ toolApproval => !toolApproval.toolCall.providerExecuted,
525
+ );
526
+
527
+ if (
528
+ deniedToolApprovals.length > 0 ||
529
+ localApprovedToolApprovals.length > 0
530
+ ) {
531
+ const toolOutputs = await executeTools({
532
+ toolCalls: localApprovedToolApprovals.map(
533
+ toolApproval => toolApproval.toolCall,
534
+ ),
535
+ tools: tools as TOOLS,
536
+ callId,
537
+ messages: initialMessages,
538
+ abortSignal: mergedAbortSignal,
539
+ timeout,
540
+ toolsContext,
541
+ onToolExecutionStart: event =>
542
+ notify({
543
+ event,
544
+ callbacks: [
545
+ onToolExecutionStart,
546
+ telemetryDispatcher.onToolExecutionStart as
547
+ | undefined
548
+ | OnToolExecutionStartCallback<TOOLS>,
549
+ ],
550
+ }),
551
+ onToolExecutionEnd: event =>
552
+ notify({
553
+ event,
554
+ callbacks: [
555
+ onToolExecutionEnd,
556
+ telemetryDispatcher.onToolExecutionEnd as
557
+ | undefined
558
+ | OnToolExecutionEndCallback<TOOLS>,
559
+ ],
560
+ }),
561
+ executeToolInTelemetryContext: telemetryDispatcher.executeTool,
562
+ });
563
+
564
+ const toolContent: Array<any> = [];
565
+
566
+ // add regular tool results for approved tool calls:
567
+ for (const output of toolOutputs) {
568
+ const modelOutput = await createToolModelOutput({
569
+ toolCallId: output.toolCallId,
570
+ input: output.input,
571
+ tool: tools?.[output.toolName],
572
+ output: output.type === 'tool-result' ? output.output : output.error,
573
+ errorMode: output.type === 'tool-error' ? 'text' : 'none',
574
+ });
575
+
576
+ toolContent.push({
577
+ type: 'tool-result' as const,
578
+ toolCallId: output.toolCallId,
579
+ toolName: output.toolName,
580
+ output: modelOutput,
581
+ });
582
+ }
583
+
584
+ // add execution denied tool results for all denied tool approvals:
585
+ for (const toolApproval of deniedToolApprovals) {
586
+ toolContent.push({
587
+ type: 'tool-result' as const,
588
+ toolCallId: toolApproval.toolCall.toolCallId,
589
+ toolName: toolApproval.toolCall.toolName,
590
+ output: {
591
+ type: 'execution-denied' as const,
592
+ reason: toolApproval.approvalResponse.reason,
593
+ // For provider-executed tools, include approvalId so provider can correlate
594
+ ...(toolApproval.toolCall.providerExecuted && {
595
+ providerOptions: {
596
+ openai: {
597
+ approvalId: toolApproval.approvalResponse.approvalId,
598
+ },
599
+ },
600
+ }),
601
+ },
602
+ });
603
+ }
604
+
605
+ responseMessages.push({
606
+ role: 'tool',
607
+ content: toolContent,
608
+ });
609
+ }
610
+
611
+ const callSettings = prepareLanguageModelCallOptions(settings);
612
+
613
+ let currentModelResponse: LanguageModelV4GenerateResult & {
614
+ response: { id: string; timestamp: Date; modelId: string };
615
+ };
616
+ let clientToolCalls: Array<TypedToolCall<TOOLS>> = [];
617
+ let clientToolOutputs: Array<ToolOutput<TOOLS>> = [];
618
+ let toolApprovalResponses: Array<ToolApprovalResponseOutput<TOOLS>> = [];
619
+ let deniedToolApprovalResponses: Array<ToolApprovalResponseOutput<TOOLS>> =
620
+ [];
621
+ const steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'] =
622
+ [];
623
+
624
+ // Track provider-executed tool calls that support deferred results
625
+ // (e.g., code_execution in programmatic tool calling scenarios).
626
+ // These tools may not return their results in the same turn as their call.
627
+ const pendingDeferredToolCalls = new Map<string, { toolName: string }>();
628
+
629
+ do {
630
+ // Set up step timeout if configured
631
+ const stepTimeoutId =
632
+ stepTimeoutMs != null
633
+ ? setTimeout(() => stepAbortController!.abort(), stepTimeoutMs)
634
+ : undefined;
635
+
636
+ try {
637
+ const stepInputMessages = [...initialMessages, ...responseMessages];
638
+
639
+ const prepareStepResult = await prepareStep?.({
640
+ model,
641
+ steps,
642
+ stepNumber: steps.length,
643
+ messages: stepInputMessages,
644
+ runtimeContext,
645
+ toolsContext,
646
+ });
647
+
648
+ const stepModel = resolveLanguageModel(
649
+ prepareStepResult?.model ?? model,
650
+ );
651
+
652
+ const promptMessages = await convertToLanguageModelPrompt({
653
+ prompt: {
654
+ system: prepareStepResult?.system ?? initialPrompt.system,
655
+ messages: prepareStepResult?.messages ?? stepInputMessages,
656
+ },
657
+ supportedUrls: await stepModel.supportedUrls,
658
+ download,
659
+ provider: stepModel.provider.split('.')[0],
660
+ });
661
+
662
+ runtimeContext = prepareStepResult?.runtimeContext ?? runtimeContext;
663
+ toolsContext = prepareStepResult?.toolsContext ?? toolsContext;
664
+
665
+ const stepActiveTools = filterActiveTools({
666
+ tools,
667
+ activeTools: prepareStepResult?.activeTools ?? activeTools,
668
+ });
669
+
670
+ const stepTools = await prepareTools({
671
+ tools: stepActiveTools,
672
+ });
673
+
674
+ const stepToolChoice = prepareToolChoice({
675
+ toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
676
+ });
677
+
678
+ const stepMessages = prepareStepResult?.messages ?? stepInputMessages;
679
+
680
+ const stepSystem = prepareStepResult?.system ?? initialPrompt.system;
681
+
682
+ const stepProviderOptions = mergeObjects(
683
+ providerOptions,
684
+ prepareStepResult?.providerOptions,
685
+ );
686
+ const stepNumber = steps.length;
687
+
688
+ await notify({
689
+ event: {
690
+ callId,
691
+ provider: stepModel.provider,
692
+ modelId: stepModel.modelId,
693
+ stepNumber,
694
+ system: stepSystem,
695
+ messages: stepMessages,
696
+ tools,
697
+ toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
698
+ activeTools: prepareStepResult?.activeTools ?? activeTools,
699
+ steps: [...steps],
700
+ providerOptions: stepProviderOptions,
701
+ output,
702
+ runtimeContext,
703
+ promptMessages,
704
+ stepTools,
705
+ stepToolChoice,
706
+ toolsContext,
707
+ },
708
+ callbacks: [
709
+ onStepStart,
710
+ telemetryDispatcher.onStepStart as
711
+ | undefined
712
+ | GenerateTextOnStepStartCallback<TOOLS, RUNTIME_CONTEXT, OUTPUT>,
713
+ ],
714
+ });
715
+
716
+ await notify({
717
+ event: {
718
+ callId,
719
+ provider: stepModel.provider,
720
+ modelId: stepModel.modelId,
721
+ system: stepSystem,
722
+ messages: stepMessages,
723
+ tools: stepTools,
724
+ ...callSettings,
725
+ },
726
+ callbacks: [
727
+ onLanguageModelCallStart,
728
+ telemetryDispatcher.onLanguageModelCallStart as
729
+ | undefined
730
+ | OnLanguageModelCallStartCallback,
731
+ ],
732
+ });
733
+
734
+ currentModelResponse = await retry(async () => {
735
+ const result = await stepModel.doGenerate({
736
+ ...callSettings,
737
+ tools: stepTools,
738
+ toolChoice: stepToolChoice,
739
+ responseFormat: await output?.responseFormat,
740
+ prompt: promptMessages,
741
+ providerOptions: stepProviderOptions,
742
+ abortSignal: mergedAbortSignal,
743
+ headers: headersWithUserAgent,
744
+ });
745
+
746
+ const responseData = {
747
+ id: result.response?.id ?? generateId(),
748
+ timestamp: result.response?.timestamp ?? new Date(),
749
+ modelId: result.response?.modelId ?? stepModel.modelId,
750
+ headers: result.response?.headers,
751
+ body: result.response?.body,
752
+ };
753
+
754
+ return { ...result, response: responseData };
755
+ });
756
+
757
+ // parse tool calls:
758
+ const stepToolCalls: TypedToolCall<TOOLS>[] = await Promise.all(
759
+ currentModelResponse.content
760
+ .filter(
761
+ (part): part is LanguageModelV4ToolCall =>
762
+ part.type === 'tool-call',
763
+ )
764
+ .map(toolCall =>
765
+ parseToolCall({
766
+ toolCall,
767
+ tools,
768
+ repairToolCall,
769
+ system,
770
+ messages: stepInputMessages,
771
+ }),
772
+ ),
773
+ );
774
+ const toolApprovalRequests: Record<
775
+ string,
776
+ ToolApprovalRequestOutput<TOOLS>
777
+ > = {};
778
+ const stepToolApprovalResponses: Record<
779
+ string,
780
+ ToolApprovalResponseOutput<TOOLS>
781
+ > = {};
782
+ const blockedToolCallIds = new Set<string>();
783
+
784
+ const modelCallContent = asContent({
785
+ content: currentModelResponse.content,
786
+ toolCalls: stepToolCalls,
787
+ toolOutputs: [],
788
+ toolApprovalRequests: [],
789
+ toolApprovalResponses: [],
790
+ tools,
791
+ });
792
+
793
+ await notify({
794
+ event: {
795
+ callId,
796
+ provider: stepModel.provider,
797
+ modelId: stepModel.modelId,
798
+ finishReason: currentModelResponse.finishReason.unified,
799
+ usage: asLanguageModelUsage(currentModelResponse.usage),
800
+ content: modelCallContent,
801
+ responseId: currentModelResponse.response.id,
802
+ },
803
+ callbacks: [
804
+ onLanguageModelCallEnd,
805
+ telemetryDispatcher.onLanguageModelCallEnd as
806
+ | undefined
807
+ | OnLanguageModelCallEndCallback<TOOLS>,
808
+ ],
809
+ });
810
+
811
+ // notify the tools that the tool calls are available:
812
+ for (const toolCall of stepToolCalls) {
813
+ if (toolCall.invalid) {
814
+ continue; // ignore invalid tool calls
815
+ }
816
+
817
+ const tool = tools?.[toolCall.toolName];
818
+
819
+ if (tool == null) {
820
+ // ignore tool calls for tools that are not available,
821
+ // e.g. provider-executed dynamic tools
822
+ continue;
823
+ }
824
+
825
+ if (tool?.onInputAvailable != null) {
826
+ await tool.onInputAvailable({
827
+ input: toolCall.input,
828
+ toolCallId: toolCall.toolCallId,
829
+ messages: stepInputMessages,
830
+ abortSignal: mergedAbortSignal,
831
+ context: runtimeContext,
832
+ });
833
+ }
834
+
835
+ const toolApprovalStatus = await resolveToolApproval({
836
+ tools,
837
+ toolApproval,
838
+ toolCall,
839
+ messages: stepInputMessages,
840
+ toolsContext,
841
+ runtimeContext,
842
+ });
843
+
844
+ switch (toolApprovalStatus.type) {
845
+ case 'user-approval': {
846
+ toolApprovalRequests[toolCall.toolCallId] = {
847
+ type: 'tool-approval-request',
848
+ approvalId: generateId(),
849
+ toolCall,
850
+ };
851
+ blockedToolCallIds.add(toolCall.toolCallId);
852
+ break;
853
+ }
854
+
855
+ case 'approved': {
856
+ const approvalId = generateId();
857
+
858
+ toolApprovalRequests[toolCall.toolCallId] = {
859
+ type: 'tool-approval-request',
860
+ approvalId,
861
+ toolCall,
862
+ isAutomatic: true,
863
+ };
864
+ stepToolApprovalResponses[toolCall.toolCallId] = {
865
+ type: 'tool-approval-response',
866
+ approvalId,
867
+ toolCall,
868
+ approved: true,
869
+ reason: toolApprovalStatus.reason,
870
+ providerExecuted: toolCall.providerExecuted,
871
+ };
872
+ break;
873
+ }
874
+
875
+ case 'denied': {
876
+ const approvalId = generateId();
877
+
878
+ toolApprovalRequests[toolCall.toolCallId] = {
879
+ type: 'tool-approval-request',
880
+ approvalId,
881
+ toolCall,
882
+ isAutomatic: true,
883
+ };
884
+ stepToolApprovalResponses[toolCall.toolCallId] = {
885
+ type: 'tool-approval-response',
886
+ approvalId,
887
+ toolCall,
888
+ approved: false,
889
+ reason: toolApprovalStatus.reason,
890
+ providerExecuted: toolCall.providerExecuted,
891
+ };
892
+ blockedToolCallIds.add(toolCall.toolCallId);
893
+ break;
894
+ }
895
+ }
896
+ }
897
+
898
+ // insert error tool outputs for invalid tool calls:
899
+ // TODO AI SDK 6: invalid inputs should not require output parts
900
+ const invalidToolCalls = stepToolCalls.filter(
901
+ toolCall => toolCall.invalid && toolCall.dynamic,
902
+ );
903
+
904
+ clientToolOutputs = [];
905
+
906
+ for (const toolCall of invalidToolCalls) {
907
+ clientToolOutputs.push({
908
+ type: 'tool-error',
909
+ toolCallId: toolCall.toolCallId,
910
+ toolName: toolCall.toolName,
911
+ input: toolCall.input,
912
+ error: getErrorMessage(toolCall.error!),
913
+ dynamic: true,
914
+ });
915
+ }
916
+
917
+ // execute client tool calls:
918
+ clientToolCalls = stepToolCalls.filter(
919
+ toolCall => !toolCall.providerExecuted,
920
+ );
921
+ toolApprovalResponses = Object.values(stepToolApprovalResponses);
922
+ deniedToolApprovalResponses = toolApprovalResponses.filter(
923
+ toolApprovalResponse => toolApprovalResponse.approved === false,
924
+ );
925
+
926
+ if (tools != null) {
927
+ clientToolOutputs.push(
928
+ ...(await executeTools({
929
+ toolCalls: clientToolCalls.filter(
930
+ toolCall =>
931
+ !toolCall.invalid &&
932
+ !blockedToolCallIds.has(toolCall.toolCallId),
933
+ ),
934
+ tools,
935
+ callId,
936
+ messages: stepInputMessages,
937
+ abortSignal: mergedAbortSignal,
938
+ timeout,
939
+ toolsContext,
940
+ onToolExecutionStart: event =>
941
+ notify({
942
+ event,
943
+ callbacks: [
944
+ onToolExecutionStart,
945
+ telemetryDispatcher.onToolExecutionStart as
946
+ | undefined
947
+ | OnToolExecutionStartCallback<TOOLS>,
948
+ ],
949
+ }),
950
+ onToolExecutionEnd: event =>
951
+ notify({
952
+ event,
953
+ callbacks: [
954
+ onToolExecutionEnd,
955
+ telemetryDispatcher.onToolExecutionEnd as
956
+ | undefined
957
+ | OnToolExecutionEndCallback<TOOLS>,
958
+ ],
959
+ }),
960
+ executeToolInTelemetryContext: telemetryDispatcher.executeTool,
961
+ })),
962
+ );
963
+ }
964
+
965
+ // Track provider-executed tool calls that support deferred results.
966
+ // In programmatic tool calling, a server tool (e.g., code_execution) may
967
+ // trigger a client tool, and the server tool's result is deferred until
968
+ // the client tool's result is sent back.
969
+ for (const toolCall of stepToolCalls) {
970
+ if (!toolCall.providerExecuted) continue;
971
+ const tool = tools?.[toolCall.toolName];
972
+ if (tool?.type === 'provider' && tool.supportsDeferredResults) {
973
+ // Check if this tool call already has a result in the current response
974
+ const hasResultInResponse = currentModelResponse.content.some(
975
+ part =>
976
+ part.type === 'tool-result' &&
977
+ part.toolCallId === toolCall.toolCallId,
978
+ );
979
+ if (!hasResultInResponse) {
980
+ pendingDeferredToolCalls.set(toolCall.toolCallId, {
981
+ toolName: toolCall.toolName,
982
+ });
983
+ }
984
+ }
985
+ }
986
+
987
+ // Mark deferred tool calls as resolved when we receive their results
988
+ for (const part of currentModelResponse.content) {
989
+ if (part.type === 'tool-result') {
990
+ pendingDeferredToolCalls.delete(part.toolCallId);
991
+ }
992
+ }
993
+
994
+ // content:
995
+ const stepContent = asContent({
996
+ content: currentModelResponse.content,
997
+ toolCalls: stepToolCalls,
998
+ toolOutputs: clientToolOutputs,
999
+ toolApprovalRequests: Object.values(toolApprovalRequests),
1000
+ toolApprovalResponses,
1001
+ tools,
1002
+ });
1003
+
1004
+ // append to messages for potential next step:
1005
+ responseMessages.push(
1006
+ ...(await toResponseMessages({
1007
+ content: stepContent,
1008
+ tools,
1009
+ })),
1010
+ );
1011
+
1012
+ // Add step information (after response messages are updated):
1013
+ // Conditionally include request.body and response.body based on include settings.
1014
+ // Large payloads (e.g., base64-encoded images) can cause memory issues.
1015
+ const stepRequest: LanguageModelRequestMetadata =
1016
+ (include?.requestBody ?? true)
1017
+ ? (currentModelResponse.request ?? {})
1018
+ : { ...currentModelResponse.request, body: undefined };
1019
+
1020
+ const stepResponse = {
1021
+ ...currentModelResponse.response,
1022
+ // deep clone msgs to avoid mutating past messages in multi-step:
1023
+ messages: structuredClone(responseMessages),
1024
+ // Conditionally include response body:
1025
+ body:
1026
+ (include?.responseBody ?? true)
1027
+ ? currentModelResponse.response?.body
1028
+ : undefined,
1029
+ };
1030
+
1031
+ const currentStepResult: StepResult<TOOLS, RUNTIME_CONTEXT> =
1032
+ new DefaultStepResult({
1033
+ callId,
1034
+ stepNumber,
1035
+ provider: stepModel.provider,
1036
+ modelId: stepModel.modelId,
1037
+ runtimeContext,
1038
+ content: stepContent,
1039
+ finishReason: currentModelResponse.finishReason.unified,
1040
+ rawFinishReason: currentModelResponse.finishReason.raw,
1041
+ usage: asLanguageModelUsage(currentModelResponse.usage),
1042
+ warnings: currentModelResponse.warnings,
1043
+ providerMetadata: currentModelResponse.providerMetadata,
1044
+ request: stepRequest,
1045
+ response: stepResponse,
1046
+ toolsContext,
1047
+ });
1048
+
1049
+ logWarnings({
1050
+ warnings: currentModelResponse.warnings ?? [],
1051
+ provider: stepModel.provider,
1052
+ model: stepModel.modelId,
1053
+ });
1054
+
1055
+ steps.push(currentStepResult);
1056
+
1057
+ await notify({
1058
+ event: currentStepResult,
1059
+ callbacks: [
1060
+ onStepFinish,
1061
+ telemetryDispatcher.onStepFinish as
1062
+ | undefined
1063
+ | GenerateTextOnStepFinishCallback<TOOLS, RUNTIME_CONTEXT>,
1064
+ ],
1065
+ });
1066
+ } finally {
1067
+ if (stepTimeoutId != null) {
1068
+ clearTimeout(stepTimeoutId);
1069
+ }
1070
+ }
1071
+ } while (
1072
+ // Continue if:
1073
+ // 1. There are client tool calls that have all been executed or denied, OR
1074
+ // 2. There are pending deferred results from provider-executed tools
1075
+ ((clientToolCalls.length > 0 &&
1076
+ clientToolOutputs.length + deniedToolApprovalResponses.length ===
1077
+ clientToolCalls.length) ||
1078
+ pendingDeferredToolCalls.size > 0) &&
1079
+ // continue until a stop condition is met:
1080
+ !(await isStopConditionMet({ stopConditions, steps }))
1081
+ );
1082
+
1083
+ const lastStep = steps[steps.length - 1];
1084
+
1085
+ const totalUsage = steps.reduce(
1086
+ (totalUsage, step) => {
1087
+ return addLanguageModelUsage(totalUsage, step.usage);
1088
+ },
1089
+ {
1090
+ inputTokens: undefined,
1091
+ outputTokens: undefined,
1092
+ totalTokens: undefined,
1093
+ reasoningTokens: undefined,
1094
+ cachedInputTokens: undefined,
1095
+ } as LanguageModelUsage,
1096
+ );
1097
+
1098
+ const onFinishEvent = {
1099
+ callId,
1100
+ stepNumber: lastStep.stepNumber,
1101
+ model: lastStep.model,
1102
+ runtimeContext: lastStep.runtimeContext,
1103
+ finishReason: lastStep.finishReason,
1104
+ rawFinishReason: lastStep.rawFinishReason,
1105
+ usage: lastStep.usage,
1106
+ content: lastStep.content,
1107
+ text: lastStep.text,
1108
+ reasoningText: lastStep.reasoningText,
1109
+ reasoning: lastStep.reasoning,
1110
+ files: lastStep.files,
1111
+ sources: lastStep.sources,
1112
+ toolCalls: lastStep.toolCalls,
1113
+ staticToolCalls: lastStep.staticToolCalls,
1114
+ dynamicToolCalls: lastStep.dynamicToolCalls,
1115
+ toolResults: lastStep.toolResults,
1116
+ staticToolResults: lastStep.staticToolResults,
1117
+ dynamicToolResults: lastStep.dynamicToolResults,
1118
+ request: lastStep.request,
1119
+ response: lastStep.response,
1120
+ warnings: lastStep.warnings,
1121
+ providerMetadata: lastStep.providerMetadata,
1122
+ steps,
1123
+ totalUsage,
1124
+ toolsContext,
1125
+ };
1126
+
1127
+ await notify({
1128
+ event: onFinishEvent,
1129
+ callbacks: [
1130
+ onFinish,
1131
+ telemetryDispatcher.onFinish as
1132
+ | undefined
1133
+ | GenerateTextOnFinishCallback<TOOLS, RUNTIME_CONTEXT>,
1134
+ ],
1135
+ });
1136
+
1137
+ // parse output only if the last step was finished with "stop":
1138
+ let resolvedOutput;
1139
+ if (lastStep.finishReason === 'stop') {
1140
+ const outputSpecification = output ?? text();
1141
+ resolvedOutput = await outputSpecification.parseCompleteOutput(
1142
+ { text: lastStep.text },
1143
+ {
1144
+ response: lastStep.response,
1145
+ usage: lastStep.usage,
1146
+ finishReason: lastStep.finishReason,
1147
+ },
1148
+ );
1149
+ }
1150
+
1151
+ return new DefaultGenerateTextResult({
1152
+ steps,
1153
+ totalUsage,
1154
+ output: resolvedOutput,
1155
+ });
1156
+ } catch (error) {
1157
+ await telemetryDispatcher.onError?.({ callId, error });
1158
+ throw wrapGatewayError(error);
1159
+ }
1160
+ }
1161
+
1162
+ async function executeTools<TOOLS extends ToolSet>({
1163
+ toolCalls,
1164
+ tools,
1165
+ callId,
1166
+ messages,
1167
+ abortSignal,
1168
+ timeout,
1169
+ toolsContext,
1170
+ onToolExecutionStart,
1171
+ onToolExecutionEnd,
1172
+ executeToolInTelemetryContext,
1173
+ }: {
1174
+ toolCalls: Array<TypedToolCall<TOOLS>>;
1175
+ tools: TOOLS;
1176
+ callId: string;
1177
+ messages: ModelMessage[];
1178
+ abortSignal: AbortSignal | undefined;
1179
+ timeout?: TimeoutConfiguration<TOOLS>;
1180
+ toolsContext: InferToolSetContext<TOOLS>;
1181
+ onToolExecutionStart?: OnToolExecutionStartCallback<TOOLS>;
1182
+ onToolExecutionEnd?: OnToolExecutionEndCallback<TOOLS>;
1183
+ executeToolInTelemetryContext?: Telemetry['executeTool'];
1184
+ }): Promise<Array<ToolOutput<TOOLS>>> {
1185
+ const toolOutputs = await Promise.all(
1186
+ toolCalls.map(
1187
+ async toolCall =>
1188
+ await executeToolCall({
1189
+ toolCall,
1190
+ tools,
1191
+ callId,
1192
+ messages,
1193
+ abortSignal,
1194
+ timeout,
1195
+ toolsContext,
1196
+ onToolExecutionStart,
1197
+ onToolExecutionEnd,
1198
+ executeToolInTelemetryContext,
1199
+ }),
1200
+ ),
1201
+ );
1202
+
1203
+ return toolOutputs.filter(
1204
+ (output): output is NonNullable<typeof output> => output != null,
1205
+ );
1206
+ }
1207
+
1208
+ class DefaultGenerateTextResult<
1209
+ TOOLS extends ToolSet,
1210
+ RUNTIME_CONTEXT extends Context,
1211
+ OUTPUT extends Output,
1212
+ > implements GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT> {
1213
+ readonly steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'];
1214
+ readonly totalUsage: LanguageModelUsage;
1215
+ private readonly _output: InferCompleteOutput<OUTPUT> | undefined;
1216
+
1217
+ constructor(options: {
1218
+ steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'];
1219
+ output: InferCompleteOutput<OUTPUT> | undefined;
1220
+ totalUsage: LanguageModelUsage;
1221
+ }) {
1222
+ this.steps = options.steps;
1223
+ this._output = options.output;
1224
+ this.totalUsage = options.totalUsage;
1225
+ }
1226
+
1227
+ private get finalStep() {
1228
+ return this.steps[this.steps.length - 1];
1229
+ }
1230
+
1231
+ get content() {
1232
+ return this.finalStep.content;
1233
+ }
1234
+
1235
+ get text() {
1236
+ return this.finalStep.text;
1237
+ }
1238
+
1239
+ get files() {
1240
+ return this.finalStep.files;
1241
+ }
1242
+
1243
+ get reasoningText() {
1244
+ return this.finalStep.reasoningText;
1245
+ }
1246
+
1247
+ get reasoning() {
1248
+ return convertToReasoningOutputs(this.finalStep.reasoning);
1249
+ }
1250
+
1251
+ get toolCalls() {
1252
+ return this.finalStep.toolCalls;
1253
+ }
1254
+
1255
+ get staticToolCalls() {
1256
+ return this.finalStep.staticToolCalls;
1257
+ }
1258
+
1259
+ get dynamicToolCalls() {
1260
+ return this.finalStep.dynamicToolCalls;
1261
+ }
1262
+
1263
+ get toolResults() {
1264
+ return this.finalStep.toolResults;
1265
+ }
1266
+
1267
+ get staticToolResults() {
1268
+ return this.finalStep.staticToolResults;
1269
+ }
1270
+
1271
+ get dynamicToolResults() {
1272
+ return this.finalStep.dynamicToolResults;
1273
+ }
1274
+
1275
+ get sources() {
1276
+ return this.finalStep.sources;
1277
+ }
1278
+
1279
+ get finishReason() {
1280
+ return this.finalStep.finishReason;
1281
+ }
1282
+
1283
+ get rawFinishReason() {
1284
+ return this.finalStep.rawFinishReason;
1285
+ }
1286
+
1287
+ get warnings() {
1288
+ return this.finalStep.warnings;
1289
+ }
1290
+
1291
+ get providerMetadata() {
1292
+ return this.finalStep.providerMetadata;
1293
+ }
1294
+
1295
+ get response() {
1296
+ return this.finalStep.response;
1297
+ }
1298
+
1299
+ get request() {
1300
+ return this.finalStep.request;
1301
+ }
1302
+
1303
+ get usage() {
1304
+ return this.finalStep.usage;
1305
+ }
1306
+
1307
+ get output() {
1308
+ if (this._output == null) {
1309
+ throw new NoOutputGeneratedError();
1310
+ }
1311
+
1312
+ return this._output;
1313
+ }
1314
+ }
1315
+
1316
+ function asContent<TOOLS extends ToolSet>({
1317
+ content,
1318
+ toolCalls,
1319
+ toolOutputs,
1320
+ toolApprovalRequests,
1321
+ toolApprovalResponses,
1322
+ tools,
1323
+ }: {
1324
+ content: Array<LanguageModelV4Content>;
1325
+ toolCalls: Array<TypedToolCall<TOOLS>>;
1326
+ toolOutputs: Array<ToolOutput<TOOLS>>;
1327
+ toolApprovalRequests: Array<ToolApprovalRequestOutput<TOOLS>>;
1328
+ toolApprovalResponses: Array<ToolApprovalResponseOutput<TOOLS>>;
1329
+ tools: TOOLS | undefined;
1330
+ }): Array<ContentPart<TOOLS>> {
1331
+ const contentParts: Array<ContentPart<TOOLS>> = [];
1332
+ const toolOutputsWithApprovalResponses: Array<ToolOutput<TOOLS>> = [];
1333
+ const toolOutputsWithoutApprovalResponses: Array<ToolOutput<TOOLS>> = [];
1334
+ const toolCallIdsWithApprovalResponses = new Set(
1335
+ toolApprovalResponses.map(
1336
+ toolApprovalResponse => toolApprovalResponse.toolCall.toolCallId,
1337
+ ),
1338
+ );
1339
+
1340
+ for (const part of content) {
1341
+ switch (part.type) {
1342
+ case 'text':
1343
+ case 'reasoning':
1344
+ case 'custom':
1345
+ case 'source':
1346
+ contentParts.push(part);
1347
+ break;
1348
+
1349
+ case 'file':
1350
+ case 'reasoning-file': {
1351
+ contentParts.push({
1352
+ type: part.type as 'file' | 'reasoning-file',
1353
+ file: new DefaultGeneratedFile(part),
1354
+ ...(part.providerMetadata != null
1355
+ ? { providerMetadata: part.providerMetadata }
1356
+ : {}),
1357
+ });
1358
+ break;
1359
+ }
1360
+
1361
+ case 'tool-call': {
1362
+ contentParts.push(
1363
+ toolCalls.find(toolCall => toolCall.toolCallId === part.toolCallId)!,
1364
+ );
1365
+ break;
1366
+ }
1367
+
1368
+ case 'tool-result': {
1369
+ const toolCall = toolCalls.find(
1370
+ toolCall => toolCall.toolCallId === part.toolCallId,
1371
+ );
1372
+
1373
+ // Handle deferred results for provider-executed tools (e.g., programmatic tool calling).
1374
+ // When a server tool (like code_execution) triggers a client tool, the server tool's
1375
+ // result may be deferred to a later turn. In this case, there's no matching tool-call
1376
+ // in the current response.
1377
+ if (toolCall == null) {
1378
+ const tool = tools?.[part.toolName];
1379
+ const supportsDeferredResults =
1380
+ tool?.type === 'provider' && tool.supportsDeferredResults;
1381
+
1382
+ if (!supportsDeferredResults) {
1383
+ throw new Error(`Tool call ${part.toolCallId} not found.`);
1384
+ }
1385
+
1386
+ // Create tool result without tool call input (deferred result)
1387
+ if (part.isError) {
1388
+ contentParts.push({
1389
+ type: 'tool-error' as const,
1390
+ toolCallId: part.toolCallId,
1391
+ toolName: part.toolName as keyof TOOLS & string,
1392
+ input: undefined,
1393
+ error: part.result,
1394
+ providerExecuted: true,
1395
+ dynamic: part.dynamic,
1396
+ ...(part.providerMetadata != null
1397
+ ? { providerMetadata: part.providerMetadata }
1398
+ : {}),
1399
+ } as TypedToolError<TOOLS>);
1400
+ } else {
1401
+ contentParts.push({
1402
+ type: 'tool-result' as const,
1403
+ toolCallId: part.toolCallId,
1404
+ toolName: part.toolName as keyof TOOLS & string,
1405
+ input: undefined,
1406
+ output: part.result,
1407
+ providerExecuted: true,
1408
+ dynamic: part.dynamic,
1409
+ ...(part.providerMetadata != null
1410
+ ? { providerMetadata: part.providerMetadata }
1411
+ : {}),
1412
+ } as TypedToolResult<TOOLS>);
1413
+ }
1414
+ break;
1415
+ }
1416
+
1417
+ if (part.isError) {
1418
+ contentParts.push({
1419
+ type: 'tool-error' as const,
1420
+ toolCallId: part.toolCallId,
1421
+ toolName: part.toolName as keyof TOOLS & string,
1422
+ input: toolCall.input,
1423
+ error: part.result,
1424
+ providerExecuted: true,
1425
+ dynamic: toolCall.dynamic,
1426
+ ...(part.providerMetadata != null
1427
+ ? { providerMetadata: part.providerMetadata }
1428
+ : {}),
1429
+ } as TypedToolError<TOOLS>);
1430
+ } else {
1431
+ contentParts.push({
1432
+ type: 'tool-result' as const,
1433
+ toolCallId: part.toolCallId,
1434
+ toolName: part.toolName as keyof TOOLS & string,
1435
+ input: toolCall.input,
1436
+ output: part.result,
1437
+ providerExecuted: true,
1438
+ dynamic: toolCall.dynamic,
1439
+ ...(part.providerMetadata != null
1440
+ ? { providerMetadata: part.providerMetadata }
1441
+ : {}),
1442
+ } as TypedToolResult<TOOLS>);
1443
+ }
1444
+ break;
1445
+ }
1446
+
1447
+ case 'tool-approval-request': {
1448
+ const toolCall = toolCalls.find(
1449
+ toolCall => toolCall.toolCallId === part.toolCallId,
1450
+ );
1451
+
1452
+ if (toolCall == null) {
1453
+ throw new ToolCallNotFoundForApprovalError({
1454
+ toolCallId: part.toolCallId,
1455
+ approvalId: part.approvalId,
1456
+ });
1457
+ }
1458
+
1459
+ contentParts.push({
1460
+ type: 'tool-approval-request' as const,
1461
+ approvalId: part.approvalId,
1462
+ toolCall,
1463
+ });
1464
+ break;
1465
+ }
1466
+ }
1467
+ }
1468
+
1469
+ for (const toolOutput of toolOutputs) {
1470
+ if (toolCallIdsWithApprovalResponses.has(toolOutput.toolCallId)) {
1471
+ toolOutputsWithApprovalResponses.push(toolOutput);
1472
+ } else {
1473
+ toolOutputsWithoutApprovalResponses.push(toolOutput);
1474
+ }
1475
+ }
1476
+
1477
+ return [
1478
+ ...contentParts,
1479
+ ...toolOutputsWithoutApprovalResponses,
1480
+ ...toolApprovalRequests,
1481
+ ...toolApprovalResponses,
1482
+ ...toolOutputsWithApprovalResponses,
1483
+ ];
1484
+ }