@alvin0/ai-agent-sdk-core 0.1.0

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 (623) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/dist/agent/accounting/common.js +2 -0
  4. package/dist/agent/accounting/common.js.map +1 -0
  5. package/dist/agent/accounting/config.js +2 -0
  6. package/dist/agent/accounting/config.js.map +1 -0
  7. package/dist/agent/accounting/contracts.d.ts +36 -0
  8. package/dist/agent/accounting/contracts.d.ts.map +1 -0
  9. package/dist/agent/accounting/delivery/accounting-data.js +2 -0
  10. package/dist/agent/accounting/delivery/accounting-data.js.map +1 -0
  11. package/dist/agent/accounting/delivery/config.js +2 -0
  12. package/dist/agent/accounting/delivery/config.js.map +1 -0
  13. package/dist/agent/accounting/delivery/data.js +2 -0
  14. package/dist/agent/accounting/delivery/data.js.map +1 -0
  15. package/dist/agent/accounting/delivery/support-errors.js +2 -0
  16. package/dist/agent/accounting/delivery/support-errors.js.map +1 -0
  17. package/dist/agent/accounting/delivery/terminal.js +2 -0
  18. package/dist/agent/accounting/delivery/terminal.js.map +1 -0
  19. package/dist/agent/accounting/delivery-types.d.ts +43 -0
  20. package/dist/agent/accounting/delivery-types.d.ts.map +1 -0
  21. package/dist/agent/accounting/error.d.ts +18 -0
  22. package/dist/agent/accounting/error.d.ts.map +1 -0
  23. package/dist/agent/accounting/error.js +2 -0
  24. package/dist/agent/accounting/error.js.map +1 -0
  25. package/dist/agent/accounting/estimate.js +2 -0
  26. package/dist/agent/accounting/estimate.js.map +1 -0
  27. package/dist/agent/accounting/event-buffer.js +2 -0
  28. package/dist/agent/accounting/event-buffer.js.map +1 -0
  29. package/dist/agent/accounting/ledger.js +2 -0
  30. package/dist/agent/accounting/ledger.js.map +1 -0
  31. package/dist/agent/accounting/report.d.ts +70 -0
  32. package/dist/agent/accounting/report.d.ts.map +1 -0
  33. package/dist/agent/accounting/usage.d.ts +13 -0
  34. package/dist/agent/accounting/usage.d.ts.map +1 -0
  35. package/dist/agent/accounting/usage.js +2 -0
  36. package/dist/agent/accounting/usage.js.map +1 -0
  37. package/dist/agent/context/section.d.ts +15 -0
  38. package/dist/agent/context/section.d.ts.map +1 -0
  39. package/dist/agent/context/section.js +2 -0
  40. package/dist/agent/context/section.js.map +1 -0
  41. package/dist/agent/context/types.d.ts +98 -0
  42. package/dist/agent/context/types.d.ts.map +1 -0
  43. package/dist/agent/define/definition.d.ts +110 -0
  44. package/dist/agent/define/definition.d.ts.map +1 -0
  45. package/dist/agent/define/definition.js +2 -0
  46. package/dist/agent/define/definition.js.map +1 -0
  47. package/dist/agent/define/instructions.js +2 -0
  48. package/dist/agent/define/instructions.js.map +1 -0
  49. package/dist/agent/define/output-format.js +2 -0
  50. package/dist/agent/define/output-format.js.map +1 -0
  51. package/dist/agent/define/session/accounting.js +2 -0
  52. package/dist/agent/define/session/accounting.js.map +1 -0
  53. package/dist/agent/define/session/common.js +2 -0
  54. package/dist/agent/define/session/common.js.map +1 -0
  55. package/dist/agent/define/session/config.js +2 -0
  56. package/dist/agent/define/session/config.js.map +1 -0
  57. package/dist/agent/define/session/model-config.js +2 -0
  58. package/dist/agent/define/session/model-config.js.map +1 -0
  59. package/dist/agent/define/session/observer.js +2 -0
  60. package/dist/agent/define/session/observer.js.map +1 -0
  61. package/dist/agent/define/session/run-seal.js +2 -0
  62. package/dist/agent/define/session/run-seal.js.map +1 -0
  63. package/dist/agent/define/session/runtime-binding.js +2 -0
  64. package/dist/agent/define/session/runtime-binding.js.map +1 -0
  65. package/dist/agent/define/session/runtime-compaction.js +2 -0
  66. package/dist/agent/define/session/runtime-compaction.js.map +1 -0
  67. package/dist/agent/define/session/runtime-memory.js +2 -0
  68. package/dist/agent/define/session/runtime-memory.js.map +1 -0
  69. package/dist/agent/define/session/skills.js +2 -0
  70. package/dist/agent/define/session/skills.js.map +1 -0
  71. package/dist/agent/define/session/trace-accounting.js +2 -0
  72. package/dist/agent/define/session/trace-accounting.js.map +1 -0
  73. package/dist/agent/define/session/types.d.ts +217 -0
  74. package/dist/agent/define/session/types.d.ts.map +1 -0
  75. package/dist/agent/define/session/validation.js +2 -0
  76. package/dist/agent/define/session/validation.js.map +1 -0
  77. package/dist/agent/define/session.d.ts +77 -0
  78. package/dist/agent/define/session.d.ts.map +1 -0
  79. package/dist/agent/define/session.js +2 -0
  80. package/dist/agent/define/session.js.map +1 -0
  81. package/dist/agent/history/config.js +2 -0
  82. package/dist/agent/history/config.js.map +1 -0
  83. package/dist/agent/history/history.d.ts +33 -0
  84. package/dist/agent/history/history.d.ts.map +1 -0
  85. package/dist/agent/history/history.js +2 -0
  86. package/dist/agent/history/history.js.map +1 -0
  87. package/dist/agent/history/normalize.d.ts +7 -0
  88. package/dist/agent/history/normalize.d.ts.map +1 -0
  89. package/dist/agent/history/normalize.js +2 -0
  90. package/dist/agent/history/normalize.js.map +1 -0
  91. package/dist/agent/history/project.d.ts +14 -0
  92. package/dist/agent/history/project.d.ts.map +1 -0
  93. package/dist/agent/history/project.js +2 -0
  94. package/dist/agent/history/project.js.map +1 -0
  95. package/dist/agent/history/types.d.ts +85 -0
  96. package/dist/agent/history/types.d.ts.map +1 -0
  97. package/dist/agent/history/validation.js +2 -0
  98. package/dist/agent/history/validation.js.map +1 -0
  99. package/dist/agent/loop/events.d.ts +213 -0
  100. package/dist/agent/loop/events.d.ts.map +1 -0
  101. package/dist/agent/loop/queue.js +2 -0
  102. package/dist/agent/loop/queue.js.map +1 -0
  103. package/dist/agent/loop/run-turn.d.ts +8 -0
  104. package/dist/agent/loop/run-turn.d.ts.map +1 -0
  105. package/dist/agent/loop/run-turn.js +2 -0
  106. package/dist/agent/loop/run-turn.js.map +1 -0
  107. package/dist/agent/loop/schedule.d.ts +62 -0
  108. package/dist/agent/loop/schedule.d.ts.map +1 -0
  109. package/dist/agent/loop/schedule.js +3 -0
  110. package/dist/agent/loop/schedule.js.map +1 -0
  111. package/dist/agent/loop/turn/cancellation.js +2 -0
  112. package/dist/agent/loop/turn/cancellation.js.map +1 -0
  113. package/dist/agent/loop/turn/common.js +2 -0
  114. package/dist/agent/loop/turn/common.js.map +1 -0
  115. package/dist/agent/loop/turn/config.js +2 -0
  116. package/dist/agent/loop/turn/config.js.map +1 -0
  117. package/dist/agent/loop/turn/content.js +4 -0
  118. package/dist/agent/loop/turn/content.js.map +1 -0
  119. package/dist/agent/loop/turn/hooks.js +2 -0
  120. package/dist/agent/loop/turn/hooks.js.map +1 -0
  121. package/dist/agent/loop/turn/model-round.js +2 -0
  122. package/dist/agent/loop/turn/model-round.js.map +1 -0
  123. package/dist/agent/loop/turn/repetition.js +2 -0
  124. package/dist/agent/loop/turn/repetition.js.map +1 -0
  125. package/dist/agent/loop/turn/types.d.ts +82 -0
  126. package/dist/agent/loop/turn/types.d.ts.map +1 -0
  127. package/dist/agent/loop/turn/usage-stop.js +2 -0
  128. package/dist/agent/loop/turn/usage-stop.js.map +1 -0
  129. package/dist/agent/loop/turn/validation.js +2 -0
  130. package/dist/agent/loop/turn/validation.js.map +1 -0
  131. package/dist/agent/loop/types.d.ts +82 -0
  132. package/dist/agent/loop/types.d.ts.map +1 -0
  133. package/dist/agent/memory/accounting-binding.js +2 -0
  134. package/dist/agent/memory/accounting-binding.js.map +1 -0
  135. package/dist/agent/memory/compaction-config.d.ts +63 -0
  136. package/dist/agent/memory/compaction-config.d.ts.map +1 -0
  137. package/dist/agent/memory/compaction-config.js +2 -0
  138. package/dist/agent/memory/compaction-config.js.map +1 -0
  139. package/dist/agent/memory/compaction.d.ts +62 -0
  140. package/dist/agent/memory/compaction.d.ts.map +1 -0
  141. package/dist/agent/memory/compaction.js +6 -0
  142. package/dist/agent/memory/compaction.js.map +1 -0
  143. package/dist/agent/memory/memory.d.ts +61 -0
  144. package/dist/agent/memory/memory.d.ts.map +1 -0
  145. package/dist/agent/memory/memory.js +5 -0
  146. package/dist/agent/memory/memory.js.map +1 -0
  147. package/dist/agent/memory/persistence-types.d.ts +44 -0
  148. package/dist/agent/memory/persistence-types.d.ts.map +1 -0
  149. package/dist/agent/memory/surface-compaction.d.ts +6 -0
  150. package/dist/agent/memory/surface-compaction.d.ts.map +1 -0
  151. package/dist/agent/memory/surface-compaction.js +4 -0
  152. package/dist/agent/memory/surface-compaction.js.map +1 -0
  153. package/dist/agent/memory/token-estimator.d.ts +12 -0
  154. package/dist/agent/memory/token-estimator.d.ts.map +1 -0
  155. package/dist/agent/memory/token-estimator.js +2 -0
  156. package/dist/agent/memory/token-estimator.js.map +1 -0
  157. package/dist/agent/mode/run-agent.d.ts +79 -0
  158. package/dist/agent/mode/run-agent.d.ts.map +1 -0
  159. package/dist/agent/mode/run-agent.js +4 -0
  160. package/dist/agent/mode/run-agent.js.map +1 -0
  161. package/dist/agent/mode/user-input.d.ts +61 -0
  162. package/dist/agent/mode/user-input.d.ts.map +1 -0
  163. package/dist/agent/mode/user-input.js +2 -0
  164. package/dist/agent/mode/user-input.js.map +1 -0
  165. package/dist/agent/skill/catalog.d.ts +53 -0
  166. package/dist/agent/skill/catalog.d.ts.map +1 -0
  167. package/dist/agent/skill/catalog.js +2 -0
  168. package/dist/agent/skill/catalog.js.map +1 -0
  169. package/dist/agent/skill/definition.d.ts +106 -0
  170. package/dist/agent/skill/definition.d.ts.map +1 -0
  171. package/dist/agent/skill/definition.js +2 -0
  172. package/dist/agent/skill/definition.js.map +1 -0
  173. package/dist/agent/skill/provider/config.d.ts +11 -0
  174. package/dist/agent/skill/provider/config.d.ts.map +1 -0
  175. package/dist/agent/skill/provider/config.js +2 -0
  176. package/dist/agent/skill/provider/config.js.map +1 -0
  177. package/dist/agent/skill/provider/context.js +2 -0
  178. package/dist/agent/skill/provider/context.js.map +1 -0
  179. package/dist/agent/skill/provider/definition.d.ts +6 -0
  180. package/dist/agent/skill/provider/definition.d.ts.map +1 -0
  181. package/dist/agent/skill/provider/definition.js +2 -0
  182. package/dist/agent/skill/provider/definition.js.map +1 -0
  183. package/dist/agent/skill/provider/snapshot.js +2 -0
  184. package/dist/agent/skill/provider/snapshot.js.map +1 -0
  185. package/dist/agent/skill/provider/types.d.ts +49 -0
  186. package/dist/agent/skill/provider/types.d.ts.map +1 -0
  187. package/dist/agent/skill/tools.d.ts +45 -0
  188. package/dist/agent/skill/tools.d.ts.map +1 -0
  189. package/dist/agent/skill/tools.js +14 -0
  190. package/dist/agent/skill/tools.js.map +1 -0
  191. package/dist/agent/team/common.d.ts +26 -0
  192. package/dist/agent/team/common.d.ts.map +1 -0
  193. package/dist/agent/team/common.js +2 -0
  194. package/dist/agent/team/common.js.map +1 -0
  195. package/dist/agent/team/composed.d.ts +45 -0
  196. package/dist/agent/team/composed.d.ts.map +1 -0
  197. package/dist/agent/team/composed.js +2 -0
  198. package/dist/agent/team/composed.js.map +1 -0
  199. package/dist/agent/team/contracts.d.ts +54 -0
  200. package/dist/agent/team/contracts.d.ts.map +1 -0
  201. package/dist/agent/team/managed.d.ts +527 -0
  202. package/dist/agent/team/managed.d.ts.map +1 -0
  203. package/dist/agent/team/managed.js +4 -0
  204. package/dist/agent/team/managed.js.map +1 -0
  205. package/dist/agent/team/team.d.ts +142 -0
  206. package/dist/agent/team/team.d.ts.map +1 -0
  207. package/dist/agent/team/team.js +2 -0
  208. package/dist/agent/team/team.js.map +1 -0
  209. package/dist/agent/team/types.d.ts +170 -0
  210. package/dist/agent/team/types.d.ts.map +1 -0
  211. package/dist/agent/tool/approval.d.ts +106 -0
  212. package/dist/agent/tool/approval.d.ts.map +1 -0
  213. package/dist/agent/tool/approval.js +2 -0
  214. package/dist/agent/tool/approval.js.map +1 -0
  215. package/dist/agent/tool/capture.js +2 -0
  216. package/dist/agent/tool/capture.js.map +1 -0
  217. package/dist/agent/tool/config.js +2 -0
  218. package/dist/agent/tool/config.js.map +1 -0
  219. package/dist/agent/tool/definition.d.ts +227 -0
  220. package/dist/agent/tool/definition.d.ts.map +1 -0
  221. package/dist/agent/tool/definition.js +2 -0
  222. package/dist/agent/tool/definition.js.map +1 -0
  223. package/dist/agent/tool/errors.d.ts +82 -0
  224. package/dist/agent/tool/errors.d.ts.map +1 -0
  225. package/dist/agent/tool/errors.js +2 -0
  226. package/dist/agent/tool/errors.js.map +1 -0
  227. package/dist/agent/tool/execution.d.ts +60 -0
  228. package/dist/agent/tool/execution.d.ts.map +1 -0
  229. package/dist/agent/tool/execution.js +2 -0
  230. package/dist/agent/tool/execution.js.map +1 -0
  231. package/dist/agent/tool/output-budget.d.ts +159 -0
  232. package/dist/agent/tool/output-budget.d.ts.map +1 -0
  233. package/dist/agent/tool/output-budget.js +3 -0
  234. package/dist/agent/tool/output-budget.js.map +1 -0
  235. package/dist/agent/tool/pipeline.d.ts +98 -0
  236. package/dist/agent/tool/pipeline.d.ts.map +1 -0
  237. package/dist/agent/tool/pipeline.js +4 -0
  238. package/dist/agent/tool/pipeline.js.map +1 -0
  239. package/dist/agent/tool/registry.d.ts +70 -0
  240. package/dist/agent/tool/registry.d.ts.map +1 -0
  241. package/dist/agent/tool/registry.js +2 -0
  242. package/dist/agent/tool/registry.js.map +1 -0
  243. package/dist/agent/tool/schema.d.ts +12 -0
  244. package/dist/agent/tool/schema.d.ts.map +1 -0
  245. package/dist/agent/tool/schema.js +2 -0
  246. package/dist/agent/tool/schema.js.map +1 -0
  247. package/dist/agent/tool/source-types.d.ts +25 -0
  248. package/dist/agent/tool/source-types.d.ts.map +1 -0
  249. package/dist/agent/trace/trace.d.ts +63 -0
  250. package/dist/agent/trace/trace.d.ts.map +1 -0
  251. package/dist/agent/trace/trace.js +2 -0
  252. package/dist/agent/trace/trace.js.map +1 -0
  253. package/dist/agent.d.ts +52 -0
  254. package/dist/agent.js +1 -0
  255. package/dist/async/settlement.d.ts +6 -0
  256. package/dist/async/settlement.d.ts.map +1 -0
  257. package/dist/async/settlement.js +2 -0
  258. package/dist/async/settlement.js.map +1 -0
  259. package/dist/capability/common/config.js +2 -0
  260. package/dist/capability/common/config.js.map +1 -0
  261. package/dist/capability/common/data.js +2 -0
  262. package/dist/capability/common/data.js.map +1 -0
  263. package/dist/composition/agent/author.d.ts +12 -0
  264. package/dist/composition/agent/author.d.ts.map +1 -0
  265. package/dist/composition/agent/author.js +2 -0
  266. package/dist/composition/agent/author.js.map +1 -0
  267. package/dist/composition/agent/definition.js +2 -0
  268. package/dist/composition/agent/definition.js.map +1 -0
  269. package/dist/composition/agent/native-event.js +2 -0
  270. package/dist/composition/agent/native-event.js.map +1 -0
  271. package/dist/composition/agent/native-tools.js +2 -0
  272. package/dist/composition/agent/native-tools.js.map +1 -0
  273. package/dist/composition/agent/options.js +2 -0
  274. package/dist/composition/agent/options.js.map +1 -0
  275. package/dist/composition/agent/policy.js +2 -0
  276. package/dist/composition/agent/policy.js.map +1 -0
  277. package/dist/composition/agent/public-message.js +2 -0
  278. package/dist/composition/agent/public-message.js.map +1 -0
  279. package/dist/composition/agent/session.js +2 -0
  280. package/dist/composition/agent/session.js.map +1 -0
  281. package/dist/composition/agent/types.d.ts +218 -0
  282. package/dist/composition/agent/types.d.ts.map +1 -0
  283. package/dist/composition/common/counter.js +2 -0
  284. package/dist/composition/common/counter.js.map +1 -0
  285. package/dist/composition/common/errors.d.ts +15 -0
  286. package/dist/composition/common/errors.d.ts.map +1 -0
  287. package/dist/composition/common/errors.js +2 -0
  288. package/dist/composition/common/errors.js.map +1 -0
  289. package/dist/composition/common/json-data.js +2 -0
  290. package/dist/composition/common/json-data.js.map +1 -0
  291. package/dist/composition/credential/config.d.ts +5 -0
  292. package/dist/composition/credential/config.d.ts.map +1 -0
  293. package/dist/composition/credential/config.js +2 -0
  294. package/dist/composition/credential/config.js.map +1 -0
  295. package/dist/composition/credential/definition.d.ts +9 -0
  296. package/dist/composition/credential/definition.d.ts.map +1 -0
  297. package/dist/composition/credential/definition.js +2 -0
  298. package/dist/composition/credential/definition.js.map +1 -0
  299. package/dist/composition/credential/types.d.ts +38 -0
  300. package/dist/composition/credential/types.d.ts.map +1 -0
  301. package/dist/composition/delivery/ack.js +2 -0
  302. package/dist/composition/delivery/ack.js.map +1 -0
  303. package/dist/composition/delivery/attempt.js +2 -0
  304. package/dist/composition/delivery/attempt.js.map +1 -0
  305. package/dist/composition/delivery/batch.js +2 -0
  306. package/dist/composition/delivery/batch.js.map +1 -0
  307. package/dist/composition/delivery/checkpoint.js +2 -0
  308. package/dist/composition/delivery/checkpoint.js.map +1 -0
  309. package/dist/composition/delivery/event.js +2 -0
  310. package/dist/composition/delivery/event.js.map +1 -0
  311. package/dist/composition/delivery/resource.d.ts +11 -0
  312. package/dist/composition/delivery/resource.d.ts.map +1 -0
  313. package/dist/composition/delivery/resource.js +2 -0
  314. package/dist/composition/delivery/resource.js.map +1 -0
  315. package/dist/composition/delivery/staging.js +2 -0
  316. package/dist/composition/delivery/staging.js.map +1 -0
  317. package/dist/composition/diagnostics/config.js +2 -0
  318. package/dist/composition/diagnostics/config.js.map +1 -0
  319. package/dist/composition/diagnostics/ring.d.ts +12 -0
  320. package/dist/composition/diagnostics/ring.d.ts.map +1 -0
  321. package/dist/composition/diagnostics/ring.js +2 -0
  322. package/dist/composition/diagnostics/ring.js.map +1 -0
  323. package/dist/composition/exporter/definition.d.ts +7 -0
  324. package/dist/composition/exporter/definition.d.ts.map +1 -0
  325. package/dist/composition/exporter/definition.js +2 -0
  326. package/dist/composition/exporter/definition.js.map +1 -0
  327. package/dist/composition/exporter/lifecycle.js +2 -0
  328. package/dist/composition/exporter/lifecycle.js.map +1 -0
  329. package/dist/composition/exporter/preflight.js +2 -0
  330. package/dist/composition/exporter/preflight.js.map +1 -0
  331. package/dist/composition/exporter/types.d.ts +25 -0
  332. package/dist/composition/exporter/types.d.ts.map +1 -0
  333. package/dist/composition/exporter/types.js +2 -0
  334. package/dist/composition/exporter/types.js.map +1 -0
  335. package/dist/composition/identity/agent.js +2 -0
  336. package/dist/composition/identity/agent.js.map +1 -0
  337. package/dist/composition/lifecycle/bounded.js +2 -0
  338. package/dist/composition/lifecycle/bounded.js.map +1 -0
  339. package/dist/composition/lifecycle/operations.js +2 -0
  340. package/dist/composition/lifecycle/operations.js.map +1 -0
  341. package/dist/composition/lifecycle/types.d.ts +13 -0
  342. package/dist/composition/lifecycle/types.d.ts.map +1 -0
  343. package/dist/composition/lifecycle/types.js +2 -0
  344. package/dist/composition/lifecycle/types.js.map +1 -0
  345. package/dist/composition/logging/config.js +2 -0
  346. package/dist/composition/logging/config.js.map +1 -0
  347. package/dist/composition/logging/integration.js +2 -0
  348. package/dist/composition/logging/integration.js.map +1 -0
  349. package/dist/composition/logging/logger.d.ts +9 -0
  350. package/dist/composition/logging/logger.d.ts.map +1 -0
  351. package/dist/composition/logging/logger.js +2 -0
  352. package/dist/composition/logging/logger.js.map +1 -0
  353. package/dist/composition/memory/config.d.ts +10 -0
  354. package/dist/composition/memory/config.d.ts.map +1 -0
  355. package/dist/composition/memory/config.js +2 -0
  356. package/dist/composition/memory/config.js.map +1 -0
  357. package/dist/composition/memory/definition.d.ts +7 -0
  358. package/dist/composition/memory/definition.d.ts.map +1 -0
  359. package/dist/composition/memory/definition.js +2 -0
  360. package/dist/composition/memory/definition.js.map +1 -0
  361. package/dist/composition/memory/key.js +2 -0
  362. package/dist/composition/memory/key.js.map +1 -0
  363. package/dist/composition/memory/resume.js +2 -0
  364. package/dist/composition/memory/resume.js.map +1 -0
  365. package/dist/composition/memory/run.js +2 -0
  366. package/dist/composition/memory/run.js.map +1 -0
  367. package/dist/composition/model-catalog/config.js +2 -0
  368. package/dist/composition/model-catalog/config.js.map +1 -0
  369. package/dist/composition/model-catalog/manager.js +2 -0
  370. package/dist/composition/model-catalog/manager.js.map +1 -0
  371. package/dist/composition/model-catalog/options.js +2 -0
  372. package/dist/composition/model-catalog/options.js.map +1 -0
  373. package/dist/composition/model-catalog/types.d.ts +9 -0
  374. package/dist/composition/model-catalog/types.d.ts.map +1 -0
  375. package/dist/composition/observation/config.js +2 -0
  376. package/dist/composition/observation/config.js.map +1 -0
  377. package/dist/composition/observation/extensions.js +2 -0
  378. package/dist/composition/observation/extensions.js.map +1 -0
  379. package/dist/composition/observation/final-report.d.ts +6 -0
  380. package/dist/composition/observation/final-report.d.ts.map +1 -0
  381. package/dist/composition/observation/final-report.js +2 -0
  382. package/dist/composition/observation/final-report.js.map +1 -0
  383. package/dist/composition/observation/health.d.ts +13 -0
  384. package/dist/composition/observation/health.d.ts.map +1 -0
  385. package/dist/composition/observation/port.d.ts +11 -0
  386. package/dist/composition/observation/port.d.ts.map +1 -0
  387. package/dist/composition/observation/port.js +2 -0
  388. package/dist/composition/observation/port.js.map +1 -0
  389. package/dist/composition/preflight.js +2 -0
  390. package/dist/composition/preflight.js.map +1 -0
  391. package/dist/composition/provider/activation.js +2 -0
  392. package/dist/composition/provider/activation.js.map +1 -0
  393. package/dist/composition/provider/definition.d.ts +7 -0
  394. package/dist/composition/provider/definition.d.ts.map +1 -0
  395. package/dist/composition/provider/definition.js +2 -0
  396. package/dist/composition/provider/definition.js.map +1 -0
  397. package/dist/composition/provider/model-selection.js +2 -0
  398. package/dist/composition/provider/model-selection.js.map +1 -0
  399. package/dist/composition/provider/preflight.js +2 -0
  400. package/dist/composition/provider/preflight.js.map +1 -0
  401. package/dist/composition/provider/types.d.ts +38 -0
  402. package/dist/composition/provider/types.d.ts.map +1 -0
  403. package/dist/composition/provider/types.js +2 -0
  404. package/dist/composition/provider/types.js.map +1 -0
  405. package/dist/composition/queue/config.js +2 -0
  406. package/dist/composition/queue/config.js.map +1 -0
  407. package/dist/composition/queue/scheduler.js +2 -0
  408. package/dist/composition/queue/scheduler.js.map +1 -0
  409. package/dist/composition/queue/store.js +2 -0
  410. package/dist/composition/queue/store.js.map +1 -0
  411. package/dist/composition/runtime/config.js +2 -0
  412. package/dist/composition/runtime/config.js.map +1 -0
  413. package/dist/composition/runtime/owner.js +2 -0
  414. package/dist/composition/runtime/owner.js.map +1 -0
  415. package/dist/composition/runtime/public.d.ts +7 -0
  416. package/dist/composition/runtime/public.d.ts.map +1 -0
  417. package/dist/composition/runtime/public.js +2 -0
  418. package/dist/composition/runtime/public.js.map +1 -0
  419. package/dist/composition/runtime/types.d.ts +76 -0
  420. package/dist/composition/runtime/types.d.ts.map +1 -0
  421. package/dist/composition/startup.js +2 -0
  422. package/dist/composition/startup.js.map +1 -0
  423. package/dist/composition/team/config.js +2 -0
  424. package/dist/composition/team/config.js.map +1 -0
  425. package/dist/composition/team/options.js +2 -0
  426. package/dist/composition/team/options.js.map +1 -0
  427. package/dist/composition/team/runtime.js +2 -0
  428. package/dist/composition/team/runtime.js.map +1 -0
  429. package/dist/composition/team/types.d.ts +63 -0
  430. package/dist/composition/team/types.d.ts.map +1 -0
  431. package/dist/composition/tool-source/config.d.ts +5 -0
  432. package/dist/composition/tool-source/config.d.ts.map +1 -0
  433. package/dist/composition/tool-source/config.js +2 -0
  434. package/dist/composition/tool-source/config.js.map +1 -0
  435. package/dist/composition/tool-source/definition.d.ts +7 -0
  436. package/dist/composition/tool-source/definition.d.ts.map +1 -0
  437. package/dist/composition/tool-source/definition.js +2 -0
  438. package/dist/composition/tool-source/definition.js.map +1 -0
  439. package/dist/composition/tool-source/snapshot.js +2 -0
  440. package/dist/composition/tool-source/snapshot.js.map +1 -0
  441. package/dist/contract/adapter.d.ts +91 -0
  442. package/dist/contract/adapter.d.ts.map +1 -0
  443. package/dist/contract/adapter.js +2 -0
  444. package/dist/contract/adapter.js.map +1 -0
  445. package/dist/contract/call-config.d.ts +36 -0
  446. package/dist/contract/call-config.d.ts.map +1 -0
  447. package/dist/contract/call-config.js +2 -0
  448. package/dist/contract/call-config.js.map +1 -0
  449. package/dist/contract/generate-options.d.ts +41 -0
  450. package/dist/contract/generate-options.d.ts.map +1 -0
  451. package/dist/contract/model-info.d.ts +99 -0
  452. package/dist/contract/model-info.d.ts.map +1 -0
  453. package/dist/contract/output-format.d.ts +18 -0
  454. package/dist/contract/output-format.d.ts.map +1 -0
  455. package/dist/contract/retry-policy.d.ts +104 -0
  456. package/dist/contract/retry-policy.d.ts.map +1 -0
  457. package/dist/contract/retry-policy.js +2 -0
  458. package/dist/contract/retry-policy.js.map +1 -0
  459. package/dist/contract/tool.d.ts +65 -0
  460. package/dist/contract/tool.d.ts.map +1 -0
  461. package/dist/contract/tool.js +2 -0
  462. package/dist/contract/tool.js.map +1 -0
  463. package/dist/errors/agent-sdk-error.d.ts +88 -0
  464. package/dist/errors/agent-sdk-error.d.ts.map +1 -0
  465. package/dist/errors/agent-sdk-error.js +2 -0
  466. package/dist/errors/agent-sdk-error.js.map +1 -0
  467. package/dist/errors/capability-identity.d.ts +10 -0
  468. package/dist/errors/capability-identity.d.ts.map +1 -0
  469. package/dist/errors/capability-identity.js +2 -0
  470. package/dist/errors/capability-identity.js.map +1 -0
  471. package/dist/errors/failure.d.ts +33 -0
  472. package/dist/errors/failure.d.ts.map +1 -0
  473. package/dist/errors/failure.js +2 -0
  474. package/dist/errors/failure.js.map +1 -0
  475. package/dist/errors/model-error.d.ts +83 -0
  476. package/dist/errors/model-error.d.ts.map +1 -0
  477. package/dist/errors/model-error.js +2 -0
  478. package/dist/errors/model-error.js.map +1 -0
  479. package/dist/http/api-key.d.ts +47 -0
  480. package/dist/http/api-key.d.ts.map +1 -0
  481. package/dist/http/api-key.js +2 -0
  482. package/dist/http/api-key.js.map +1 -0
  483. package/dist/http/attribution.d.ts +51 -0
  484. package/dist/http/attribution.d.ts.map +1 -0
  485. package/dist/http/attribution.js +2 -0
  486. package/dist/http/attribution.js.map +1 -0
  487. package/dist/index.d.ts +70 -0
  488. package/dist/index.js +1 -0
  489. package/dist/logging/types.d.ts +53 -0
  490. package/dist/logging/types.d.ts.map +1 -0
  491. package/dist/logging/types.js +2 -0
  492. package/dist/logging/types.js.map +1 -0
  493. package/dist/memory.d.ts +10 -0
  494. package/dist/memory.js +1 -0
  495. package/dist/message/content.d.ts +125 -0
  496. package/dist/message/content.d.ts.map +1 -0
  497. package/dist/message/message.d.ts +154 -0
  498. package/dist/message/message.d.ts.map +1 -0
  499. package/dist/message/message.js +2 -0
  500. package/dist/message/message.js.map +1 -0
  501. package/dist/message/projection.d.ts +34 -0
  502. package/dist/message/projection.d.ts.map +1 -0
  503. package/dist/message/projection.js +2 -0
  504. package/dist/message/projection.js.map +1 -0
  505. package/dist/observability/bus.d.ts +7 -0
  506. package/dist/observability/bus.d.ts.map +1 -0
  507. package/dist/observability/bus.js +2 -0
  508. package/dist/observability/bus.js.map +1 -0
  509. package/dist/observability/exporters.d.ts +39 -0
  510. package/dist/observability/exporters.d.ts.map +1 -0
  511. package/dist/observability/exporters.js +2 -0
  512. package/dist/observability/exporters.js.map +1 -0
  513. package/dist/observability/logger.js +2 -0
  514. package/dist/observability/logger.js.map +1 -0
  515. package/dist/observability/projections.d.ts +12 -0
  516. package/dist/observability/projections.d.ts.map +1 -0
  517. package/dist/observability/projections.js +2 -0
  518. package/dist/observability/projections.js.map +1 -0
  519. package/dist/observability/types.d.ts +103 -0
  520. package/dist/observability/types.d.ts.map +1 -0
  521. package/dist/observability.d.ts +20 -0
  522. package/dist/observability.js +1 -0
  523. package/dist/observation/boundaries.js +2 -0
  524. package/dist/observation/boundaries.js.map +1 -0
  525. package/dist/observation/context.d.ts +39 -0
  526. package/dist/observation/context.d.ts.map +1 -0
  527. package/dist/observation/context.js +2 -0
  528. package/dist/observation/context.js.map +1 -0
  529. package/dist/observation/event.d.ts +50 -0
  530. package/dist/observation/event.d.ts.map +1 -0
  531. package/dist/observation/event.js +2 -0
  532. package/dist/observation/event.js.map +1 -0
  533. package/dist/observation/port.d.ts +56 -0
  534. package/dist/observation/port.d.ts.map +1 -0
  535. package/dist/observation/port.js +2 -0
  536. package/dist/observation/port.js.map +1 -0
  537. package/dist/observation/privacy.js +2 -0
  538. package/dist/observation/privacy.js.map +1 -0
  539. package/dist/observation/report.d.ts +117 -0
  540. package/dist/observation/report.d.ts.map +1 -0
  541. package/dist/observation/report.js +2 -0
  542. package/dist/observation/report.js.map +1 -0
  543. package/dist/observation/telemetry-types.d.ts +29 -0
  544. package/dist/observation/telemetry-types.d.ts.map +1 -0
  545. package/dist/observation/usage.d.ts +52 -0
  546. package/dist/observation/usage.d.ts.map +1 -0
  547. package/dist/observation/usage.js +2 -0
  548. package/dist/observation/usage.js.map +1 -0
  549. package/dist/platform/adapter.js +2 -0
  550. package/dist/platform/adapter.js.map +1 -0
  551. package/dist/platform/capability-operation.js +2 -0
  552. package/dist/platform/capability-operation.js.map +1 -0
  553. package/dist/platform/config.js +2 -0
  554. package/dist/platform/config.js.map +1 -0
  555. package/dist/platform/logger-platform.js +2 -0
  556. package/dist/platform/logger-platform.js.map +1 -0
  557. package/dist/platform/resources.js +2 -0
  558. package/dist/platform/resources.js.map +1 -0
  559. package/dist/plugin/provider-plugin.d.ts +37 -0
  560. package/dist/plugin/provider-plugin.d.ts.map +1 -0
  561. package/dist/plugin/provider-plugin.js +2 -0
  562. package/dist/plugin/provider-plugin.js.map +1 -0
  563. package/dist/primitives/brand.d.ts +61 -0
  564. package/dist/primitives/brand.d.ts.map +1 -0
  565. package/dist/primitives/brand.js +2 -0
  566. package/dist/primitives/brand.js.map +1 -0
  567. package/dist/primitives/freeze.d.ts +20 -0
  568. package/dist/primitives/freeze.d.ts.map +1 -0
  569. package/dist/primitives/freeze.js +2 -0
  570. package/dist/primitives/freeze.js.map +1 -0
  571. package/dist/primitives/json-snapshot.js +2 -0
  572. package/dist/primitives/json-snapshot.js.map +1 -0
  573. package/dist/primitives/json.d.ts +32 -0
  574. package/dist/primitives/json.d.ts.map +1 -0
  575. package/dist/primitives/json.js +2 -0
  576. package/dist/primitives/json.js.map +1 -0
  577. package/dist/primitives/never.d.ts +22 -0
  578. package/dist/primitives/never.d.ts.map +1 -0
  579. package/dist/primitives/never.js +2 -0
  580. package/dist/primitives/never.js.map +1 -0
  581. package/dist/primitives/snapshot.d.ts +10 -0
  582. package/dist/primitives/snapshot.d.ts.map +1 -0
  583. package/dist/primitives/snapshot.js +2 -0
  584. package/dist/primitives/snapshot.js.map +1 -0
  585. package/dist/primitives/version.d.ts +6 -0
  586. package/dist/primitives/version.d.ts.map +1 -0
  587. package/dist/primitives/version.js +2 -0
  588. package/dist/primitives/version.js.map +1 -0
  589. package/dist/provider.d.ts +19 -0
  590. package/dist/provider.js +1 -0
  591. package/dist/runtime/model-call-handle.js +2 -0
  592. package/dist/runtime/model-call-handle.js.map +1 -0
  593. package/dist/runtime/model-metadata.js +2 -0
  594. package/dist/runtime/model-metadata.js.map +1 -0
  595. package/dist/runtime/model-stream.js +2 -0
  596. package/dist/runtime/model-stream.js.map +1 -0
  597. package/dist/runtime/registry.d.ts +171 -0
  598. package/dist/runtime/registry.d.ts.map +1 -0
  599. package/dist/runtime/registry.js +2 -0
  600. package/dist/runtime/registry.js.map +1 -0
  601. package/dist/runtime/with-retry.d.ts +45 -0
  602. package/dist/runtime/with-retry.d.ts.map +1 -0
  603. package/dist/runtime/with-retry.js +2 -0
  604. package/dist/runtime/with-retry.js.map +1 -0
  605. package/dist/skills.d.ts +8 -0
  606. package/dist/skills.js +1 -0
  607. package/dist/stream/assembler.d.ts +86 -0
  608. package/dist/stream/assembler.d.ts.map +1 -0
  609. package/dist/stream/assembler.js +2 -0
  610. package/dist/stream/assembler.js.map +1 -0
  611. package/dist/stream/chunk.d.ts +135 -0
  612. package/dist/stream/chunk.d.ts.map +1 -0
  613. package/dist/stream/idle-timeout.d.ts +30 -0
  614. package/dist/stream/idle-timeout.d.ts.map +1 -0
  615. package/dist/stream/idle-timeout.js +2 -0
  616. package/dist/stream/idle-timeout.js.map +1 -0
  617. package/dist/support-safe/error.d.ts +29 -0
  618. package/dist/support-safe/error.d.ts.map +1 -0
  619. package/dist/support-safe/error.js +2 -0
  620. package/dist/support-safe/error.js.map +1 -0
  621. package/dist/tools.d.ts +15 -0
  622. package/dist/tools.js +1 -0
  623. package/package.json +96 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-turn.js","names":[],"sources":["../../../src/agent/loop/run-turn.ts"],"sourcesContent":["import { createUserMessage } from '../../message/index.ts'\nimport { detachedFrozen } from '../../primitives/index.ts'\nimport type { ModelCallReport } from '../../observation/index.ts'\nimport { waitForSettlement } from '../../async/index.ts'\nimport { authoritativeTokenUsage, budgetTokenTotal, summarizeModelCallUsage } from '../accounting/ledger.ts'\nimport { createSpanId, createTraceId, type TraceRef } from '../trace/trace.ts'\nimport type { AgentEvent, ExhaustedBudget, ToolDeclineReason, TurnHooks, TurnOutcome } from './types.ts'\nimport { AwaitedEventQueue } from './queue.ts'\nimport { runToolCalls } from './schedule.ts'\nimport { type RunTurnOptions } from './turn/types.ts'\nimport { resolveBounds, positiveFinite, snapshotRunTurnOptions } from './turn/config.ts'\nimport { codedRuntimeError, messageOf, errorCodeOf, now } from './turn/common.ts'\nimport { runOptionalHook, runHook } from './turn/hooks.ts'\nimport { maintenanceEmitter, emitAssistantContent, textOf } from './turn/content.ts'\nimport { repeatKey, toolActionPattern, repeatedSuffixCycle } from './turn/repetition.ts'\nimport { modelRound } from './turn/model-round.ts'\nimport { accountingUsageStop } from './turn/usage-stop.ts'\nimport { ContextSectionRuntime } from '../context/section.ts'\nimport type { ContextToolTouch } from '../context/types.ts'\n\nfunction hasCallableTools(options: RunTurnOptions): boolean {\n if (options.toolChoice === 'none') return false\n return (options.tools?.names().length ?? 0) > 0 || (options.nativeTools?.length ?? 0) > 0\n}\n\n/** Run one bounded turn as a backpressured event stream. */\nexport function runTurn(options: RunTurnOptions): AsyncIterable<AgentEvent> {\n return {\n async * [Symbol.asyncIterator]() {\n const invocation = snapshotRunTurnOptions(options)\n const queue = new AwaitedEventQueue<AgentEvent>()\n const consumer = new AbortController()\n const teardownTimeoutMs = positiveFinite(invocation.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n const signal = invocation.signal === undefined\n ? consumer.signal\n : AbortSignal.any([invocation.signal, consumer.signal])\n const task = driveTurn(invocation, signal, event => queue.push(detachedFrozen(event)))\n .then(() => queue.close(), error => queue.fail(error))\n try {\n while (true) {\n const item = await queue.take()\n if (item.done) break\n yield item.value\n }\n await task\n } finally {\n consumer.abort(new Error('turn event consumer stopped'))\n queue.close()\n if (!await waitForSettlement(task, teardownTimeoutMs)) {\n throw codedRuntimeError(\n `turn producer ignored cancellation for more than ${teardownTimeoutMs}ms`,\n 'TURN_TEARDOWN_TIMEOUT',\n consumer.signal.reason,\n )\n }\n }\n },\n }\n}\n\nasync function driveTurn(\n options: RunTurnOptions,\n signal: AbortSignal,\n emit: (event: AgentEvent) => Promise<void>,\n): Promise<void> {\n const bounds = resolveBounds(options.bounds)\n const maxTotalTokens = bounds.maxTotalTokens === 'auto' ? Infinity : bounds.maxTotalTokens\n // Infinity is local control flow only. Public configuration/events retain\n // the serializable 'auto' value, and all other admission guards still apply.\n const maxSteps = bounds.maxSteps === 'auto' ? Infinity : bounds.maxSteps\n const traceId = options.trace?.traceId ?? createTraceId()\n const root: TraceRef = { traceId, spanId: createSpanId(), parentSpanId: options.trace?.parentSpanId ?? null }\n const turn = Math.max(1, options.history.entries().filter(entry =>\n entry.event.kind === 'user' && entry.event.message.source.kind === 'user').length)\n const startedAt = now()\n let steps = 0\n let toolCalls = 0\n // Descending, so \"how many are below the remainder\" counts the crossings.\n const budgetReminders = [...bounds.toolBudgetRemindAt]\n .filter(threshold => threshold > 0 && threshold < bounds.maxToolCalls)\n .sort((left, right) => right - left)\n let budgetRemindersSent = 0\n /** How many full budgets an unwalled turn has spent and been told about. */\n let overBudgetNoticesSent = 0\n /** Sequence of the budget notice currently on the surface, if any. */\n let budgetNoticeSeq: number | undefined\n let stepReminderSent = false\n let tokenRemindersSent = 0\n let consecutiveErrors = 0\n let text = ''\n const modelCallReports: ModelCallReport[] = []\n let reason: TurnOutcome['reason'] | undefined\n let outcome: TurnOutcome\n let lastRepeat: { key: string; count: number } | undefined\n const actionSteps: string[] = []\n const emitMaintenance = maintenanceEmitter(emit, root)\n /**\n * Put the current budget notice on the surface, replacing the previous one.\n *\n * One live notice, never a pile of them. Appending each new remainder leaves\n * \"16 calls remain\" and \"6 calls remain\" both readable, and a model that\n * plans against the older number plans against a budget it no longer has.\n * Codex keeps exactly one `<rollout_budget>` fragment for the same reason\n * (`context/rollout_budget.rs`), replacing it as the number moves.\n * @param text - What the model should read now.\n */\n const appendBudgetNotice = (text: string): void => {\n const message = createUserMessage({\n source: { kind: 'app', producer: 'tool-loop-budget-guard' },\n content: [{ type: 'text', text }],\n })\n const previous = budgetNoticeSeq\n // Replacing is best-effort. Compaction can shadow the earlier notice\n // between steps, and a replace whose target is no longer on the surface is\n // rejected — which must cost the model a reminder, never the turn.\n if (previous !== undefined) {\n try {\n budgetNoticeSeq = options.history.append(\n { kind: 'user', message },\n { op: 'replace', from: previous, to: previous, targets: [previous] },\n ).seq\n return\n } catch {\n budgetNoticeSeq = undefined\n }\n }\n budgetNoticeSeq = options.history.append({ kind: 'user', message }).seq\n }\n const contextSections = options.contextSections === undefined || options.contextSections.length === 0\n ? undefined\n : new ContextSectionRuntime({\n sections: options.contextSections,\n history: options.history,\n ...options.logger === undefined ? {} : { logger: options.logger },\n guard: (pending, name) => runHook(pending, options, signal, name),\n scope: { agentId: options.trace?.agentId, conversationId: options.trace?.conversationId },\n })\n /** Tool calls committed since the last section reconcile. */\n let contextTouches: ContextToolTouch[] = []\n let rootStarted = false\n let rootEnded = false\n const callableTools = hasCallableTools(options)\n const dedicatedFinalOutput = options.outputFormat?.type === 'json_schema' && callableTools\n const turnOperationId = options.accounting?.startOperation('turn', {\n data: { turn, model: options.config.model },\n })\n let turnOperationEnded = false\n let usageStop: TurnOutcome['reason'] | undefined\n // Shared by retries, hook continuations, and both finalizer paths. Finalizers\n // may have a separate step allowance, never a separate token allowance.\n const admissionStop = (): TurnOutcome['reason'] | undefined => {\n if (signal.aborted) return { kind: 'aborted' }\n const mandatoryStop = accountingUsageStop(options.accounting)\n if (mandatoryStop !== undefined) return mandatoryStop\n if (usageStop !== undefined) return usageStop\n const tokens = budgetTokenTotal(summarizeModelCallUsage(modelCallReports))\n return tokens !== undefined && tokens >= maxTotalTokens\n ? { kind: 'budget-exhausted', budget: 'tokens', forcedFinalAnswer: false }\n : undefined\n }\n\n try {\n await emit({\n type: 'span-start', trace: root, at: startedAt,\n name: `invoke_agent ${options.trace?.agentId ?? 'agent'}`, kind: 'invoke_agent',\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.id': options.trace?.agentId ?? 'agent',\n 'gen_ai.agent.name': options.trace?.agentName ?? options.trace?.agentId ?? 'agent',\n 'gen_ai.request.model': options.config.model,\n ...options.trace?.conversationId === undefined\n ? {}\n : { 'gen_ai.conversation.id': options.trace.conversationId },\n },\n })\n rootStarted = true\n await emit({ type: 'turn-start', turn, trace: root })\n\n turnLifecycle: while (true) {\n while (reason === undefined && steps < maxSteps && !signal.aborted) {\n reason = admissionStop()\n if (reason !== undefined) break\n // Auto has no step countdown. Warn from the same usage total as admission,\n // before a hard token stop can leave the agent without a reporting call.\n const usedTokens = budgetTokenTotal(summarizeModelCallUsage(modelCallReports))\n if (bounds.maxTotalTokens !== 'auto' && usedTokens !== undefined) {\n const crossed = [0.5, 0.75, 0.9].filter(ratio => usedTokens >= maxTotalTokens * ratio).length\n if (crossed > tokenRemindersSent) {\n tokenRemindersSent = crossed\n const remaining = Math.max(0, maxTotalTokens - usedTokens)\n options.history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'tool-loop-token-guard' },\n content: [{ type: 'text', text: `Token budget: ${remaining} of ${bounds.maxTotalTokens} aggregate tokens remain. Each request also spends input tokens on the accumulated context. `\n + (crossed >= 2 ? 'Stop broad exploration. ' : 'Prioritize outstanding verification and reporting. ')\n + 'Reserve capacity for the required self-check, honest todo reconciliation and substantive final report. State unavailable evidence and unfinished work; do not claim it is verified. No extra model call is allowed after the hard token limit.',\n }],\n }) })\n }\n }\n // Leave time to reconcile a plan and submit a result before the final\n // tools-disabled summary. Tool-call reminders do not cover step limits.\n if (!stepReminderSent && steps > 0 && maxSteps - steps <= 2) {\n stepReminderSent = true\n options.history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'tool-loop-step-guard' },\n content: [{ type: 'text', text:\n `${maxSteps - steps} work steps remain. Finish essential verification, update any task list honestly, and submit the result if required. Summarize findings, evidence, and unfinished work; do not start new exploration.`,\n }],\n }) })\n }\n // Recomputed before the request that will read it, so a section reacting to\n // the previous step's tool calls is already on the surface.\n if (contextSections !== undefined) {\n await contextSections.reconcile(steps, contextTouches, signal)\n contextTouches = []\n }\n const step = steps + 1\n const round = await modelRound(\n options, signal, emit, emitMaintenance, root, turn, step,\n dedicatedFinalOutput\n ? 'process'\n : options.outputFormat?.type === 'json_schema' ? 'final' : 'standard',\n )\n steps++\n if (round.report !== undefined) modelCallReports.push(round.report)\n if (round.message !== undefined) {\n options.history.append({\n kind: 'assistant', message: round.message,\n ...round.finish.kind === 'aborted' ? { interrupted: true as const } : {},\n ...round.usage === undefined ? {} : { usage: round.usage },\n })\n await emit({ type: 'assistant-message', message: round.message, trace: round.trace })\n await emitAssistantContent(round, emit)\n text = textOf(round.message.content)\n }\n usageStop = accountingUsageStop(options.accounting) ?? (round.usageRequired\n ? { kind: 'error', failure: { message: 'provider usage is required by the configured run policy', code: 'USAGE_REQUIRED' } }\n : round.usageUnavailable\n ? { kind: 'usage-unavailable', modelCallId: round.report?.modelCallId ?? 'unknown' }\n : undefined)\n if (signal.aborted || round.finish.kind === 'aborted') { reason = { kind: 'aborted' }; break }\n // Pair emitted tool calls with declined results even when policy stops the\n // run; never execute those calls or allow a retry hook to override policy.\n if (round.finish.kind === 'error' && usageStop !== undefined) {\n reason = { kind: 'error', failure: round.finish.failure }\n break\n }\n if (round.usageRequired && (round.calls.length === 0 || options.tools === undefined)) { reason = usageStop; break }\n if (round.finish.kind === 'error' && !round.usageRequired) {\n reason = admissionStop()\n if (reason !== undefined) break\n const decision = await runOptionalHook(options.hooks?.onRequestError, [{\n turn, step, failure: round.finish.failure, snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n emit: emitMaintenance,\n }], options, signal, 'onRequestError')\n const maintenanceStop = accountingUsageStop(options.accounting)\n if (maintenanceStop !== undefined) { reason = signal.aborted ? { kind: 'aborted' } : maintenanceStop; break }\n if (decision === 'retry' && steps < maxSteps) continue\n reason = { kind: 'error', failure: round.finish.failure }\n break\n }\n if (round.finish.kind === 'max-tokens' && !round.usageRequired) { reason = { kind: 'max-tokens' }; break }\n if (round.calls.length === 0 && round.usageUnavailable) {\n reason = accountingUsageStop(options.accounting) ?? { kind: 'usage-unavailable', modelCallId: round.report?.modelCallId ?? 'unknown' }\n break\n }\n if (round.calls.length === 0 && dedicatedFinalOutput) {\n reason = admissionStop()\n if (reason !== undefined) break\n options.history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'structured-output-finalizer' },\n content: [{\n type: 'text',\n text: 'The process phase is complete. Return the final answer now in the requested output format. Do not call tools.',\n }],\n }) })\n const final = await modelRound(\n options, signal, emit, emitMaintenance, root, turn, steps + 1, 'final',\n )\n steps++\n if (final.report !== undefined) modelCallReports.push(final.report)\n if (final.message !== undefined) {\n options.history.append({\n kind: 'assistant', message: final.message,\n ...final.usage === undefined ? {} : { usage: final.usage },\n })\n await emit({ type: 'assistant-message', message: final.message, trace: final.trace })\n await emitAssistantContent(final, emit)\n text = textOf(final.message.content)\n }\n if (final.finish.kind === 'aborted') reason = { kind: 'aborted' }\n else if (final.finish.kind === 'error') reason = { kind: 'error', failure: final.finish.failure }\n else if (final.finish.kind === 'max-tokens') reason = { kind: 'max-tokens' }\n else if (final.usageRequired) reason = { kind: 'error', failure: {\n message: 'provider usage is required by the configured run policy',\n code: 'USAGE_REQUIRED',\n } }\n else if (final.usageUnavailable) {\n reason = accountingUsageStop(options.accounting) ?? { kind: 'usage-unavailable', modelCallId: final.report?.modelCallId ?? 'unknown' }\n } else reason = { kind: 'completed' }\n break\n }\n // A provider that repeated an id had the repeat dropped. Saying so is what\n // keeps the model from reading one result for two calls as a tool that\n // silently ignored it.\n if (round.droppedDuplicateCalls !== undefined) {\n options.history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'tool-loop-duplicate-guard' },\n content: [{\n type: 'text',\n text: `You reused the tool-call id ${round.droppedDuplicateCalls.map(id => `'${id}'`).join(', ')}.`\n + ' A result pairs to exactly one call, so the repeat was not run and only the first'\n + ' call of that id has a result. Give every call its own id, and call again if you'\n + ' still need what the dropped one would have done.',\n }],\n }) })\n }\n if (round.calls.length === 0 || options.tools === undefined) { reason = { kind: 'completed' }; break }\n\n // Calls the budget does not govern: submitting, asking, delegating. They\n // are dispatched even when the budget is spent, so the model always has a\n // legal way to finish. See `ToolDefinition.budgetExempt`.\n const budgetedCalls = round.calls\n .filter(call => options.tools?.get(call.toolName)?.budgetExempt !== true).length\n const remaining = Math.max(0, bounds.maxToolCalls - toolCalls)\n let repeatProjection = lastRepeat\n const projectedRepeats = round.calls.map(call => {\n const key = repeatKey(call)\n // Count consecutive calls, not lifetime visits to a source or test command.\n // Distinct intervening work may change its result. Alternating loops are\n // handled separately by the step-cycle guard below.\n const count = repeatProjection?.key === key ? repeatProjection.count + 1 : 1\n repeatProjection = { key, count }\n return count\n })\n const repeatedLimitBeforeDispatch = projectedRepeats.some(count => count >= bounds.repeatToolLimit)\n const actionPattern = toolActionPattern(round.calls)\n const projectedCycle = repeatedSuffixCycle(\n [...actionSteps, actionPattern],\n bounds.maxToolCycleLength,\n )\n const cycleLimitBeforeDispatch = projectedCycle !== undefined\n && projectedCycle.repetitions >= bounds.toolCycleLimit\n const currentUsage = summarizeModelCallUsage(modelCallReports)\n const budgetTokens = budgetTokenTotal(currentUsage)\n const tokenLimitBeforeDispatch = budgetTokens !== undefined\n && budgetTokens >= maxTotalTokens\n const guardDeclined = repeatedLimitBeforeDispatch || cycleLimitBeforeDispatch || tokenLimitBeforeDispatch || round.usageRequired\n // Name the limit that actually declined the call. Reporting a repeat guard\n // as an empty budget teaches the model the wrong lesson, and it repeats the\n // call on the next turn with the budget it was told it lacked.\n const declineReason: ToolDeclineReason = tokenLimitBeforeDispatch\n ? 'tokens'\n : cycleLimitBeforeDispatch\n ? 'tool-call-cycle'\n : repeatedLimitBeforeDispatch\n ? 'repeated-tool-call'\n : round.usageRequired\n ? 'usage-required'\n : 'tool-calls'\n // `continue` takes the wall down: the budget becomes a notice and the turn\n // is bounded by steps, tokens, and the run-level ledger instead. Guards\n // that mean \"this is not working\" still decline, whatever the setting.\n const budgetIsAWall = bounds.onExhausted !== 'continue'\n const scheduled = await runToolCalls({\n calls: round.calls, catalog: options.tools, history: options.history,\n position: { turn, step,\n ...(options.accounting === undefined ? {} : { runId: options.accounting.runId }),\n ...(options.trace?.conversationId === undefined ? {} : { conversationId: options.trace.conversationId }),\n }, signal, parentTrace: root,\n maxParallel: bounds.maxParallel,\n dispatchLimit: guardDeclined ? 0 : budgetIsAWall ? remaining : round.calls.length,\n declineReason,\n maxResultBytes: bounds.maxToolResultBytes,\n maxResultTokens: bounds.maxToolResultTokens,\n resultOverflow: bounds.toolResultOverflow,\n ...options.spillStore === undefined ? {} : { spillStore: options.spillStore },\n maxDurationMs: bounds.maxToolDurationMs,\n teardownTimeoutMs: bounds.toolTeardownTimeoutMs,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n ...options.interceptors === undefined ? {} : { interceptors: options.interceptors },\n ...options.approvals === undefined ? {} : { approvals: options.approvals },\n ...options.accounting === undefined ? {} : { accounting: options.accounting },\n emit,\n ...options.hooks?.checkpoint === undefined ? {} : {\n checkpoint: (context: Parameters<NonNullable<TurnHooks['checkpoint']>>[0]) => runHook(\n Promise.resolve(options.hooks?.checkpoint?.(context)), options, signal, 'checkpoint',\n ),\n },\n })\n // Results commit in model order, one per requested call, so the pairing\n // holds for declined calls too. A short result list means a sibling failed\n // its contract and the turn is already unwinding; reporting a guessed\n // outcome would be worse than reporting nothing.\n if (contextSections !== undefined && scheduled.results.length === round.calls.length) {\n contextTouches.push(...round.calls.map((call, index) => ({\n toolName: call.toolName,\n rawArguments: call.rawArguments,\n failed: scheduled.results[index]?.isError ?? true,\n })))\n }\n toolCalls += scheduled.budgeted\n const remainingAfterDispatch = Math.max(0, bounds.maxToolCalls - toolCalls)\n // One reminder per threshold crossed, not one per turn.\n //\n // This was a single boolean: the model was told once, at 25% remaining,\n // and then never again however close it came to the end. A model warned at\n // sixteen calls left and still exploring at four has been told nothing\n // since, and runs into the wall with no notice — which is what produces a\n // red \"no remaining tool-call budget\" where an answer should have been.\n //\n // Codex counts thresholds rather than remembering a flag\n // (`rollout_budget.rs`, `reminder_index`): every threshold now below the\n // remaining budget that has not been reported yet gets reported. Crossing\n // several at once collapses into the one that matters, the lowest.\n const crossed = budgetReminders.filter(threshold => remainingAfterDispatch <= threshold).length\n if (crossed > budgetRemindersSent && remainingAfterDispatch > 0) {\n budgetRemindersSent = crossed\n appendBudgetNotice(\n `Tool budget: ${remainingAfterDispatch} of ${bounds.maxToolCalls} calls remain in this turn.`\n + ' Stop broad exploration, make the necessary edits, and reserve calls for'\n + (budgetIsAWall\n ? ' verification. When the budget runs out no further work call will run, so'\n + ' finish with what you can still verify.'\n : ' verification. Past the budget you are expected to be wrapping up, not'\n + ' opening new lines of work.'),\n )\n }\n // Past the budget with the wall down. The turn is not stopped — the model\n // keeps its tools — but it is told, once per further budget spent, that it\n // is now expected to be finishing. This is the shape of Codex's\n // `budget_limit` goal prompt: no new substantive work, wrap up, name what\n // is left.\n if (!budgetIsAWall && remainingAfterDispatch === 0) {\n const windows = Math.floor(toolCalls / bounds.maxToolCalls)\n if (windows > overBudgetNoticesSent) {\n overBudgetNoticesSent = windows\n appendBudgetNotice(\n `Tool budget spent: ${toolCalls} calls made against a budget of ${bounds.maxToolCalls}.`\n + ' Do not start new substantive work. Finish what is in flight, verify what you'\n + ' can, and answer — stating plainly what is unverified or unfinished.',\n )\n }\n }\n await emit({ type: 'step-end', turn, step, trace: round.trace })\n\n actionSteps.push(actionPattern)\n let repeatedLimit = repeatedLimitBeforeDispatch\n for (let index = 0; index < round.calls.length; index++) {\n const call = round.calls[index]\n const result = scheduled.results[index]\n if (call === undefined || result === undefined) continue\n consecutiveErrors = result.isError ? consecutiveErrors + 1 : 0\n const key = repeatKey(call)\n const count = lastRepeat?.key === key ? lastRepeat.count + 1 : 1\n lastRepeat = { key, count }\n if (count === bounds.repeatToolWarningAt) {\n options.history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'tool-loop-repeat-guard' },\n content: [{ type: 'text', text: `You have called ${call.toolName} with the same arguments ${count} consecutive times. Reassess before repeating it.` }],\n }) })\n }\n if (count >= bounds.repeatToolLimit) repeatedLimit = true\n }\n if (projectedCycle?.repetitions === bounds.toolCycleWarningAt) {\n options.history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'tool-loop-cycle-guard' },\n content: [{\n type: 'text',\n text: `Tool-use pattern repeated ${projectedCycle.repetitions} times across ${projectedCycle.period} step(s). Reassess the approach and identify concrete new evidence before continuing.`,\n }],\n }) })\n }\n if (scheduled.concluded) { reason = { kind: 'concluded-by-tool', toolName: scheduled.concludedBy ?? 'unknown' }; break }\n if (signal.aborted) { reason = { kind: 'aborted' }; break }\n if (round.usageRequired) { reason = usageStop; break }\n if (round.usageUnavailable) {\n reason = accountingUsageStop(options.accounting) ?? { kind: 'usage-unavailable', modelCallId: round.report?.modelCallId ?? 'unknown' }\n break\n }\n let exhausted: ExhaustedBudget | undefined\n const reportReserveReached = bounds.maxTotalTokens !== 'auto'\n && bounds.finalReportReserveTokens > 0 && budgetTokens !== undefined\n && budgetTokens >= maxTotalTokens - bounds.finalReportReserveTokens\n if (tokenLimitBeforeDispatch) exhausted = 'tokens'\n else if (reportReserveReached) exhausted = 'tokens'\n else if (cycleLimitBeforeDispatch) exhausted = 'tool-call-cycle'\n else if (budgetIsAWall && budgetedCalls > remaining) exhausted = 'tool-calls'\n else if (consecutiveErrors >= bounds.maxConsecutiveToolErrors) exhausted = 'consecutive-tool-errors'\n else if (repeatedLimit) exhausted = 'repeated-tool-call'\n else if (steps >= maxSteps) exhausted = 'steps'\n if (exhausted !== undefined) {\n const forced = (exhausted !== 'tokens' || (reportReserveReached && !tokenLimitBeforeDispatch))\n && bounds.onExhausted !== 'stop'\n && admissionStop() === undefined\n if (forced) {\n const final = await modelRound(\n options, signal, emit, emitMaintenance, root, turn, steps + 1, 'forced-final',\n )\n steps++\n if (final.report !== undefined) modelCallReports.push(final.report)\n if (final.message !== undefined) {\n options.history.append({ kind: 'assistant', message: final.message, ...final.usage === undefined ? {} : { usage: final.usage } })\n await emit({ type: 'assistant-message', message: final.message, trace: final.trace })\n await emitAssistantContent(final, emit)\n text = textOf(final.message.content)\n }\n if (final.finish.kind === 'aborted') {\n reason = { kind: 'aborted' }\n break\n }\n if (final.finish.kind === 'error') {\n reason = { kind: 'error', failure: final.finish.failure }\n break\n }\n if (final.finish.kind === 'max-tokens') {\n reason = { kind: 'max-tokens' }\n break\n }\n if (final.usageRequired) {\n reason = { kind: 'error', failure: {\n message: 'provider usage is required by the configured run policy',\n code: 'USAGE_REQUIRED',\n } }\n break\n }\n if (final.usageUnavailable) {\n reason = accountingUsageStop(options.accounting) ?? { kind: 'usage-unavailable', modelCallId: final.report?.modelCallId ?? 'unknown' }\n break\n }\n }\n reason = { kind: 'budget-exhausted', budget: exhausted, forcedFinalAnswer: forced,\n ...(exhausted === 'tokens' && reportReserveReached && !tokenLimitBeforeDispatch\n ? { trigger: 'report-reserve' as const } : {}),\n }\n }\n }\n\n if (reason === undefined) {\n reason = signal.aborted\n ? { kind: 'aborted' }\n : { kind: 'budget-exhausted', budget: 'steps', forcedFinalAnswer: false }\n }\n const usageReport = summarizeModelCallUsage(modelCallReports)\n const usage = authoritativeTokenUsage(usageReport)\n const candidate: TurnOutcome = {\n reason, text, steps, usageReport, toolCalls, traceId,\n ...usage === undefined ? {} : { usage },\n }\n const entriesBeforeHook = options.history.entries().length\n const canContinue = reason.kind === 'completed'\n && steps < maxSteps\n && admissionStop() === undefined\n await runOptionalHook(options.hooks?.onTurnEnd, [{\n outcome: candidate,\n snapshot: options.history.snapshot(),\n canContinue,\n }], options, signal, 'onTurnEnd')\n // Hooks object by appending context rather than by returning a veto. Re-run only\n // a normally completed turn; abort/error/budget outcomes remain terminal.\n if (canContinue\n && options.history.entries().length > entriesBeforeHook\n && !signal.aborted) {\n reason = undefined\n continue turnLifecycle\n }\n outcome = candidate\n break\n }\n await emit({\n type: 'span-end', trace: root, at: now(),\n status: outcome.reason.kind === 'error' ? 'error' : outcome.reason.kind === 'aborted' ? 'aborted' : 'success',\n output: { reason: outcome.reason, text },\n ...outcome.usage === undefined ? {} : { usage: outcome.usage },\n ...outcome.reason.kind === 'error' ? { error: { type: 'ModelError', message: outcome.reason.failure.message, code: outcome.reason.failure.code } } : {},\n })\n rootEnded = true\n if (turnOperationId !== undefined) {\n options.accounting?.endOperation(\n turnOperationId,\n outcome.reason.kind === 'error' ? 'error' : outcome.reason.kind === 'aborted' ? 'aborted' : 'success',\n { data: { reason: outcome.reason.kind, steps, toolCalls } },\n )\n turnOperationEnded = true\n }\n await emit({ type: 'turn-end', outcome, trace: root })\n } catch (error: unknown) {\n const code = errorCodeOf(error)\n if (rootStarted && !rootEnded) {\n await emit({\n type: 'span-end', trace: root, at: now(), status: signal.aborted ? 'aborted' : 'error',\n error: {\n type: error instanceof Error ? error.name : 'RuntimeError',\n message: messageOf(error),\n ...code === undefined ? {} : { code },\n },\n }).catch(() => undefined)\n }\n if (turnOperationId !== undefined && !turnOperationEnded) {\n options.accounting?.endOperation(\n turnOperationId,\n signal.aborted ? 'aborted' : 'error',\n { error },\n )\n turnOperationEnded = true\n }\n throw error\n }\n}\n\n\nexport type { RunTurnOptions } from './turn/types.ts'\n"],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { SdkLogger } from "../../logging/types.js";
2
+ import { ToolCallPosition, ToolExecutionResult } from "../tool/definition.js";
3
+ import { SpillStore, ToolOutputOverflowPolicy } from "../tool/output-budget.js";
4
+ import { History } from "../history/history.js";
5
+ import { ApprovalBroker } from "../tool/approval.js";
6
+ import { ToolCatalog } from "../tool/registry.js";
7
+ import { ToolCallRequest, ToolInterceptor } from "../tool/pipeline.js";
8
+ import { TraceRef } from "../trace/trace.js";
9
+ import { AgentEvent, ToolDeclineReason, TurnHooks } from "./events.js";
10
+ import { RunAccountingPort } from "../accounting/contracts.js";
11
+ //#region src/agent/loop/schedule.d.ts
12
+ interface RunToolCallsOptions {
13
+ readonly calls: readonly ToolCallRequest[];
14
+ readonly catalog: ToolCatalog;
15
+ readonly history: History;
16
+ readonly position: ToolCallPosition;
17
+ readonly signal: AbortSignal;
18
+ readonly logger?: SdkLogger;
19
+ readonly parentTrace: TraceRef;
20
+ readonly maxParallel?: number;
21
+ /**
22
+ * How many BUDGETED calls may still be dispatched this step.
23
+ *
24
+ * Calls to a `budgetExempt` tool are not counted against it, so a spent
25
+ * budget never blocks the model from submitting, asking, or delegating.
26
+ */
27
+ readonly dispatchLimit?: number;
28
+ /** Why calls past `dispatchLimit` are not run; shown to the model verbatim. */
29
+ readonly declineReason?: ToolDeclineReason;
30
+ /** Estimated tokens of text one result may put in front of the model. */
31
+ readonly maxResultTokens?: number;
32
+ /** What happens to output over that budget. Defaults to `auto`. */
33
+ readonly resultOverflow?: ToolOutputOverflowPolicy;
34
+ /** Where spilled output goes; `auto` spills only when this is mounted. */
35
+ readonly spillStore?: SpillStore;
36
+ /** Maximum serialized bytes retained for one finalized result. Defaults to 4 MiB. */
37
+ readonly maxResultBytes?: number;
38
+ /** End-to-end wall-clock allowance for one call. Defaults to 10 minutes. */
39
+ readonly maxDurationMs?: number;
40
+ /** Maximum cancellation settlement wait. Defaults to 30 seconds. */
41
+ readonly teardownTimeoutMs?: number;
42
+ readonly interceptors?: readonly ToolInterceptor[];
43
+ readonly approvals?: ApprovalBroker;
44
+ readonly emit?: (event: AgentEvent) => Promise<void>;
45
+ readonly checkpoint?: TurnHooks['checkpoint'];
46
+ readonly accounting?: RunAccountingPort;
47
+ }
48
+ interface ToolCallsOutcome {
49
+ readonly results: readonly ToolExecutionResult[];
50
+ readonly concluded: boolean;
51
+ readonly concludedBy?: string;
52
+ readonly dispatched: number;
53
+ /** Dispatched calls that spent budget; exempt tools are excluded. */
54
+ readonly budgeted: number;
55
+ /** Calls the loop refused to run, for the reason in `declineReason`. */
56
+ readonly declined: number;
57
+ }
58
+ /** Execute safe siblings concurrently while committing every result in model order. */
59
+ declare function runToolCalls(options: RunToolCallsOptions): Promise<ToolCallsOutcome>;
60
+ //#endregion
61
+ export { RunToolCallsOptions, ToolCallsOutcome, runToolCalls };
62
+ //# sourceMappingURL=schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.d.ts","names":[],"sources":["../../../src/agent/loop/schedule.ts"],"mappings":";;;;;;;;;;;UAuBiB;WACN,gBAAgB;WAChB,SAAS;WACT,SAAS;WACT,UAAU;WACV,QAAQ;WACR,SAAS;WACT,aAAa;WACb;;;;;;;WAOA;;WAEA,gBAAgB;;WAEhB;;WAEA,iBAAiB;;WAEjB,aAAa;;WAEb;;WAEA;;WAEA;WACA,wBAAwB;WACxB,YAAY;WACZ,QAAQ,OAAO,eAAe;WAC9B,aAAa;WACb,aAAa;;UAEP;WACN,kBAAkB;WAClB;WACA;WACA;;WAEA;;WAEA;;;iBAmBW,aAAa,SAAS,sBAAsB,QAAQ"}
@@ -0,0 +1,3 @@
1
+ import{detachedFrozen as e}from"../../primitives/snapshot.js";import{waitForSettlement as t}from"../../async/settlement.js";import{createSpanId as n}from"../../observation/context.js";import{createToolResultMessage as r,createUserMessage as i}from"../../message/message.js";import{estimateTextBlockTokens as a,previewForSpill as o,truncateMiddleToTokens as s}from"../tool/output-budget.js";import{TOOL_ERROR_CODES as c,ToolError as l,toolErrorDisposition as u}from"../tool/errors.js";import{authorizeToolCall as d,dispatchAuthorizedToolCall as f,finalizeToolCall as p,prepareToolCall as m,toolFailure as h}from"../tool/pipeline.js";async function g(e){let t=M(e.maxParallel??8,`maxParallel`),n=M(e.maxResultBytes??4194304,`maxResultBytes`),r=M(e.maxDurationMs??6e5,`maxDurationMs`),i=M(e.teardownTimeoutMs??3e4,`teardownTimeoutMs`),a=Object.freeze(e.calls.map(T)),o=Math.max(0,e.dispatchLimit??a.length),s=[],c=0,l=0,u=0,d,f=0,p;for(;f<a.length;){let m=a[f];if(m===void 0)break;let h=p??_(e,m);if(p=void 0,h.mode===`exclusive`){let t=await v(e,h,l<o,r,i);c+=+!!t.dispatched,l+=+(t.budgeted===!0),u+=+(t.declined===!0);let a=await S(e,t,n);s.push(a),d===void 0&&!a.isError&&a.concludesTurn&&(d=m.toolName),f++;continue}let g=[],y=new AbortController,b={...e,signal:AbortSignal.any([e.signal,y.signal])},C=h;try{for(;f<a.length&&g.length<t&&a[f]!==void 0;){let e=C;if(e.mode!==`parallel`)break;let n=await v(b,e,l<o,r,i);c+=+!!n.dispatched,l+=+(n.budgeted===!0),u+=+(n.declined===!0),g.push(n),f++;let s=a[f];s!==void 0&&g.length<t&&(C=_(b,s),C.mode!==`parallel`&&(p=C))}}catch(t){throw y.abort(t),await x(e,g,n),t}if(g.length===0)continue;let w,T=!1;for(let t of g)try{let r=await S(e,t,n);s.push(r),d===void 0&&!r.isError&&r.concludesTurn&&(d=t.call.toolName)}catch(e){T||(w=e),T=!0,y.abort(e)}if(T)throw w}return{results:Object.freeze(s),concluded:d!==void 0,...d===void 0?{}:{concludedBy:d},dispatched:c,budgeted:l,declined:u}}function _(e,t){return m({catalog:e.catalog,call:t,position:e.position,signal:e.signal,...e.logger===void 0?{}:{logger:e.logger},...e.interceptors===void 0?{}:{interceptors:e.interceptors},...e.approvals===void 0?{}:{approvals:e.approvals}})}async function v(e,r,i,a,o){let s=AbortSignal.timeout(a),l=AbortSignal.any([e.signal,s]),u={...r,options:{...r.options,signal:l,teardownTimeoutMs:o},context:{...r.context,signal:l}},p=u.options.call,m={traceId:e.parentTrace.traceId,spanId:n(),parentSpanId:e.parentTrace.spanId};e.history.append({kind:`tool-call`,callId:p.callId,name:p.toolName,rawArguments:p.rawArguments}),await j(e,{type:`span-start`,trace:m,at:F(),name:`execute_tool ${p.toolName}`,kind:`execute_tool`,attributes:{"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.name":p.toolName,"gen_ai.tool.call.id":p.callId}}),await j(e,{type:`tool-call`,call:p,trace:m});let g=e.catalog.get(p.toolName)?.budgetExempt===!0;if(!i&&!g)return{call:p,trace:m,signal:l,deadline:s,teardownTimeoutMs:o,dispatched:!1,declined:!0,pending:Promise.resolve(y(e.declineReason??`tool-calls`))};if(e.signal.aborted)return{call:p,trace:m,signal:l,deadline:s,teardownTimeoutMs:o,dispatched:!1,pending:Promise.resolve(h(`the call was cancelled before it started`,c.ABORTED_BEFORE_DISPATCH))};let _,v={...u,options:{...u.options,onApprovalRequest:async t=>{_=e.accounting?.startOperation(`user-input`,{toolCallId:t.callId,data:{action:`approval`,toolName:t.toolName}}),await j(e,{type:`approval-request`,request:t,trace:m})},...e.accounting===void 0?{}:{onApprovalSettled:(t,n)=>{_!==void 0&&(e.accounting?.endOperation(_,t,n===void 0?{}:{error:n}),_=void 0)}}}},b=d(v),x;try{x=await A(b,l)}catch(e){if(!l.aborted)throw e;if(!await t(b,o))throw k(p.toolName,`authorization`,o,e);return{call:p,trace:m,signal:l,deadline:s,teardownTimeoutMs:o,dispatched:!1,pending:Promise.resolve(O(s,a))}}if(x.kind===`final`)return{call:p,trace:m,signal:l,deadline:s,teardownTimeoutMs:o,dispatched:!1,pending:Promise.resolve(x.result)};try{await e.checkpoint?.({kind:`before-tool-dispatch`,call:p,snapshot:e.history.snapshot(),signal:l,...e.logger===void 0?{}:{logger:e.logger}})}catch(e){return{call:p,trace:m,signal:l,deadline:s,teardownTimeoutMs:o,dispatched:!1,pending:Promise.resolve(h(`history checkpoint failed: ${P(e)}`,c.CHECKPOINT_FAILED))}}let S=f(x.call);return S.catch(()=>void 0),{call:p,trace:m,signal:l,deadline:s,teardownTimeoutMs:o,authorized:x.call,dispatched:!0,budgeted:!g,pending:S}}function y(e){return{isError:!1,value:void 0,content:[{type:`text`,text:b(e)}],meta:{declined:!0,reason:e}}}function b(e){let t=` Answer now from what you already have, and say plainly what is unverified or unfinished.`;switch(e){case`tool-calls`:return`This call was not run: the turn has spent its tool-call budget. Further work calls will not run either, so do not retry it.`+t;case`repeated-tool-call`:return`This call was not run: it repeats a call already made with the same arguments, and repeating it cannot produce a new result. Change approach or finish.`+t;case`tool-call-cycle`:return`This call was not run: the same sequence of calls has repeated several times without progress. Break the cycle rather than re-entering it.`+t;case`tokens`:return`This call was not run: the turn has spent its token budget.`+t;case`consecutive-tool-errors`:return`This call was not run: too many calls in a row have failed. Something in the approach is wrong, not the individual call.`+t;case`steps`:return`This call was not run: the turn has no model steps left.`+t;case`usage-required`:return`This call was not run: the run policy requires provider usage reporting that the last model call did not supply.`+t}}async function x(e,t,n){for(let r of t)try{await S(e,r,n)}catch{}}async function S(e,n,a){let o,s,c=!1;try{let r;try{r=await A(n.pending,n.signal)}catch(e){if(!n.signal.aborted)throw e;if(!await t(n.pending,n.teardownTimeoutMs))throw k(n.call.toolName,`execution`,n.teardownTimeoutMs,e);r=O(n.deadline)}let i=r;if(n.authorized!==void 0){let e=p(n.authorized,r);try{i=await A(e,n.signal)}catch(r){if(!n.signal.aborted)throw r;if(!await t(e,n.teardownTimeoutMs))throw k(n.call.toolName,`finalization`,n.teardownTimeoutMs,r);i=O(n.deadline)}}o=E(await C(e,n,i),a)}catch(e){c=u(e)===`fatal`,s=e,o=E(h(P(e),N(e)),a)}let l=r({callId:n.call.callId,content:[...o.content],isError:o.isError});if(e.history.append({kind:`tool-result`,callId:n.call.callId,message:l,result:o}),await j(e,{type:`tool-result`,call:n.call,result:o,trace:n.trace}),await j(e,{type:`span-end`,trace:n.trace,at:F(),status:o.isError?`error`:`success`,output:o.isError?{error:o.error}:o.value,...o.isError?{error:{type:`ToolError`,message:o.error.message,code:o.error.code}}:{}}),o.additionalContext!==void 0&&e.history.append({kind:`user`,message:i({content:[...o.additionalContext],source:{kind:`app`,producer:`tool:${n.call.toolName}`}})}),c)throw s;return o}async function C(e,t,n){let r=e.maxResultTokens,i=e.catalog.get(t.call.toolName)?.maxOutputTokens,c=r===void 0?i:i===void 0?r:Math.min(r,i);if(c===void 0)return n;let l=a(n.content);if(l<=c)return n;let u=n.content.filter(e=>e.type===`text`);if(u.length===0)return n;let d=u.map(e=>e.text).join(`
2
+ `),f=e.resultOverflow??`auto`,p=e.spillStore;if(f!==`truncate`&&p!==void 0)try{let e=await p.save(d,{toolName:t.call.toolName,callId:String(t.call.callId)});return w(n,`${o(d,Math.max(1,Math.floor(c*.75)))}\n\n[Output exceeded this call's budget of ${String(c)} estimated tokens. The full ${String(e.bytes)} bytes are saved. ${e.retrieval}]`,{outputSpilled:{locator:e.locator,bytes:e.bytes,estimatedTokens:l}})}catch{}let m=s(d,c);return w(n,m.text+`\n\n[Output was ${String(m.originalTokens)} estimated tokens, over this call's budget of ${String(c)}. Re-run more narrowly if you need the omitted part.]`,{outputTruncated:{estimatedTokens:m.originalTokens,budget:c}})}function w(e,t,n){let r=!1,i=[];for(let n of e.content){if(n.type!==`text`){i.push(n);continue}r||(r=!0,i.push({type:`text`,text:t}))}return{...e,content:i,meta:{...e.meta,...n}}}function T(t){if(typeof t.callId!=`string`||t.callId.length===0||typeof t.toolName!=`string`||t.toolName.length===0||typeof t.rawArguments!=`string`)throw TypeError(`tool call identity, name, and raw arguments must be strings`);return e(t)}function E(t,n){try{if(D(t)>n)return e(h(`tool result exceeds the ${n}-byte retention limit`,c.INVALID_RESULT));let r=e(t);return D(r)>n?e(h(`tool result exceeds the ${n}-byte retention limit`,c.INVALID_RESULT)):r}catch(e){throw l.fatal(`tool result could not be detached as lossless structured data`,c.INVALID_RESULT,{cause:e})}}function D(e){let t=JSON.stringify(e);if(t===void 0)throw TypeError(`tool result is not lossless JSON`);return new TextEncoder().encode(t).byteLength}function O(e,t){let n=t===void 0?`configured time limit`:`${t}ms time limit`;return e.aborted?h(`the tool exceeded its ${n}`,c.TIMEOUT):h(`the call was cancelled`,c.ABORTED)}function k(e,t,n,r){return l.fatal(`tool "${e}" ${t} ignored cancellation for more than ${n}ms; the in-process operation may still be running`,c.TEARDOWN_TIMEOUT,{cause:r})}async function A(e,t){if(t.aborted)throw t.reason??Error(`tool call aborted`);return await new Promise((n,r)=>{let i=()=>{t.removeEventListener(`abort`,i),r(t.reason??Error(`tool call aborted`))};t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}async function j(t,n){await t.emit?.(e(n))}function M(e,t){if(!Number.isInteger(e)||e<1)throw RangeError(`${t} must be a positive integer`);return e}function N(e){return typeof e==`object`&&e&&`code`in e&&typeof e.code==`string`?e.code:c.FAILED}function P(e){return e instanceof Error?e.message:String(e)}function F(){return new Date().toISOString()}export{g as runToolCalls};
3
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","names":[],"sources":["../../../src/agent/loop/schedule.ts"],"sourcesContent":["import { createToolResultMessage, createUserMessage } from '../../message/index.ts'\nimport type { ContentBlock } from '../../message/index.ts'\nimport { detachedFrozen } from '../../primitives/index.ts'\nimport type { JsonObject } from '../../primitives/index.ts'\nimport { waitForSettlement } from '../../async/index.ts'\nimport type { History } from '../history/history.ts'\nimport type { ApprovalBroker } from '../tool/approval.ts'\nimport type { ToolCallPosition, ToolExecutionResult } from '../tool/definition.ts'\nimport {\n estimateTextBlockTokens, previewForSpill, truncateMiddleToTokens,\n type SpillStore, type ToolOutputOverflowPolicy,\n} from '../tool/output-budget.ts'\nimport { TOOL_ERROR_CODES, ToolError, toolErrorDisposition } from '../tool/errors.ts'\nimport {\n authorizeToolCall, dispatchAuthorizedToolCall, finalizeToolCall, prepareToolCall, toolFailure,\n type AuthorizedToolCall, type ToolCallRequest, type ToolInterceptor,\n} from '../tool/pipeline.ts'\nimport type { ToolCatalog } from '../tool/registry.ts'\nimport { createSpanId, type TraceRef } from '../trace/trace.ts'\nimport type { AgentEvent, ToolDeclineReason, TurnHooks } from './events.ts'\nimport type { RunAccountingPort } from '../accounting/contracts.ts'\nimport type { SdkLogger } from '../../logging/types.ts'\n\nexport interface RunToolCallsOptions {\n readonly calls: readonly ToolCallRequest[]\n readonly catalog: ToolCatalog\n readonly history: History\n readonly position: ToolCallPosition\n readonly signal: AbortSignal\n readonly logger?: SdkLogger\n readonly parentTrace: TraceRef\n readonly maxParallel?: number\n /**\n * How many BUDGETED calls may still be dispatched this step.\n *\n * Calls to a `budgetExempt` tool are not counted against it, so a spent\n * budget never blocks the model from submitting, asking, or delegating.\n */\n readonly dispatchLimit?: number\n /** Why calls past `dispatchLimit` are not run; shown to the model verbatim. */\n readonly declineReason?: ToolDeclineReason\n /** Estimated tokens of text one result may put in front of the model. */\n readonly maxResultTokens?: number\n /** What happens to output over that budget. Defaults to `auto`. */\n readonly resultOverflow?: ToolOutputOverflowPolicy\n /** Where spilled output goes; `auto` spills only when this is mounted. */\n readonly spillStore?: SpillStore\n /** Maximum serialized bytes retained for one finalized result. Defaults to 4 MiB. */\n readonly maxResultBytes?: number\n /** End-to-end wall-clock allowance for one call. Defaults to 10 minutes. */\n readonly maxDurationMs?: number\n /** Maximum cancellation settlement wait. Defaults to 30 seconds. */\n readonly teardownTimeoutMs?: number\n readonly interceptors?: readonly ToolInterceptor[]\n readonly approvals?: ApprovalBroker\n readonly emit?: (event: AgentEvent) => Promise<void>\n readonly checkpoint?: TurnHooks['checkpoint']\n readonly accounting?: RunAccountingPort\n}\nexport interface ToolCallsOutcome {\n readonly results: readonly ToolExecutionResult[]\n readonly concluded: boolean\n readonly concludedBy?: string\n readonly dispatched: number\n /** Dispatched calls that spent budget; exempt tools are excluded. */\n readonly budgeted: number\n /** Calls the loop refused to run, for the reason in `declineReason`. */\n readonly declined: number\n}\n\ninterface Slot {\n readonly call: ToolCallRequest\n readonly trace: TraceRef\n readonly authorized?: AuthorizedToolCall\n readonly pending: Promise<ToolExecutionResult>\n readonly dispatched: boolean\n /** Whether this dispatch spent turn budget; exempt tools never do. */\n readonly budgeted?: boolean\n /** Set when the loop refused to run the call. */\n readonly declined?: boolean\n readonly signal: AbortSignal\n readonly deadline: AbortSignal\n readonly teardownTimeoutMs: number\n}\n\n/** Execute safe siblings concurrently while committing every result in model order. */\nexport async function runToolCalls(options: RunToolCallsOptions): Promise<ToolCallsOutcome> {\n const maxParallel = positiveInteger(options.maxParallel ?? 8, 'maxParallel')\n const maxResultBytes = positiveInteger(options.maxResultBytes ?? 4 * 1024 * 1024, 'maxResultBytes')\n const maxDurationMs = positiveInteger(options.maxDurationMs ?? 10 * 60_000, 'maxDurationMs')\n const teardownTimeoutMs = positiveInteger(options.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n const calls = Object.freeze(options.calls.map(immutableCall))\n const dispatchLimit = Math.max(0, options.dispatchLimit ?? calls.length)\n const results: ToolExecutionResult[] = []\n let dispatched = 0\n let budgeted = 0\n let declined = 0\n let concludedBy: string | undefined\n let index = 0\n let carried: ReturnType<typeof prepareToolCall> | undefined\n\n while (index < calls.length) {\n const first = calls[index]\n if (first === undefined) break\n const prepared = carried ?? prepare(options, first)\n carried = undefined\n if (prepared.mode === 'exclusive') {\n const slot = await start(options, prepared, budgeted < dispatchLimit, maxDurationMs, teardownTimeoutMs)\n dispatched += slot.dispatched ? 1 : 0\n budgeted += slot.budgeted === true ? 1 : 0\n declined += slot.declined === true ? 1 : 0\n const result = await commit(options, slot, maxResultBytes)\n results.push(result)\n if (concludedBy === undefined && !result.isError && result.concludesTurn) concludedBy = first.toolName\n index++\n continue\n }\n\n // A rolling parallel segment. Re-prepare each call immediately before start;\n // an updated registry can therefore turn the next call into a barrier.\n const segment: Slot[] = []\n const segmentAbort = new AbortController()\n const segmentOptions: RunToolCallsOptions = {\n ...options,\n signal: AbortSignal.any([options.signal, segmentAbort.signal]),\n }\n let nextPrepared = prepared\n try {\n while (index < calls.length && segment.length < maxParallel) {\n const call = calls[index]\n if (call === undefined) break\n const candidate = nextPrepared\n if (candidate.mode !== 'parallel') break\n const slot = await start(segmentOptions, candidate, budgeted < dispatchLimit, maxDurationMs, teardownTimeoutMs)\n dispatched += slot.dispatched ? 1 : 0\n budgeted += slot.budgeted === true ? 1 : 0\n declined += slot.declined === true ? 1 : 0\n segment.push(slot)\n index++\n const nextCall = calls[index]\n if (nextCall !== undefined && segment.length < maxParallel) {\n nextPrepared = prepare(segmentOptions, nextCall)\n if (nextPrepared.mode !== 'parallel') carried = nextPrepared\n }\n }\n } catch (error: unknown) {\n // Admission of a later sibling failed after earlier bodies started.\n // Cancel and drain everything already owned before propagating that error.\n segmentAbort.abort(error)\n await drainSegment(options, segment, maxResultBytes)\n throw error\n }\n if (segment.length === 0) continue\n // Bodies have already started. Finalization and history publication remain ordered.\n let fatal: unknown\n let hasFatal = false\n for (const slot of segment) {\n try {\n const result = await commit(options, slot, maxResultBytes)\n results.push(result)\n if (concludedBy === undefined && !result.isError && result.concludesTurn) concludedBy = slot.call.toolName\n } catch (error: unknown) {\n if (!hasFatal) fatal = error\n hasFatal = true\n segmentAbort.abort(error)\n }\n }\n // Every parallel body was already dispatched. Commit/drain all siblings so\n // none is orphaned, then propagate the first fatal contract violation.\n if (hasFatal) throw fatal\n }\n return {\n results: Object.freeze(results),\n concluded: concludedBy !== undefined,\n ...concludedBy === undefined ? {} : { concludedBy },\n dispatched,\n budgeted,\n declined,\n }\n}\n\nfunction prepare(options: RunToolCallsOptions, call: ToolCallRequest) {\n return prepareToolCall({\n catalog: options.catalog, call, position: options.position, signal: options.signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n ...options.interceptors === undefined ? {} : { interceptors: options.interceptors },\n ...options.approvals === undefined ? {} : { approvals: options.approvals },\n })\n}\n\nasync function start(\n options: RunToolCallsOptions,\n prepared: ReturnType<typeof prepareToolCall>,\n hasBudget: boolean,\n maxDurationMs: number,\n teardownTimeoutMs: number,\n): Promise<Slot> {\n const deadline = AbortSignal.timeout(maxDurationMs)\n const signal = AbortSignal.any([options.signal, deadline])\n const boundedPrepared = {\n ...prepared,\n options: { ...prepared.options, signal, teardownTimeoutMs },\n context: { ...prepared.context, signal },\n }\n const call = boundedPrepared.options.call\n const trace: TraceRef = {\n traceId: options.parentTrace.traceId,\n spanId: createSpanId(),\n parentSpanId: options.parentTrace.spanId,\n }\n options.history.append({ kind: 'tool-call', callId: call.callId, name: call.toolName, rawArguments: call.rawArguments })\n await emitEvent(options, { type: 'span-start', trace, at: now(), name: `execute_tool ${call.toolName}`, kind: 'execute_tool', attributes: {\n 'gen_ai.operation.name': 'execute_tool', 'gen_ai.tool.name': call.toolName, 'gen_ai.tool.call.id': call.callId,\n } })\n await emitEvent(options, { type: 'tool-call', call, trace })\n // A tool the model may always reach: submitting, asking, delegating. Letting\n // a budget block these is what turns a spent budget into a dead run.\n const exempt = options.catalog.get(call.toolName)?.budgetExempt === true\n if (!hasBudget && !exempt) return {\n call, trace, signal, deadline, teardownTimeoutMs, dispatched: false, declined: true,\n pending: Promise.resolve(declinedResult(options.declineReason ?? 'tool-calls')),\n }\n if (options.signal.aborted) return {\n call, trace, signal, deadline, teardownTimeoutMs, dispatched: false,\n pending: Promise.resolve(toolFailure('the call was cancelled before it started', TOOL_ERROR_CODES.ABORTED_BEFORE_DISPATCH)),\n }\n let approvalOperation: string | undefined\n const withApprovalEvent = {\n ...boundedPrepared,\n options: {\n ...boundedPrepared.options,\n onApprovalRequest: async (request: Parameters<NonNullable<typeof prepared.options.onApprovalRequest>>[0]) => {\n approvalOperation = options.accounting?.startOperation('user-input', {\n toolCallId: request.callId,\n data: { action: 'approval', toolName: request.toolName },\n })\n await emitEvent(options, { type: 'approval-request', request, trace })\n },\n ...options.accounting === undefined ? {} : {\n onApprovalSettled: (status: 'success' | 'error' | 'aborted', error?: unknown) => {\n if (approvalOperation !== undefined) {\n options.accounting?.endOperation(approvalOperation, status, error === undefined ? {} : { error })\n approvalOperation = undefined\n }\n },\n },\n },\n }\n const authorizationPending = authorizeToolCall(withApprovalEvent)\n let authorization: Awaited<ReturnType<typeof authorizeToolCall>>\n try {\n authorization = await raceWithSignal(authorizationPending, signal)\n } catch (error: unknown) {\n if (!signal.aborted) throw error\n const settled = await waitForSettlement(authorizationPending, teardownTimeoutMs)\n if (!settled) throw teardownFailure(call.toolName, 'authorization', teardownTimeoutMs, error)\n return {\n call, trace, signal, deadline, teardownTimeoutMs, dispatched: false,\n pending: Promise.resolve(cancelledResult(deadline, maxDurationMs)),\n }\n }\n if (authorization.kind === 'final') return {\n call, trace, signal, deadline, teardownTimeoutMs,\n dispatched: false, pending: Promise.resolve(authorization.result),\n }\n try {\n await options.checkpoint?.({\n kind: 'before-tool-dispatch', call, snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n })\n } catch (error: unknown) {\n return {\n call, trace, signal, deadline, teardownTimeoutMs, dispatched: false,\n pending: Promise.resolve(toolFailure(`history checkpoint failed: ${messageOf(error)}`, TOOL_ERROR_CODES.CHECKPOINT_FAILED)),\n }\n }\n const pending = dispatchAuthorizedToolCall(authorization.call)\n // Observe rejection in the same turn in which dispatch creates the promise.\n // commit() still receives and propagates the original rejection in order.\n void pending.catch(() => undefined)\n return {\n call, trace, signal, deadline, teardownTimeoutMs,\n authorized: authorization.call, dispatched: true, budgeted: !exempt,\n pending,\n }\n}\n\n/**\n * What the model reads when the loop refuses to run a call.\n *\n * Not a failure. A failure is something that went wrong, and a model answers\n * one by retrying — with a smaller argument, a different path — which spends\n * exactly what is no longer there. This says what happened and what to do\n * instead, in the plainest terms available, and nothing about it reads as\n * broken tooling.\n * @param reason - Which limit refused the call.\n * @returns A successful result carrying the instruction.\n */\nfunction declinedResult(reason: ToolDeclineReason): ToolExecutionResult {\n return {\n isError: false,\n value: undefined,\n content: [{ type: 'text', text: declineText(reason) }],\n // Never shown to the model; lets a UI render this as declined rather than\n // as work that succeeded.\n meta: { declined: true, reason },\n }\n}\n\n/**\n * The instruction for one decline reason.\n *\n * Each limit gets its own wording: a model told \"no remaining tool-call\n * budget\" when it actually tripped the repeat guard learns the wrong lesson\n * and repeats the call in the next turn.\n * @param reason - Which limit refused the call.\n * @returns The sentence the model reads.\n */\nfunction declineText(reason: ToolDeclineReason): string {\n const finish = ' Answer now from what you already have, and say plainly what is'\n + ' unverified or unfinished.'\n switch (reason) {\n case 'tool-calls':\n return 'This call was not run: the turn has spent its tool-call budget.'\n + ' Further work calls will not run either, so do not retry it.' + finish\n case 'repeated-tool-call':\n return 'This call was not run: it repeats a call already made with the same'\n + ' arguments, and repeating it cannot produce a new result. Change'\n + ' approach or finish.' + finish\n case 'tool-call-cycle':\n return 'This call was not run: the same sequence of calls has repeated'\n + ' several times without progress. Break the cycle rather than'\n + ' re-entering it.' + finish\n case 'tokens':\n return 'This call was not run: the turn has spent its token budget.' + finish\n case 'consecutive-tool-errors':\n return 'This call was not run: too many calls in a row have failed.'\n + ' Something in the approach is wrong, not the individual call.' + finish\n case 'steps':\n return 'This call was not run: the turn has no model steps left.' + finish\n case 'usage-required':\n return 'This call was not run: the run policy requires provider usage'\n + ' reporting that the last model call did not supply.' + finish\n }\n}\n\nasync function drainSegment(\n options: RunToolCallsOptions,\n segment: readonly Slot[],\n maxResultBytes: number,\n): Promise<void> {\n for (const slot of segment) {\n try { await commit(options, slot, maxResultBytes) }\n catch { /* The admission failure remains primary after every owned slot settles. */ }\n }\n}\n\nasync function commit(\n options: RunToolCallsOptions,\n slot: Slot,\n maxResultBytes: number,\n): Promise<ToolExecutionResult> {\n let result: ToolExecutionResult\n let fatal: unknown\n let hasFatal = false\n try {\n let pending: ToolExecutionResult\n try {\n pending = await raceWithSignal(slot.pending, slot.signal)\n } catch (error: unknown) {\n if (!slot.signal.aborted) throw error\n const settled = await waitForSettlement(slot.pending, slot.teardownTimeoutMs)\n if (!settled) throw teardownFailure(slot.call.toolName, 'execution', slot.teardownTimeoutMs, error)\n pending = cancelledResult(slot.deadline)\n }\n let finalized = pending\n if (slot.authorized !== undefined) {\n const finalizing = finalizeToolCall(slot.authorized, pending)\n try {\n finalized = await raceWithSignal(finalizing, slot.signal)\n } catch (error: unknown) {\n if (!slot.signal.aborted) throw error\n const settled = await waitForSettlement(finalizing, slot.teardownTimeoutMs)\n if (!settled) throw teardownFailure(slot.call.toolName, 'finalization', slot.teardownTimeoutMs, error)\n finalized = cancelledResult(slot.deadline)\n }\n }\n result = immutableResult(await boundOutput(options, slot, finalized), maxResultBytes)\n } catch (error: unknown) {\n hasFatal = toolErrorDisposition(error) === 'fatal'\n fatal = error\n result = immutableResult(toolFailure(messageOf(error), errorCode(error)), maxResultBytes)\n }\n const message = createToolResultMessage({ callId: slot.call.callId, content: [...result.content], isError: result.isError })\n options.history.append({ kind: 'tool-result', callId: slot.call.callId, message, result })\n await emitEvent(options, { type: 'tool-result', call: slot.call, result, trace: slot.trace })\n await emitEvent(options, {\n type: 'span-end', trace: slot.trace, at: now(), status: result.isError ? 'error' : 'success',\n output: result.isError ? { error: result.error } : result.value,\n ...result.isError ? { error: { type: 'ToolError', message: result.error.message, code: result.error.code } } : {},\n })\n if (result.additionalContext !== undefined) {\n // Additional context is deliberately a separate application message.\n options.history.append({ kind: 'user', message: createUserMessage({\n content: [...result.additionalContext], source: { kind: 'app', producer: `tool:${slot.call.toolName}` },\n }) })\n }\n if (hasFatal) throw fatal\n return result\n}\n\n/**\n * Keep one tool result inside its share of the context window.\n *\n * This runs at the RESULT boundary rather than when the request is assembled,\n * which is the whole point: by the time an oversized result reaches the model\n * the window is already gone, and the turn's only remaining move is to lose\n * everything it has paid for. Both reference harnesses cut here.\n *\n * The budget is the stricter of the turn's and the tool's own declaration, so\n * a tool that knows it returns a lot can ask for room without any tool being\n * able to exceed what the host allows.\n * @param options - The scheduling options carrying budget and store.\n * @param slot - The call this result belongs to.\n * @param result - The finalized result.\n * @returns The result the model will read.\n */\nasync function boundOutput(\n options: RunToolCallsOptions,\n slot: Slot,\n result: ToolExecutionResult,\n): Promise<ToolExecutionResult> {\n const turnBudget = options.maxResultTokens\n const toolBudget = options.catalog.get(slot.call.toolName)?.maxOutputTokens\n const budget = turnBudget === undefined\n ? toolBudget\n : toolBudget === undefined ? turnBudget : Math.min(turnBudget, toolBudget)\n if (budget === undefined) return result\n const tokens = estimateTextBlockTokens(result.content)\n if (tokens <= budget) return result\n\n // Only text is shortened. Cutting an image block produces a corrupt image\n // rather than a smaller one, so those pass through and are counted by the\n // byte cap instead.\n const texts = result.content.filter(block => block.type === 'text')\n if (texts.length === 0) return result\n const full = texts.map(block => block.text).join('\\n')\n const policy = options.resultOverflow ?? 'auto'\n const store = options.spillStore\n\n if (policy !== 'truncate' && store !== undefined) {\n try {\n // Reserve room for the notice inside the budget, so the replacement is\n // never bigger than what it replaced.\n const record = await store.save(full, {\n toolName: slot.call.toolName, callId: String(slot.call.callId),\n })\n const preview = previewForSpill(full, Math.max(1, Math.floor(budget * 0.75)))\n return replaceText(result, `${preview}\\n\\n[Output exceeded this call's budget of `\n + `${String(budget)} estimated tokens. The full ${String(record.bytes)} bytes are saved. `\n + `${record.retrieval}]`, {\n outputSpilled: { locator: record.locator, bytes: record.bytes, estimatedTokens: tokens },\n })\n } catch {\n // Best-effort, deliberately: a store that is full or unreachable must not\n // cost the model a result it can still read most of.\n }\n }\n\n const truncated = truncateMiddleToTokens(full, budget)\n return replaceText(result, truncated.text\n + `\\n\\n[Output was ${String(truncated.originalTokens)} estimated tokens, over this call's `\n + `budget of ${String(budget)}. Re-run more narrowly if you need the omitted part.]`, {\n outputTruncated: { estimatedTokens: truncated.originalTokens, budget },\n })\n}\n\n/**\n * Swap a result's text for one shortened block, keeping everything else.\n * @param result - The original result.\n * @param text - The replacement text.\n * @param meta - What a UI should know about the replacement.\n * @returns The rewritten result.\n */\nfunction replaceText(\n result: ToolExecutionResult,\n text: string,\n meta: JsonObject,\n): ToolExecutionResult {\n // The replacement takes the FIRST text block's position and the other text\n // blocks drop out. Appending it after the non-text blocks instead would\n // reorder a result whose image came after its caption.\n let placed = false\n const content: ContentBlock[] = []\n for (const block of result.content) {\n if (block.type !== 'text') { content.push(block); continue }\n if (placed) continue\n placed = true\n content.push({ type: 'text', text })\n }\n // `value` is deliberately untouched: it is what a host logs and replays, and\n // shortening it would make the record disagree with what the tool returned.\n return { ...result, content, meta: { ...result.meta, ...meta } }\n}\n\nfunction immutableCall(call: ToolCallRequest): ToolCallRequest {\n if (typeof call.callId !== 'string' || call.callId.length === 0\n || typeof call.toolName !== 'string' || call.toolName.length === 0\n || typeof call.rawArguments !== 'string') {\n throw new TypeError('tool call identity, name, and raw arguments must be strings')\n }\n return detachedFrozen(call)\n}\n\nfunction immutableResult(result: ToolExecutionResult, maxResultBytes: number): ToolExecutionResult {\n try {\n if (serializedBytes(result) > maxResultBytes) {\n return detachedFrozen(toolFailure(\n `tool result exceeds the ${maxResultBytes}-byte retention limit`,\n TOOL_ERROR_CODES.INVALID_RESULT,\n ))\n }\n const detached = detachedFrozen(result)\n const bytes = serializedBytes(detached)\n if (bytes > maxResultBytes) {\n return detachedFrozen(toolFailure(\n `tool result exceeds the ${maxResultBytes}-byte retention limit`,\n TOOL_ERROR_CODES.INVALID_RESULT,\n ))\n }\n return detached\n } catch (error: unknown) {\n throw ToolError.fatal(\n 'tool result could not be detached as lossless structured data',\n TOOL_ERROR_CODES.INVALID_RESULT,\n { cause: error },\n )\n }\n}\n\nfunction serializedBytes(value: unknown): number {\n const serialized = JSON.stringify(value)\n if (serialized === undefined) throw new TypeError('tool result is not lossless JSON')\n return new TextEncoder().encode(serialized).byteLength\n}\n\nfunction cancelledResult(deadline: AbortSignal, maxDurationMs?: number): ToolExecutionResult {\n const limit = maxDurationMs === undefined ? 'configured time limit' : `${maxDurationMs}ms time limit`\n return deadline.aborted\n ? toolFailure(\n `the tool exceeded its ${limit}`,\n TOOL_ERROR_CODES.TIMEOUT,\n )\n : toolFailure('the call was cancelled', TOOL_ERROR_CODES.ABORTED)\n}\n\nfunction teardownFailure(\n toolName: string,\n stage: string,\n timeoutMs: number,\n cause: unknown,\n): ToolError {\n return ToolError.fatal(\n `tool \"${toolName}\" ${stage} ignored cancellation for more than ${timeoutMs}ms; the in-process operation may still be running`,\n TOOL_ERROR_CODES.TEARDOWN_TIMEOUT,\n { cause },\n )\n}\n\nasync function raceWithSignal<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) throw signal.reason ?? new Error('tool call aborted')\n return await new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener('abort', abort)\n reject(signal.reason ?? new Error('tool call aborted'))\n }\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { signal.removeEventListener('abort', abort); resolve(value) },\n error => { signal.removeEventListener('abort', abort); reject(error) },\n )\n })\n}\n\nasync function emitEvent(options: RunToolCallsOptions, event: AgentEvent): Promise<void> {\n await options.emit?.(detachedFrozen(event))\n}\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isInteger(value) || value < 1) throw new RangeError(`${name} must be a positive integer`)\n return value\n}\nfunction errorCode(error: unknown): string {\n return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string'\n ? error.code : TOOL_ERROR_CODES.FAILED\n}\nfunction messageOf(error: unknown): string { return error instanceof Error ? error.message : String(error) }\nfunction now(): string { return new Date().toISOString() }\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{waitForSettlement as e}from"../../../async/settlement.js";var t=class extends Error{cause;constructor(e){super(`model stream was aborted`),this.cause=e,this.name=`StreamAbortError`}};async function n(e,n){if(n.aborted)throw e.catch(()=>void 0),new t(n.reason);return await new Promise((r,i)=>{let a=()=>{n.removeEventListener(`abort`,a),i(new t(n.reason))};n.addEventListener(`abort`,a,{once:!0}),e.then(e=>{n.removeEventListener(`abort`,a),r(e)},e=>{n.removeEventListener(`abort`,a),i(e)})})}async function r(t,n){let r=t.return?.bind(t);if(r===void 0)return!0;let i=Promise.resolve().then(async()=>{await r()});return await e(i,n)}async function i(e,n){if(n.aborted)throw e.catch(()=>void 0),new t(n.reason);return await new Promise((r,i)=>{let a=()=>{n.removeEventListener(`abort`,a),i(new t(n.reason))};n.addEventListener(`abort`,a,{once:!0}),e.then(e=>{n.removeEventListener(`abort`,a),r(e)},e=>{n.removeEventListener(`abort`,a),i(e)})})}export{t as StreamAbortError,r as closeIterator,i as nextValueWithAbort,n as nextWithAbort};
2
+ //# sourceMappingURL=cancellation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancellation.js","names":[],"sources":["../../../../src/agent/loop/turn/cancellation.ts"],"sourcesContent":["import { waitForSettlement } from '../../../async/index.ts'\n\nexport class StreamAbortError extends Error {\n constructor(override readonly cause: unknown) {\n super('model stream was aborted')\n this.name = 'StreamAbortError'\n }\n}\nexport async function nextWithAbort<T>(\n pending: Promise<IteratorResult<T>>,\n signal: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (signal.aborted) {\n void pending.catch(() => undefined)\n throw new StreamAbortError(signal.reason)\n }\n return await new Promise<IteratorResult<T>>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener('abort', onAbort)\n reject(new StreamAbortError(signal.reason))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n void pending.then(\n value => {\n signal.removeEventListener('abort', onAbort)\n resolve(value)\n },\n error => {\n signal.removeEventListener('abort', onAbort)\n reject(error)\n },\n )\n })\n}\nexport async function closeIterator<T>(iterator: AsyncIterator<T>, timeoutMs: number): Promise<boolean> {\n const close = iterator.return?.bind(iterator)\n if (close === undefined) return true\n const closing = Promise.resolve().then(async () => { await close() })\n return await waitForSettlement(closing, timeoutMs)\n}\nexport async function nextValueWithAbort<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) {\n void pending.catch(() => undefined)\n throw new StreamAbortError(signal.reason)\n }\n return await new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener('abort', abort)\n reject(new StreamAbortError(signal.reason))\n }\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { signal.removeEventListener('abort', abort); resolve(value) },\n error => { signal.removeEventListener('abort', abort); reject(error) },\n )\n })\n}\n"],"mappings":"iEAEA,IAAa,EAAb,cAAsC,KAAM,CACZ,MAA9B,YAAY,EAAkC,CAC5C,MAAM,0BAA0B,EADJ,KAAA,MAAA,EAE5B,KAAK,KAAO,kBACd,CACF,EACA,eAAsB,EACpB,EACA,EAC4B,CAC5B,GAAI,EAAO,QAET,MADA,EAAa,UAAY,IAAA,EAAS,EAC5B,IAAI,EAAiB,EAAO,MAAM,EAE1C,OAAO,MAAM,IAAI,SAA4B,EAAS,IAAW,CAC/D,IAAM,MAAgB,CACpB,EAAO,oBAAoB,QAAS,CAAO,EAC3C,EAAO,IAAI,EAAiB,EAAO,MAAM,CAAC,CAC5C,EACA,EAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EACxD,EAAa,KACX,GAAS,CACP,EAAO,oBAAoB,QAAS,CAAO,EAC3C,EAAQ,CAAK,CACf,EACA,GAAS,CACP,EAAO,oBAAoB,QAAS,CAAO,EAC3C,EAAO,CAAK,CACd,CACF,CACF,CAAC,CACH,CACA,eAAsB,EAAiB,EAA4B,EAAqC,CACtG,IAAM,EAAQ,EAAS,QAAQ,KAAK,CAAQ,EAC5C,GAAI,IAAU,IAAA,GAAW,MAAO,GAChC,IAAM,EAAU,QAAQ,QAAQ,CAAC,CAAC,KAAK,SAAY,CAAE,MAAM,EAAM,CAAE,CAAC,EACpE,OAAO,MAAM,EAAkB,EAAS,CAAS,CACnD,CACA,eAAsB,EAAsB,EAAqB,EAAiC,CAChG,GAAI,EAAO,QAET,MADA,EAAa,UAAY,IAAA,EAAS,EAC5B,IAAI,EAAiB,EAAO,MAAM,EAE1C,OAAO,MAAM,IAAI,SAAY,EAAS,IAAW,CAC/C,IAAM,MAAc,CAClB,EAAO,oBAAoB,QAAS,CAAK,EACzC,EAAO,IAAI,EAAiB,EAAO,MAAM,CAAC,CAC5C,EACA,EAAO,iBAAiB,QAAS,EAAO,CAAE,KAAM,EAAK,CAAC,EACtD,EAAa,KACX,GAAS,CAAE,EAAO,oBAAoB,QAAS,CAAK,EAAG,EAAQ,CAAK,CAAE,EACtE,GAAS,CAAE,EAAO,oBAAoB,QAAS,CAAK,EAAG,EAAO,CAAK,CAAE,CACvE,CACF,CAAC,CACH"}
@@ -0,0 +1,2 @@
1
+ function e(e){let t=JSON.stringify(e);if(t===void 0)throw TypeError(`value is not JSON serializable`);return new TextEncoder().encode(t).byteLength}function t(e,t){return{type:`finish`,reason:{kind:`error`,failure:{message:e,code:t}}}}function n(e){return{type:`finish`,reason:{kind:`aborted`,failure:{message:e,code:`ABORTED`}}}}function r(e,t,n){let r=Error(e,{cause:n});return r.code=t,r}function i(e){return e instanceof Error?e.message:String(e)}function a(e){return typeof e==`object`&&e&&`code`in e&&typeof e.code==`string`?e.code:void 0}function o(){return new Date().toISOString()}export{r as codedRuntimeError,a as errorCodeOf,i as messageOf,n as modelAbortedFinish,t as modelFailureFinish,o as now,e as serializedBytes};
2
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","names":[],"sources":["../../../../src/agent/loop/turn/common.ts"],"sourcesContent":["import type { StreamChunk } from '../../../stream/index.ts'\n\nexport function serializedBytes(value: unknown): number {\n const serialized = JSON.stringify(value)\n if (serialized === undefined) throw new TypeError('value is not JSON serializable')\n return new TextEncoder().encode(serialized).byteLength\n}\nexport function modelFailureFinish(message: string, code: string): StreamChunk {\n return { type: 'finish', reason: { kind: 'error', failure: { message, code } } }\n}\nexport function modelAbortedFinish(message: string): StreamChunk {\n return { type: 'finish', reason: { kind: 'aborted', failure: { message, code: 'ABORTED' } } }\n}\nexport function codedRuntimeError(message: string, code: string, cause: unknown): Error & { code: string } {\n const error = new Error(message, { cause }) as Error & { code: string }\n error.code = code\n return error\n}\nexport function messageOf(error: unknown): string { return error instanceof Error ? error.message : String(error) }\nexport function errorCodeOf(error: unknown): string | undefined {\n return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string'\n ? error.code : undefined\n}\nexport function now(): string { return new Date().toISOString() }\n"],"mappings":"AAEA,SAAgB,EAAgB,EAAwB,CACtD,IAAM,EAAa,KAAK,UAAU,CAAK,EACvC,GAAI,IAAe,IAAA,GAAW,MAAU,UAAU,gCAAgC,EAClF,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,CAAU,CAAC,CAAC,UAC9C,CACA,SAAgB,EAAmB,EAAiB,EAA2B,CAC7E,MAAO,CAAE,KAAM,SAAU,OAAQ,CAAE,KAAM,QAAS,QAAS,CAAE,UAAS,MAAK,CAAE,CAAE,CACjF,CACA,SAAgB,EAAmB,EAA8B,CAC/D,MAAO,CAAE,KAAM,SAAU,OAAQ,CAAE,KAAM,UAAW,QAAS,CAAE,UAAS,KAAM,SAAU,CAAE,CAAE,CAC9F,CACA,SAAgB,EAAkB,EAAiB,EAAc,EAA0C,CACzG,IAAM,EAAY,MAAM,EAAS,CAAE,OAAM,CAAC,EAE1C,MADA,GAAM,KAAO,EACN,CACT,CACA,SAAgB,EAAU,EAAwB,CAAE,OAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAAE,CAClH,SAAgB,EAAY,EAAoC,CAC9D,OAAO,OAAO,GAAU,UAAY,GAAkB,SAAU,GAAS,OAAO,EAAM,MAAS,SAC3F,EAAM,KAAO,IAAA,EACnB,CACA,SAAgB,GAAc,CAAE,OAAO,IAAI,KAAK,CAAA,CAAE,YAAY,CAAE"}
@@ -0,0 +1,2 @@
1
+ const e=Object.freeze({maxSteps:16,maxToolCalls:64,toolBudgetRemindAt:Object.freeze([32,16,6]),onExhausted:`force-final-answer`,maxConsecutiveToolErrors:8,repeatToolWarningAt:3,repeatToolLimit:6,toolCycleWarningAt:2,toolCycleLimit:3,maxToolCycleLength:4,maxTotalTokens:`auto`,finalReportReserveTokens:0,maxParallel:8,maxToolResultBytes:4194304,maxToolResultTokens:1e4,toolResultOverflow:`auto`,maxToolDurationMs:6e5,toolTeardownTimeoutMs:3e4});function t(t){let n={...e,...t};if(n.maxTotalTokens!==`auto`&&(!Number.isSafeInteger(n.maxTotalTokens)||n.maxTotalTokens<1))throw RangeError(`maxTotalTokens must be a positive safe integer or 'auto'`);if(!Number.isSafeInteger(n.finalReportReserveTokens)||n.finalReportReserveTokens<0||n.maxTotalTokens!==`auto`&&n.finalReportReserveTokens>=n.maxTotalTokens)throw RangeError(`finalReportReserveTokens must be a non-negative safe integer below maxTotalTokens`);if(n.maxSteps!==`auto`&&(!Number.isSafeInteger(n.maxSteps)||n.maxSteps<1))throw RangeError(`maxSteps must be a positive safe integer or 'auto'`);for(let e of[`maxToolCalls`,`maxConsecutiveToolErrors`,`repeatToolWarningAt`,`repeatToolLimit`,`toolCycleWarningAt`,`toolCycleLimit`,`maxToolCycleLength`,`maxParallel`,`maxToolResultBytes`,`maxToolResultTokens`,`maxToolDurationMs`,`toolTeardownTimeoutMs`])if(!Number.isSafeInteger(n[e])||n[e]<1)throw RangeError(`${e} must be a positive safe integer`);if(![`auto`,`truncate`,`spill`].includes(n.toolResultOverflow))throw RangeError(`toolResultOverflow must be 'auto', 'truncate', or 'spill'`);if(![`force-final-answer`,`stop`,`continue`].includes(n.onExhausted))throw RangeError(`onExhausted must be 'force-final-answer', 'stop', or 'continue'`);if(n.repeatToolLimit<n.repeatToolWarningAt)throw RangeError(`repeatToolLimit must be >= repeatToolWarningAt`);if(n.toolCycleLimit<n.toolCycleWarningAt)throw RangeError(`toolCycleLimit must be >= toolCycleWarningAt`);if(!Array.isArray(n.toolBudgetRemindAt)||n.toolBudgetRemindAt.some(e=>!Number.isSafeInteger(e)||e<1))throw RangeError(`toolBudgetRemindAt must contain only positive safe integers`);return Object.freeze(n)}function n(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}function r(e,t){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`${t} must be a positive safe integer`);return e}function i(e){let t=Object.freeze({provider:e.config.provider,model:e.config.model,...e.config.reasoningEffort===void 0?{}:{reasoningEffort:e.config.reasoningEffort},...e.config.temperature===void 0?{}:{temperature:e.config.temperature},...e.config.topP===void 0?{}:{topP:e.config.topP},...e.config.maxTokens===void 0?{}:{maxTokens:e.config.maxTokens},...e.config.stop===void 0?{}:{stop:Object.freeze([...e.config.stop])}});return Object.freeze({...e,config:t,...e.bounds===void 0?{}:{bounds:Object.freeze({...e.bounds})},...e.nativeTools===void 0?{}:{nativeTools:Object.freeze([...e.nativeTools])},...e.interceptors===void 0?{}:{interceptors:Object.freeze([...e.interceptors])},...e.hooks===void 0?{}:{hooks:Object.freeze({...e.hooks})},...e.trace===void 0?{}:{trace:Object.freeze({...e.trace})}})}export{e as DEFAULT_BOUNDS,n as positiveFinite,r as positiveSafeInteger,t as resolveBounds,i as snapshotRunTurnOptions};
2
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../../src/agent/loop/turn/config.ts"],"sourcesContent":["import type { TurnBounds } from '../types.ts'\nimport { type RunTurnOptions } from './types.ts'\n\nexport const DEFAULT_BOUNDS: TurnBounds = Object.freeze({\n maxSteps: 16,\n maxToolCalls: 64,\n // Halfway, a quarter left, and nearly gone. Three notices, spaced so the\n // first is still early enough to change the plan and the last is impossible\n // to ignore.\n toolBudgetRemindAt: Object.freeze([32, 16, 6]),\n onExhausted: 'force-final-answer',\n maxConsecutiveToolErrors: 8,\n repeatToolWarningAt: 3,\n repeatToolLimit: 6,\n toolCycleWarningAt: 2,\n toolCycleLimit: 3,\n maxToolCycleLength: 4,\n maxTotalTokens: 'auto',\n finalReportReserveTokens: 0,\n maxParallel: 8,\n maxToolResultBytes: 4 * 1024 * 1024,\n // Codex's own default for a shell call. Large enough for a real build log,\n // small enough that a handful of them cannot spend a context window.\n maxToolResultTokens: 10_000,\n toolResultOverflow: 'auto',\n maxToolDurationMs: 10 * 60_000,\n toolTeardownTimeoutMs: 30_000,\n})\nexport function resolveBounds(input: Partial<TurnBounds> | undefined): TurnBounds {\n const bounds = { ...DEFAULT_BOUNDS, ...input }\n if (bounds.maxTotalTokens !== 'auto' && (!Number.isSafeInteger(bounds.maxTotalTokens) || bounds.maxTotalTokens < 1)) {\n throw new RangeError(\"maxTotalTokens must be a positive safe integer or 'auto'\")\n }\n if (!Number.isSafeInteger(bounds.finalReportReserveTokens) || bounds.finalReportReserveTokens < 0\n || (bounds.maxTotalTokens !== 'auto' && bounds.finalReportReserveTokens >= bounds.maxTotalTokens)) {\n throw new RangeError('finalReportReserveTokens must be a non-negative safe integer below maxTotalTokens')\n }\n if (bounds.maxSteps !== 'auto' && (!Number.isSafeInteger(bounds.maxSteps) || bounds.maxSteps < 1)) {\n throw new RangeError(\"maxSteps must be a positive safe integer or 'auto'\")\n }\n for (const key of [\n 'maxToolCalls', 'maxConsecutiveToolErrors', 'repeatToolWarningAt',\n 'repeatToolLimit', 'toolCycleWarningAt', 'toolCycleLimit', 'maxToolCycleLength',\n 'maxParallel', 'maxToolResultBytes', 'maxToolResultTokens',\n 'maxToolDurationMs',\n 'toolTeardownTimeoutMs',\n ] as const) {\n if (!Number.isSafeInteger(bounds[key]) || bounds[key] < 1) throw new RangeError(`${key} must be a positive safe integer`)\n }\n if (!['auto', 'truncate', 'spill'].includes(bounds.toolResultOverflow)) {\n throw new RangeError(\"toolResultOverflow must be 'auto', 'truncate', or 'spill'\")\n }\n if (!['force-final-answer', 'stop', 'continue'].includes(bounds.onExhausted)) {\n throw new RangeError(\"onExhausted must be 'force-final-answer', 'stop', or 'continue'\")\n }\n if (bounds.repeatToolLimit < bounds.repeatToolWarningAt) throw new RangeError('repeatToolLimit must be >= repeatToolWarningAt')\n if (bounds.toolCycleLimit < bounds.toolCycleWarningAt) {\n throw new RangeError('toolCycleLimit must be >= toolCycleWarningAt')\n }\n if (!Array.isArray(bounds.toolBudgetRemindAt)\n || bounds.toolBudgetRemindAt.some(value => !Number.isSafeInteger(value) || value < 1)) {\n // Out-of-range thresholds are dropped rather than rejected, but a\n // fractional or negative one is a mistake worth naming: silently ignoring\n // `0.25` would leave a host believing it had asked for a reminder.\n throw new RangeError('toolBudgetRemindAt must contain only positive safe integers')\n }\n return Object.freeze(bounds)\n}\nexport function positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number`)\n return value\n}\nexport function positiveSafeInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${name} must be a positive safe integer`)\n return value\n}\nexport function snapshotRunTurnOptions(options: RunTurnOptions): RunTurnOptions {\n const config = Object.freeze({\n provider: options.config.provider,\n model: options.config.model,\n ...(options.config.reasoningEffort === undefined ? {} : { reasoningEffort: options.config.reasoningEffort }),\n ...(options.config.temperature === undefined ? {} : { temperature: options.config.temperature }),\n ...(options.config.topP === undefined ? {} : { topP: options.config.topP }),\n ...(options.config.maxTokens === undefined ? {} : { maxTokens: options.config.maxTokens }),\n ...(options.config.stop === undefined ? {} : { stop: Object.freeze([...options.config.stop]) }),\n })\n return Object.freeze({\n ...options,\n config,\n ...(options.bounds === undefined ? {} : { bounds: Object.freeze({ ...options.bounds }) }),\n ...(options.nativeTools === undefined ? {} : { nativeTools: Object.freeze([...options.nativeTools]) }),\n ...(options.interceptors === undefined ? {} : { interceptors: Object.freeze([...options.interceptors]) }),\n ...(options.hooks === undefined ? {} : { hooks: Object.freeze({ ...options.hooks }) }),\n ...(options.trace === undefined ? {} : { trace: Object.freeze({ ...options.trace }) }),\n })\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import{createSpanId as e}from"../../../observation/context.js";import{createMessage as t}from"../../../message/message.js";import{now as n}from"./common.js";function r(t,r){let i=new Map;return async a=>{if(a.type===`compaction-start`){let o={traceId:r.traceId,spanId:e(),parentSpanId:r.spanId};i.set(a.compactionId,o),await t({type:`span-start`,trace:o,at:n(),name:`compact ${a.trigger}`,kind:`compact`,attributes:{"gen_ai.operation.name":`compact`,"gen_ai.compaction.id":a.compactionId,"gen_ai.compaction.trigger":a.trigger,"gen_ai.input.tokens.estimated":a.estimatedInputTokens}}),await t({...a,trace:o});return}let o=i.get(a.compactionId)??r;await t({...a,trace:o}),await t({type:`span-end`,trace:o,at:n(),status:a.status===`completed`?`success`:`error`,output:{shadowedSeqs:a.shadowedSeqs,estimatedTokensBefore:a.estimatedTokensBefore,estimatedTokensAfter:a.estimatedTokensAfter,...a.thresholdTokens===void 0?{}:{thresholdTokens:a.thresholdTokens},...a.estimatedNonCompactableTokens===void 0?{}:{estimatedNonCompactableTokens:a.estimatedNonCompactableTokens},...a.backoffReason===void 0?{}:{backoffReason:a.backoffReason}},...a.usage===void 0?{}:{usage:a.usage},...a.error===void 0?{}:{error:{type:`CompactionError`,message:a.error}}}),i.delete(a.compactionId)}}async function i(e,t){let n=e.message;if(n===void 0)return;let r=Object.freeze(e.calls.map(e=>e.callId));for(let i of n.content)i.type===`text`&&i.text.length>0?await t({type:`assistant-text`,trace:e.trace,messageId:n.id,text:i.text,phase:i.phase??(e.calls.length>0?`commentary`:`final-answer`),timing:e.timing,toolCallIds:r,afterToolCallIds:e.afterToolCallIds}):i.type===`reasoning`&&i.text.length>0?await t({type:`assistant-reasoning`,trace:e.trace,messageId:n.id,text:i.text,timing:e.timing,toolCallIds:r,afterToolCallIds:e.afterToolCallIds}):i.type===`native-tool-call`&&await t({type:`assistant-native-tool`,trace:e.trace,messageId:n.id,call:i})}function a(e,t=!1,n=e.some(e=>e.type===`tool-call`)){let r=e.findLastIndex(e=>e.type===`native-tool-call`);return e.map((e,i)=>{if(e.type!==`text`)return e;if(t)return{...e,phase:`commentary`};if(e.phase!==void 0)return e;let a=t||n||r>=0&&i<r?`commentary`:`final-answer`;return{...e,phase:a}})}function o(e,t){for(let t of e)if(t.type===`tool-call`&&(typeof t.id!=`string`||t.id.trim().length===0||typeof t.name!=`string`||t.name.trim().length===0||typeof t.arguments!=`string`))return{message:`provider emitted a host tool call with invalid identity, name, or arguments`,code:`INVALID_TOOL_CALL`}}function s(e,t){let n=new Set;for(let e of t.entries())if(e.event.kind===`assistant`)for(let t of e.event.message.content)t.type===`tool-call`&&n.add(t.id);let r=[],i=e.filter(e=>e.type!==`tool-call`||typeof e.id!=`string`?!0:n.has(e.id)?(r.push(e.id),!1):(n.add(e.id),!0));return r.length===0?{blocks:e,dropped:r}:{blocks:i,dropped:r}}function c(e,t){return e&&t?`between-tools`:e?`before-tools`:t?`after-tools`:`standalone`}function l(e){let t=[],n=e.entries();for(let e=n.length-1;e>=0;e--){let r=n[e]?.event;if(r!==void 0){if(r.kind===`assistant`||r.kind===`user`&&r.message.source.kind===`user`)break;r.kind===`tool-result`&&t.unshift(r.callId)}}return Object.freeze(t)}function u(e,t){let n=[e.system];return e.commentary===`concise`?n.push(`Before calling tools, give a brief user-visible progress update about what you are about to do. After tool results, briefly summarize what changed before another action. Do not reveal private chain-of-thought; communicate only intent and observed outcomes.`):e.commentary===`off`&&n.push(`Do not emit progress commentary around tool calls; call tools directly and provide only the final answer.`),t&&n.push(`Tool use is now disabled. Write the final report from the information already gathered: findings or changes, supporting evidence and verification, and what remains unknown or unfinished. Reconcile any task list in the report without claiming unfinished items are done. Do not call a submission or planning tool; this report is the final response.`),n.filter(e=>e!==void 0&&e.length>0).join(`
2
+
3
+ `)}function d(e,n,r){let i={kind:`model`,provider:e.config.provider,model:e.config.model,...r===void 0?{}:{replayState:r}};return t({role:`assistant`,content:n,source:i})}function f(e){let t=e.filter(e=>e.type===`text`),n=t.filter(e=>e.phase===`final-answer`);return n.length>0?n.map(e=>e.text).join(``):t.filter(e=>e.phase!==`commentary`).map(e=>e.text).join(``)}export{a as classifyTextPhases,c as contentTiming,d as createAssistant,s as dropDuplicateToolCalls,i as emitAssistantContent,o as invalidHostToolCall,r as maintenanceEmitter,l as recentToolResultIds,u as systemText,f as textOf};
4
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","names":[],"sources":["../../../../src/agent/loop/turn/content.ts"],"sourcesContent":["import type { ModelFailure } from '../../../errors/index.ts'\nimport type { ContentBlock } from '../../../message/index.ts'\nimport { createMessage, type Message } from '../../../message/index.ts'\nimport type { ToolCallId } from '../../../primitives/index.ts'\nimport { History } from '../../history/history.ts'\nimport { createSpanId, type TraceRef } from '../../trace/trace.ts'\nimport type { AgentEvent, AgentMaintenanceEvent, AssistantContentTiming } from '../types.ts'\nimport { type RunTurnOptions, type RoundResult } from './types.ts'\nimport { now } from './common.ts'\n\nexport function maintenanceEmitter(\n emit: (event: AgentEvent) => Promise<void>,\n root: TraceRef,\n): (event: AgentMaintenanceEvent) => Promise<void> {\n const spans = new Map<string, TraceRef>()\n return async event => {\n if (event.type === 'compaction-start') {\n const trace: TraceRef = {\n traceId: root.traceId, spanId: createSpanId(), parentSpanId: root.spanId,\n }\n spans.set(event.compactionId, trace)\n await emit({\n type: 'span-start', trace, at: now(),\n name: `compact ${event.trigger}`, kind: 'compact',\n attributes: {\n 'gen_ai.operation.name': 'compact',\n 'gen_ai.compaction.id': event.compactionId,\n 'gen_ai.compaction.trigger': event.trigger,\n 'gen_ai.input.tokens.estimated': event.estimatedInputTokens,\n },\n })\n await emit({ ...event, trace })\n return\n }\n const trace = spans.get(event.compactionId) ?? root\n await emit({ ...event, trace })\n await emit({\n type: 'span-end', trace, at: now(), status: event.status === 'completed' ? 'success' : 'error',\n output: {\n shadowedSeqs: event.shadowedSeqs,\n estimatedTokensBefore: event.estimatedTokensBefore,\n estimatedTokensAfter: event.estimatedTokensAfter,\n ...(event.thresholdTokens === undefined ? {} : { thresholdTokens: event.thresholdTokens }),\n ...(event.estimatedNonCompactableTokens === undefined\n ? {} : { estimatedNonCompactableTokens: event.estimatedNonCompactableTokens }),\n ...(event.backoffReason === undefined ? {} : { backoffReason: event.backoffReason }),\n },\n ...(event.usage === undefined ? {} : { usage: event.usage }),\n ...(event.error === undefined ? {} : {\n error: { type: 'CompactionError', message: event.error },\n }),\n })\n spans.delete(event.compactionId)\n }\n}\n\nexport async function emitAssistantContent(\n round: RoundResult,\n emit: (event: AgentEvent) => Promise<void>,\n): Promise<void> {\n const message = round.message\n if (message === undefined) return\n const toolCallIds = Object.freeze(round.calls.map(call => call.callId))\n for (const block of message.content) {\n if (block.type === 'text' && block.text.length > 0) {\n await emit({\n type: 'assistant-text', trace: round.trace, messageId: message.id, text: block.text,\n phase: block.phase ?? (round.calls.length > 0 ? 'commentary' : 'final-answer'),\n timing: round.timing, toolCallIds, afterToolCallIds: round.afterToolCallIds,\n })\n } else if (block.type === 'reasoning' && block.text.length > 0) {\n await emit({\n type: 'assistant-reasoning', trace: round.trace, messageId: message.id, text: block.text,\n timing: round.timing, toolCallIds, afterToolCallIds: round.afterToolCallIds,\n })\n } else if (block.type === 'native-tool-call') {\n await emit({ type: 'assistant-native-tool', trace: round.trace, messageId: message.id, call: block })\n }\n }\n}\n\nexport function classifyTextPhases(\n blocks: readonly ContentBlock[],\n processOnly = false,\n hasHostCalls = blocks.some(block => block.type === 'tool-call'),\n): ContentBlock[] {\n const lastNative = blocks.findLastIndex(block => block.type === 'native-tool-call')\n return blocks.map((block, index) => {\n if (block.type !== 'text') return block\n // The host's dedicated process phase is authoritative even when the\n // provider calls this individual generation a final answer.\n if (processOnly) return { ...block, phase: 'commentary' as const }\n if (block.phase !== undefined) return block\n const phase = processOnly || hasHostCalls || (lastNative >= 0 && index < lastNative)\n ? 'commentary' as const\n : 'final-answer' as const\n return { ...block, phase }\n })\n}\n\nexport function invalidHostToolCall(\n blocks: readonly ContentBlock[],\n _history: History,\n): ModelFailure | undefined {\n for (const block of blocks) {\n if (block.type !== 'tool-call') continue\n if (typeof block.id !== 'string' || block.id.trim().length === 0\n || typeof block.name !== 'string' || block.name.trim().length === 0\n || typeof block.arguments !== 'string') {\n return {\n message: 'provider emitted a host tool call with invalid identity, name, or arguments',\n code: 'INVALID_TOOL_CALL',\n }\n }\n }\n return undefined\n}\n\n/**\n * Drop a repeated tool-call id instead of failing the round over it.\n *\n * Results are paired to calls by id, so two calls sharing one id cannot both be\n * answered — but the FIRST of them is perfectly good work, and killing the turn\n * throws it away along with everything the model had done to get there. Codex\n * treats a duplicate as something to reconcile rather than to abort on. The\n * repeat is removed, the original stands, and the model is told which id it\n * reused so its next round does not repeat the mistake.\n * @param blocks - The assistant content as the provider sent it.\n * @param history - The turn so far; ids already used are duplicates too.\n * @returns The content to keep, and the ids that were dropped.\n */\nexport function dropDuplicateToolCalls(\n blocks: readonly ContentBlock[],\n history: History,\n): { readonly blocks: readonly ContentBlock[]; readonly dropped: readonly string[] } {\n const seen = new Set<string>()\n for (const entry of history.entries()) {\n if (entry.event.kind !== 'assistant') continue\n for (const block of entry.event.message.content) {\n if (block.type === 'tool-call') seen.add(block.id)\n }\n }\n const dropped: string[] = []\n const kept = blocks.filter((block) => {\n if (block.type !== 'tool-call' || typeof block.id !== 'string') return true\n if (seen.has(block.id)) {\n dropped.push(block.id)\n return false\n }\n seen.add(block.id)\n return true\n })\n return dropped.length === 0 ? { blocks, dropped } : { blocks: kept, dropped }\n}\n\nexport function contentTiming(hasToolCalls: boolean, followsToolResults: boolean): AssistantContentTiming {\n if (hasToolCalls && followsToolResults) return 'between-tools'\n if (hasToolCalls) return 'before-tools'\n if (followsToolResults) return 'after-tools'\n return 'standalone'\n}\n\nexport function recentToolResultIds(history: History): readonly ToolCallId[] {\n const ids: ToolCallId[] = []\n const entries = history.entries()\n for (let index = entries.length - 1; index >= 0; index--) {\n const event = entries[index]?.event\n if (event === undefined) continue\n if (event.kind === 'assistant' || (event.kind === 'user' && event.message.source.kind === 'user')) break\n if (event.kind === 'tool-result') ids.unshift(event.callId)\n }\n return Object.freeze(ids)\n}\n\nexport function systemText(options: RunTurnOptions, forcedFinal: boolean): string {\n const parts = [options.system]\n if (options.commentary === 'concise') {\n parts.push(\n 'Before calling tools, give a brief user-visible progress update about what you are about to do. After tool results, briefly summarize what changed before another action. Do not reveal private chain-of-thought; communicate only intent and observed outcomes.',\n )\n } else if (options.commentary === 'off') {\n parts.push('Do not emit progress commentary around tool calls; call tools directly and provide only the final answer.')\n }\n if (forcedFinal) parts.push(\n 'Tool use is now disabled. Write the final report from the information already gathered: findings or changes, supporting evidence and verification, and what remains unknown or unfinished. Reconcile any task list in the report without claiming unfinished items are done. Do not call a submission or planning tool; this report is the final response.',\n )\n return parts.filter((part): part is string => part !== undefined && part.length > 0).join('\\n\\n')\n}\n\nexport function createAssistant(options: RunTurnOptions, content: readonly ContentBlock[], replayState: unknown): Message {\n const source = {\n kind: 'model' as const, provider: options.config.provider, model: options.config.model,\n ...replayState === undefined ? {} : { replayState },\n }\n return createMessage({ role: 'assistant', content, source })\n}\n\nexport function textOf(blocks: readonly ContentBlock[]): string {\n const text = blocks.filter((block): block is Extract<ContentBlock, { type: 'text' }> => block.type === 'text')\n const final = text.filter(block => block.phase === 'final-answer')\n if (final.length > 0) return final.map(block => block.text).join('')\n return text.filter(block => block.phase !== 'commentary').map(block => block.text).join('')\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{waitForSettlement as e}from"../../../async/settlement.js";import{positiveSafeInteger as t}from"./config.js";import{codedRuntimeError as n}from"./common.js";import{nextValueWithAbort as r}from"./cancellation.js";async function i(e,t,n,r,i){if(e!==void 0)return await a(Promise.resolve().then(()=>e(...t)),n,r,i)}async function a(i,a,o,s){let c=a.accounting?.startOperation(`hook`,{data:{name:s}}),l=t(a.hookTimeoutMs??6e5,`hookTimeoutMs`),u=t(a.hookTeardownTimeoutMs??3e4,`hookTeardownTimeoutMs`),d=AbortSignal.timeout(l),f=AbortSignal.any([o,d]);try{let e=await r(i,f);return c!==void 0&&a.accounting?.endOperation(c,`success`),e}catch(t){if(!f.aborted)throw c!==void 0&&a.accounting?.endOperation(c,`error`,{error:t}),t;if(!await e(i,u)){let e=n(`turn hook '${s}' ignored cancellation for more than ${u}ms`,`HOOK_TEARDOWN_TIMEOUT`,t);throw c!==void 0&&a.accounting?.endOperation(c,`error`,{error:e}),e}if(d.aborted&&!o.aborted){let e=n(`turn hook '${s}' exceeded ${l}ms`,`HOOK_TIMEOUT`,t);throw c!==void 0&&a.accounting?.endOperation(c,`error`,{error:e}),e}throw c!==void 0&&a.accounting?.endOperation(c,`aborted`,{error:t}),t}}export{a as runHook,i as runOptionalHook};
2
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","names":[],"sources":["../../../../src/agent/loop/turn/hooks.ts"],"sourcesContent":["import { waitForSettlement } from '../../../async/index.ts'\nimport { type RunTurnOptions } from './types.ts'\nimport { positiveSafeInteger } from './config.ts'\nimport { codedRuntimeError } from './common.ts'\nimport { nextValueWithAbort } from './cancellation.ts'\n\nexport async function runOptionalHook<TArgs extends readonly unknown[], TResult>(\n hook: ((...args: TArgs) => TResult | Promise<TResult>) | undefined,\n args: TArgs,\n options: RunTurnOptions,\n signal: AbortSignal,\n name: string,\n): Promise<Awaited<TResult> | undefined> {\n if (hook === undefined) return undefined\n const pending = Promise.resolve().then(() => hook(...args))\n return await runHook(pending, options, signal, name)\n}\nexport async function runHook<T>(\n pending: Promise<T>,\n options: RunTurnOptions,\n signal: AbortSignal,\n name: string,\n): Promise<T> {\n const operation = options.accounting?.startOperation('hook', { data: { name } })\n const timeoutMs = positiveSafeInteger(options.hookTimeoutMs ?? 10 * 60_000, 'hookTimeoutMs')\n const teardownTimeoutMs = positiveSafeInteger(\n options.hookTeardownTimeoutMs ?? 30_000,\n 'hookTeardownTimeoutMs',\n )\n const deadline = AbortSignal.timeout(timeoutMs)\n const combined = AbortSignal.any([signal, deadline])\n try {\n const value = await nextValueWithAbort(pending, combined)\n if (operation !== undefined) options.accounting?.endOperation(operation, 'success')\n return value\n } catch (error: unknown) {\n if (!combined.aborted) {\n if (operation !== undefined) options.accounting?.endOperation(operation, 'error', { error })\n throw error\n }\n const settled = await waitForSettlement(pending, teardownTimeoutMs)\n if (!settled) {\n const runtimeError = codedRuntimeError(\n `turn hook '${name}' ignored cancellation for more than ${teardownTimeoutMs}ms`,\n 'HOOK_TEARDOWN_TIMEOUT',\n error,\n )\n if (operation !== undefined) options.accounting?.endOperation(operation, 'error', { error: runtimeError })\n throw runtimeError\n }\n if (deadline.aborted && !signal.aborted) {\n const runtimeError = codedRuntimeError(`turn hook '${name}' exceeded ${timeoutMs}ms`, 'HOOK_TIMEOUT', error)\n if (operation !== undefined) options.accounting?.endOperation(operation, 'error', { error: runtimeError })\n throw runtimeError\n }\n if (operation !== undefined) options.accounting?.endOperation(operation, 'aborted', { error })\n throw error\n }\n}\n"],"mappings":"0NAMA,eAAsB,EACpB,EACA,EACA,EACA,EACA,EACuC,CACnC,OAAS,IAAA,GAEb,OAAO,MAAM,EADG,QAAQ,QAAQ,CAAC,CAAC,SAAW,EAAK,GAAG,CAAI,CAC9B,EAAG,EAAS,EAAQ,CAAI,CACrD,CACA,eAAsB,EACpB,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAY,EAAQ,YAAY,eAAe,OAAQ,CAAE,KAAM,CAAE,MAAK,CAAE,CAAC,EACzE,EAAY,EAAoB,EAAQ,eAAiB,IAAa,eAAe,EACrF,EAAoB,EACxB,EAAQ,uBAAyB,IACjC,uBACF,EACM,EAAW,YAAY,QAAQ,CAAS,EACxC,EAAW,YAAY,IAAI,CAAC,EAAQ,CAAQ,CAAC,EACnD,GAAI,CACF,IAAM,EAAQ,MAAM,EAAmB,EAAS,CAAQ,EAExD,OADI,IAAc,IAAA,IAAW,EAAQ,YAAY,aAAa,EAAW,SAAS,EAC3E,CACT,OAAS,EAAgB,CACvB,GAAI,CAAC,EAAS,QAEZ,MADI,IAAc,IAAA,IAAW,EAAQ,YAAY,aAAa,EAAW,QAAS,CAAE,OAAM,CAAC,EACrF,EAGR,GAAI,CAAC,MADiB,EAAkB,EAAS,CAAiB,EACpD,CACZ,IAAM,EAAe,EACnB,cAAc,EAAK,uCAAuC,EAAkB,IAC5E,wBACA,CACF,EAEA,MADI,IAAc,IAAA,IAAW,EAAQ,YAAY,aAAa,EAAW,QAAS,CAAE,MAAO,CAAa,CAAC,EACnG,CACR,CACA,GAAI,EAAS,SAAW,CAAC,EAAO,QAAS,CACvC,IAAM,EAAe,EAAkB,cAAc,EAAK,aAAa,EAAU,IAAK,eAAgB,CAAK,EAE3G,MADI,IAAc,IAAA,IAAW,EAAQ,YAAY,aAAa,EAAW,QAAS,CAAE,MAAO,CAAa,CAAC,EACnG,CACR,CAEA,MADI,IAAc,IAAA,IAAW,EAAQ,YAAY,aAAa,EAAW,UAAW,CAAE,OAAM,CAAC,EACvF,CACR,CACF"}
@@ -0,0 +1,2 @@
1
+ import{createSpanId as e}from"../../../observation/context.js";import{MODEL_ERROR_CODES as t}from"../../../errors/model-error.js";import{BlockAssembler as n}from"../../../stream/assembler.js";import{normalizeToolPairing as r}from"../../history/normalize.js";import{positiveFinite as i,positiveSafeInteger as a}from"./config.js";import{messageOf as o,modelAbortedFinish as ee,modelFailureFinish as s,now as c,serializedBytes as te}from"./common.js";import{StreamAbortError as ne,closeIterator as re,nextWithAbort as ie}from"./cancellation.js";import{runOptionalHook as l}from"./hooks.js";import{classifyTextPhases as u,contentTiming as d,createAssistant as f,dropDuplicateToolCalls as p,invalidHostToolCall as ae,recentToolResultIds as oe,systemText as se,textOf as m}from"./content.js";import{validateStreamChunk as ce}from"./validation.js";import{accountingUsageStop as le}from"./usage-stop.js";function h(e){let t=e.replace(/\s+/gu,` `).trim();return t.length>600?`${t.slice(0,600)}…`:t}function g(e){let t=[],n=[];for(let r of e.content)r.type===`text`||r.type===`reasoning`?t.push(r.text):r.type===`tool-call`?n.push(`${r.name}(${h(r.arguments)})`):r.type===`tool-result`?t.push(m(r.content)):t.push(`[${r.type}]`);return{role:e.role,producer:e.source.kind,...t.length===0?{}:{text:h(t.join(` `))},...n.length===0?{}:{toolCalls:n}}}function ue(e){let t=e.messages??[],n=Math.max(0,t.length-8);return{messageCount:t.length,...t.at(-1)===void 0?{}:{lastMessageId:t.at(-1)?.id},...e.system===void 0?{}:{system:h(e.system)},...e.tools===void 0||e.tools.length===0?{}:{tools:e.tools.map(e=>e.name)},...e.toolChoice===void 0?{}:{toolChoice:e.toolChoice},...n===0?{}:{earlierMessagesOmitted:n},messages:t.slice(-8).map(g)}}async function _(h,g,_,fe,v,y,b,x){let S=x===`forced-final`,C=x===`final`||S,w={traceId:v.traceId,spanId:e(),parentSpanId:v.spanId},T=r(h.history.messages()),E=oe(h.history),pe=h.history.generation(),me=h.history.entries().length,D=()=>{let e=le(h.accounting);if(!(e===void 0&&!g.aborted))return{trace:w,finish:g.aborted?{kind:`aborted`,failure:{code:`ABORTED`,message:o(g.reason)}}:{kind:`stop`},calls:[],afterToolCallIds:E,timing:d(!1,E.length>0),...e?.kind===`error`?{usageRequired:!0}:{},...e?.kind===`usage-unavailable`?{usageUnavailable:!0}:{}}},he=D();if(he!==void 0)return he;let O=await l(h.hooks?.beforeStep,[{turn:y,step:b,messages:T,snapshot:h.history.snapshot(),signal:g,...h.logger===void 0?{}:{logger:h.logger},emit:fe}],h,g,`beforeStep`),ge=D();if(ge!==void 0)return ge;if(O?.kind===`reject`)return{trace:w,finish:{kind:`error`,failure:{message:O.reason,code:`STEP_REJECTED`}},calls:[],afterToolCallIds:E,timing:d(!1,E.length>0)};(h.history.generation()!==pe||h.history.entries().length!==me)&&(T=r(h.history.messages())),O?.prepend!==void 0&&(T=Object.freeze([...O.prepend,...T]));let k=se(h,S),A=[...h.tools?.schemas()??[],...h.nativeTools??[]],j=!C&&h.outputFormat?.type===`json_schema`?{type:`text`}:h.outputFormat,M={...h.config,messages:T,...k.length===0?{}:{system:k},...A.length===0?{}:{tools:A},...C&&A.length>0?{toolChoice:`none`}:h.toolChoice===void 0?{}:{toolChoice:h.toolChoice},...h.imagePolicy===void 0?{}:{imagePolicy:h.imagePolicy},...j===void 0?{}:{outputFormat:j}},_e={...M,signal:g};try{await l(h.hooks?.checkpoint,[{kind:`before-model-request`,request:_e,snapshot:h.history.snapshot(),signal:g,...h.logger===void 0?{}:{logger:h.logger}}],h,g,`checkpoint`)}catch(e){return{trace:w,finish:{kind:`error`,failure:{message:`history checkpoint failed: ${o(e)}`,code:`CHECKPOINT_FAILED`}},calls:[],afterToolCallIds:E,timing:d(!1,E.length>0)}}let N=D();if(N!==void 0)return N;await _({type:`span-start`,trace:w,at:c(),name:`chat ${h.config.model}`,kind:`chat`,attributes:{"gen_ai.operation.name":`chat`,"gen_ai.request.model":h.config.model,...h.config.reasoningEffort===void 0?{}:{"gen_ai.request.reasoning_effort":h.config.reasoningEffort},turn:y,step:b,forcedFinal:S,phase:x},input:ue(M)}),await _({type:`step-start`,turn:y,step:b,trace:w,...S?{forcedFinal:!0}:{}});let P=new n,F=new Set,I=i(h.modelTimeoutMs??6e5,`modelTimeoutMs`),L=a(h.maxModelRequestBytes??33554432,`maxModelRequestBytes`),R=a(h.maxModelResponseBytes??33554432,`maxModelResponseBytes`),z=a(h.maxModelStreamEvents??1e5,`maxModelStreamEvents`),B=i(h.teardownTimeoutMs??3e4,`teardownTimeoutMs`),V,ve=!1,ye=!1,H;try{H=te(M)}catch(e){H=-1,P.push(s(`model request is not serializable: ${o(e)}`,`INVALID_MODEL_REQUEST`))}if(H>L)P.push(s(`model request exceeds the ${L}-byte limit`,`MODEL_REQUEST_TOO_LARGE`));else if(H>=0){let e=new AbortController,t=AbortSignal.any([g,e.signal]),n=!1,r=setTimeout(()=>{n=!0,e.abort(Error(`model stream exceeded ${I}ms`))},I),i=h.registry.stream({...M,signal:t},h.accounting?.modelInvocation),a=i[Symbol.asyncIterator](),c=!1,l=0,u=0,d=!1;try{for(;;){let n=await ie(a.next(),t);if(n.done===!0){c=!0;break}let r=n.value;try{ce(r,z)}catch(t){P.push(s(`model adapter emitted an invalid stream chunk: ${o(t)}`,`INVALID_MODEL_STREAM`)),e.abort(Error(`invalid model stream chunk`));break}l++;try{u+=te(r)}catch(t){P.push(s(`model adapter emitted a non-serializable stream chunk: ${o(t)}`,`INVALID_MODEL_STREAM`)),e.abort(Error(`non-serializable model stream chunk`));break}if(l>z||u>R){let t=l>z?`${z}-event`:`${R}-byte`;P.push(s(`model response exceeds the ${t} limit`,`MODEL_RESPONSE_TOO_LARGE`)),e.abort(Error(`model response resource limit exceeded`));break}if(d){P.push(s(`model adapter emitted data after its terminal finish chunk`,`INVALID_MODEL_STREAM`)),e.abort(Error(`invalid model stream`));break}P.push(r),!((r.type===`text-delta`||r.type===`reasoning-delta`||r.type===`tool-call-delta`)&&F.has(r.index))&&(r.type===`block-end`&&F.add(r.index),r.type===`finish`&&(d=!0),r.type===`text-delta`?await _({type:`text-delta`,index:r.index,text:r.text,phase:x===`process`?`commentary`:r.phase??`unknown`,trace:w}):r.type===`reasoning-delta`?await _({type:`reasoning-delta`,index:r.index,text:r.text,trace:w}):r.type===`image-delta`?await _({type:`image-delta`,itemId:r.itemId,data:r.data,mediaType:r.mediaType,...r.partialIndex===void 0?{}:{partialIndex:r.partialIndex},trace:w}):r.type===`usage`&&await _({type:`usage`,usage:r.usage,trace:w}))}}catch(e){if(!(e instanceof ne))throw e;P.push(g.aborted?ee(o(g.reason??e)):n?s(`model stream exceeded ${I}ms`,`MODEL_TIMEOUT`):s(o(e.cause??e),`MODEL_STREAM_ABORTED`))}finally{clearTimeout(r),c||(e.abort(Error(`model stream closed before exhaustion`)),await re(a,B)||P.push(s(`model stream ignored cancellation for more than ${B}ms; the adapter operation may still be running`,`MODEL_TEARDOWN_TIMEOUT`)))}let f=await i.report,p=h.accounting===void 0?void 0:await h.accounting.recordModelCall(f,{...M,signal:g});V=p?.report??f,ve=p?.usageRequired??!1,ye=p?.usageUnavailable??!1}let U=P.finish,W=U.kind===`aborted`,G;try{G=U.kind===`aborted`?P.interruptedBlocks():P.blocks()}catch(e){U={kind:`error`,failure:{message:`model adapter emitted an invalid block sequence: ${o(e)}`,code:`INVALID_MODEL_STREAM`}},W=!0,G=P.interruptedBlocks()}let K=P.textBlocks().filter(({block:e})=>!W||e.text.trim()!==``),be=0,xe=u(G.map(e=>{if(e.type!==`text`)return e;let t=K[be++];return e.phase===void 0&&t?.beforeNativeCall?{...e,phase:`commentary`}:e}),x===`process`,P.hasToolCalls),q=p(xe,h.history),J=q.blocks,Se=C&&h.outputFormat?.type===`json_schema`&&U.kind===`stop`&&!de(m(J),h.validateOutput)?{message:`model returned invalid JSON or failed the structured output validator`,code:t.MALFORMED_RESPONSE}:void 0,Y=(C&&J.some(e=>e.type===`tool-call`)?{message:`model emitted a host tool call during the final output phase`,code:`INVALID_TOOL_CALL`}:void 0)??Se??ae(J,h.history),X=Y===void 0?J:J.filter(e=>e.type!==`tool-call`),Z=Y===void 0?U:{kind:`error`,failure:Y},Q=X.length===0&&(Z.kind===`error`||Z.kind===`aborted`)?void 0:f(h,X,W?void 0:P.replayState),$=Q?.content.filter(e=>e.type===`tool-call`).map(e=>({callId:e.id,toolName:e.name,rawArguments:e.arguments}))??[],Ce=d($.length>0,E.length>0);if(X.some(e=>e.type===`text`)){let e=K.map(({index:e})=>e),t=Z.kind===`error`||Z.kind===`aborted`||Z.kind===`max-tokens`,n=0;for(let r of X){if(r.type!==`text`)continue;let i=e[n++];i!==void 0&&await _({type:`text-end`,index:i,text:r.text,phase:r.phase??`final-answer`,trace:w,...t?{incomplete:!0}:{}})}}return await _({type:`span-end`,trace:w,at:c(),status:Z.kind===`error`?`error`:Z.kind===`aborted`?`aborted`:`success`,output:Q===void 0?void 0:{text:m(Q.content),commentary:Q.content.flatMap(e=>e.type===`text`&&e.phase===`commentary`?[e.text]:[]),reasoning:Q.content.flatMap(e=>e.type===`reasoning`?[e.text]:[]),toolCalls:$.length},...P.usage===void 0?{}:{usage:P.usage},...Z.kind===`error`||Z.kind===`aborted`?{error:{type:`ModelError`,message:Z.failure.message,code:Z.failure.code}}:{}}),($.length===0||C)&&await _({type:`step-end`,turn:y,step:b,trace:w}),{trace:w,...Q===void 0?{}:{message:Q},finish:Z,...P.usage===void 0?{}:{usage:P.usage},...V===void 0?{}:{report:V},...ve?{usageRequired:!0}:{},...ye?{usageUnavailable:!0}:{},calls:$,afterToolCallIds:E,timing:Ce,...q.dropped.length===0?{}:{droppedDuplicateCalls:q.dropped}}}function de(e,t){try{let n=JSON.parse(e);return t?.(n),!0}catch{return!1}}export{_ as modelRound};
2
+ //# sourceMappingURL=model-round.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-round.js","names":[],"sources":["../../../../src/agent/loop/turn/model-round.ts"],"sourcesContent":["import type { GenerateOptions } from '../../../contract/index.ts'\nimport { MODEL_ERROR_CODES, type ModelFailure } from '../../../errors/index.ts'\nimport type { ContentBlock, Message, ToolCallBlock } from '../../../message/index.ts'\nimport { BlockAssembler } from '../../../stream/index.ts'\nimport type { FinishReason } from '../../../stream/index.ts'\nimport type { ModelCallReport } from '../../../observation/index.ts'\nimport { normalizeToolPairing } from '../../history/normalize.ts'\nimport { createSpanId, type TraceRef } from '../../trace/trace.ts'\nimport type { AgentEvent, AgentMaintenanceEvent } from '../types.ts'\nimport { type ModelRoundPhase, type RunTurnOptions, type RoundResult } from './types.ts'\nimport { positiveFinite, positiveSafeInteger } from './config.ts'\nimport { serializedBytes, modelFailureFinish, modelAbortedFinish, messageOf, now } from './common.ts'\nimport { validateStreamChunk } from './validation.ts'\nimport { StreamAbortError, nextWithAbort, closeIterator } from './cancellation.ts'\nimport { runOptionalHook } from './hooks.ts'\nimport { accountingUsageStop } from './usage-stop.ts'\nimport {\n classifyTextPhases, dropDuplicateToolCalls, invalidHostToolCall, contentTiming,\n recentToolResultIds, systemText,\n createAssistant, textOf,\n} from './content.ts'\n\n/** How much of one message the trace keeps. */\nconst PREVIEW_CHARS = 600\n\n/** How many trailing messages the trace keeps. */\nconst PREVIEW_MESSAGES = 8\n\nfunction clip(text: string): string {\n const flattened = text.replace(/\\s+/gu, ' ').trim()\n return flattened.length > PREVIEW_CHARS ? `${flattened.slice(0, PREVIEW_CHARS)}…` : flattened\n}\n\n/** One message as a line: who spoke, and what the model could read of it. */\nfunction previewMessage(message: Message): Record<string, unknown> {\n const parts: string[] = []\n const calls: string[] = []\n for (const block of message.content) {\n if (block.type === 'text' || block.type === 'reasoning') parts.push(block.text)\n else if (block.type === 'tool-call') calls.push(`${block.name}(${clip(block.arguments)})`)\n else if (block.type === 'tool-result') parts.push(textOf(block.content))\n else parts.push(`[${block.type}]`)\n }\n return {\n role: message.role,\n producer: message.source.kind,\n ...parts.length === 0 ? {} : { text: clip(parts.join(' ')) },\n ...calls.length === 0 ? {} : { toolCalls: calls },\n }\n}\n\n/**\n * What this round sent the model, in a form a person can read.\n *\n * A summary, not a copy: the request can be the whole conversation plus every\n * tool schema, and a trace that stored it verbatim would be larger than the\n * work it describes. What survives is the part that explains the round — which\n * tools were on offer, how long the context was, and the tail of the\n * conversation the model was actually answering, each message clipped.\n * @param request - The request about to be dispatched.\n * @returns The summary for the span.\n */\nfunction requestSummary(request: GenerateOptions): Record<string, unknown> {\n const messages = request.messages ?? []\n const dropped = Math.max(0, messages.length - PREVIEW_MESSAGES)\n return {\n messageCount: messages.length,\n // The identity of the request, for a host that records the provider call\n // separately and has to say WHICH round each recording belongs to. Message\n // ids are stable across every representation boundary, so the last one plus\n // the count names one round of one agent without ambiguity.\n ...messages.at(-1) === undefined ? {} : { lastMessageId: messages.at(-1)?.id },\n ...request.system === undefined ? {} : { system: clip(request.system) },\n ...request.tools === undefined || request.tools.length === 0\n ? {}\n : { tools: request.tools.map(tool => tool.name) },\n ...request.toolChoice === undefined ? {} : { toolChoice: request.toolChoice },\n ...dropped === 0 ? {} : { earlierMessagesOmitted: dropped },\n messages: messages.slice(-PREVIEW_MESSAGES).map(previewMessage),\n }\n}\n\nexport async function modelRound(\n options: RunTurnOptions,\n signal: AbortSignal,\n emit: (event: AgentEvent) => Promise<void>,\n emitMaintenance: (event: AgentMaintenanceEvent) => Promise<void>,\n root: TraceRef,\n turn: number,\n step: number,\n phase: ModelRoundPhase,\n): Promise<RoundResult> {\n const forcedFinal = phase === 'forced-final'\n const finalOutput = phase === 'final' || forcedFinal\n const trace: TraceRef = { traceId: root.traceId, spanId: createSpanId(), parentSpanId: root.spanId }\n let messages = normalizeToolPairing(options.history.messages())\n const afterToolCallIds = recentToolResultIds(options.history)\n const generation = options.history.generation()\n const entries = options.history.entries().length\n const stopped = (): RoundResult | undefined => {\n const stop = accountingUsageStop(options.accounting)\n if (stop === undefined && !signal.aborted) return undefined\n return {\n trace, finish: signal.aborted\n ? { kind: 'aborted', failure: { code: 'ABORTED', message: messageOf(signal.reason) } }\n : { kind: 'stop' },\n calls: [], afterToolCallIds, timing: contentTiming(false, afterToolCallIds.length > 0),\n ...(stop?.kind === 'error' ? { usageRequired: true } : {}),\n ...(stop?.kind === 'usage-unavailable' ? { usageUnavailable: true } : {}),\n }\n }\n const beforeMaintenance = stopped()\n if (beforeMaintenance !== undefined) return beforeMaintenance\n const decision = await runOptionalHook(options.hooks?.beforeStep, [{\n turn, step, messages, snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n emit: emitMaintenance,\n }], options, signal, 'beforeStep')\n const afterMaintenance = stopped()\n if (afterMaintenance !== undefined) return afterMaintenance\n if (decision?.kind === 'reject') {\n const failure: ModelFailure = { message: decision.reason, code: 'STEP_REJECTED' }\n return {\n trace, finish: { kind: 'error', failure }, calls: [], afterToolCallIds,\n timing: contentTiming(false, afterToolCallIds.length > 0),\n }\n }\n // Hooks may append live steering as well as replacing compacted history.\n // Refresh for either mutation so new user input stays at the chronological\n // tail instead of needing to be prepended ahead of older history.\n if (options.history.generation() !== generation\n || options.history.entries().length !== entries) {\n messages = normalizeToolPairing(options.history.messages())\n }\n if (decision?.prepend !== undefined) messages = Object.freeze([...decision.prepend, ...messages])\n const system = systemText(options, forcedFinal)\n const availableTools = [\n ...options.tools?.schemas() ?? [],\n ...options.nativeTools ?? [],\n ]\n const tools = availableTools\n const outputFormat = !finalOutput && options.outputFormat?.type === 'json_schema'\n ? { type: 'text' as const }\n : options.outputFormat\n const requestBase: GenerateOptions = {\n ...options.config,\n messages,\n ...system.length === 0 ? {} : { system },\n ...tools.length === 0 ? {} : { tools },\n ...finalOutput && tools.length > 0\n ? { toolChoice: 'none' as const }\n : options.toolChoice === undefined ? {} : { toolChoice: options.toolChoice },\n ...options.imagePolicy === undefined ? {} : { imagePolicy: options.imagePolicy },\n ...outputFormat === undefined ? {} : { outputFormat },\n }\n const checkpointRequest: GenerateOptions = { ...requestBase, signal }\n try {\n await runOptionalHook(options.hooks?.checkpoint, [{\n kind: 'before-model-request', request: checkpointRequest,\n snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n }], options, signal, 'checkpoint')\n } catch (error: unknown) {\n const failure: ModelFailure = { message: `history checkpoint failed: ${messageOf(error)}`, code: 'CHECKPOINT_FAILED' }\n return {\n trace, finish: { kind: 'error', failure }, calls: [], afterToolCallIds,\n timing: contentTiming(false, afterToolCallIds.length > 0),\n }\n }\n const beforeDispatch = stopped()\n if (beforeDispatch !== undefined) return beforeDispatch\n await emit({ type: 'span-start', trace, at: now(), name: `chat ${options.config.model}`, kind: 'chat', attributes: {\n 'gen_ai.operation.name': 'chat', 'gen_ai.request.model': options.config.model,\n // The effort is part of WHICH call this was: the same model at minimal and\n // at high is two different requests, priced and paced differently, and a\n // trace that omits it cannot explain either. Absent when the route has no\n // effort ladder, rather than reported as a default nobody chose.\n ...options.config.reasoningEffort === undefined\n ? {}\n : { 'gen_ai.request.reasoning_effort': options.config.reasoningEffort },\n turn, step, forcedFinal, phase,\n }, input: requestSummary(requestBase) })\n await emit({ type: 'step-start', turn, step, trace, ...forcedFinal ? { forcedFinal: true as const } : {} })\n const assembler = new BlockAssembler()\n const closedBlockIndexes = new Set<number>()\n const modelTimeoutMs = positiveFinite(options.modelTimeoutMs ?? 10 * 60_000, 'modelTimeoutMs')\n const maxRequestBytes = positiveSafeInteger(options.maxModelRequestBytes ?? 32 * 1024 * 1024, 'maxModelRequestBytes')\n const maxResponseBytes = positiveSafeInteger(options.maxModelResponseBytes ?? 32 * 1024 * 1024, 'maxModelResponseBytes')\n const maxStreamEvents = positiveSafeInteger(options.maxModelStreamEvents ?? 100_000, 'maxModelStreamEvents')\n const teardownTimeoutMs = positiveFinite(options.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n let modelCallReport: ModelCallReport | undefined\n let usageRequired = false\n let usageUnavailable = false\n let requestBytes: number\n try {\n requestBytes = serializedBytes(requestBase)\n } catch (error: unknown) {\n requestBytes = -1\n assembler.push(modelFailureFinish(`model request is not serializable: ${messageOf(error)}`, 'INVALID_MODEL_REQUEST'))\n }\n if (requestBytes > maxRequestBytes) {\n assembler.push(modelFailureFinish(\n `model request exceeds the ${maxRequestBytes}-byte limit`,\n 'MODEL_REQUEST_TOO_LARGE',\n ))\n } else if (requestBytes >= 0) {\n const owned = new AbortController()\n const roundSignal = AbortSignal.any([signal, owned.signal])\n let timedOut = false\n const timeout = setTimeout(() => {\n timedOut = true\n owned.abort(new Error(`model stream exceeded ${modelTimeoutMs}ms`))\n }, modelTimeoutMs)\n const handle = options.registry.stream(\n { ...requestBase, signal: roundSignal },\n options.accounting?.modelInvocation,\n )\n const iterator = handle[Symbol.asyncIterator]()\n let exhausted = false\n let events = 0\n let responseBytes = 0\n let sawFinish = false\n try {\n while (true) {\n const next = await nextWithAbort(iterator.next(), roundSignal)\n if (next.done === true) {\n exhausted = true\n break\n }\n const chunk = next.value\n try {\n validateStreamChunk(chunk, maxStreamEvents)\n } catch (error: unknown) {\n assembler.push(modelFailureFinish(\n `model adapter emitted an invalid stream chunk: ${messageOf(error)}`,\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('invalid model stream chunk'))\n break\n }\n events++\n try {\n responseBytes += serializedBytes(chunk)\n } catch (error: unknown) {\n assembler.push(modelFailureFinish(\n `model adapter emitted a non-serializable stream chunk: ${messageOf(error)}`,\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('non-serializable model stream chunk'))\n break\n }\n if (events > maxStreamEvents || responseBytes > maxResponseBytes) {\n const dimension = events > maxStreamEvents\n ? `${maxStreamEvents}-event`\n : `${maxResponseBytes}-byte`\n assembler.push(modelFailureFinish(\n `model response exceeds the ${dimension} limit`,\n 'MODEL_RESPONSE_TOO_LARGE',\n ))\n owned.abort(new Error('model response resource limit exceeded'))\n break\n }\n if (sawFinish) {\n assembler.push(modelFailureFinish(\n 'model adapter emitted data after its terminal finish chunk',\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('invalid model stream'))\n break\n }\n assembler.push(chunk)\n // The assembler ignores deltas after the first close. The visible\n // stream must do the same or UI text can disagree with stored history.\n if ((chunk.type === 'text-delta' || chunk.type === 'reasoning-delta' || chunk.type === 'tool-call-delta')\n && closedBlockIndexes.has(chunk.index)) continue\n if (chunk.type === 'block-end') closedBlockIndexes.add(chunk.index)\n if (chunk.type === 'finish') sawFinish = true\n if (chunk.type === 'text-delta') await emit({\n type: 'text-delta', index: chunk.index, text: chunk.text,\n phase: phase === 'process' ? 'commentary' : chunk.phase ?? 'unknown', trace,\n })\n else if (chunk.type === 'reasoning-delta') await emit({\n type: 'reasoning-delta', index: chunk.index, text: chunk.text, trace,\n })\n else if (chunk.type === 'image-delta') await emit({\n type: 'image-delta', itemId: chunk.itemId, data: chunk.data,\n mediaType: chunk.mediaType, ...chunk.partialIndex === undefined ? {} : { partialIndex: chunk.partialIndex }, trace,\n })\n else if (chunk.type === 'usage') await emit({ type: 'usage', usage: chunk.usage, trace })\n }\n } catch (error: unknown) {\n if (!(error instanceof StreamAbortError)) throw error\n assembler.push(signal.aborted\n ? modelAbortedFinish(messageOf(signal.reason ?? error))\n : timedOut\n ? modelFailureFinish(`model stream exceeded ${modelTimeoutMs}ms`, 'MODEL_TIMEOUT')\n : modelFailureFinish(messageOf(error.cause ?? error), 'MODEL_STREAM_ABORTED'))\n } finally {\n clearTimeout(timeout)\n if (!exhausted) {\n owned.abort(new Error('model stream closed before exhaustion'))\n const settled = await closeIterator(iterator, teardownTimeoutMs)\n if (!settled) {\n assembler.push(modelFailureFinish(\n `model stream ignored cancellation for more than ${teardownTimeoutMs}ms; the adapter operation may still be running`,\n 'MODEL_TEARDOWN_TIMEOUT',\n ))\n }\n }\n }\n const report = await handle.report\n const decision = options.accounting === undefined\n ? undefined\n : await options.accounting.recordModelCall(report, { ...requestBase, signal })\n modelCallReport = decision?.report ?? report\n usageRequired = decision?.usageRequired ?? false\n usageUnavailable = decision?.usageUnavailable ?? false\n }\n let providerFinish = assembler.finish\n let retainedPrefix = providerFinish.kind === 'aborted'\n let rawBlocks: ContentBlock[]\n try {\n rawBlocks = providerFinish.kind === 'aborted' ? assembler.interruptedBlocks() : assembler.blocks()\n } catch (error: unknown) {\n providerFinish = {\n kind: 'error',\n failure: {\n message: `model adapter emitted an invalid block sequence: ${messageOf(error)}`,\n code: 'INVALID_MODEL_STREAM',\n },\n }\n // A broken extension must not discard text already delivered to the user.\n // This prefix deliberately excludes tools and unassembled extension data.\n retainedPrefix = true\n rawBlocks = assembler.interruptedBlocks()\n }\n // Interrupted/truncated assembly drops unfinished calls, but the text that\n // introduced those calls is still process narration, not a final answer.\n const canonicalTexts = assembler.textBlocks()\n .filter(({ block }) => !retainedPrefix || block.text.trim() !== '')\n let textPosition = 0\n const classifiedRaw = classifyTextPhases(rawBlocks.map(block => {\n if (block.type !== 'text') return block\n const canonical = canonicalTexts[textPosition++]\n // Safe-prefix recovery removes native calls too. Retain their position so\n // search narration cannot become an answer merely because a call was removed.\n return block.phase === undefined && canonical?.beforeNativeCall\n ? { ...block, phase: 'commentary' as const } : block\n }), phase === 'process', assembler.hasToolCalls)\n // A repeated id costs the model that one call, not its whole turn.\n const deduped = dropDuplicateToolCalls(classifiedRaw, options.history)\n const classified = deduped.blocks\n const structuredOutputFailure = finalOutput\n && options.outputFormat?.type === 'json_schema'\n && providerFinish.kind === 'stop'\n && !isJsonText(textOf(classified), options.validateOutput)\n ? {\n message: 'model returned invalid JSON or failed the structured output validator',\n code: MODEL_ERROR_CODES.MALFORMED_RESPONSE,\n }\n : undefined\n const disabledCall = finalOutput && classified.some(block => block.type === 'tool-call')\n ? { message: 'model emitted a host tool call during the final output phase', code: 'INVALID_TOOL_CALL' }\n : undefined\n const invalidCall = disabledCall\n ?? structuredOutputFailure\n ?? invalidHostToolCall(classified, options.history)\n const blocks = invalidCall === undefined\n ? classified\n : classified.filter(block => block.type !== 'tool-call')\n const finish: FinishReason = invalidCall === undefined\n ? providerFinish\n : { kind: 'error', failure: invalidCall }\n const message = blocks.length === 0 && (finish.kind === 'error' || finish.kind === 'aborted')\n ? undefined\n : createAssistant(options, blocks, retainedPrefix ? undefined : assembler.replayState)\n const calls = message?.content\n .filter((block): block is ToolCallBlock => block.type === 'tool-call')\n .map(block => ({ callId: block.id, toolName: block.name, rawArguments: block.arguments })) ?? []\n const timing = contentTiming(calls.length > 0, afterToolCallIds.length > 0)\n // Deltas may have no phase, or block-end may correct it. Publish the\n // canonical snapshot before consumers close this step, including providers\n // that only emit block-end. Keep provider indexes (which may be sparse).\n if (blocks.some(block => block.type === 'text')) {\n const indexes = canonicalTexts.map(({ index }) => index)\n const incomplete = finish.kind === 'error' || finish.kind === 'aborted' || finish.kind === 'max-tokens'\n let position = 0\n for (const block of blocks) {\n if (block.type !== 'text') continue\n const index = indexes[position++]\n if (index !== undefined) await emit({\n type: 'text-end', index, text: block.text,\n phase: block.phase ?? 'final-answer', trace,\n ...incomplete ? { incomplete: true as const } : {},\n })\n }\n }\n await emit({\n type: 'span-end', trace, at: now(),\n status: finish.kind === 'error' ? 'error' : finish.kind === 'aborted' ? 'aborted' : 'success',\n output: message === undefined ? undefined : {\n text: textOf(message.content),\n commentary: message.content.flatMap(block => block.type === 'text' && block.phase === 'commentary' ? [block.text] : []),\n reasoning: message.content.flatMap(block => block.type === 'reasoning' ? [block.text] : []),\n toolCalls: calls.length,\n },\n ...assembler.usage === undefined ? {} : { usage: assembler.usage },\n ...finish.kind === 'error' || finish.kind === 'aborted'\n ? { error: { type: 'ModelError', message: finish.failure.message, code: finish.failure.code } }\n : {},\n })\n if (calls.length === 0 || finalOutput) await emit({ type: 'step-end', turn, step, trace })\n return {\n trace, ...message === undefined ? {} : { message }, finish,\n ...assembler.usage === undefined ? {} : { usage: assembler.usage },\n ...modelCallReport === undefined ? {} : { report: modelCallReport },\n ...usageRequired ? { usageRequired: true as const } : {},\n ...usageUnavailable ? { usageUnavailable: true as const } : {},\n calls, afterToolCallIds, timing,\n ...deduped.dropped.length === 0 ? {} : { droppedDuplicateCalls: deduped.dropped },\n }\n}\n\nfunction isJsonText(value: string, validate?: (value: unknown) => void): boolean {\n try {\n const parsed: unknown = JSON.parse(value)\n validate?.(parsed)\n return true\n } catch {\n return false\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ function e(e){return`${e.toolName}:${r(e.rawArguments.trim())}`}function t(t){return t.map(t=>e(t)).join(`|`)}function n(e,t){let n=Math.min(t,Math.floor(e.length/2)),r;for(let t=1;t<=n;t++){let n=1;for(;(n+1)*t<=e.length;){let r=e.length-t,i=r-n*t,a=!0;for(let n=0;n<t;n++)if(e[i+n]!==e[r+n]){a=!1;break}if(!a)break;n++}n>=2&&(r===void 0||n>r.repetitions)&&(r={period:t,repetitions:n})}return r}function r(e){let t=2166136261,n=2654435769,r=0,i=!1,a=!1;for(let o=0;o<e.length;o++){let s=e.charCodeAt(o);!i&&(s===32||s===9||s===10||s===13)||(r++,t=Math.imul(t^s,16777619),n=Math.imul(n^s+r,2246822507),i?a?a=!1:s===92?a=!0:s===34&&(i=!1):s===34&&(i=!0))}return`${r.toString(36)}:${(t>>>0).toString(36)}:${(n>>>0).toString(36)}`}export{r as jsonTextFingerprint,e as repeatKey,n as repeatedSuffixCycle,t as toolActionPattern};
2
+ //# sourceMappingURL=repetition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repetition.js","names":[],"sources":["../../../../src/agent/loop/turn/repetition.ts"],"sourcesContent":["import type { ToolCallRequest } from '../../tool/pipeline.ts'\n\nexport function repeatKey(call: ToolCallRequest): string {\n // This is a heuristic guard, not a semantic JSON comparator. Keeping the\n // provider's bounded raw arguments avoids recursively normalizing a deeply\n // nested payload and turning repeat detection into a stack-exhaustion vector.\n return `${call.toolName}:${jsonTextFingerprint(call.rawArguments.trim())}`\n}\nexport function toolActionPattern(calls: readonly ToolCallRequest[]): string {\n return calls.map(call => repeatKey(call)).join('|')\n}\nexport function repeatedSuffixCycle(\n steps: readonly string[],\n maxPeriod: number,\n): { readonly period: number; readonly repetitions: number } | undefined {\n const maximum = Math.min(maxPeriod, Math.floor(steps.length / 2))\n let best: { readonly period: number; readonly repetitions: number } | undefined\n for (let period = 1; period <= maximum; period++) {\n let repetitions = 1\n while ((repetitions + 1) * period <= steps.length) {\n const rightStart = steps.length - period\n const leftStart = rightStart - repetitions * period\n let equal = true\n for (let offset = 0; offset < period; offset++) {\n if (steps[leftStart + offset] !== steps[rightStart + offset]) {\n equal = false\n break\n }\n }\n if (!equal) break\n repetitions++\n }\n if (repetitions >= 2 && (best === undefined || repetitions > best.repetitions)) {\n best = { period, repetitions }\n }\n }\n return best\n}\nexport function jsonTextFingerprint(value: string): string {\n let first = 0x811c9dc5\n let second = 0x9e3779b9\n let length = 0\n let quoted = false\n let escaped = false\n for (let index = 0; index < value.length; index++) {\n const code = value.charCodeAt(index)\n if (!quoted && (code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d)) continue\n length++\n first = Math.imul(first ^ code, 0x01000193)\n second = Math.imul(second ^ (code + length), 0x85ebca6b)\n if (quoted) {\n if (escaped) escaped = false\n else if (code === 0x5c) escaped = true\n else if (code === 0x22) quoted = false\n } else if (code === 0x22) quoted = true\n }\n return `${length.toString(36)}:${(first >>> 0).toString(36)}:${(second >>> 0).toString(36)}`\n}\n"],"mappings":"AAEA,SAAgB,EAAU,EAA+B,CAIvD,MAAO,GAAG,EAAK,SAAS,GAAG,EAAoB,EAAK,aAAa,KAAK,CAAC,GACzE,CACA,SAAgB,EAAkB,EAA2C,CAC3E,OAAO,EAAM,IAAI,GAAQ,EAAU,CAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CACpD,CACA,SAAgB,EACd,EACA,EACuE,CACvE,IAAM,EAAU,KAAK,IAAI,EAAW,KAAK,MAAM,EAAM,OAAS,CAAC,CAAC,EAC5D,EACJ,IAAK,IAAI,EAAS,EAAG,GAAU,EAAS,IAAU,CAChD,IAAI,EAAc,EAClB,MAAQ,EAAc,GAAK,GAAU,EAAM,QAAQ,CACjD,IAAM,EAAa,EAAM,OAAS,EAC5B,EAAY,EAAa,EAAc,EACzC,EAAQ,GACZ,IAAK,IAAI,EAAS,EAAG,EAAS,EAAQ,IACpC,GAAI,EAAM,EAAY,KAAY,EAAM,EAAa,GAAS,CAC5D,EAAQ,GACR,KACF,CAEF,GAAI,CAAC,EAAO,MACZ,GACF,CACI,GAAe,IAAM,IAAS,IAAA,IAAa,EAAc,EAAK,eAChE,EAAO,CAAE,SAAQ,aAAY,EAEjC,CACA,OAAO,CACT,CACA,SAAgB,EAAoB,EAAuB,CACzD,IAAI,EAAQ,WACR,EAAS,WACT,EAAS,EACT,EAAS,GACT,EAAU,GACd,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAM,OAAQ,IAAS,CACjD,IAAM,EAAO,EAAM,WAAW,CAAK,EAC/B,CAAC,IAAW,IAAS,IAAQ,IAAS,GAAQ,IAAS,IAAQ,IAAS,MAC5E,IACA,EAAQ,KAAK,KAAK,EAAQ,EAAM,QAAU,EAC1C,EAAS,KAAK,KAAK,EAAU,EAAO,EAAS,UAAU,EACnD,EACE,EAAS,EAAU,GACd,IAAS,GAAM,EAAU,GACzB,IAAS,KAAM,EAAS,IACxB,IAAS,KAAM,EAAS,IACrC,CACA,MAAO,GAAG,EAAO,SAAS,EAAE,EAAE,IAAI,IAAU,EAAA,CAAG,SAAS,EAAE,EAAE,IAAI,IAAW,EAAA,CAAG,SAAS,EAAE,GAC3F"}