@nhtio/adk 0.1.0-master-2a4e1bd2 → 0.1.0-master-cd595e6f

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 (413) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/artifact_methods-CJDQ5Lv-.mjs +1 -0
  3. package/artifact_methods-D6k_82r3.js +1 -0
  4. package/batteries/artifacts/ecmascript.cjs +1 -1
  5. package/batteries/artifacts/ecmascript.mjs +1 -1
  6. package/batteries/artifacts/toon.cjs +1 -1
  7. package/batteries/artifacts/toon.mjs +1 -1
  8. package/batteries/artifacts/xml.cjs +1 -1
  9. package/batteries/artifacts/xml.mjs +1 -1
  10. package/batteries/artifacts/yaml.cjs +1 -1
  11. package/batteries/artifacts/yaml.mjs +1 -1
  12. package/batteries/artifacts.cjs +4 -4
  13. package/batteries/artifacts.mjs +4 -4
  14. package/batteries/dev-tools/forge.cjs +3 -3
  15. package/batteries/dev-tools/forge.mjs +3 -3
  16. package/batteries/dev-tools.cjs +2 -2
  17. package/batteries/dev-tools.mjs +2 -2
  18. package/batteries/encoding.cjs +7 -7
  19. package/batteries/encoding.mjs +7 -7
  20. package/batteries/generation/gemini/adapter.cjs +1 -1
  21. package/batteries/generation/gemini/adapter.mjs +1 -1
  22. package/batteries/generation/local_diffusion/adapter.cjs +1 -1
  23. package/batteries/generation/local_diffusion/adapter.mjs +1 -1
  24. package/batteries/generation/openai/adapter.cjs +1 -1
  25. package/batteries/generation/openai/adapter.mjs +1 -1
  26. package/batteries/isolation/browser.d.ts +1 -1
  27. package/batteries/isolation/child_process/transport.d.ts +2 -2
  28. package/batteries/isolation/child_process.cjs +4 -4
  29. package/batteries/isolation/child_process.cjs.map +1 -1
  30. package/batteries/isolation/child_process.mjs +4 -4
  31. package/batteries/isolation/child_process.mjs.map +1 -1
  32. package/batteries/isolation/codec.d.ts +2 -2
  33. package/batteries/isolation/crash_policy.d.ts +1 -1
  34. package/batteries/isolation/isolate_function.d.ts +2 -2
  35. package/batteries/isolation/protocol.d.ts +4 -4
  36. package/batteries/isolation/serve.d.ts +2 -2
  37. package/batteries/isolation/types.d.ts +4 -4
  38. package/batteries/isolation.cjs +1 -1
  39. package/batteries/isolation.mjs +1 -1
  40. package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
  41. package/batteries/llm/anthropic_messages/adapter.cjs.map +1 -1
  42. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  43. package/batteries/llm/anthropic_messages/adapter.mjs.map +1 -1
  44. package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
  45. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  46. package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
  47. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  48. package/batteries/llm/anthropic_messages/types.d.ts +2 -2
  49. package/batteries/llm/anthropic_messages/validation.cjs +3 -3
  50. package/batteries/llm/anthropic_messages/validation.cjs.map +1 -1
  51. package/batteries/llm/anthropic_messages/validation.mjs +3 -3
  52. package/batteries/llm/anthropic_messages/validation.mjs.map +1 -1
  53. package/batteries/llm/anthropic_messages.cjs +2 -2
  54. package/batteries/llm/anthropic_messages.mjs +2 -2
  55. package/batteries/llm/bedrock_converse/adapter.cjs +29 -7
  56. package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
  57. package/batteries/llm/bedrock_converse/adapter.mjs +30 -8
  58. package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
  59. package/batteries/llm/bedrock_converse/exceptions.cjs +3 -0
  60. package/batteries/llm/bedrock_converse/exceptions.cjs.map +1 -1
  61. package/batteries/llm/bedrock_converse/exceptions.d.ts +6 -0
  62. package/batteries/llm/bedrock_converse/exceptions.mjs +3 -1
  63. package/batteries/llm/bedrock_converse/exceptions.mjs.map +1 -1
  64. package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
  65. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  66. package/batteries/llm/bedrock_converse/types.d.ts +6 -2
  67. package/batteries/llm/bedrock_converse/validation.cjs +7 -1
  68. package/batteries/llm/bedrock_converse/validation.cjs.map +1 -1
  69. package/batteries/llm/bedrock_converse/validation.mjs +7 -1
  70. package/batteries/llm/bedrock_converse/validation.mjs.map +1 -1
  71. package/batteries/llm/bedrock_converse.cjs +2 -2
  72. package/batteries/llm/bedrock_converse.mjs +2 -2
  73. package/batteries/llm/claude_code_cli/adapter.cjs +6 -6
  74. package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
  75. package/batteries/llm/claude_code_cli/adapter.mjs +6 -6
  76. package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
  77. package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
  78. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  79. package/batteries/llm/claude_code_cli/types.d.ts +3 -2
  80. package/batteries/llm/claude_code_cli/validation.cjs +3 -3
  81. package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
  82. package/batteries/llm/claude_code_cli/validation.mjs +3 -3
  83. package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
  84. package/batteries/llm/claude_code_cli.cjs +1 -1
  85. package/batteries/llm/claude_code_cli.mjs +1 -1
  86. package/batteries/llm/gemini_generate_content/adapter.cjs +29 -7
  87. package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
  88. package/batteries/llm/gemini_generate_content/adapter.mjs +30 -8
  89. package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
  90. package/batteries/llm/gemini_generate_content/exceptions.cjs +3 -0
  91. package/batteries/llm/gemini_generate_content/exceptions.cjs.map +1 -1
  92. package/batteries/llm/gemini_generate_content/exceptions.d.ts +6 -0
  93. package/batteries/llm/gemini_generate_content/exceptions.mjs +3 -1
  94. package/batteries/llm/gemini_generate_content/exceptions.mjs.map +1 -1
  95. package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
  96. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  97. package/batteries/llm/gemini_generate_content/types.d.ts +7 -3
  98. package/batteries/llm/gemini_generate_content/validation.cjs +11 -2
  99. package/batteries/llm/gemini_generate_content/validation.cjs.map +1 -1
  100. package/batteries/llm/gemini_generate_content/validation.mjs +11 -2
  101. package/batteries/llm/gemini_generate_content/validation.mjs.map +1 -1
  102. package/batteries/llm/gemini_generate_content.cjs +1 -1
  103. package/batteries/llm/gemini_generate_content.mjs +1 -1
  104. package/batteries/llm/litert_lm/adapter.cjs +6 -6
  105. package/batteries/llm/litert_lm/adapter.cjs.map +1 -1
  106. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  107. package/batteries/llm/litert_lm/adapter.mjs.map +1 -1
  108. package/batteries/llm/litert_lm/helpers.cjs +3 -3
  109. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  110. package/batteries/llm/litert_lm/types.d.ts +2 -2
  111. package/batteries/llm/litert_lm/validation.cjs +3 -3
  112. package/batteries/llm/litert_lm/validation.cjs.map +1 -1
  113. package/batteries/llm/litert_lm/validation.mjs +3 -3
  114. package/batteries/llm/litert_lm/validation.mjs.map +1 -1
  115. package/batteries/llm/litert_lm.cjs +1 -1
  116. package/batteries/llm/litert_lm.mjs +1 -1
  117. package/batteries/llm/ollama/adapter.cjs +6 -6
  118. package/batteries/llm/ollama/adapter.cjs.map +1 -1
  119. package/batteries/llm/ollama/adapter.mjs +6 -6
  120. package/batteries/llm/ollama/adapter.mjs.map +1 -1
  121. package/batteries/llm/ollama/helpers.cjs +4 -4
  122. package/batteries/llm/ollama/helpers.mjs +4 -4
  123. package/batteries/llm/ollama/types.d.ts +2 -2
  124. package/batteries/llm/ollama/validation.cjs +3 -3
  125. package/batteries/llm/ollama/validation.cjs.map +1 -1
  126. package/batteries/llm/ollama/validation.mjs +3 -3
  127. package/batteries/llm/ollama/validation.mjs.map +1 -1
  128. package/batteries/llm/ollama.cjs +2 -2
  129. package/batteries/llm/ollama.mjs +2 -2
  130. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  131. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
  132. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  133. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
  134. package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
  135. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  136. package/batteries/llm/openai_chat_completions/types.d.ts +2 -2
  137. package/batteries/llm/openai_chat_completions/validation.cjs +3 -3
  138. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
  139. package/batteries/llm/openai_chat_completions/validation.mjs +3 -3
  140. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
  141. package/batteries/llm/openai_chat_completions.cjs +2 -2
  142. package/batteries/llm/openai_chat_completions.mjs +2 -2
  143. package/batteries/llm/openai_responses/adapter.cjs +6 -6
  144. package/batteries/llm/openai_responses/adapter.cjs.map +1 -1
  145. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  146. package/batteries/llm/openai_responses/adapter.mjs.map +1 -1
  147. package/batteries/llm/openai_responses/helpers.cjs +3 -3
  148. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  149. package/batteries/llm/openai_responses/types.d.ts +2 -2
  150. package/batteries/llm/openai_responses/validation.cjs +3 -3
  151. package/batteries/llm/openai_responses/validation.cjs.map +1 -1
  152. package/batteries/llm/openai_responses/validation.mjs +3 -3
  153. package/batteries/llm/openai_responses/validation.mjs.map +1 -1
  154. package/batteries/llm/openai_responses.cjs +2 -2
  155. package/batteries/llm/openai_responses.mjs +2 -2
  156. package/batteries/llm/transformers_js/adapter.cjs +6 -6
  157. package/batteries/llm/transformers_js/adapter.cjs.map +1 -1
  158. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  159. package/batteries/llm/transformers_js/adapter.mjs.map +1 -1
  160. package/batteries/llm/transformers_js/helpers.cjs +3 -3
  161. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  162. package/batteries/llm/transformers_js/types.d.ts +2 -2
  163. package/batteries/llm/transformers_js/validation.cjs +3 -3
  164. package/batteries/llm/transformers_js/validation.cjs.map +1 -1
  165. package/batteries/llm/transformers_js/validation.mjs +3 -3
  166. package/batteries/llm/transformers_js/validation.mjs.map +1 -1
  167. package/batteries/llm/transformers_js.cjs +1 -1
  168. package/batteries/llm/transformers_js.mjs +1 -1
  169. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  170. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
  171. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  172. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
  173. package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
  174. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  175. package/batteries/llm/webllm_chat_completions/validation.cjs +3 -3
  176. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
  177. package/batteries/llm/webllm_chat_completions/validation.mjs +3 -3
  178. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
  179. package/batteries/llm/webllm_chat_completions.cjs +2 -2
  180. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  181. package/batteries/llm.cjs +2 -2
  182. package/batteries/llm.mjs +2 -2
  183. package/batteries/media/builder.d.ts +3 -0
  184. package/batteries/media/contracts.cjs.map +1 -1
  185. package/batteries/media/contracts.d.ts +40 -1
  186. package/batteries/media/contracts.mjs.map +1 -1
  187. package/batteries/media/engines/sharp.cjs +36 -2
  188. package/batteries/media/engines/sharp.cjs.map +1 -1
  189. package/batteries/media/engines/sharp.mjs +36 -2
  190. package/batteries/media/engines/sharp.mjs.map +1 -1
  191. package/batteries/media/forge.cjs +5 -5
  192. package/batteries/media/forge.mjs +5 -5
  193. package/batteries/media/index.d.ts +1 -1
  194. package/batteries/media/lint.cjs +3 -2
  195. package/batteries/media/lint.cjs.map +1 -1
  196. package/batteries/media/lint.mjs +3 -2
  197. package/batteries/media/lint.mjs.map +1 -1
  198. package/batteries/media.cjs +66 -2
  199. package/batteries/media.cjs.map +1 -1
  200. package/batteries/media.mjs +66 -2
  201. package/batteries/media.mjs.map +1 -1
  202. package/batteries/orchestration/conformance.cjs +123 -74
  203. package/batteries/orchestration/conformance.cjs.map +1 -1
  204. package/batteries/orchestration/conformance.d.ts +10 -8
  205. package/batteries/orchestration/conformance.mjs +54 -5
  206. package/batteries/orchestration/conformance.mjs.map +1 -1
  207. package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
  208. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  209. package/batteries/orchestration/executor.cjs +2 -2
  210. package/batteries/orchestration/executor.mjs +2 -2
  211. package/batteries/orchestration/forge.cjs +4 -4
  212. package/batteries/orchestration/forge.mjs +4 -4
  213. package/batteries/orchestration/validation.cjs +2 -2
  214. package/batteries/orchestration/validation.mjs +2 -2
  215. package/batteries/orchestration.cjs +4 -4
  216. package/batteries/orchestration.mjs +4 -4
  217. package/batteries/sandbox/contracts/policy_enforcer.d.ts +13 -1
  218. package/batteries/sandbox/js/compartment.d.ts +7 -2
  219. package/batteries/sandbox/js/exceptions.d.ts +4 -0
  220. package/batteries/sandbox/js/runner.d.ts +1 -1
  221. package/batteries/sandbox/js/service.d.ts +1 -1
  222. package/batteries/sandbox/js/ses_contracts.d.ts +4 -3
  223. package/batteries/sandbox/js.cjs +17 -8
  224. package/batteries/sandbox/js.cjs.map +1 -1
  225. package/batteries/sandbox/js.mjs +17 -9
  226. package/batteries/sandbox/js.mjs.map +1 -1
  227. package/batteries/sandbox/manager.d.ts +4 -3
  228. package/batteries/sandbox/node/srt_enforcer.d.ts +1 -1
  229. package/batteries/sandbox/node.cjs +36 -12
  230. package/batteries/sandbox/node.cjs.map +1 -1
  231. package/batteries/sandbox/node.mjs +36 -12
  232. package/batteries/sandbox/node.mjs.map +1 -1
  233. package/batteries/sandbox/tools.cjs +1 -1
  234. package/batteries/sandbox/tools.mjs +1 -1
  235. package/batteries/sandbox/types.d.ts +10 -1
  236. package/batteries/sandbox.cjs +27 -9
  237. package/batteries/sandbox.cjs.map +1 -1
  238. package/batteries/sandbox.mjs +28 -11
  239. package/batteries/sandbox.mjs.map +1 -1
  240. package/batteries/skills.cjs +9 -9
  241. package/batteries/skills.mjs +9 -9
  242. package/batteries/tools/_shared.cjs +1 -1
  243. package/batteries/tools/_shared.mjs +1 -1
  244. package/batteries/tools/color.cjs +2 -2
  245. package/batteries/tools/color.mjs +2 -2
  246. package/batteries/tools/comparison.cjs +2 -2
  247. package/batteries/tools/comparison.mjs +2 -2
  248. package/batteries/tools/data_structure.cjs +2 -2
  249. package/batteries/tools/data_structure.mjs +2 -2
  250. package/batteries/tools/datetime_extended.cjs +3 -3
  251. package/batteries/tools/datetime_extended.mjs +3 -3
  252. package/batteries/tools/datetime_math.cjs +3 -3
  253. package/batteries/tools/datetime_math.mjs +3 -3
  254. package/batteries/tools/encoding.cjs +2 -2
  255. package/batteries/tools/encoding.mjs +2 -2
  256. package/batteries/tools/formatting.cjs +2 -2
  257. package/batteries/tools/formatting.mjs +2 -2
  258. package/batteries/tools/geo_basics.cjs +2 -2
  259. package/batteries/tools/geo_basics.mjs +2 -2
  260. package/batteries/tools/math.cjs +2 -2
  261. package/batteries/tools/math.mjs +2 -2
  262. package/batteries/tools/memory.cjs +5 -5
  263. package/batteries/tools/memory.mjs +5 -5
  264. package/batteries/tools/parsing.cjs +3 -3
  265. package/batteries/tools/parsing.mjs +3 -3
  266. package/batteries/tools/retrievables.cjs +5 -5
  267. package/batteries/tools/retrievables.mjs +5 -5
  268. package/batteries/tools/scrapper.cjs +1 -1
  269. package/batteries/tools/scrapper.mjs +1 -1
  270. package/batteries/tools/searxng.cjs +1 -1
  271. package/batteries/tools/searxng.mjs +1 -1
  272. package/batteries/tools/standing_instructions.cjs +3 -3
  273. package/batteries/tools/standing_instructions.mjs +3 -3
  274. package/batteries/tools/statistics.cjs +3 -3
  275. package/batteries/tools/statistics.mjs +3 -3
  276. package/batteries/tools/string_processing.cjs +2 -2
  277. package/batteries/tools/string_processing.mjs +2 -2
  278. package/batteries/tools/structured_data.cjs +2 -2
  279. package/batteries/tools/structured_data.mjs +2 -2
  280. package/batteries/tools/text_analysis.cjs +3 -3
  281. package/batteries/tools/text_analysis.mjs +3 -3
  282. package/batteries/tools/text_comparison.cjs +2 -2
  283. package/batteries/tools/text_comparison.mjs +2 -2
  284. package/batteries/tools/time.cjs +3 -3
  285. package/batteries/tools/time.mjs +3 -3
  286. package/batteries/tools/unit_conversion.cjs +2 -2
  287. package/batteries/tools/unit_conversion.mjs +2 -2
  288. package/batteries/tools.cjs +2 -2
  289. package/batteries/tools.mjs +2 -2
  290. package/batteries/validation.cjs +5 -5
  291. package/batteries/validation.mjs +5 -5
  292. package/batteries/vector/conformance/index.d.ts +11 -16
  293. package/batteries/vector/conformance.cjs +107 -36
  294. package/batteries/vector/conformance.cjs.map +1 -1
  295. package/batteries/vector/conformance.mjs +84 -13
  296. package/batteries/vector/conformance.mjs.map +1 -1
  297. package/batteries/vector/retrievable.cjs +1 -1
  298. package/batteries/vector/retrievable.mjs +1 -1
  299. package/batteries.cjs +5 -5
  300. package/batteries.mjs +5 -5
  301. package/{chat_common-DbbIESdo.mjs → chat_common-CmKV5Dz4.mjs} +2 -2
  302. package/{chat_common-DbbIESdo.mjs.map → chat_common-CmKV5Dz4.mjs.map} +1 -1
  303. package/{chat_common-B3O3zz-i.js → chat_common-Dpan9moo.js} +2 -2
  304. package/{chat_common-B3O3zz-i.js.map → chat_common-Dpan9moo.js.map} +1 -1
  305. package/{common-v9Jo9M5k.mjs → common-BpdHIpQE.mjs} +7 -7
  306. package/{common-v9Jo9M5k.mjs.map → common-BpdHIpQE.mjs.map} +1 -1
  307. package/{common-BV3HGeLj.js → common-H44Ik9ou.js} +7 -7
  308. package/{common-BV3HGeLj.js.map → common-H44Ik9ou.js.map} +1 -1
  309. package/common.cjs +7 -7
  310. package/common.mjs +7 -7
  311. package/{dispatch_runner-CbNyqSMy.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
  312. package/{dispatch_runner-CbNyqSMy.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
  313. package/{dispatch_runner-Bl3Xwebu.js → dispatch_runner-CKhm-scw.js} +5 -5
  314. package/{dispatch_runner-Bl3Xwebu.js.map → dispatch_runner-CKhm-scw.js.map} +1 -1
  315. package/dispatch_runner.cjs +1 -1
  316. package/dispatch_runner.mjs +1 -1
  317. package/{ecmascript-BSnvyY8T.js → ecmascript-CCtgamDh.js} +3 -3
  318. package/{ecmascript-BSnvyY8T.js.map → ecmascript-CCtgamDh.js.map} +1 -1
  319. package/{ecmascript-CZ7_YKfZ.mjs → ecmascript-DcmUQ9Jx.mjs} +3 -3
  320. package/{ecmascript-CZ7_YKfZ.mjs.map → ecmascript-DcmUQ9Jx.mjs.map} +1 -1
  321. package/eslint.cjs +1 -1
  322. package/eslint.mjs +1 -1
  323. package/exceptions.cjs +1 -1
  324. package/exceptions.mjs +1 -1
  325. package/forge.cjs +2 -2
  326. package/forge.mjs +2 -2
  327. package/guards.cjs +7 -7
  328. package/guards.mjs +7 -7
  329. package/{helpers-CDmLDBq5.mjs → helpers-BH7HTtkD.mjs} +3 -3
  330. package/{helpers-CDmLDBq5.mjs.map → helpers-BH7HTtkD.mjs.map} +1 -1
  331. package/{helpers-Tvvwpx1M.js → helpers-CEjjkXso.js} +3 -3
  332. package/{helpers-Tvvwpx1M.js.map → helpers-CEjjkXso.js.map} +1 -1
  333. package/index.cjs +10 -10
  334. package/index.mjs +10 -10
  335. package/{isolation-BQCTQYZ_.js → isolation-7Jrcucgc.js} +11 -11
  336. package/isolation-7Jrcucgc.js.map +1 -0
  337. package/{isolation-7xbkc12r.mjs → isolation-CO0NiK8R.mjs} +11 -11
  338. package/isolation-CO0NiK8R.mjs.map +1 -0
  339. package/lib/classes/tokenizable.d.ts +2 -3
  340. package/mcp/adk-docs-corpus.json +2 -2
  341. package/package.json +469 -469
  342. package/{retrievable-C5dXuDhD.js → retrievable-BTwjmPnl.js} +3 -3
  343. package/{retrievable-C5dXuDhD.js.map → retrievable-BTwjmPnl.js.map} +1 -1
  344. package/{retrievable-gl_TIHnX.mjs → retrievable-CXTAUuuv.mjs} +3 -3
  345. package/{retrievable-gl_TIHnX.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
  346. package/{scrapper-DD6-_2u-.js → scrapper-CJexXXK-.js} +4 -4
  347. package/{scrapper-DD6-_2u-.js.map → scrapper-CJexXXK-.js.map} +1 -1
  348. package/{scrapper-u_orpxIB.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
  349. package/{scrapper-u_orpxIB.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
  350. package/{searxng-fVdJUCK2.mjs → searxng-BFTJ6rTE.mjs} +4 -4
  351. package/{searxng-fVdJUCK2.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
  352. package/{searxng-C7GK0Nrz.js → searxng-DzlGZG4V.js} +4 -4
  353. package/{searxng-C7GK0Nrz.js.map → searxng-DzlGZG4V.js.map} +1 -1
  354. package/server.json +2 -2
  355. package/skills/adk-assembly/SKILL.md +2 -2
  356. package/{spooled_artifact-DriNQRj7.js → spooled_artifact-BpcesRBv.js} +384 -384
  357. package/spooled_artifact-BpcesRBv.js.map +1 -0
  358. package/{spooled_artifact-BkueYJhR.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
  359. package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
  360. package/spooled_artifact.cjs +2 -2
  361. package/spooled_artifact.mjs +2 -2
  362. package/{spooled_markdown_artifact-CfHRZUkl.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
  363. package/{spooled_markdown_artifact-CfHRZUkl.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
  364. package/{spooled_markdown_artifact-C_VkCDhF.js → spooled_markdown_artifact-wJPnE8Ij.js} +3 -3
  365. package/{spooled_markdown_artifact-C_VkCDhF.js.map → spooled_markdown_artifact-wJPnE8Ij.js.map} +1 -1
  366. package/{thought-B8JAi3-W.mjs → thought-BE1KGEhV.mjs} +3 -3
  367. package/{thought-B8JAi3-W.mjs.map → thought-BE1KGEhV.mjs.map} +1 -1
  368. package/{thought--fRgOwTP.js → thought-bS7O9O5H.js} +3 -3
  369. package/{thought--fRgOwTP.js.map → thought-bS7O9O5H.js.map} +1 -1
  370. package/{tokenizable-CWW7iSrD.js → tokenizable-BMZuGWRd.js} +35 -29
  371. package/tokenizable-BMZuGWRd.js.map +1 -0
  372. package/{tokenizable-DLMP68ZV.mjs → tokenizable-VB4Av8GF.mjs} +36 -30
  373. package/tokenizable-VB4Av8GF.mjs.map +1 -0
  374. package/{tool_call-CPjyvkm4.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
  375. package/{tool_call-CPjyvkm4.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
  376. package/{tool_call-DgqVwL5n.js → tool_call-Fs_Uh5wQ.js} +4 -4
  377. package/{tool_call-DgqVwL5n.js.map → tool_call-Fs_Uh5wQ.js.map} +1 -1
  378. package/{tools-BmLzkvNr.mjs → tools-B3_8C78Q.mjs} +6 -6
  379. package/{tools-BmLzkvNr.mjs.map → tools-B3_8C78Q.mjs.map} +1 -1
  380. package/{tools-DmcIe2Cb.js → tools-CqOcmHR8.js} +6 -6
  381. package/{tools-DmcIe2Cb.js.map → tools-CqOcmHR8.js.map} +1 -1
  382. package/{toon-BvTQsKdN.mjs → toon-BSlr88px.mjs} +5 -5
  383. package/{toon-BvTQsKdN.mjs.map → toon-BSlr88px.mjs.map} +1 -1
  384. package/{toon-B05eKx-q.js → toon-D71tkyI3.js} +5 -5
  385. package/{toon-B05eKx-q.js.map → toon-D71tkyI3.js.map} +1 -1
  386. package/{turn_runner-DEGCvfVZ.mjs → turn_runner-BHHD6h77.mjs} +5 -5
  387. package/{turn_runner-DEGCvfVZ.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
  388. package/{turn_runner-DT8TseR4.js → turn_runner-DhLI7OTH.js} +5 -5
  389. package/{turn_runner-DT8TseR4.js.map → turn_runner-DhLI7OTH.js.map} +1 -1
  390. package/turn_runner.cjs +1 -1
  391. package/turn_runner.mjs +1 -1
  392. package/types-D6X_aUIb.mjs.map +1 -1
  393. package/types-DrSosVaM.js.map +1 -1
  394. package/{validate-lzy9nG_E.mjs → validate-Bi7FGjoq.mjs} +13 -1
  395. package/{validate-lzy9nG_E.mjs.map → validate-Bi7FGjoq.mjs.map} +1 -1
  396. package/{validate-CdOS7S2u.js → validate-CkQI-48O.js} +13 -1
  397. package/{validate-CdOS7S2u.js.map → validate-CkQI-48O.js.map} +1 -1
  398. package/{xml-DDTIMpY3.js → xml-BeNvlifb.js} +5 -5
  399. package/{xml-DDTIMpY3.js.map → xml-BeNvlifb.js.map} +1 -1
  400. package/{xml-VhJ4NrMB.mjs → xml-vyCZZiF_.mjs} +5 -5
  401. package/{xml-VhJ4NrMB.mjs.map → xml-vyCZZiF_.mjs.map} +1 -1
  402. package/{yaml-Cx16IYJq.js → yaml-DhLLa2cj.js} +5 -5
  403. package/{yaml-Cx16IYJq.js.map → yaml-DhLLa2cj.js.map} +1 -1
  404. package/{yaml-Du4wFGzL.mjs → yaml-Dtz0Bd7J.mjs} +5 -5
  405. package/{yaml-Du4wFGzL.mjs.map → yaml-Dtz0Bd7J.mjs.map} +1 -1
  406. package/artifact_methods-BMCahBLn.mjs +0 -1
  407. package/artifact_methods-f_bSy4kX.js +0 -1
  408. package/isolation-7xbkc12r.mjs.map +0 -1
  409. package/isolation-BQCTQYZ_.js.map +0 -1
  410. package/spooled_artifact-BkueYJhR.mjs.map +0 -1
  411. package/spooled_artifact-DriNQRj7.js.map +0 -1
  412. package/tokenizable-CWW7iSrD.js.map +0 -1
  413. package/tokenizable-DLMP68ZV.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.mjs","names":["#baseline"],"sources":["../../../../src/batteries/llm/openai_responses/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter for the OpenAI Responses API.\n *\n * @module @nhtio/adk/batteries/llm/openai_responses/adapter\n *\n * @remarks\n * Cross-environment LLM adapter for the OpenAI Responses wire shape — a flat `input: Item[]` array\n * (not `messages[]`), where a tool call and its result are two SIBLING top-level items\n * (`function_call` / `function_call_output`), and the system prompt defaults to a top-level\n * `instructions` string rather than a leading message item.\n *\n * The adapter is built around the same three pluggable layers as `openai_chat_completions`:\n *\n * 1. **Translation helpers** — the swappable functions exported from `./helpers` turn ADK\n * primitives into Responses wire shapes. Consumers override individual helpers via\n * `options.helpers.*`.\n * 2. **Three-layer options merging** — constructor baseline, per-`executor()` overrides, and\n * per-iteration `ctx.stash.openaiResponses` overrides combine with key-by-key precedence for\n * `headers`/`helpers`/`retry` and wholesale replacement for everything else. The merged shape\n * is re-validated on every iteration.\n * 3. **Cross-env transport** — hand-rolled `fetch` + SSE parsing, mirroring\n * `openai_chat_completions/adapter.ts`'s transport exactly. No `openai` SDK dependency.\n *\n * This adapter is STATELESS by design: `store: false` is always sent (never a settable option),\n * and the full `input` array is resent every iteration. There is no `[DONE]` sentinel on the\n * Responses SSE stream — termination is `response.completed` / `.incomplete` / `.failed`; EOF\n * without one of these is a best-effort recovery, not a hard failure: it warn-logs and drains\n * whatever was accumulated rather than nacking with {@link E_OPENAI_RESPONSES_STREAM_ERROR} (that\n * exception is reserved for a genuine stream-level error, e.g. the connection itself failing).\n *\n * Recoverable-failure handling: a 400 whose body matches `invalid_encrypted_content` drops every\n * reasoning item from the resolved input and retries the request once — a documented real-world\n * failure mode when a persisted reasoning `Thought` outlives a server-side key rotation. A 400\n * matching the reasoning/output-item pairing violation phrases translates to\n * {@link E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED} instead of a generic HTTP error.\n *\n * `background` is NOT supported: this executor has no polling/resumption loop for a\n * `queued`/`in_progress` background response (the Responses API's async mode; see\n * https://platform.openai.com/docs/guides/background), so `background: true` is rejected up front\n * by the options schema (`E_INVALID_OPENAI_RESPONSES_OPTIONS`, see `validation.ts`) rather than\n * reaching this executor at all — accepting it here would otherwise fall straight into the\n * ordinary streaming/non-streaming response handling below and treat the initial\n * `queued`/`in_progress` response body as a complete, empty answer, silently discarding whatever\n * the background job eventually produces.\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport { looksLikeSpooledArtifact, normalizeToolName } from '../chat_common/helpers'\nimport {\n computeBackoff,\n sleepWithJitter,\n parseRetryAfter,\n linkAbortSignals,\n} from '../../../lib/utils/retry'\nimport {\n Tokenizable,\n ToolCall,\n Message,\n Thought,\n SpooledArtifact,\n Media,\n ArtifactTool,\n} from '@nhtio/adk/common'\nimport {\n E_INVALID_OPENAI_RESPONSES_OPTIONS,\n E_OPENAI_RESPONSES_CONTEXT_OVERFLOW,\n E_OPENAI_RESPONSES_HTTP_ERROR,\n E_OPENAI_RESPONSES_STREAM_ERROR,\n E_OPENAI_RESPONSES_STREAM_STALLED,\n E_OPENAI_RESPONSES_REQUEST_TIMEOUT,\n E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS,\n E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED,\n} from './exceptions'\nimport {\n defaultDescriptionToChatCompletionsJsonSchema,\n defaultRenderUntrustedContent,\n defaultRenderTrustedContent,\n defaultRenderStandingInstructions,\n defaultRenderMemories,\n defaultRenderRetrievables,\n defaultRenderRetrievableHandleBody,\n defaultRenderRetrievableSafetyDirective,\n defaultRenderFirstPartyRetrievables,\n defaultRenderThirdPartyPublicRetrievables,\n defaultRenderThirdPartyPrivateRetrievables,\n defaultRenderArtifactHandleBody,\n defaultRenderThought,\n defaultFilterThoughts,\n defaultToolsToChatCompletionsTools,\n defaultRenderChatCompletionsSystemPrompt,\n defaultRenderOpenAIResponsesMediaBlocks,\n defaultRenderOpenAIResponsesTimelineMessage,\n defaultRenderOpenAIResponsesToolCallResult,\n defaultToolsToOpenAIResponsesTools,\n fingerprintOpenAIResponsesPrefix,\n defaultRenderOpenAIResponsesReasoningItem,\n defaultBuildOpenAIResponsesInput,\n defaultCreateResponsesOutputSlotMachine,\n normalizeOpenAIResponsesItemId,\n} from './helpers'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { Tool, Memory, TokenEncoding } from '@nhtio/adk/common'\nimport type {\n DispatchExecutorFn,\n DispatchExecutorHelpers,\n GenerationStats,\n} from '@nhtio/adk/dispatch_runner'\nimport type {\n OpenAIResponsesAdapterOptions,\n OpenAIResponsesHelpers,\n ChatCompletionsRetryConfig,\n OpenAIResponsesRequestBody,\n OpenAIResponsesInputItem,\n OpenAIResponsesInputContentBlock,\n OpenAIResponsesReasoningItem,\n OpenAIResponsesFunctionCallItem,\n OpenAIResponsesStreamEvent,\n OpenAIResponsesResponseObject,\n OpenAIResponsesReasoningReplayPayload,\n OpenAIResponsesTool,\n} from './types'\n\n// ─── ADK-control keys (stripped before sending the request body) ──────────\n\nconst ADK_CONTROL_KEYS: ReadonlySet<string> = new Set([\n 'apiKey',\n 'baseURL',\n 'organization',\n 'project',\n 'headers',\n 'fetch',\n 'stream',\n 'bucketOrder',\n 'contextWindow',\n 'selfIdentity',\n 'thoughtSurfacing',\n 'tokenEncoding',\n 'replayCompatibility',\n 'helpers',\n 'streamIdleTimeoutMs',\n 'requestTimeoutMs',\n 'retry',\n 'strictToolChoice',\n // `strict` configures the EMITTED TOOL DECLARATIONS (it becomes each function tool's own\n // `strict` field via `toolsToOpenAIResponsesTools`) — it is not a top-level Responses request\n // property. Without this entry the generic body spread forwarded it verbatim, so an adapter\n // constructed with `strict: true` put `\"strict\": true` on the wire alongside `model`/`input`,\n // where the API can reject the request before generation. Verified against the real wire body:\n // the keys sent were `input, instructions, model, store, stream, strict`.\n 'strict',\n 'autoAck',\n 'unsupportedMediaPolicy',\n 'localToolCallParser',\n 'forgeToolsFilter',\n 'spoolStore',\n // Responses-specific ADK control\n 'systemPromptChannel',\n 'reasoningReplay',\n // Observability hooks — never sent to the provider.\n 'onRawGeneration',\n 'onPromptAssembled',\n 'toolCallIdFilter',\n])\n\n// ─── Option merging ───────────────────────────────────────────────────────────\n\nconst mergeRetry = (\n layers: ReadonlyArray<ChatCompletionsRetryConfig | undefined>\n): ChatCompletionsRetryConfig | undefined => {\n let merged: ChatCompletionsRetryConfig | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeHeaders = (\n layers: ReadonlyArray<Record<string, string> | undefined>\n): Record<string, string> | undefined => {\n let merged: Record<string, string> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeHelpers = (\n layers: ReadonlyArray<Partial<OpenAIResponsesHelpers> | undefined>\n): Partial<OpenAIResponsesHelpers> | undefined => {\n let merged: Partial<OpenAIResponsesHelpers> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: OpenAIResponsesAdapterOptions,\n exec: Partial<OpenAIResponsesAdapterOptions> | undefined,\n stash: Partial<OpenAIResponsesAdapterOptions> | undefined\n): Partial<OpenAIResponsesAdapterOptions> => {\n const layers = [baseline as Partial<OpenAIResponsesAdapterOptions>, exec ?? {}, stash ?? {}]\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n for (const [k, v] of Object.entries(layer)) {\n if (v === undefined) continue\n if (k === 'headers' || k === 'helpers' || k === 'retry') continue\n out[k] = v\n }\n }\n const headers = mergeHeaders(layers.map((l) => l.headers))\n if (headers !== undefined) out.headers = headers\n const helpers = mergeHelpers(layers.map((l) => l.helpers))\n if (helpers !== undefined) out.helpers = helpers\n const retry = mergeRetry(layers.map((l) => l.retry))\n if (retry !== undefined) out.retry = retry\n return out as Partial<OpenAIResponsesAdapterOptions>\n}\n\n// ─── Helper resolution ────────────────────────────────────────────────────────\n\nconst resolveHelpers = (\n overrides: Partial<OpenAIResponsesHelpers> | undefined\n): OpenAIResponsesHelpers => {\n const src = overrides ?? {}\n return {\n descriptionToChatCompletionsJsonSchema:\n src.descriptionToChatCompletionsJsonSchema ?? defaultDescriptionToChatCompletionsJsonSchema,\n renderUntrustedContent: src.renderUntrustedContent ?? defaultRenderUntrustedContent,\n renderTrustedContent: src.renderTrustedContent ?? defaultRenderTrustedContent,\n renderStandingInstructions: src.renderStandingInstructions ?? defaultRenderStandingInstructions,\n renderMemories: src.renderMemories ?? defaultRenderMemories,\n renderRetrievables: src.renderRetrievables ?? defaultRenderRetrievables,\n renderRetrievableHandleBody:\n src.renderRetrievableHandleBody ?? defaultRenderRetrievableHandleBody,\n renderRetrievableSafetyDirective:\n src.renderRetrievableSafetyDirective ?? defaultRenderRetrievableSafetyDirective,\n renderFirstPartyRetrievables:\n src.renderFirstPartyRetrievables ?? defaultRenderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables:\n src.renderThirdPartyPublicRetrievables ?? defaultRenderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables:\n src.renderThirdPartyPrivateRetrievables ?? defaultRenderThirdPartyPrivateRetrievables,\n renderArtifactHandleBody: src.renderArtifactHandleBody ?? defaultRenderArtifactHandleBody,\n renderThought: src.renderThought ?? defaultRenderThought,\n filterThoughts: src.filterThoughts ?? defaultFilterThoughts,\n toolsToChatCompletionsTools:\n src.toolsToChatCompletionsTools ?? defaultToolsToChatCompletionsTools,\n renderChatCompletionsSystemPrompt:\n src.renderChatCompletionsSystemPrompt ?? defaultRenderChatCompletionsSystemPrompt,\n renderOpenAIResponsesMediaBlocks:\n src.renderOpenAIResponsesMediaBlocks ?? defaultRenderOpenAIResponsesMediaBlocks,\n renderOpenAIResponsesTimelineMessage:\n src.renderOpenAIResponsesTimelineMessage ?? defaultRenderOpenAIResponsesTimelineMessage,\n renderOpenAIResponsesToolCallResult:\n src.renderOpenAIResponsesToolCallResult ?? defaultRenderOpenAIResponsesToolCallResult,\n toolsToOpenAIResponsesTools:\n src.toolsToOpenAIResponsesTools ?? defaultToolsToOpenAIResponsesTools,\n fingerprintOpenAIResponsesPrefix:\n src.fingerprintOpenAIResponsesPrefix ?? fingerprintOpenAIResponsesPrefix,\n renderOpenAIResponsesReasoningItem:\n src.renderOpenAIResponsesReasoningItem ?? defaultRenderOpenAIResponsesReasoningItem,\n buildOpenAIResponsesInput: src.buildOpenAIResponsesInput ?? defaultBuildOpenAIResponsesInput,\n createResponsesOutputSlotMachine:\n src.createResponsesOutputSlotMachine ?? defaultCreateResponsesOutputSlotMachine,\n }\n}\n\n// ─── ID helpers ───────────────────────────────────────────────────────────────\n\n// Canonical (key-order-insensitive) checksum — MUST match the contract documented on\n// canonicalStringify and used by Tool.executor + dispatch_runner's streaming helper, so\n// ctx.toolCallCount(checksum) detects semantically-identical repeat calls regardless of argument\n// key order.\nconst computeChecksum = (tool: string, args: unknown): string =>\n sha256(canonicalStringify({ tool, args }))\n\nconst nowIso = (): string => DateTime.now().toISO() ?? new Date().toISOString()\n\n// ─── Token measurement ────────────────────────────────────────────────────────\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncoding\n): Promise<number> => {\n return Promise.resolve(value.estimateTokens(encoding))\n}\n\n// ─── Generation-stats extraction ───────────────────────────────────────────────\n\nconst extractGenerationStats = (input: {\n model: string\n usage?: OpenAIResponsesResponseObject['usage']\n finishReason?: string | null\n raw: Record<string, unknown>\n}): GenerationStats => {\n const stats: GenerationStats = {\n provider: 'openai_responses',\n model: input.model,\n raw: input.raw,\n }\n const usage = input.usage\n if (usage) {\n const cached = usage.input_tokens_details?.cached_tokens ?? 0\n if (typeof usage.input_tokens === 'number') {\n stats.promptTokens = Math.max(0, usage.input_tokens - cached)\n }\n if (typeof usage.output_tokens === 'number') stats.completionTokens = usage.output_tokens\n if (typeof usage.total_tokens === 'number') stats.totalTokens = usage.total_tokens\n }\n if (typeof input.finishReason === 'string') stats.finishReason = input.finishReason\n return stats\n}\n\n// ─── Stop-reason mapping ───────────────────────────────────────────────────────\n\nconst mapStopReason = (\n status: OpenAIResponsesResponseObject['status'],\n incompleteReason: string | undefined,\n hadToolCalls: boolean\n): string => {\n if (status === 'completed') return hadToolCalls ? 'tool_calls' : 'stop'\n if (status === 'incomplete') {\n if (incompleteReason === 'content_filter') return 'content_filter'\n return 'length'\n }\n return 'error'\n}\n\n// ─── Reasoning-replay error detection ─────────────────────────────────────────\n\nconst INVALID_ENCRYPTED_CONTENT_PHRASE = 'invalid_encrypted_content'\n// Both directions of the bidirectional pairing constraint (openai/openai-node#1791). The first\n// phrase catches a REASONING item rejected for missing its required FOLLOWING item; the second\n// catches the mirror case reported as that issue's headline error — a MESSAGE item rejected for\n// missing its required PRECEDING reasoning item (`Item 'msg_…' of type 'message' was provided\n// without its required preceding item of type 'reasoning'`), which the narrower\n// \"of type 'reasoning' was provided without\" phrasing does not match.\nconst REASONING_PAIRING_PHRASES = [\n \"of type 'reasoning' was provided without\",\n \"was provided without its required preceding item of type 'reasoning'\",\n 'items are not persisted when store is set to false',\n]\n\nconst bodyMatches = (body: string, phrases: ReadonlyArray<string>): boolean => {\n const lower = body.toLowerCase()\n return phrases.some((p) => lower.includes(p.toLowerCase()))\n}\n\n// ─── SSE framing ────────────────────────────────────────────────────────────────\n\n// A blank line delimits SSE frames. Tolerate CRLF alongside LF — some gateways/proxies\n// normalise line endings to \\r\\n, which a bare `\\n\\n` search never matches.\nconst SSE_FRAME_SEPARATOR = /\\r?\\n\\r?\\n/\n\n// ─── Adapter class ────────────────────────────────────────────────────────────\n\n/**\n * Opinionated cross-environment LLM adapter for the OpenAI Responses wire shape.\n *\n * @remarks\n * Construction validates options eagerly via {@link validateOptions} and throws\n * {@link E_INVALID_OPENAI_RESPONSES_OPTIONS} on failure. The returned instance is reusable: call\n * {@link OpenAIResponsesAdapter.executor} once per `DispatchRunner` configuration.\n *\n * Per-iteration overrides live on the active `DispatchContext`'s `stash.openaiResponses` slot and\n * take highest precedence — they merge into the executor-scope shape on every iteration.\n * `headers`, `helpers`, and `retry` merge key-by-key across all three layers; every other field is\n * replaced wholesale at the highest layer that sets it.\n */\nexport class OpenAIResponsesAdapter {\n /**\n * Customary key for per-iteration overrides on `ctx.stash`. The adapter reads\n * `ctx.stash.get(OpenAIResponsesAdapter.STASH_KEY, {})` at the start of every iteration and\n * merges the value into the resolved options shape.\n */\n public static readonly STASH_KEY = 'openaiResponses' as const\n\n readonly #baseline: OpenAIResponsesAdapterOptions\n\n /**\n * @param options - Constructor-baseline options. Re-validated on every iteration after\n * per-dispatch and per-iteration overrides are layered in.\n * @throws {@link E_INVALID_OPENAI_RESPONSES_OPTIONS} when `options` does not satisfy\n * `openAIResponsesOptionsSchema`.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n }\n\n /**\n * Returns a `DispatchExecutorFn` bound to this adapter's baseline plus optional executor-scope\n * overrides. The returned function is reusable across iterations — every iteration re-merges\n * with `ctx.stash[STASH_KEY]` and re-validates the result.\n *\n * @param overrides - Optional executor-scope overrides. Higher precedence than the baseline,\n * lower precedence than `ctx.stash[STASH_KEY]`.\n * @returns A `DispatchExecutorFn` suitable for `DispatchRunner`.\n */\n executor(overrides?: Partial<OpenAIResponsesAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = OpenAIResponsesAdapter\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n const localWarn = (msg: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message: msg })\n }\n\n // ── Step 1: merge & validate ──────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<OpenAIResponsesAdapterOptions>)\n : {}\n const mergedRaw = mergeOptions(baseline, overrides, stashOverrides)\n const merged = validateOptions(mergedRaw)\n\n if (merged.tokenEncoding !== null && merged.contextWindow === undefined) {\n throw new E_INVALID_OPENAI_RESPONSES_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n\n // ── Step 2: resolve helpers ───────────────────────────────────────────\n const resolvedHelpers = resolveHelpers(merged.helpers)\n\n // ── Step 3: artifact-reader tools ─────────────────────────────────────\n // Forged by the DispatchRunner CORE into `ctx.tools` before the input pipeline runs\n // (generation is a generic core concern; this battery owns only representation). Read the\n // pre-forged `ctx.tools` directly — no local merge, no bindContext here.\n\n // ── Step 4: pre-render tool-call results ──────────────────────────────\n const renderedToolCallResults = new Map<\n ToolCall,\n string | OpenAIResponsesInputContentBlock[]\n >()\n for (const tc of ctx.turnToolCalls) {\n const rendered = await resolvedHelpers.renderOpenAIResponsesToolCallResult({\n toolCall: tc,\n results: tc.results as\n | Tokenizable\n | SpooledArtifact\n | SpooledArtifact[]\n | Media\n | Media[],\n tool: ctx.tools.get(tc.tool) as Tool | ArtifactTool | undefined,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n renderOpenAIResponsesMediaBlocks: resolvedHelpers.renderOpenAIResponsesMediaBlocks,\n renderArtifactHandleBody: resolvedHelpers.renderArtifactHandleBody,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn: localWarn,\n })\n renderedToolCallResults.set(tc, rendered)\n }\n\n // ── Step 5: context window enforcement ────────────────────────────────\n if (merged.tokenEncoding !== null && merged.contextWindow !== undefined) {\n const encoding = merged.tokenEncoding as TokenEncoding\n let spTokens = await estimateTokensOf(ctx.systemPrompt, encoding)\n let siTokens = 0\n {\n // The wire ships ONE `<system_instructions kind=\"developer-rules\">` block wrapping every\n // standing instruction (+68 chars over a 15-char body), not the raw strings. Counting the\n // rendered block captures both the bodies and that wrapper.\n const siBlock = resolvedHelpers.renderStandingInstructions(ctx.standingInstructions)\n if (siBlock.length > 0) {\n siTokens = await estimateTokensOf(new Tokenizable(siBlock), encoding)\n }\n }\n let memTokens = 0\n for (const mem of ctx.turnMemories as Set<Memory>) {\n memTokens += await estimateTokensOf(mem.content, encoding)\n }\n let retTokens = 0\n for (const r of ctx.turnRetrievables) {\n retTokens +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n encoding,\n resolvedHelpers.renderRetrievableHandleBody\n )\n : await estimateTokensOf(r.content, encoding)\n }\n let tlTokens = 0\n for (const msg of ctx.turnMessages) {\n if (msg.content !== undefined) {\n // Count the RENDERED message, not the raw content. Every timeline message goes on the\n // wire wrapped in an identity envelope — `<message_<id> from=… role=… createdAt=…>` —\n // which the guard previously ignored entirely. Measured: a 30-char message ships as\n // 118 chars (3.9x), and the envelope is a near-fixed ~90 chars regardless of body\n // length, so a 40-turn conversation of short messages leaked ~880 tokens the guard\n // never saw. Rendering it here is the honest measure: it is the same helper the\n // builder uses, so the count tracks the wire by construction rather than by a\n // hand-maintained estimate that drifts when the envelope changes.\n const renderedMsg = await resolvedHelpers.renderOpenAIResponsesTimelineMessage({\n message: msg,\n selfIdentity: merged.selfIdentity ?? 'assistant',\n // Media is tallied separately below, from byte length; asking this renderer to\n // resolve attachments would duplicate the base64 work and can throw under\n // `unsupportedMediaPolicy: 'throw'` purely to measure it.\n unsupportedMediaPolicy: 'synthetic-description',\n renderOpenAIResponsesMediaBlocks: resolvedHelpers.renderOpenAIResponsesMediaBlocks,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n })\n const renderedText =\n renderedMsg === null\n ? ''\n : (\n ((renderedMsg as { content?: unknown }).content as\n | Array<{ type: string; text?: string }>\n | undefined) ?? []\n )\n .filter((b) => b.type === 'input_text')\n .map((b) => b.text ?? '')\n .join('')\n tlTokens += await estimateTokensOf(\n new Tokenizable(renderedText.length > 0 ? renderedText : msg.content.toString()),\n encoding\n )\n }\n // A message's ATTACHMENTS render into real wire content — `renderOpenAIResponsesTimeline\n // Message` turns each one into `input_image`/`input_file` blocks carrying a base64\n // payload — so they must be tallied too. Counting only `msg.content` left a user turn\n // with an image attachment entirely invisible to the guard, which is the same\n // undercount already fixed for rendered tool-call results below, one code path over.\n //\n // The media is measured by its own byte length rather than by rendering it here:\n // re-rendering would duplicate the base64 work (and can throw under\n // `unsupportedMediaPolicy: 'throw'`) purely to measure it. base64 inflates bytes by 4/3,\n // and a token is ~4 base64 chars, so `byteLength / 3` is the honest FLOOR for the\n // payload — same doctrine as the tool-declaration and native-block floors.\n for (const media of msg.attachments ?? []) {\n try {\n const bytes = await media.byteLength()\n if (bytes !== undefined && Number.isFinite(bytes) && bytes > 0) {\n tlTokens += Math.ceil(bytes / 3)\n }\n } catch {\n /* unreadable attachment — cannot measure it; the floor simply omits it */\n }\n }\n }\n for (const th of ctx.turnThoughts) {\n // Same envelope problem as messages: a surfaced thought ships wrapped in\n // `<thought_<id> nonce=… kind=… from=… createdAt=…>`, measured at +113 chars over a\n // 19-char body. Count the rendered form so the tally tracks the wire.\n const renderedThought = resolvedHelpers.renderThought(th.content.toString(), {\n nonce: th.id,\n kind: 'self-reasoning',\n from: String(th.identity?.identifier ?? merged.selfIdentity ?? 'assistant'),\n createdAt: th.createdAt?.toISO?.() ?? undefined,\n })\n tlTokens += await estimateTokensOf(new Tokenizable(renderedThought), encoding)\n }\n for (const rendered of renderedToolCallResults.values()) {\n if (typeof rendered === 'string') {\n tlTokens += await estimateTokensOf(new Tokenizable(rendered), encoding)\n continue\n }\n // Count EVERY block that is actually transmitted, not just `input_text`. A native\n // `input_image`/`input_file` block carries a base64 payload in `image_url`/`file_data`\n // that is real request content; filtering those out understated the request by the\n // entire attachment, so a prompt the guard accepted could still exceed the provider's\n // window. Tallying the block's own wire JSON keeps this an honest FLOOR (the provider\n // bills images by its own tiling rules, which are not reproducible client-side) rather\n // than a pretend-exact count — same doctrine as the tool-declaration floor below.\n for (const block of rendered) {\n const text =\n block.type === 'input_text' ? block.text : JSON.stringify(block satisfies object)\n tlTokens += await estimateTokensOf(new Tokenizable(text), encoding)\n }\n }\n // Tool-call REQUEST items. A tool call goes on the wire as two sibling items — the\n // `function_call` (carrying `name` + `arguments`) and its `function_call_output` — but only\n // the OUTPUT was tallied above, via `renderedToolCallResults`. A prior call with large\n // arguments was therefore invisible to the guard. Counting the `function_call` item's own\n // wire JSON keeps this the same honest FLOOR as the blocks above.\n for (const tc of ctx.turnToolCalls) {\n const argsText = typeof tc.args === 'string' ? tc.args : JSON.stringify(tc.args ?? {})\n const callItemJson = JSON.stringify({\n type: 'function_call',\n call_id: tc.id,\n name: tc.tool,\n arguments: argsText,\n })\n tlTokens += await estimateTokensOf(new Tokenizable(callItemJson), encoding)\n }\n // Tool DECLARATIONS: tally the tokens of the wire `tools` JSON as an honest FLOOR — same\n // rationale as `openai_chat_completions/adapter.ts`.\n let toolTokens = 0\n const visibleTools = ctx.tools.visible()\n if (visibleTools.length > 0) {\n const toolsJson = JSON.stringify(\n resolvedHelpers.toolsToOpenAIResponsesTools(visibleTools, {\n descriptionToChatCompletionsJsonSchema: (d: unknown) =>\n resolvedHelpers.descriptionToChatCompletionsJsonSchema(d as never),\n strict: merged.strict,\n })\n )\n toolTokens = await estimateTokensOf(new Tokenizable(toolsJson), encoding)\n }\n const total = spTokens + siTokens + memTokens + retTokens + tlTokens + toolTokens\n const perBucketObj = {\n systemPrompt: spTokens,\n standingInstructions: siTokens,\n memories: memTokens,\n retrievables: retTokens,\n timeline: tlTokens,\n tools: toolTokens,\n }\n helpers.log.debug({\n kind: 'context-window-usage',\n message: `Context window usage: ${total}/${merged.contextWindow} tokens`,\n payload: {\n total,\n limit: merged.contextWindow,\n encoding,\n perBucket: perBucketObj,\n },\n })\n if (total > merged.contextWindow) {\n const perBucket = JSON.stringify(perBucketObj)\n throw new E_OPENAI_RESPONSES_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n encoding,\n perBucket,\n ])\n }\n }\n\n // ── Step 5b: tool_choice + forged artifact-tools guard ────────────────\n const toolChoice = merged.tool_choice\n const forcedToolNames: string[] = []\n if (toolChoice && typeof toolChoice === 'object' && toolChoice.type === 'function') {\n forcedToolNames.push(toolChoice.name)\n }\n const forcedForgedHits: Array<{ toolName: string }> = []\n for (const name of forcedToolNames) {\n const t = ctx.tools.get(name) as { ephemeral?: boolean } | undefined\n if (t?.ephemeral === true) {\n forcedForgedHits.push({ toolName: name })\n }\n }\n if (forcedForgedHits.length > 0) {\n if (merged.strictToolChoice === true) {\n throw new E_INVALID_OPENAI_RESPONSES_OPTIONS([\n `tool_choice forces forged ephemeral artifact-query tool(s): ${forcedForgedHits\n .map((h) => h.toolName)\n .join(\n ', '\n )} — these may not exist on the next iteration. Remove the override or unset strictToolChoice.`,\n ])\n }\n helpers.log.warn({\n kind: 'tool-choice-forged-artifact',\n message: `tool_choice forces ${forcedForgedHits.length} forged ephemeral artifact-query tool(s); this is almost always a misconfiguration`,\n payload: { toolNames: forcedForgedHits.map((h) => h.toolName) },\n })\n }\n\n // ── Step 6: build request body ────────────────────────────────────────\n const buildInput = async (\n dropReasoning: boolean\n ): Promise<{\n instructions?: string\n input: OpenAIResponsesInputItem[]\n tools?: OpenAIResponsesTool[]\n fingerprintableLength: number\n }> => {\n return resolvedHelpers.buildOpenAIResponsesInput({\n model: merged.model,\n systemPrompt: ctx.systemPrompt,\n // The live dispatch context, so a DYNAMIC system prompt (a `Tokenizable` built from a\n // `(ctx) => string` resolver) sees it. Previously nothing passed this, so such a prompt\n // rendered against `undefined` and quietly dropped everything it read from context.\n renderCtx: ctx,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: dropReasoning ? [] : ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: ctx.tools,\n strict: merged.strict,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? [\n 'standingInstructions',\n 'memories',\n 'retrievables',\n 'timeline',\n ],\n selfIdentity: merged.selfIdentity ?? 'assistant',\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n reasoningReplay: dropReasoning ? 'off' : (merged.reasoningReplay ?? 'off'),\n systemPromptChannel: merged.systemPromptChannel ?? 'instructions',\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n renderOpenAIResponsesToolCallResult: resolvedHelpers.renderOpenAIResponsesToolCallResult,\n renderOpenAIResponsesMediaBlocks: resolvedHelpers.renderOpenAIResponsesMediaBlocks,\n renderChatCompletionsSystemPrompt: resolvedHelpers.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: resolvedHelpers.renderStandingInstructions,\n renderMemories: resolvedHelpers.renderMemories,\n renderRetrievables: resolvedHelpers.renderRetrievables,\n renderRetrievableSafetyDirective: resolvedHelpers.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: resolvedHelpers.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: resolvedHelpers.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: resolvedHelpers.renderThirdPartyPrivateRetrievables,\n renderRetrievableHandleBody: resolvedHelpers.renderRetrievableHandleBody,\n renderOpenAIResponsesTimelineMessage:\n resolvedHelpers.renderOpenAIResponsesTimelineMessage,\n renderOpenAIResponsesReasoningItem: resolvedHelpers.renderOpenAIResponsesReasoningItem,\n fingerprintOpenAIResponsesPrefix: resolvedHelpers.fingerprintOpenAIResponsesPrefix,\n toolsToOpenAIResponsesTools: resolvedHelpers.toolsToOpenAIResponsesTools,\n descriptionToChatCompletionsJsonSchema:\n resolvedHelpers.descriptionToChatCompletionsJsonSchema,\n renderThought: resolvedHelpers.renderThought,\n filterThoughts: resolvedHelpers.filterThoughts,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n warn: localWarn,\n })\n }\n\n let assembled = await buildInput(false)\n\n const stream = merged.stream ?? true\n const buildBody = (a: {\n instructions?: string\n input: OpenAIResponsesInputItem[]\n tools?: OpenAIResponsesTool[]\n }): OpenAIResponsesRequestBody => {\n const b: OpenAIResponsesRequestBody = {\n model: merged.model,\n input: a.input,\n stream,\n store: false,\n }\n if (a.instructions !== undefined) b.instructions = a.instructions\n for (const [k, v] of Object.entries(merged)) {\n if (ADK_CONTROL_KEYS.has(k)) continue\n if (\n k === 'model' ||\n k === 'input' ||\n k === 'stream' ||\n k === 'store' ||\n k === 'instructions' ||\n k === 'tool_choice' ||\n k === 'tools'\n )\n continue\n if (v === undefined) continue\n ;(b as Record<string, unknown>)[k] = v\n }\n if (merged.tool_choice !== undefined) b.tool_choice = merged.tool_choice\n if (a.tools && a.tools.length > 0) b.tools = a.tools\n // reasoningReplay 'encrypted' auto-adds 'reasoning.encrypted_content' to `include`.\n if (merged.reasoningReplay === 'encrypted') {\n const include = new Set(b.include ?? [])\n include.add('reasoning.encrypted_content')\n b.include = Array.from(include)\n }\n return b\n }\n\n let body = buildBody(assembled)\n\n const dispatchStreamId = uuidv6()\n\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'openai_responses',\n kind: 'request-body',\n messages: body.input,\n tools: body.tools,\n requestBody: body,\n streamed: stream,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // ── Step 7: POST with retry / timeout loop ────────────────────────────\n const rawBase = merged.baseURL ?? 'https://api.openai.com/v1'\n const baseURL = rawBase.endsWith('/') ? rawBase.slice(0, -1) : rawBase\n const url = `${baseURL}/responses`\n\n const buildHeaders = (): Record<string, string> => {\n const h: Record<string, string> = { 'Content-Type': 'application/json' }\n if (stream) h['Accept'] = 'text/event-stream'\n if (merged.apiKey) h['Authorization'] = `Bearer ${merged.apiKey}`\n if (merged.organization) h['OpenAI-Organization'] = merged.organization\n if (merged.project) h['OpenAI-Project'] = merged.project\n if (merged.headers) Object.assign(h, merged.headers)\n return h\n }\n\n const retryCfg: ChatCompletionsRetryConfig = {\n maxAttempts: merged.retry?.maxAttempts ?? 1,\n baseDelayMs: merged.retry?.baseDelayMs ?? 500,\n maxDelayMs: merged.retry?.maxDelayMs ?? 30_000,\n retriableStatuses: merged.retry?.retriableStatuses ?? [429, 502, 503, 504],\n honorRetryAfter: merged.retry?.honorRetryAfter ?? true,\n }\n\n const fetchFn = merged.fetch ?? globalThis.fetch\n const maxAttempts = retryCfg.maxAttempts ?? 1\n\n // The one-time reasoning-drop retry (Known Gotcha / recoverable-failure handling) is\n // ORTHOGONAL to the retry/backoff loop below — it re-assembles the request body once (with\n // every reasoning item stripped) and re-enters the whole POST loop fresh, rather than being\n // counted against `maxAttempts`.\n let usedReasoningDropRetry = false\n\n let response: Response | undefined\n let attempt = 1\n let attemptStartedAtMs = Date.now()\n let disposeLink: () => void = () => {}\n requestLoop: while (attempt <= maxAttempts) {\n if (ctx.abortSignal.aborted) return\n\n const internalController = new AbortController()\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n // When THIS attempt's HTTP exchange began. `requestTimeoutMs` is a whole-exchange budget,\n // so the body-read deadline further down is measured from here rather than from the moment\n // headers arrived — otherwise a response that spent most of the budget before sending\n // headers was granted a second, full interval to stream its body.\n attemptStartedAtMs = Date.now()\n const requestTimeoutMs = merged.requestTimeoutMs ?? 0\n if (requestTimeoutMs > 0) {\n timeoutHandle = setTimeout(() => internalController.abort(), requestTimeoutMs)\n }\n disposeLink()\n const { signal: linkedSignal, dispose: disposeCurrentLink } = linkAbortSignals([\n ctx.abortSignal,\n internalController.signal,\n ])\n disposeLink = disposeCurrentLink\n\n try {\n response = await fetchFn(url, {\n method: 'POST',\n headers: buildHeaders(),\n body: JSON.stringify(body),\n signal: linkedSignal,\n })\n } catch (err) {\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n if (ctx.abortSignal.aborted) return\n if (internalController.signal.aborted) {\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Request timed out after ${requestTimeoutMs}ms on attempt ${attempt}/${maxAttempts}`,\n payload: { requestTimeoutMs, attempt, maxAttempts },\n })\n if (attempt < maxAttempts) {\n const delay = computeBackoff(attempt, retryCfg)\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n ctx.nack(new E_OPENAI_RESPONSES_REQUEST_TIMEOUT([requestTimeoutMs]))\n return\n }\n helpers.log.error({\n kind: 'transport-error',\n message: `Transport failure on attempt ${attempt}/${maxAttempts}: ${isError(err) ? err.message : String(err)}`,\n payload: { attempt, maxAttempts, detail: isError(err) ? err.message : String(err) },\n })\n if (attempt < maxAttempts) {\n const delay = computeBackoff(attempt, retryCfg)\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n ctx.nack(new E_OPENAI_RESPONSES_HTTP_ERROR([0, isError(err) ? err.message : String(err)]))\n return\n }\n\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n\n if (!response.ok) {\n const status = response.status\n const errBody = await response.text().catch(() => '')\n\n // ── Recoverable-failure handling: a rejected REPLAYED reasoning item ──\n //\n // Two upstream 400s mean the same thing — \"the reasoning item you replayed is not\n // acceptable\" — and both have the same safe recovery: strip every reasoning item and\n // resend. They are handled identically:\n //\n // 1. `invalid_encrypted_content` — a persisted `encrypted_content` payload outlived a\n // server-side key rotation.\n // 2. A reasoning/output-item PAIRING violation — the adjacency constraint reported in\n // `openai/openai-node#1791` (see below).\n //\n // Case 2 previously nacked immediately, killing the turn and telling the caller to set\n // `reasoningReplay: 'off'` by hand. That was the wrong default for a failure the adapter\n // can recover from unaided, and it mattered most exactly where the constraint is least\n // certain: the pairing rule is UNDOCUMENTED, and the official docs actively contradict\n // it (the reasoning guide and cookbook both state that irrelevant reasoning items are\n // silently discarded — \"including them is harmless\"), while #1791 reports a hard 400\n // reproduced across five official SDKs. Because our adjacency sweep enforces a stricter\n // rule than the documented span rule, an upstream behavior shift could make the sweep\n // wrong — and the correct outcome then is a turn that degrades to no-replay, not a turn\n // that dies. The retry is still ONE-SHOT, so a genuinely broken request cannot loop.\n if (\n status === 400 &&\n !usedReasoningDropRetry &&\n bodyMatches(errBody, [INVALID_ENCRYPTED_CONTENT_PHRASE, ...REASONING_PAIRING_PHRASES])\n ) {\n usedReasoningDropRetry = true\n helpers.log.warn({\n kind: 'reasoning-replay-rejected',\n message:\n 'Upstream rejected a replayed reasoning item; dropping all reasoning items and retrying once.',\n payload: { status, body: errBody.slice(0, 512) },\n })\n assembled = await buildInput(true)\n body = buildBody(assembled)\n // Give the REBUILT request its own transport-retry budget. Plain `continue` leaves\n // `attempt` where the failed original left it, so a reasoning rejection arriving on the\n // last attempt handed the replacement a fully-spent budget: one transient 503 on the\n // rebuilt request then ended the turn, even though the recovery itself had worked. That\n // contradicts this block's own contract (the reasoning-drop retry is ORTHOGONAL to the\n // retry/backoff loop, not counted against it).\n //\n // Deliberately a FRESH BUDGET, not an unbounded one: `usedReasoningDropRetry` is\n // one-shot, so this reset can happen at most once per dispatch. Worst case is one\n // additional `maxAttempts` worth of POSTs, never a loop.\n attempt = 1\n continue requestLoop\n }\n\n // ── Reasoning/output-item pairing violation translation ─────────────\n // Reached only when the reasoning-free retry ALSO failed, so the rejection is not\n // attributable to a replayed reasoning item after all — the self-explaining error is\n // then the honest answer rather than a recovery the adapter has already tried.\n if (status === 400 && bodyMatches(errBody, REASONING_PAIRING_PHRASES)) {\n const offendingId =\n assembled.input.find((i): i is OpenAIResponsesReasoningItem => i.type === 'reasoning')\n ?.id ?? 'unknown'\n ctx.nack(new E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED([offendingId, errBody]))\n return\n }\n\n const retriable = (retryCfg.retriableStatuses ?? [429, 502, 503, 504]).includes(status)\n if (retriable && attempt < maxAttempts) {\n let delay = computeBackoff(attempt, retryCfg)\n if (retryCfg.honorRetryAfter !== false) {\n const ra = response.headers.get('Retry-After')\n if (ra) {\n const raMs = parseRetryAfter(ra)\n if (raMs > 0) delay = Math.min(Math.max(delay, raMs), retryCfg.maxDelayMs ?? 30_000)\n }\n }\n helpers.log.warn({\n kind: 'retry-attempt',\n message: `HTTP ${status} on attempt ${attempt}/${maxAttempts}; retrying in ~${delay}ms`,\n payload: {\n reason: 'http-status',\n status,\n delayMs: delay,\n attempt: attempt + 1,\n maxAttempts,\n },\n })\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n helpers.log.error({\n kind: 'http-error',\n message: `HTTP ${status} (terminal): ${errBody.slice(0, 256)}`,\n payload: { status, body: errBody, attempt, maxAttempts, retriable },\n })\n ctx.nack(new E_OPENAI_RESPONSES_HTTP_ERROR([status, errBody]))\n return\n }\n\n break\n }\n\n if (!response) return\n\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n\n // ── Inner helper: persist + execute one assembled tool call ───────────\n const executeAndPersistToolCall = async (call: {\n id: string\n name: string\n args: string\n }): Promise<void> => {\n // Resolve the vendor id once at ingress so reporting, persistence, and spooling agree.\n const callId = merged.toolCallIdFilter?.(call.id, ctx) ?? call.id\n const tool = ctx.tools.get(call.name)\n let args: Record<string, unknown> = {}\n let parseError: InstanceType<typeof E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS> | undefined\n if (call.args && call.args.length > 0) {\n try {\n const parsed: unknown = JSON.parse(call.args)\n if (isObject(parsed)) {\n args = parsed\n } else {\n const receivedKind = Array.isArray(parsed)\n ? 'array'\n : parsed === null\n ? 'null'\n : typeof parsed\n parseError = new E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS([\n `must be a JSON object; received ${receivedKind}`,\n call.args,\n ])\n }\n } catch {\n parseError = new E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS([\n 'are not valid JSON',\n call.args,\n ])\n }\n }\n const completedAt = nowIso()\n if (parseError !== undefined) {\n const toolName = normalizeToolName(call.name)\n const results = new Tokenizable(parseError.message)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, { results, isError: true, isComplete: true })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\n args,\n checksum,\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n if (!tool) {\n const toolName = normalizeToolName(call.name)\n const available = ctx.tools\n .all()\n .map((t) => t.name)\n .sort()\n const errText =\n available.length > 0\n ? `Tool not found: ${toolName}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${toolName}. No tools are available this turn.`\n const results = new Tokenizable(errText)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, { results, isError: true, isComplete: true })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\n args,\n checksum,\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n helpers.reportToolCall(callId, { tool: tool.name, args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(args)\n if (isArtifactTool) {\n if (Tokenizable.isTokenizable(raw)) {\n results = raw\n } else if (typeof raw === 'string') {\n results = new Tokenizable(raw)\n } else {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n }\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(callId, raw as string | Uint8Array)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(callId, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n let detailMsg = isError(err) ? err.message : String(err)\n if (\n isError(err) &&\n isError(err.cause) &&\n err.cause.message &&\n err.cause.message !== err.message\n ) {\n detailMsg = `${detailMsg} ${err.cause.message}`\n }\n results = new Tokenizable(detailMsg)\n }\n helpers.reportToolCall(callId, { results, isError: toolHadError, isComplete: true })\n const checksum = computeChecksum(tool.name, args)\n const completedAt2 = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: tool.name,\n args,\n checksum,\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n inline: isArtifactTool,\n createdAt: completedAt2,\n updatedAt: completedAt2,\n completedAt: completedAt2,\n })\n )\n }\n\n // FALLBACK tool-call recovery — consulted only when the provider returned zero structured\n // calls AND the caller opted in via `localToolCallParser`.\n const parseFallbackToolCalls = (\n content: string\n ): Array<{ id: string; name: string; args: string }> => {\n if (merged.localToolCallParser === undefined) return []\n if (typeof content !== 'string' || content.length === 0) return []\n const parser = resolveToolCallParser(merged.localToolCallParser)\n const toolNames = ctx.tools.visible().map((t) => t.name)\n return parser(content, { toolNames }).calls.map((c) => ({\n id: uuidv6(),\n name: c.name,\n args: JSON.stringify(c.arguments),\n }))\n }\n\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n\n // The wire shape a persisted reasoning item will actually REPLAY as, which is what the next\n // turn's adjacency sweep hashes. Under `summary-only` the renderer strips `content` and\n // `encrypted_content` (see `renderOpenAIResponsesReasoningItem`), so an accumulator that\n // recorded the FULL item produced a prefix the sweep never reproduces and every later item\n // dropped as stale. Building the replay shape here keeps persist and validate in agreement\n // for every mode.\n const replayShapeOf = (slot: {\n itemId: string\n summaryText: string\n reasoningText: string\n encryptedContent?: string\n }): OpenAIResponsesInputItem => {\n const summaryOnly = merged.reasoningReplay === 'summary-only'\n return {\n type: 'reasoning',\n id: normalizeOpenAIResponsesItemId(slot.itemId, 'rs'),\n summary:\n slot.summaryText.length > 0 ? [{ type: 'summary_text', text: slot.summaryText }] : [],\n ...(!summaryOnly && slot.reasoningText.length > 0\n ? { content: [{ type: 'reasoning_text', text: slot.reasoningText }] }\n : {}),\n ...(!summaryOnly && slot.encryptedContent\n ? { encrypted_content: slot.encryptedContent }\n : {}),\n }\n }\n\n // ── Persist a reasoning Thought from a finalized thinking slot ─────────\n const persistThought = async (\n slot: {\n itemId: string\n summaryText: string\n reasoningText: string\n encryptedContent?: string\n },\n pairedItemId: string | undefined,\n // Explicit timestamp so a caller draining several slots can order them monotonically —\n // see `stampFor` in the streaming drain. Defaults to \"now\" for the non-streaming path.\n stamp: string = nowIso(),\n // Items produced EARLIER IN THIS SAME RESPONSE that will sit between the request prefix\n // and this reasoning item once the whole response is replayed on the next turn.\n //\n // Without this, a response carrying two or more reasoning items replayed only the FIRST.\n // Every item's fingerprint was taken over the request prefix alone, but the next turn's\n // adjacency sweep re-derives each candidate's hash through its OWN position — which for\n // the second reasoning item includes the first reasoning item and its paired message. The\n // hashes could not match, so every item after the first was dropped as stale.\n precedingReplayItems: OpenAIResponsesInputItem[] = []\n ): Promise<void> => {\n const content = slot.reasoningText.length > 0 ? slot.reasoningText : slot.summaryText\n let payload: OpenAIResponsesReasoningReplayPayload | undefined\n if (merged.reasoningReplay !== 'off') {\n const item: OpenAIResponsesReasoningItem = {\n type: 'reasoning',\n id: normalizeOpenAIResponsesItemId(slot.itemId, 'rs'),\n summary:\n slot.summaryText.length > 0 ? [{ type: 'summary_text', text: slot.summaryText }] : [],\n ...(slot.reasoningText.length > 0\n ? { content: [{ type: 'reasoning_text', text: slot.reasoningText }] }\n : {}),\n ...(slot.encryptedContent ? { encrypted_content: slot.encryptedContent } : {}),\n }\n const prefixFingerprint = await resolvedHelpers.fingerprintOpenAIResponsesPrefix({\n model: merged.model,\n instructions: assembled.instructions,\n // Pass `assembled.tools` THROUGH, without an `?? []` fallback: the next turn's\n // adjacency sweep re-derives this hash against the same `undefined`-when-empty shape.\n // Coercing to `[]` here hashes different bytes than the sweep does and drops every\n // replayed reasoning item as stale whenever no tools are registered.\n tools: assembled.tools,\n // Hash the sweep-visible request prefix PLUS whatever this same response already\n // contributed ahead of this item (see `precedingReplayItems`). On the next turn the\n // sweep hashes exactly this sequence when it reaches this item's position.\n //\n // `throughItem` is the length of that combined array: the sweep-visible region of the\n // request (a trailing-bucket item is appended AFTER the sweep runs, so it is absent\n // from every prefix the sweep hashes — including it here would guarantee a mismatch\n // whenever `bucketOrder` puts a non-empty bucket after `'timeline'`) plus the\n // preceding items from this response.\n input: [\n ...assembled.input.slice(0, assembled.fingerprintableLength),\n ...precedingReplayItems,\n ],\n throughItem: assembled.fingerprintableLength + precedingReplayItems.length,\n })\n payload = {\n variant: 'responses-reasoning',\n item,\n pairedItemId,\n prefixFingerprint,\n }\n }\n await ctx.storeThought(\n new Thought({\n id: slot.itemId,\n content,\n identity: selfIdentity,\n payload,\n replayCompatibility: payload ? 'openai-responses-reasoning-v1' : undefined,\n createdAt: stamp,\n updatedAt: stamp,\n })\n )\n }\n\n // ── Step 8: streaming path ────────────────────────────────────────────\n if (stream) {\n if (!response.body) {\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR(['response has no body']))\n return\n }\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n const slotMachine = resolvedHelpers.createResponsesOutputSlotMachine()\n const streamId = dispatchStreamId\n\n let buffer = ''\n let idleTimer: ReturnType<typeof setTimeout> | undefined\n let stalled = false\n let terminalSeen = false\n let terminalStatus: OpenAIResponsesResponseObject['status'] | undefined\n let incompleteReason: string | undefined\n let finalUsage: OpenAIResponsesResponseObject['usage'] | undefined\n let finalModel: string | undefined\n let finalRaw: Record<string, unknown> = {}\n const collectedToolCalls: Array<{ id: string; name: string; args: string }> = []\n let sawMessageDelta = false\n\n const idleMs = merged.streamIdleTimeoutMs ?? 0\n const armIdleTimer = (): void => {\n if (idleMs <= 0) return\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(() => {\n stalled = true\n helpers.log.warn({\n kind: 'stream-idle-timeout',\n message: `SSE stream went idle for ${idleMs}ms; cancelling`,\n payload: { idleMs },\n })\n reader.cancel().catch(() => {\n /* swallow */\n })\n }, idleMs)\n }\n const clearIdleTimer = (): void => {\n if (idleTimer) {\n clearTimeout(idleTimer)\n idleTimer = undefined\n }\n }\n\n const drainAndPersist = async (): Promise<void> => {\n // Persist every open text / thinking slot.\n const orderedIndices = Array.from(slotMachine.slots().keys()).sort((a, b) => a - b)\n // Timestamps are derived MONOTONICALLY from each slot's position in output-index order,\n // never from independent `nowIso()` calls. Two back-to-back `nowIso()` calls return an\n // identical ISO string ~998 times in 1000, and `buildOpenAIResponsesInput` pushes\n // messages into the timeline before thoughts and then stable-sorts by `createdAt` — so\n // on a tie the assistant message sorted AHEAD of its own reasoning item, leaving that\n // item last with nothing after it, and the adjacency sweep dropped it as unpaired. That\n // made reasoning replay fail most of the time even under the default configuration.\n const drainBaseMs = DateTime.now().toMillis()\n // Same multi-reasoning accumulator as the non-streaming path: items from THIS response\n // that will precede a later reasoning item once the whole response replays next turn.\n const replayedSoFar: OpenAIResponsesInputItem[] = []\n const stampFor = (pos: number): string =>\n DateTime.fromMillis(drainBaseMs + pos).toISO() ??\n new Date(drainBaseMs + pos).toISOString()\n for (const [pos, idx] of orderedIndices.entries()) {\n const slot = slotMachine.getSlot(idx)\n if (!slot) continue\n if (slot.kind === 'text') {\n if (slot.text.length > 0 || slot.refusal.length > 0) {\n sawMessageDelta = true\n const text = slot.refusal.length > 0 ? slot.refusal : slot.text\n helpers.reportMessage(slot.itemId || streamId, '', { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: slot.itemId || streamId,\n role: 'assistant',\n content: text,\n identity: selfIdentity,\n createdAt: stampFor(pos),\n updatedAt: stampFor(pos),\n })\n )\n replayedSoFar.push({\n type: 'message',\n role: 'assistant',\n status: 'completed',\n id: slot.itemId || streamId,\n content: [{ type: 'output_text', text, annotations: [] }],\n })\n }\n } else if (slot.kind === 'thinking') {\n helpers.reportThought(slot.itemId || streamId, '', { isComplete: true })\n // `pairedItemId` records the id of the item that FOLLOWS this reasoning item on the\n // wire (per its own contract in types.ts) — look ahead to the next slot in output-index\n // order, not back at whatever slot preceded this one.\n const nextIdx = orderedIndices[pos + 1]\n const nextSlot = nextIdx !== undefined ? slotMachine.getSlot(nextIdx) : undefined\n const pairedItemId = nextSlot?.itemId\n await persistThought(slot, pairedItemId, stampFor(pos), [...replayedSoFar])\n replayedSoFar.push(replayShapeOf(slot))\n } else if (slot.kind === 'toolCall') {\n collectedToolCalls.push({\n id: `${slot.callId}|${slot.itemId}`,\n name: slot.name,\n args: slot.args,\n })\n }\n }\n\n if (finalUsage !== undefined || terminalStatus !== undefined) {\n const calls = collectedToolCalls.length > 0\n helpers.reportGenerationStats(\n extractGenerationStats({\n model: finalModel ?? merged.model,\n usage: finalUsage,\n finishReason: mapStopReason(terminalStatus, incompleteReason, calls),\n raw:\n Object.keys(finalRaw).length > 0\n ? finalRaw\n : { usage: finalUsage, status: terminalStatus },\n })\n )\n }\n\n const nativeCalls = collectedToolCalls\n const combinedText = Array.from(slotMachine.slots().values())\n .filter((s): s is Extract<typeof s, { kind: 'text' }> => s.kind === 'text')\n .map((s) => (s.refusal.length > 0 ? s.refusal : s.text))\n .join('')\n const calls = nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(combinedText)\n\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: combinedText,\n cleanedText: combinedText,\n reasoning: Array.from(slotMachine.slots().values())\n .filter(\n (s): s is Extract<typeof s, { kind: 'thinking' }> => s.kind === 'thinking'\n )\n .map((s) => (s.reasoningText.length > 0 ? s.reasoningText : s.summaryText)),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n helpers.log.debug({\n kind: 'stream-finalised',\n message: `Stream finalised: ${calls.length} tool call(s), message=${sawMessageDelta}`,\n payload: { toolCallCount: calls.length, sawMessageDelta, terminalSeen },\n })\n\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n\n // Processes one SSE frame's `data:` lines. Returns `'stop'` once a terminal event (or a\n // fatal stream-level error) has been handled — the caller must stop reading and return\n // immediately — or `'continue'` otherwise. Extracted so the SAME logic can run once more\n // on whatever is left in `buffer` after EOF (Known finding: a final frame lacking its\n // trailing blank-line separator was previously left unprocessed and silently dropped).\n const processFrame = async (frame: string): Promise<'stop' | 'continue'> => {\n // Per the SSE spec an event's `data:` FIELDS are concatenated (newline-separated) and the\n // result parsed ONCE — a single JSON value may legally be split across several `data:`\n // lines. Parsing each line independently produced two invalid JSON fragments and silently\n // skipped both, losing the whole event. OpenAI does not split events today, but an\n // intermediary may, exactly as one already forced the CRLF handling above.\n //\n // Concatenating per frame is a superset of the previous behaviour for the single-line\n // case (one field joins to itself), so nothing that parsed before stops parsing.\n const dataLines = frame\n .split('\\n')\n .filter((line) => line.startsWith('data:'))\n .map((line) => line.slice(5).trim())\n for (const data of dataLines.length > 1 ? [dataLines.join('\\n')] : dataLines) {\n if (data.length === 0) continue\n let payload: OpenAIResponsesStreamEvent\n try {\n payload = JSON.parse(data) as OpenAIResponsesStreamEvent\n } catch {\n helpers.log.trace({\n kind: 'sse-parse-failure',\n message: 'Failed to parse SSE chunk as JSON; skipping',\n payload: { dataPreview: data.slice(0, 256) },\n })\n continue\n }\n // The union's structural fallback member (`OpenAIResponsesStreamEventBase &\n // Record<string, unknown>`, covering every event type this battery does not act\n // on) carries a loose `type: string`, which prevents TypeScript from narrowing the\n // discriminant inside a `switch` the way it would for a \"closed\" union — the same\n // issue documented in `helpers.ts`'s output-slot-machine `openSlot`/`finalizeSlot`.\n // Cast to the specific event type inside each case rather than rely on narrowing.\n switch (payload.type) {\n case 'response.output_item.added': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.output_item.added' }\n >\n const slot = slotMachine.openSlot(ev.output_index, ev.item)\n if (!slot) {\n helpers.log.debug({\n kind: 'unhandled-output-item',\n message: `No slot opened for output item type \"${ev.item.type}\" at index ${ev.output_index}`,\n payload: { itemType: ev.item.type, outputIndex: ev.output_index },\n })\n }\n break\n }\n case 'response.output_text.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.output_text.delta' }\n >\n slotMachine.appendText(ev.output_index, ev.delta)\n sawMessageDelta = true\n helpers.reportMessage(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.refusal.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.refusal.delta' }\n >\n slotMachine.appendRefusal(ev.output_index, ev.delta)\n sawMessageDelta = true\n helpers.reportMessage(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.reasoning_summary_text.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.reasoning_summary_text.delta' }\n >\n slotMachine.appendReasoningSummary(ev.output_index, ev.delta)\n helpers.reportThought(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.reasoning_text.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.reasoning_text.delta' }\n >\n slotMachine.appendReasoningText(ev.output_index, ev.delta)\n helpers.reportThought(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.function_call_arguments.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.function_call_arguments.delta' }\n >\n slotMachine.appendFunctionCallArgumentsDelta(ev.output_index, ev.delta)\n break\n }\n case 'response.function_call_arguments.done': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.function_call_arguments.done' }\n >\n slotMachine.setFunctionCallArgumentsDone(ev.output_index, ev.arguments)\n break\n }\n case 'response.output_item.done': {\n // The ONLY point at which a reasoning item's encrypted_content is captured\n // (Known Gotcha #3) — never at `.added`, before it's populated.\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.output_item.done' }\n >\n slotMachine.finalizeSlot(ev.output_index, ev.item)\n break\n }\n case 'response.completed':\n case 'response.incomplete': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.completed' | 'response.incomplete' }\n >\n terminalSeen = true\n terminalStatus = ev.response.status\n incompleteReason = ev.response.incomplete_details?.reason ?? undefined\n finalUsage = ev.response.usage\n finalModel = ev.response.model\n finalRaw = { ...ev.response } as unknown as Record<string, unknown>\n // Backfill `encrypted_content` from the terminal event's own `response.output`\n // for any reasoning item whose `.done` event omitted it.\n const output = ev.response.output ?? []\n for (const [i, item] of output.entries()) {\n if (item && item.type === 'reasoning') {\n const reasoningItem = item as OpenAIResponsesReasoningItem\n if (reasoningItem.encrypted_content) {\n slotMachine.backfillEncryptedContent(i, reasoningItem.encrypted_content)\n }\n }\n }\n clearIdleTimer()\n await drainAndPersist()\n return 'stop'\n }\n case 'response.failed': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.failed' }\n >\n terminalSeen = true\n clearIdleTimer()\n const msg = ev.response.error?.message ?? 'response.failed'\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([msg]))\n return 'stop'\n }\n case 'error': {\n const ev = payload as Extract<OpenAIResponsesStreamEvent, { type: 'error' }>\n terminalSeen = true\n clearIdleTimer()\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([ev.message]))\n return 'stop'\n }\n default:\n // Every other event type (response.created, .in_progress,\n // content_part.added/.done, hosted-tool progress events, etc.) — not acted on.\n break\n }\n }\n return 'continue'\n }\n\n // `requestTimeoutMs` bounds the COMPLETE HTTP exchange, not just the headers. The\n // per-attempt timer above is cleared as soon as `fetch` resolves — which happens on\n // headers — so without this a response whose BODY then stalls waits forever whenever\n // `streamIdleTimeoutMs` is unset (verified: with `requestTimeoutMs: 300` and a body that\n // never yields a byte, the dispatch hung indefinitely). The deadline is measured from the\n // START OF THE ATTEMPT (not from when headers arrived) and races every `reader.read()`,\n // so slow headers and a slow body share one budget rather than getting one each.\n const bodyTimeoutMs = merged.requestTimeoutMs ?? 0\n const bodyDeadline = bodyTimeoutMs > 0 ? attemptStartedAtMs + bodyTimeoutMs : undefined\n const readWithDeadline = async (): Promise<\n ReadableStreamReadResult<Uint8Array> | 'timeout'\n > => {\n if (bodyDeadline === undefined) return reader.read()\n const remaining = bodyDeadline - Date.now()\n if (remaining <= 0) return 'timeout'\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n reader.read(),\n new Promise<'timeout'>((resolve) => {\n timer = setTimeout(() => resolve('timeout'), remaining)\n }),\n ])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n }\n\n try {\n armIdleTimer()\n while (true) {\n const read = await readWithDeadline()\n if (read === 'timeout') {\n clearIdleTimer()\n reader.cancel().catch(() => {\n /* swallow */\n })\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Response body exceeded requestTimeoutMs (${bodyTimeoutMs}ms) while streaming`,\n payload: { requestTimeoutMs: bodyTimeoutMs },\n })\n ctx.nack(new E_OPENAI_RESPONSES_REQUEST_TIMEOUT([bodyTimeoutMs]))\n return\n }\n const { done, value } = read\n if (done) break\n armIdleTimer()\n if (ctx.abortSignal.aborted) {\n clearIdleTimer()\n return\n }\n buffer += decoder.decode(value, { stream: true })\n let sepMatch = SSE_FRAME_SEPARATOR.exec(buffer)\n while (sepMatch !== null) {\n const frame = buffer.slice(0, sepMatch.index)\n buffer = buffer.slice(sepMatch.index + sepMatch[0].length)\n if ((await processFrame(frame)) === 'stop') return\n sepMatch = SSE_FRAME_SEPARATOR.exec(buffer)\n }\n }\n // EOF: flush the decoder's own internal state (a dangling multi-byte UTF-8 sequence split\n // across the last two chunks) and process whatever is left in `buffer` as one final frame\n // even without its own trailing blank-line separator — a terminal event (or any other\n // event) arriving as the very last bytes of the stream, with no `\\n\\n` after it, was\n // previously left sitting in `buffer` and silently dropped when the loop broke.\n buffer += decoder.decode()\n if (buffer.trim().length > 0) {\n const finalFrame = buffer\n buffer = ''\n if ((await processFrame(finalFrame)) === 'stop') return\n }\n clearIdleTimer()\n if (stalled) {\n // DELIBERATE ASYMMETRY with the EOF path below: a stall DISCARDS accumulated state\n // rather than draining it, even though both arrive here holding the same partial slots.\n //\n // The difference is what the two conditions tell you about the stream. EOF means the\n // provider CLOSED it — the turn is over and whatever arrived is all there will ever be,\n // so draining preserves a complete-if-short answer. A stall means the connection is\n // still OPEN and simply quiet: more content may well be in flight, and the reader is\n // being cancelled underneath it. Persisting a mid-sentence fragment as though it were\n // the model's answer would put text into history that the model never finished, which\n // the next turn would then treat as a completed assistant turn.\n //\n // The nack is therefore the whole outcome: the caller retries the turn rather than\n // inheriting a truncated answer. Same treatment in `openai_chat_completions` and\n // `anthropic_messages` — the convention was previously undocumented in all three,\n // which reads as an oversight rather than a choice, so it is stated here.\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_STALLED([idleMs]))\n return\n }\n if (!terminalSeen) {\n helpers.log.warn({\n kind: 'sse-eof-without-terminal-event',\n message:\n 'SSE stream ended without a terminal event (response.completed/.incomplete/.failed); draining accumulated state',\n })\n await drainAndPersist()\n }\n } catch (err) {\n clearIdleTimer()\n if (ctx.abortSignal.aborted) return\n if (stalled) {\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_STALLED([idleMs]))\n return\n }\n helpers.log.error({\n kind: 'stream-error',\n message: `SSE stream failed: ${isError(err) ? err.message : String(err)}`,\n payload: { detail: isError(err) ? err.message : String(err) },\n })\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n return\n }\n\n // ── Step 9: non-streaming path ────────────────────────────────────────\n let parsed: OpenAIResponsesResponseObject\n try {\n // `response.json()` consumes the BODY, and the per-attempt timer was cleared the moment\n // `fetch` resolved (which happens on headers) — so a response whose body then stalls hung\n // forever here despite a configured `requestTimeoutMs`. Verified before fixing: with\n // `requestTimeoutMs: 200` and a body that never yields a byte, the dispatch never returned.\n //\n // Bounded by the SAME whole-exchange deadline the streaming path uses (measured from\n // `attemptStartedAtMs`, not from when headers arrived), so slow headers and a slow body\n // share one budget rather than getting one each.\n const jsonTimeoutMs = merged.requestTimeoutMs ?? 0\n if (jsonTimeoutMs > 0) {\n const remaining = attemptStartedAtMs + jsonTimeoutMs - Date.now()\n let timer: ReturnType<typeof setTimeout> | undefined\n const timedOut = Symbol('timeout')\n const raced = await Promise.race([\n response.json(),\n new Promise<typeof timedOut>((resolve) => {\n timer = setTimeout(() => resolve(timedOut), Math.max(0, remaining))\n }),\n ]).finally(() => {\n if (timer !== undefined) clearTimeout(timer)\n })\n if (raced === timedOut) {\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Response body exceeded requestTimeoutMs (${jsonTimeoutMs}ms) while parsing`,\n payload: { requestTimeoutMs: jsonTimeoutMs },\n })\n ctx.nack(new E_OPENAI_RESPONSES_REQUEST_TIMEOUT([jsonTimeoutMs]))\n return\n }\n parsed = raced as OpenAIResponsesResponseObject\n } else {\n parsed = (await response.json()) as OpenAIResponsesResponseObject\n }\n } catch (err) {\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n const output = parsed.output ?? []\n const responseId = parsed.id ?? uuidv6()\n\n const nativeCalls: Array<{ id: string; name: string; args: string }> = []\n let combinedText = ''\n // Same monotonic-timestamp scheme as the streaming drain: derive each persisted record's\n // stamp from its position in `output` rather than calling `nowIso()` per item. Independent\n // calls collide on the same millisecond ~998 times in 1000, and a tie lets the assistant\n // message sort ahead of its own reasoning item (messages are pushed into the timeline before\n // thoughts, then stable-sorted), orphaning it so the adjacency sweep drops it.\n const outputBaseMs = DateTime.now().toMillis()\n const stampAt = (pos: number): string =>\n DateTime.fromMillis(outputBaseMs + pos).toISO() ??\n new Date(outputBaseMs + pos).toISOString()\n // Deliberately does NOT include `function_call`/`function_call_output` items from this\n // response, despite a review finding asking for them. A `ToolCall` is stamped with\n // `createdAt = completedAt` at EXECUTION time — after every item in the response that\n // requested it — and `buildOpenAIResponsesInput` orders the timeline by `createdAt`. So an\n // in-response tool call sorts AFTER the reasoning item, not before it. Verified on the wire:\n // turn 2 assembled as `role:user | message | function_call | function_call_output`, with the\n // tool call last. Adding it to the prefix would corrupt a hash that currently matches.\n // Items from THIS response that will precede the next reasoning item once the whole response\n // is replayed next turn, in the same wire shapes `buildOpenAIResponsesInput` emits: a\n // replayed reasoning item verbatim, and own-assistant text as the OUTPUT-message shape\n // (`renderOwnAssistantOutputItem`). Passed to `persistThought` so each item's fingerprint\n // covers the prefix the adjacency sweep will actually see at its position — without it, only\n // the first reasoning item in a multi-reasoning response ever replayed.\n const replayedSoFar: OpenAIResponsesInputItem[] = []\n for (const [i, item] of output.entries()) {\n if (!item) continue\n if (item.type === 'message') {\n const msgItem = item as Extract<typeof item, { type: 'message' }>\n const parts: string[] = []\n let refusal = ''\n for (const part of msgItem.content) {\n if (part.type === 'output_text') parts.push(part.text)\n else if (part.type === 'refusal') refusal = part.refusal\n }\n const text = refusal.length > 0 ? refusal : parts.join('')\n combinedText += text\n if (text.length > 0) {\n const messageId = msgItem.id ?? `${responseId}:message:${i}`\n helpers.reportMessage(messageId, text, { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: messageId,\n role: 'assistant',\n content: text,\n identity: selfIdentity,\n createdAt: stampAt(i),\n updatedAt: stampAt(i),\n })\n )\n // Own-assistant text replays as the OUTPUT-message shape, so record it in that exact\n // form for any later reasoning item's fingerprint prefix.\n replayedSoFar.push({\n type: 'message',\n role: 'assistant',\n status: 'completed',\n id: messageId,\n content: [{ type: 'output_text', text, annotations: [] }],\n })\n }\n } else if (item.type === 'reasoning') {\n const reasoningItem = item as OpenAIResponsesReasoningItem\n const summaryText = (reasoningItem.summary ?? []).map((s) => s.text).join('\\n\\n')\n const reasoningText = (reasoningItem.content ?? []).map((c) => c.text).join('\\n\\n')\n const thoughtId = reasoningItem.id\n helpers.reportThought(thoughtId, reasoningText.length > 0 ? reasoningText : summaryText, {\n isComplete: true,\n })\n // `pairedItemId` records the id of the item that FOLLOWS this reasoning item on the wire\n // (per its own contract in types.ts) — look ahead to the next output entry, not back at\n // whatever preceded this one.\n // `output[i + 1]` may be NULL, not merely undefined — the array is provider-supplied and\n // its element type is nullable, which is exactly why the loop head guards with\n // `if (!item) continue`. That guard does not cover this LOOKAHEAD: `'id' in null` throws\n // `TypeError: Cannot use 'in' operator to search for 'id' in null`, killing the whole\n // dispatch (no message persisted, no thought persisted, turn lost) whenever a null sits\n // between a reasoning item and its paired output item. A truthiness check covers null and\n // undefined together.\n const nextItem = output[i + 1]\n const pairedItemId = nextItem && 'id' in nextItem ? nextItem.id : undefined\n await persistThought(\n {\n itemId: reasoningItem.id,\n summaryText,\n reasoningText,\n ...(reasoningItem.encrypted_content\n ? { encryptedContent: reasoningItem.encrypted_content }\n : {}),\n },\n pairedItemId,\n stampAt(i),\n [...replayedSoFar]\n )\n // This item will itself precede any LATER reasoning item on replay.\n replayedSoFar.push(\n replayShapeOf({\n itemId: reasoningItem.id,\n summaryText,\n reasoningText,\n ...(reasoningItem.encrypted_content\n ? { encryptedContent: reasoningItem.encrypted_content }\n : {}),\n })\n )\n } else if (item.type === 'function_call') {\n const fcItem = item as OpenAIResponsesFunctionCallItem\n nativeCalls.push({\n id: fcItem.id ? `${fcItem.call_id}|${fcItem.id}` : fcItem.call_id,\n name: fcItem.name,\n args: fcItem.arguments,\n })\n } else {\n // Hosted/unrecognized output item type — never replayed, debug-log only.\n helpers.log.debug({\n kind: 'unhandled-output-item',\n message: `Unhandled output item type \"${item.type}\" at index ${i}`,\n payload: { itemType: item.type, index: i },\n })\n }\n }\n\n if (isObject(parsed.usage) || typeof parsed.status === 'string') {\n helpers.reportGenerationStats(\n extractGenerationStats({\n model: parsed.model ?? merged.model,\n usage: parsed.usage,\n finishReason: mapStopReason(\n parsed.status,\n parsed.incomplete_details?.reason ?? undefined,\n nativeCalls.length > 0\n ),\n raw: { ...parsed } as unknown as Record<string, unknown>,\n })\n )\n }\n\n if (parsed.status === 'failed' || parsed.status === 'cancelled') {\n const msg = parsed.error?.message ?? `response ${parsed.status}`\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([msg]))\n return\n }\n\n const calls = nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(combinedText)\n\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: combinedText,\n cleanedText: combinedText,\n reasoning: output\n .filter((i): i is OpenAIResponsesReasoningItem => i?.type === 'reasoning')\n .map(\n (i) =>\n (i.content ?? []).map((c) => c.text).join('\\n\\n') ||\n (i.summary ?? []).map((s) => s.text).join('\\n\\n')\n ),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: false,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n }\n\n /**\n * Returns `true` when `value` is an {@link OpenAIResponsesAdapter} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is an `OpenAIResponsesAdapter` instance.\n */\n public static isOpenAIResponsesAdapter(value: unknown): value is OpenAIResponsesAdapter {\n return isInstanceOf(value, 'OpenAIResponsesAdapter', OpenAIResponsesAdapter)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"adapter.mjs","names":["#baseline"],"sources":["../../../../src/batteries/llm/openai_responses/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter for the OpenAI Responses API.\n *\n * @module @nhtio/adk/batteries/llm/openai_responses/adapter\n *\n * @remarks\n * Cross-environment LLM adapter for the OpenAI Responses wire shape — a flat `input: Item[]` array\n * (not `messages[]`), where a tool call and its result are two SIBLING top-level items\n * (`function_call` / `function_call_output`), and the system prompt defaults to a top-level\n * `instructions` string rather than a leading message item.\n *\n * The adapter is built around the same three pluggable layers as `openai_chat_completions`:\n *\n * 1. **Translation helpers** — the swappable functions exported from `./helpers` turn ADK\n * primitives into Responses wire shapes. Consumers override individual helpers via\n * `options.helpers.*`.\n * 2. **Three-layer options merging** — constructor baseline, per-`executor()` overrides, and\n * per-iteration `ctx.stash.openaiResponses` overrides combine with key-by-key precedence for\n * `headers`/`helpers`/`retry` and wholesale replacement for everything else. The merged shape\n * is re-validated on every iteration.\n * 3. **Cross-env transport** — hand-rolled `fetch` + SSE parsing, mirroring\n * `openai_chat_completions/adapter.ts`'s transport exactly. No `openai` SDK dependency.\n *\n * This adapter is STATELESS by design: `store: false` is always sent (never a settable option),\n * and the full `input` array is resent every iteration. There is no `[DONE]` sentinel on the\n * Responses SSE stream — termination is `response.completed` / `.incomplete` / `.failed`; EOF\n * without one of these is a best-effort recovery, not a hard failure: it warn-logs and drains\n * whatever was accumulated rather than nacking with {@link E_OPENAI_RESPONSES_STREAM_ERROR} (that\n * exception is reserved for a genuine stream-level error, e.g. the connection itself failing).\n *\n * Recoverable-failure handling: a 400 whose body matches `invalid_encrypted_content` drops every\n * reasoning item from the resolved input and retries the request once — a documented real-world\n * failure mode when a persisted reasoning `Thought` outlives a server-side key rotation. A 400\n * matching the reasoning/output-item pairing violation phrases translates to\n * {@link E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED} instead of a generic HTTP error.\n *\n * `background` is NOT supported: this executor has no polling/resumption loop for a\n * `queued`/`in_progress` background response (the Responses API's async mode; see\n * https://platform.openai.com/docs/guides/background), so `background: true` is rejected up front\n * by the options schema (`E_INVALID_OPENAI_RESPONSES_OPTIONS`, see `validation.ts`) rather than\n * reaching this executor at all — accepting it here would otherwise fall straight into the\n * ordinary streaming/non-streaming response handling below and treat the initial\n * `queued`/`in_progress` response body as a complete, empty answer, silently discarding whatever\n * the background job eventually produces.\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport { looksLikeSpooledArtifact, normalizeToolName } from '../chat_common/helpers'\nimport {\n computeBackoff,\n sleepWithJitter,\n parseRetryAfter,\n linkAbortSignals,\n} from '../../../lib/utils/retry'\nimport {\n Tokenizable,\n ToolCall,\n Message,\n Thought,\n SpooledArtifact,\n Media,\n ArtifactTool,\n} from '@nhtio/adk/common'\nimport {\n E_INVALID_OPENAI_RESPONSES_OPTIONS,\n E_OPENAI_RESPONSES_CONTEXT_OVERFLOW,\n E_OPENAI_RESPONSES_HTTP_ERROR,\n E_OPENAI_RESPONSES_STREAM_ERROR,\n E_OPENAI_RESPONSES_STREAM_STALLED,\n E_OPENAI_RESPONSES_REQUEST_TIMEOUT,\n E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS,\n E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED,\n} from './exceptions'\nimport {\n defaultDescriptionToChatCompletionsJsonSchema,\n defaultRenderUntrustedContent,\n defaultRenderTrustedContent,\n defaultRenderStandingInstructions,\n defaultRenderMemories,\n defaultRenderRetrievables,\n defaultRenderRetrievableHandleBody,\n defaultRenderRetrievableSafetyDirective,\n defaultRenderFirstPartyRetrievables,\n defaultRenderThirdPartyPublicRetrievables,\n defaultRenderThirdPartyPrivateRetrievables,\n defaultRenderArtifactHandleBody,\n defaultRenderThought,\n defaultFilterThoughts,\n defaultToolsToChatCompletionsTools,\n defaultRenderChatCompletionsSystemPrompt,\n defaultRenderOpenAIResponsesMediaBlocks,\n defaultRenderOpenAIResponsesTimelineMessage,\n defaultRenderOpenAIResponsesToolCallResult,\n defaultToolsToOpenAIResponsesTools,\n fingerprintOpenAIResponsesPrefix,\n defaultRenderOpenAIResponsesReasoningItem,\n defaultBuildOpenAIResponsesInput,\n defaultCreateResponsesOutputSlotMachine,\n normalizeOpenAIResponsesItemId,\n} from './helpers'\nimport type { Tool, Memory } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\nimport type {\n DispatchExecutorFn,\n DispatchExecutorHelpers,\n GenerationStats,\n} from '@nhtio/adk/dispatch_runner'\nimport type {\n OpenAIResponsesAdapterOptions,\n OpenAIResponsesHelpers,\n ChatCompletionsRetryConfig,\n OpenAIResponsesRequestBody,\n OpenAIResponsesInputItem,\n OpenAIResponsesInputContentBlock,\n OpenAIResponsesReasoningItem,\n OpenAIResponsesFunctionCallItem,\n OpenAIResponsesStreamEvent,\n OpenAIResponsesResponseObject,\n OpenAIResponsesReasoningReplayPayload,\n OpenAIResponsesTool,\n} from './types'\n\n// ─── ADK-control keys (stripped before sending the request body) ──────────\n\nconst ADK_CONTROL_KEYS: ReadonlySet<string> = new Set([\n 'apiKey',\n 'baseURL',\n 'organization',\n 'project',\n 'headers',\n 'fetch',\n 'stream',\n 'bucketOrder',\n 'contextWindow',\n 'selfIdentity',\n 'thoughtSurfacing',\n 'tokenEncoding',\n 'replayCompatibility',\n 'helpers',\n 'streamIdleTimeoutMs',\n 'requestTimeoutMs',\n 'retry',\n 'strictToolChoice',\n // `strict` configures the EMITTED TOOL DECLARATIONS (it becomes each function tool's own\n // `strict` field via `toolsToOpenAIResponsesTools`) — it is not a top-level Responses request\n // property. Without this entry the generic body spread forwarded it verbatim, so an adapter\n // constructed with `strict: true` put `\"strict\": true` on the wire alongside `model`/`input`,\n // where the API can reject the request before generation. Verified against the real wire body:\n // the keys sent were `input, instructions, model, store, stream, strict`.\n 'strict',\n 'autoAck',\n 'unsupportedMediaPolicy',\n 'localToolCallParser',\n 'forgeToolsFilter',\n 'spoolStore',\n // Responses-specific ADK control\n 'systemPromptChannel',\n 'reasoningReplay',\n // Observability hooks — never sent to the provider.\n 'onRawGeneration',\n 'onPromptAssembled',\n 'toolCallIdFilter',\n])\n\n// ─── Option merging ───────────────────────────────────────────────────────────\n\nconst mergeRetry = (\n layers: ReadonlyArray<ChatCompletionsRetryConfig | undefined>\n): ChatCompletionsRetryConfig | undefined => {\n let merged: ChatCompletionsRetryConfig | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeHeaders = (\n layers: ReadonlyArray<Record<string, string> | undefined>\n): Record<string, string> | undefined => {\n let merged: Record<string, string> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeHelpers = (\n layers: ReadonlyArray<Partial<OpenAIResponsesHelpers> | undefined>\n): Partial<OpenAIResponsesHelpers> | undefined => {\n let merged: Partial<OpenAIResponsesHelpers> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: OpenAIResponsesAdapterOptions,\n exec: Partial<OpenAIResponsesAdapterOptions> | undefined,\n stash: Partial<OpenAIResponsesAdapterOptions> | undefined\n): Partial<OpenAIResponsesAdapterOptions> => {\n const layers = [baseline as Partial<OpenAIResponsesAdapterOptions>, exec ?? {}, stash ?? {}]\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n for (const [k, v] of Object.entries(layer)) {\n if (v === undefined) continue\n if (k === 'headers' || k === 'helpers' || k === 'retry') continue\n out[k] = v\n }\n }\n const headers = mergeHeaders(layers.map((l) => l.headers))\n if (headers !== undefined) out.headers = headers\n const helpers = mergeHelpers(layers.map((l) => l.helpers))\n if (helpers !== undefined) out.helpers = helpers\n const retry = mergeRetry(layers.map((l) => l.retry))\n if (retry !== undefined) out.retry = retry\n return out as Partial<OpenAIResponsesAdapterOptions>\n}\n\n// ─── Helper resolution ────────────────────────────────────────────────────────\n\nconst resolveHelpers = (\n overrides: Partial<OpenAIResponsesHelpers> | undefined\n): OpenAIResponsesHelpers => {\n const src = overrides ?? {}\n return {\n descriptionToChatCompletionsJsonSchema:\n src.descriptionToChatCompletionsJsonSchema ?? defaultDescriptionToChatCompletionsJsonSchema,\n renderUntrustedContent: src.renderUntrustedContent ?? defaultRenderUntrustedContent,\n renderTrustedContent: src.renderTrustedContent ?? defaultRenderTrustedContent,\n renderStandingInstructions: src.renderStandingInstructions ?? defaultRenderStandingInstructions,\n renderMemories: src.renderMemories ?? defaultRenderMemories,\n renderRetrievables: src.renderRetrievables ?? defaultRenderRetrievables,\n renderRetrievableHandleBody:\n src.renderRetrievableHandleBody ?? defaultRenderRetrievableHandleBody,\n renderRetrievableSafetyDirective:\n src.renderRetrievableSafetyDirective ?? defaultRenderRetrievableSafetyDirective,\n renderFirstPartyRetrievables:\n src.renderFirstPartyRetrievables ?? defaultRenderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables:\n src.renderThirdPartyPublicRetrievables ?? defaultRenderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables:\n src.renderThirdPartyPrivateRetrievables ?? defaultRenderThirdPartyPrivateRetrievables,\n renderArtifactHandleBody: src.renderArtifactHandleBody ?? defaultRenderArtifactHandleBody,\n renderThought: src.renderThought ?? defaultRenderThought,\n filterThoughts: src.filterThoughts ?? defaultFilterThoughts,\n toolsToChatCompletionsTools:\n src.toolsToChatCompletionsTools ?? defaultToolsToChatCompletionsTools,\n renderChatCompletionsSystemPrompt:\n src.renderChatCompletionsSystemPrompt ?? defaultRenderChatCompletionsSystemPrompt,\n renderOpenAIResponsesMediaBlocks:\n src.renderOpenAIResponsesMediaBlocks ?? defaultRenderOpenAIResponsesMediaBlocks,\n renderOpenAIResponsesTimelineMessage:\n src.renderOpenAIResponsesTimelineMessage ?? defaultRenderOpenAIResponsesTimelineMessage,\n renderOpenAIResponsesToolCallResult:\n src.renderOpenAIResponsesToolCallResult ?? defaultRenderOpenAIResponsesToolCallResult,\n toolsToOpenAIResponsesTools:\n src.toolsToOpenAIResponsesTools ?? defaultToolsToOpenAIResponsesTools,\n fingerprintOpenAIResponsesPrefix:\n src.fingerprintOpenAIResponsesPrefix ?? fingerprintOpenAIResponsesPrefix,\n renderOpenAIResponsesReasoningItem:\n src.renderOpenAIResponsesReasoningItem ?? defaultRenderOpenAIResponsesReasoningItem,\n buildOpenAIResponsesInput: src.buildOpenAIResponsesInput ?? defaultBuildOpenAIResponsesInput,\n createResponsesOutputSlotMachine:\n src.createResponsesOutputSlotMachine ?? defaultCreateResponsesOutputSlotMachine,\n }\n}\n\n// ─── ID helpers ───────────────────────────────────────────────────────────────\n\n// Canonical (key-order-insensitive) checksum — MUST match the contract documented on\n// canonicalStringify and used by Tool.executor + dispatch_runner's streaming helper, so\n// ctx.toolCallCount(checksum) detects semantically-identical repeat calls regardless of argument\n// key order.\nconst computeChecksum = (tool: string, args: unknown): string =>\n sha256(canonicalStringify({ tool, args }))\n\nconst nowIso = (): string => DateTime.now().toISO() ?? new Date().toISOString()\n\n// ─── Token measurement ────────────────────────────────────────────────────────\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncodingId\n): Promise<number> => {\n return Promise.resolve(value.estimateTokens(encoding as TokenEncoding))\n}\n\n// ─── Generation-stats extraction ───────────────────────────────────────────────\n\nconst extractGenerationStats = (input: {\n model: string\n usage?: OpenAIResponsesResponseObject['usage']\n finishReason?: string | null\n raw: Record<string, unknown>\n}): GenerationStats => {\n const stats: GenerationStats = {\n provider: 'openai_responses',\n model: input.model,\n raw: input.raw,\n }\n const usage = input.usage\n if (usage) {\n const cached = usage.input_tokens_details?.cached_tokens ?? 0\n if (typeof usage.input_tokens === 'number') {\n stats.promptTokens = Math.max(0, usage.input_tokens - cached)\n }\n if (typeof usage.output_tokens === 'number') stats.completionTokens = usage.output_tokens\n if (typeof usage.total_tokens === 'number') stats.totalTokens = usage.total_tokens\n }\n if (typeof input.finishReason === 'string') stats.finishReason = input.finishReason\n return stats\n}\n\n// ─── Stop-reason mapping ───────────────────────────────────────────────────────\n\nconst mapStopReason = (\n status: OpenAIResponsesResponseObject['status'],\n incompleteReason: string | undefined,\n hadToolCalls: boolean\n): string => {\n if (status === 'completed') return hadToolCalls ? 'tool_calls' : 'stop'\n if (status === 'incomplete') {\n if (incompleteReason === 'content_filter') return 'content_filter'\n return 'length'\n }\n return 'error'\n}\n\n// ─── Reasoning-replay error detection ─────────────────────────────────────────\n\nconst INVALID_ENCRYPTED_CONTENT_PHRASE = 'invalid_encrypted_content'\n// Both directions of the bidirectional pairing constraint (openai/openai-node#1791). The first\n// phrase catches a REASONING item rejected for missing its required FOLLOWING item; the second\n// catches the mirror case reported as that issue's headline error — a MESSAGE item rejected for\n// missing its required PRECEDING reasoning item (`Item 'msg_…' of type 'message' was provided\n// without its required preceding item of type 'reasoning'`), which the narrower\n// \"of type 'reasoning' was provided without\" phrasing does not match.\nconst REASONING_PAIRING_PHRASES = [\n \"of type 'reasoning' was provided without\",\n \"was provided without its required preceding item of type 'reasoning'\",\n 'items are not persisted when store is set to false',\n]\n\nconst bodyMatches = (body: string, phrases: ReadonlyArray<string>): boolean => {\n const lower = body.toLowerCase()\n return phrases.some((p) => lower.includes(p.toLowerCase()))\n}\n\n// ─── SSE framing ────────────────────────────────────────────────────────────────\n\n// A blank line delimits SSE frames. Tolerate CRLF alongside LF — some gateways/proxies\n// normalise line endings to \\r\\n, which a bare `\\n\\n` search never matches.\nconst SSE_FRAME_SEPARATOR = /\\r?\\n\\r?\\n/\n\n// ─── Adapter class ────────────────────────────────────────────────────────────\n\n/**\n * Opinionated cross-environment LLM adapter for the OpenAI Responses wire shape.\n *\n * @remarks\n * Construction validates options eagerly via {@link validateOptions} and throws\n * {@link E_INVALID_OPENAI_RESPONSES_OPTIONS} on failure. The returned instance is reusable: call\n * {@link OpenAIResponsesAdapter.executor} once per `DispatchRunner` configuration.\n *\n * Per-iteration overrides live on the active `DispatchContext`'s `stash.openaiResponses` slot and\n * take highest precedence — they merge into the executor-scope shape on every iteration.\n * `headers`, `helpers`, and `retry` merge key-by-key across all three layers; every other field is\n * replaced wholesale at the highest layer that sets it.\n */\nexport class OpenAIResponsesAdapter {\n /**\n * Customary key for per-iteration overrides on `ctx.stash`. The adapter reads\n * `ctx.stash.get(OpenAIResponsesAdapter.STASH_KEY, {})` at the start of every iteration and\n * merges the value into the resolved options shape.\n */\n public static readonly STASH_KEY = 'openaiResponses' as const\n\n readonly #baseline: OpenAIResponsesAdapterOptions\n\n /**\n * @param options - Constructor-baseline options. Re-validated on every iteration after\n * per-dispatch and per-iteration overrides are layered in.\n * @throws {@link E_INVALID_OPENAI_RESPONSES_OPTIONS} when `options` does not satisfy\n * `openAIResponsesOptionsSchema`.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n }\n\n /**\n * Returns a `DispatchExecutorFn` bound to this adapter's baseline plus optional executor-scope\n * overrides. The returned function is reusable across iterations — every iteration re-merges\n * with `ctx.stash[STASH_KEY]` and re-validates the result.\n *\n * @param overrides - Optional executor-scope overrides. Higher precedence than the baseline,\n * lower precedence than `ctx.stash[STASH_KEY]`.\n * @returns A `DispatchExecutorFn` suitable for `DispatchRunner`.\n */\n executor(overrides?: Partial<OpenAIResponsesAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = OpenAIResponsesAdapter\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n const localWarn = (msg: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message: msg })\n }\n\n // ── Step 1: merge & validate ──────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<OpenAIResponsesAdapterOptions>)\n : {}\n const mergedRaw = mergeOptions(baseline, overrides, stashOverrides)\n const merged = validateOptions(mergedRaw)\n\n if (merged.tokenEncoding !== null && merged.contextWindow === undefined) {\n throw new E_INVALID_OPENAI_RESPONSES_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n\n // ── Step 2: resolve helpers ───────────────────────────────────────────\n const resolvedHelpers = resolveHelpers(merged.helpers)\n\n // ── Step 3: artifact-reader tools ─────────────────────────────────────\n // Forged by the DispatchRunner CORE into `ctx.tools` before the input pipeline runs\n // (generation is a generic core concern; this battery owns only representation). Read the\n // pre-forged `ctx.tools` directly — no local merge, no bindContext here.\n\n // ── Step 4: pre-render tool-call results ──────────────────────────────\n const renderedToolCallResults = new Map<\n ToolCall,\n string | OpenAIResponsesInputContentBlock[]\n >()\n for (const tc of ctx.turnToolCalls) {\n const rendered = await resolvedHelpers.renderOpenAIResponsesToolCallResult({\n toolCall: tc,\n results: tc.results as\n | Tokenizable\n | SpooledArtifact\n | SpooledArtifact[]\n | Media\n | Media[],\n tool: ctx.tools.get(tc.tool) as Tool | ArtifactTool | undefined,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n renderOpenAIResponsesMediaBlocks: resolvedHelpers.renderOpenAIResponsesMediaBlocks,\n renderArtifactHandleBody: resolvedHelpers.renderArtifactHandleBody,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn: localWarn,\n })\n renderedToolCallResults.set(tc, rendered)\n }\n\n // ── Step 5: context window enforcement ────────────────────────────────\n if (merged.tokenEncoding !== null && merged.contextWindow !== undefined) {\n const encoding = merged.tokenEncoding as TokenEncodingId\n let spTokens = await estimateTokensOf(ctx.systemPrompt, encoding)\n let siTokens = 0\n {\n // The wire ships ONE `<system_instructions kind=\"developer-rules\">` block wrapping every\n // standing instruction (+68 chars over a 15-char body), not the raw strings. Counting the\n // rendered block captures both the bodies and that wrapper.\n const siBlock = resolvedHelpers.renderStandingInstructions(ctx.standingInstructions)\n if (siBlock.length > 0) {\n siTokens = await estimateTokensOf(new Tokenizable(siBlock), encoding)\n }\n }\n let memTokens = 0\n for (const mem of ctx.turnMemories as Set<Memory>) {\n memTokens += await estimateTokensOf(mem.content, encoding)\n }\n let retTokens = 0\n for (const r of ctx.turnRetrievables) {\n retTokens +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n encoding as TokenEncoding,\n resolvedHelpers.renderRetrievableHandleBody\n )\n : await estimateTokensOf(r.content, encoding)\n }\n let tlTokens = 0\n for (const msg of ctx.turnMessages) {\n if (msg.content !== undefined) {\n // Count the RENDERED message, not the raw content. Every timeline message goes on the\n // wire wrapped in an identity envelope — `<message_<id> from=… role=… createdAt=…>` —\n // which the guard previously ignored entirely. Measured: a 30-char message ships as\n // 118 chars (3.9x), and the envelope is a near-fixed ~90 chars regardless of body\n // length, so a 40-turn conversation of short messages leaked ~880 tokens the guard\n // never saw. Rendering it here is the honest measure: it is the same helper the\n // builder uses, so the count tracks the wire by construction rather than by a\n // hand-maintained estimate that drifts when the envelope changes.\n const renderedMsg = await resolvedHelpers.renderOpenAIResponsesTimelineMessage({\n message: msg,\n selfIdentity: merged.selfIdentity ?? 'assistant',\n // Media is tallied separately below, from byte length; asking this renderer to\n // resolve attachments would duplicate the base64 work and can throw under\n // `unsupportedMediaPolicy: 'throw'` purely to measure it.\n unsupportedMediaPolicy: 'synthetic-description',\n renderOpenAIResponsesMediaBlocks: resolvedHelpers.renderOpenAIResponsesMediaBlocks,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n })\n const renderedText =\n renderedMsg === null\n ? ''\n : (\n ((renderedMsg as { content?: unknown }).content as\n | Array<{ type: string; text?: string }>\n | undefined) ?? []\n )\n .filter((b) => b.type === 'input_text')\n .map((b) => b.text ?? '')\n .join('')\n tlTokens += await estimateTokensOf(\n new Tokenizable(renderedText.length > 0 ? renderedText : msg.content.toString()),\n encoding\n )\n }\n // A message's ATTACHMENTS render into real wire content — `renderOpenAIResponsesTimeline\n // Message` turns each one into `input_image`/`input_file` blocks carrying a base64\n // payload — so they must be tallied too. Counting only `msg.content` left a user turn\n // with an image attachment entirely invisible to the guard, which is the same\n // undercount already fixed for rendered tool-call results below, one code path over.\n //\n // The media is measured by its own byte length rather than by rendering it here:\n // re-rendering would duplicate the base64 work (and can throw under\n // `unsupportedMediaPolicy: 'throw'`) purely to measure it. base64 inflates bytes by 4/3,\n // and a token is ~4 base64 chars, so `byteLength / 3` is the honest FLOOR for the\n // payload — same doctrine as the tool-declaration and native-block floors.\n for (const media of msg.attachments ?? []) {\n try {\n const bytes = await media.byteLength()\n if (bytes !== undefined && Number.isFinite(bytes) && bytes > 0) {\n tlTokens += Math.ceil(bytes / 3)\n }\n } catch {\n /* unreadable attachment — cannot measure it; the floor simply omits it */\n }\n }\n }\n for (const th of ctx.turnThoughts) {\n // Same envelope problem as messages: a surfaced thought ships wrapped in\n // `<thought_<id> nonce=… kind=… from=… createdAt=…>`, measured at +113 chars over a\n // 19-char body. Count the rendered form so the tally tracks the wire.\n const renderedThought = resolvedHelpers.renderThought(th.content.toString(), {\n nonce: th.id,\n kind: 'self-reasoning',\n from: String(th.identity?.identifier ?? merged.selfIdentity ?? 'assistant'),\n createdAt: th.createdAt?.toISO?.() ?? undefined,\n })\n tlTokens += await estimateTokensOf(new Tokenizable(renderedThought), encoding)\n }\n for (const rendered of renderedToolCallResults.values()) {\n if (typeof rendered === 'string') {\n tlTokens += await estimateTokensOf(new Tokenizable(rendered), encoding)\n continue\n }\n // Count EVERY block that is actually transmitted, not just `input_text`. A native\n // `input_image`/`input_file` block carries a base64 payload in `image_url`/`file_data`\n // that is real request content; filtering those out understated the request by the\n // entire attachment, so a prompt the guard accepted could still exceed the provider's\n // window. Tallying the block's own wire JSON keeps this an honest FLOOR (the provider\n // bills images by its own tiling rules, which are not reproducible client-side) rather\n // than a pretend-exact count — same doctrine as the tool-declaration floor below.\n for (const block of rendered) {\n const text =\n block.type === 'input_text' ? block.text : JSON.stringify(block satisfies object)\n tlTokens += await estimateTokensOf(new Tokenizable(text), encoding)\n }\n }\n // Tool-call REQUEST items. A tool call goes on the wire as two sibling items — the\n // `function_call` (carrying `name` + `arguments`) and its `function_call_output` — but only\n // the OUTPUT was tallied above, via `renderedToolCallResults`. A prior call with large\n // arguments was therefore invisible to the guard. Counting the `function_call` item's own\n // wire JSON keeps this the same honest FLOOR as the blocks above.\n for (const tc of ctx.turnToolCalls) {\n const argsText = typeof tc.args === 'string' ? tc.args : JSON.stringify(tc.args ?? {})\n const callItemJson = JSON.stringify({\n type: 'function_call',\n call_id: tc.id,\n name: tc.tool,\n arguments: argsText,\n })\n tlTokens += await estimateTokensOf(new Tokenizable(callItemJson), encoding)\n }\n // Tool DECLARATIONS: tally the tokens of the wire `tools` JSON as an honest FLOOR — same\n // rationale as `openai_chat_completions/adapter.ts`.\n let toolTokens = 0\n const visibleTools = ctx.tools.visible()\n if (visibleTools.length > 0) {\n const toolsJson = JSON.stringify(\n resolvedHelpers.toolsToOpenAIResponsesTools(visibleTools, {\n descriptionToChatCompletionsJsonSchema: (d: unknown) =>\n resolvedHelpers.descriptionToChatCompletionsJsonSchema(d as never),\n strict: merged.strict,\n })\n )\n toolTokens = await estimateTokensOf(new Tokenizable(toolsJson), encoding)\n }\n const total = spTokens + siTokens + memTokens + retTokens + tlTokens + toolTokens\n const perBucketObj = {\n systemPrompt: spTokens,\n standingInstructions: siTokens,\n memories: memTokens,\n retrievables: retTokens,\n timeline: tlTokens,\n tools: toolTokens,\n }\n helpers.log.debug({\n kind: 'context-window-usage',\n message: `Context window usage: ${total}/${merged.contextWindow} tokens`,\n payload: {\n total,\n limit: merged.contextWindow,\n encoding,\n perBucket: perBucketObj,\n },\n })\n if (total > merged.contextWindow) {\n const perBucket = JSON.stringify(perBucketObj)\n throw new E_OPENAI_RESPONSES_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n encoding,\n perBucket,\n ])\n }\n }\n\n // ── Step 5b: tool_choice + forged artifact-tools guard ────────────────\n const toolChoice = merged.tool_choice\n const forcedToolNames: string[] = []\n if (toolChoice && typeof toolChoice === 'object' && toolChoice.type === 'function') {\n forcedToolNames.push(toolChoice.name)\n }\n const forcedForgedHits: Array<{ toolName: string }> = []\n for (const name of forcedToolNames) {\n const t = ctx.tools.get(name) as { ephemeral?: boolean } | undefined\n if (t?.ephemeral === true) {\n forcedForgedHits.push({ toolName: name })\n }\n }\n if (forcedForgedHits.length > 0) {\n if (merged.strictToolChoice === true) {\n throw new E_INVALID_OPENAI_RESPONSES_OPTIONS([\n `tool_choice forces forged ephemeral artifact-query tool(s): ${forcedForgedHits\n .map((h) => h.toolName)\n .join(\n ', '\n )} — these may not exist on the next iteration. Remove the override or unset strictToolChoice.`,\n ])\n }\n helpers.log.warn({\n kind: 'tool-choice-forged-artifact',\n message: `tool_choice forces ${forcedForgedHits.length} forged ephemeral artifact-query tool(s); this is almost always a misconfiguration`,\n payload: { toolNames: forcedForgedHits.map((h) => h.toolName) },\n })\n }\n\n // ── Step 6: build request body ────────────────────────────────────────\n const buildInput = async (\n dropReasoning: boolean\n ): Promise<{\n instructions?: string\n input: OpenAIResponsesInputItem[]\n tools?: OpenAIResponsesTool[]\n fingerprintableLength: number\n }> => {\n return resolvedHelpers.buildOpenAIResponsesInput({\n model: merged.model,\n systemPrompt: ctx.systemPrompt,\n // The live dispatch context, so a DYNAMIC system prompt (a `Tokenizable` built from a\n // `(ctx) => string` resolver) sees it. Previously nothing passed this, so such a prompt\n // rendered against `undefined` and quietly dropped everything it read from context.\n renderCtx: ctx,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: dropReasoning ? [] : ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: ctx.tools,\n strict: merged.strict,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? [\n 'standingInstructions',\n 'memories',\n 'retrievables',\n 'timeline',\n ],\n selfIdentity: merged.selfIdentity ?? 'assistant',\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n reasoningReplay: dropReasoning ? 'off' : (merged.reasoningReplay ?? 'off'),\n systemPromptChannel: merged.systemPromptChannel ?? 'instructions',\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n renderOpenAIResponsesToolCallResult: resolvedHelpers.renderOpenAIResponsesToolCallResult,\n renderOpenAIResponsesMediaBlocks: resolvedHelpers.renderOpenAIResponsesMediaBlocks,\n renderChatCompletionsSystemPrompt: resolvedHelpers.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: resolvedHelpers.renderStandingInstructions,\n renderMemories: resolvedHelpers.renderMemories,\n renderRetrievables: resolvedHelpers.renderRetrievables,\n renderRetrievableSafetyDirective: resolvedHelpers.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: resolvedHelpers.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: resolvedHelpers.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: resolvedHelpers.renderThirdPartyPrivateRetrievables,\n renderRetrievableHandleBody: resolvedHelpers.renderRetrievableHandleBody,\n renderOpenAIResponsesTimelineMessage:\n resolvedHelpers.renderOpenAIResponsesTimelineMessage,\n renderOpenAIResponsesReasoningItem: resolvedHelpers.renderOpenAIResponsesReasoningItem,\n fingerprintOpenAIResponsesPrefix: resolvedHelpers.fingerprintOpenAIResponsesPrefix,\n toolsToOpenAIResponsesTools: resolvedHelpers.toolsToOpenAIResponsesTools,\n descriptionToChatCompletionsJsonSchema:\n resolvedHelpers.descriptionToChatCompletionsJsonSchema,\n renderThought: resolvedHelpers.renderThought,\n filterThoughts: resolvedHelpers.filterThoughts,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n warn: localWarn,\n })\n }\n\n let assembled = await buildInput(false)\n\n const stream = merged.stream ?? true\n const buildBody = (a: {\n instructions?: string\n input: OpenAIResponsesInputItem[]\n tools?: OpenAIResponsesTool[]\n }): OpenAIResponsesRequestBody => {\n const b: OpenAIResponsesRequestBody = {\n model: merged.model,\n input: a.input,\n stream,\n store: false,\n }\n if (a.instructions !== undefined) b.instructions = a.instructions\n for (const [k, v] of Object.entries(merged)) {\n if (ADK_CONTROL_KEYS.has(k)) continue\n if (\n k === 'model' ||\n k === 'input' ||\n k === 'stream' ||\n k === 'store' ||\n k === 'instructions' ||\n k === 'tool_choice' ||\n k === 'tools'\n )\n continue\n if (v === undefined) continue\n ;(b as Record<string, unknown>)[k] = v\n }\n if (merged.tool_choice !== undefined) b.tool_choice = merged.tool_choice\n if (a.tools && a.tools.length > 0) b.tools = a.tools\n // reasoningReplay 'encrypted' auto-adds 'reasoning.encrypted_content' to `include`.\n if (merged.reasoningReplay === 'encrypted') {\n const include = new Set(b.include ?? [])\n include.add('reasoning.encrypted_content')\n b.include = Array.from(include)\n }\n return b\n }\n\n let body = buildBody(assembled)\n\n const dispatchStreamId = uuidv6()\n\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'openai_responses',\n kind: 'request-body',\n messages: body.input,\n tools: body.tools,\n requestBody: body,\n streamed: stream,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // ── Step 7: POST with retry / timeout loop ────────────────────────────\n const rawBase = merged.baseURL ?? 'https://api.openai.com/v1'\n const baseURL = rawBase.endsWith('/') ? rawBase.slice(0, -1) : rawBase\n const url = `${baseURL}/responses`\n\n const buildHeaders = (): Record<string, string> => {\n const h: Record<string, string> = { 'Content-Type': 'application/json' }\n if (stream) h['Accept'] = 'text/event-stream'\n if (merged.apiKey) h['Authorization'] = `Bearer ${merged.apiKey}`\n if (merged.organization) h['OpenAI-Organization'] = merged.organization\n if (merged.project) h['OpenAI-Project'] = merged.project\n if (merged.headers) Object.assign(h, merged.headers)\n return h\n }\n\n const retryCfg: ChatCompletionsRetryConfig = {\n maxAttempts: merged.retry?.maxAttempts ?? 1,\n baseDelayMs: merged.retry?.baseDelayMs ?? 500,\n maxDelayMs: merged.retry?.maxDelayMs ?? 30_000,\n retriableStatuses: merged.retry?.retriableStatuses ?? [429, 502, 503, 504],\n honorRetryAfter: merged.retry?.honorRetryAfter ?? true,\n }\n\n const fetchFn = merged.fetch ?? globalThis.fetch\n const maxAttempts = retryCfg.maxAttempts ?? 1\n\n // The one-time reasoning-drop retry (Known Gotcha / recoverable-failure handling) is\n // ORTHOGONAL to the retry/backoff loop below — it re-assembles the request body once (with\n // every reasoning item stripped) and re-enters the whole POST loop fresh, rather than being\n // counted against `maxAttempts`.\n let usedReasoningDropRetry = false\n\n let response: Response | undefined\n let attempt = 1\n let attemptStartedAtMs = Date.now()\n let disposeLink: () => void = () => {}\n requestLoop: while (attempt <= maxAttempts) {\n if (ctx.abortSignal.aborted) return\n\n const internalController = new AbortController()\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n // When THIS attempt's HTTP exchange began. `requestTimeoutMs` is a whole-exchange budget,\n // so the body-read deadline further down is measured from here rather than from the moment\n // headers arrived — otherwise a response that spent most of the budget before sending\n // headers was granted a second, full interval to stream its body.\n attemptStartedAtMs = Date.now()\n const requestTimeoutMs = merged.requestTimeoutMs ?? 0\n if (requestTimeoutMs > 0) {\n timeoutHandle = setTimeout(() => internalController.abort(), requestTimeoutMs)\n }\n disposeLink()\n const { signal: linkedSignal, dispose: disposeCurrentLink } = linkAbortSignals([\n ctx.abortSignal,\n internalController.signal,\n ])\n disposeLink = disposeCurrentLink\n\n try {\n response = await fetchFn(url, {\n method: 'POST',\n headers: buildHeaders(),\n body: JSON.stringify(body),\n signal: linkedSignal,\n })\n } catch (err) {\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n if (ctx.abortSignal.aborted) return\n if (internalController.signal.aborted) {\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Request timed out after ${requestTimeoutMs}ms on attempt ${attempt}/${maxAttempts}`,\n payload: { requestTimeoutMs, attempt, maxAttempts },\n })\n if (attempt < maxAttempts) {\n const delay = computeBackoff(attempt, retryCfg)\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n ctx.nack(new E_OPENAI_RESPONSES_REQUEST_TIMEOUT([requestTimeoutMs]))\n return\n }\n helpers.log.error({\n kind: 'transport-error',\n message: `Transport failure on attempt ${attempt}/${maxAttempts}: ${isError(err) ? err.message : String(err)}`,\n payload: { attempt, maxAttempts, detail: isError(err) ? err.message : String(err) },\n })\n if (attempt < maxAttempts) {\n const delay = computeBackoff(attempt, retryCfg)\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n ctx.nack(new E_OPENAI_RESPONSES_HTTP_ERROR([0, isError(err) ? err.message : String(err)]))\n return\n }\n\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n\n if (!response.ok) {\n const status = response.status\n const errBody = await response.text().catch(() => '')\n\n // ── Recoverable-failure handling: a rejected REPLAYED reasoning item ──\n //\n // Two upstream 400s mean the same thing — \"the reasoning item you replayed is not\n // acceptable\" — and both have the same safe recovery: strip every reasoning item and\n // resend. They are handled identically:\n //\n // 1. `invalid_encrypted_content` — a persisted `encrypted_content` payload outlived a\n // server-side key rotation.\n // 2. A reasoning/output-item PAIRING violation — the adjacency constraint reported in\n // `openai/openai-node#1791` (see below).\n //\n // Case 2 previously nacked immediately, killing the turn and telling the caller to set\n // `reasoningReplay: 'off'` by hand. That was the wrong default for a failure the adapter\n // can recover from unaided, and it mattered most exactly where the constraint is least\n // certain: the pairing rule is UNDOCUMENTED, and the official docs actively contradict\n // it (the reasoning guide and cookbook both state that irrelevant reasoning items are\n // silently discarded — \"including them is harmless\"), while #1791 reports a hard 400\n // reproduced across five official SDKs. Because our adjacency sweep enforces a stricter\n // rule than the documented span rule, an upstream behavior shift could make the sweep\n // wrong — and the correct outcome then is a turn that degrades to no-replay, not a turn\n // that dies. The retry is still ONE-SHOT, so a genuinely broken request cannot loop.\n if (\n status === 400 &&\n !usedReasoningDropRetry &&\n bodyMatches(errBody, [INVALID_ENCRYPTED_CONTENT_PHRASE, ...REASONING_PAIRING_PHRASES])\n ) {\n usedReasoningDropRetry = true\n helpers.log.warn({\n kind: 'reasoning-replay-rejected',\n message:\n 'Upstream rejected a replayed reasoning item; dropping all reasoning items and retrying once.',\n payload: { status, body: errBody.slice(0, 512) },\n })\n assembled = await buildInput(true)\n body = buildBody(assembled)\n // Give the REBUILT request its own transport-retry budget. Plain `continue` leaves\n // `attempt` where the failed original left it, so a reasoning rejection arriving on the\n // last attempt handed the replacement a fully-spent budget: one transient 503 on the\n // rebuilt request then ended the turn, even though the recovery itself had worked. That\n // contradicts this block's own contract (the reasoning-drop retry is ORTHOGONAL to the\n // retry/backoff loop, not counted against it).\n //\n // Deliberately a FRESH BUDGET, not an unbounded one: `usedReasoningDropRetry` is\n // one-shot, so this reset can happen at most once per dispatch. Worst case is one\n // additional `maxAttempts` worth of POSTs, never a loop.\n attempt = 1\n continue requestLoop\n }\n\n // ── Reasoning/output-item pairing violation translation ─────────────\n // Reached only when the reasoning-free retry ALSO failed, so the rejection is not\n // attributable to a replayed reasoning item after all — the self-explaining error is\n // then the honest answer rather than a recovery the adapter has already tried.\n if (status === 400 && bodyMatches(errBody, REASONING_PAIRING_PHRASES)) {\n const offendingId =\n assembled.input.find((i): i is OpenAIResponsesReasoningItem => i.type === 'reasoning')\n ?.id ?? 'unknown'\n ctx.nack(new E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED([offendingId, errBody]))\n return\n }\n\n const retriable = (retryCfg.retriableStatuses ?? [429, 502, 503, 504]).includes(status)\n if (retriable && attempt < maxAttempts) {\n let delay = computeBackoff(attempt, retryCfg)\n if (retryCfg.honorRetryAfter !== false) {\n const ra = response.headers.get('Retry-After')\n if (ra) {\n const raMs = parseRetryAfter(ra)\n if (raMs > 0) delay = Math.min(Math.max(delay, raMs), retryCfg.maxDelayMs ?? 30_000)\n }\n }\n helpers.log.warn({\n kind: 'retry-attempt',\n message: `HTTP ${status} on attempt ${attempt}/${maxAttempts}; retrying in ~${delay}ms`,\n payload: {\n reason: 'http-status',\n status,\n delayMs: delay,\n attempt: attempt + 1,\n maxAttempts,\n },\n })\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n helpers.log.error({\n kind: 'http-error',\n message: `HTTP ${status} (terminal): ${errBody.slice(0, 256)}`,\n payload: { status, body: errBody, attempt, maxAttempts, retriable },\n })\n ctx.nack(new E_OPENAI_RESPONSES_HTTP_ERROR([status, errBody]))\n return\n }\n\n break\n }\n\n if (!response) return\n\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n\n // ── Inner helper: persist + execute one assembled tool call ───────────\n const executeAndPersistToolCall = async (call: {\n id: string\n name: string\n args: string\n }): Promise<void> => {\n // Resolve the vendor id once at ingress so reporting, persistence, and spooling agree.\n const callId = merged.toolCallIdFilter?.(call.id, ctx) ?? call.id\n const tool = ctx.tools.get(call.name)\n let args: Record<string, unknown> = {}\n let parseError: InstanceType<typeof E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS> | undefined\n if (call.args && call.args.length > 0) {\n try {\n const parsed: unknown = JSON.parse(call.args)\n if (isObject(parsed)) {\n args = parsed\n } else {\n const receivedKind = Array.isArray(parsed)\n ? 'array'\n : parsed === null\n ? 'null'\n : typeof parsed\n parseError = new E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS([\n `must be a JSON object; received ${receivedKind}`,\n call.args,\n ])\n }\n } catch {\n parseError = new E_OPENAI_RESPONSES_INVALID_TOOL_CALL_ARGS([\n 'are not valid JSON',\n call.args,\n ])\n }\n }\n const completedAt = nowIso()\n if (parseError !== undefined) {\n const toolName = normalizeToolName(call.name)\n const results = new Tokenizable(parseError.message)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, { results, isError: true, isComplete: true })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\n args,\n checksum,\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n if (!tool) {\n const toolName = normalizeToolName(call.name)\n const available = ctx.tools\n .all()\n .map((t) => t.name)\n .sort()\n const errText =\n available.length > 0\n ? `Tool not found: ${toolName}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${toolName}. No tools are available this turn.`\n const results = new Tokenizable(errText)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, { results, isError: true, isComplete: true })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\n args,\n checksum,\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n helpers.reportToolCall(callId, { tool: tool.name, args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(args)\n if (isArtifactTool) {\n if (Tokenizable.isTokenizable(raw)) {\n results = raw\n } else if (typeof raw === 'string') {\n results = new Tokenizable(raw)\n } else {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n }\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(callId, raw as string | Uint8Array)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(callId, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n let detailMsg = isError(err) ? err.message : String(err)\n if (\n isError(err) &&\n isError(err.cause) &&\n err.cause.message &&\n err.cause.message !== err.message\n ) {\n detailMsg = `${detailMsg} ${err.cause.message}`\n }\n results = new Tokenizable(detailMsg)\n }\n helpers.reportToolCall(callId, { results, isError: toolHadError, isComplete: true })\n const checksum = computeChecksum(tool.name, args)\n const completedAt2 = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: tool.name,\n args,\n checksum,\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n inline: isArtifactTool,\n createdAt: completedAt2,\n updatedAt: completedAt2,\n completedAt: completedAt2,\n })\n )\n }\n\n // FALLBACK tool-call recovery — consulted only when the provider returned zero structured\n // calls AND the caller opted in via `localToolCallParser`.\n const parseFallbackToolCalls = (\n content: string\n ): Array<{ id: string; name: string; args: string }> => {\n if (merged.localToolCallParser === undefined) return []\n if (typeof content !== 'string' || content.length === 0) return []\n const parser = resolveToolCallParser(merged.localToolCallParser)\n const toolNames = ctx.tools.visible().map((t) => t.name)\n return parser(content, { toolNames }).calls.map((c) => ({\n id: uuidv6(),\n name: c.name,\n args: JSON.stringify(c.arguments),\n }))\n }\n\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n\n // The wire shape a persisted reasoning item will actually REPLAY as, which is what the next\n // turn's adjacency sweep hashes. Under `summary-only` the renderer strips `content` and\n // `encrypted_content` (see `renderOpenAIResponsesReasoningItem`), so an accumulator that\n // recorded the FULL item produced a prefix the sweep never reproduces and every later item\n // dropped as stale. Building the replay shape here keeps persist and validate in agreement\n // for every mode.\n const replayShapeOf = (slot: {\n itemId: string\n summaryText: string\n reasoningText: string\n encryptedContent?: string\n }): OpenAIResponsesInputItem => {\n const summaryOnly = merged.reasoningReplay === 'summary-only'\n return {\n type: 'reasoning',\n id: normalizeOpenAIResponsesItemId(slot.itemId, 'rs'),\n summary:\n slot.summaryText.length > 0 ? [{ type: 'summary_text', text: slot.summaryText }] : [],\n ...(!summaryOnly && slot.reasoningText.length > 0\n ? { content: [{ type: 'reasoning_text', text: slot.reasoningText }] }\n : {}),\n ...(!summaryOnly && slot.encryptedContent\n ? { encrypted_content: slot.encryptedContent }\n : {}),\n }\n }\n\n // ── Persist a reasoning Thought from a finalized thinking slot ─────────\n const persistThought = async (\n slot: {\n itemId: string\n summaryText: string\n reasoningText: string\n encryptedContent?: string\n },\n pairedItemId: string | undefined,\n // Explicit timestamp so a caller draining several slots can order them monotonically —\n // see `stampFor` in the streaming drain. Defaults to \"now\" for the non-streaming path.\n stamp: string = nowIso(),\n // Items produced EARLIER IN THIS SAME RESPONSE that will sit between the request prefix\n // and this reasoning item once the whole response is replayed on the next turn.\n //\n // Without this, a response carrying two or more reasoning items replayed only the FIRST.\n // Every item's fingerprint was taken over the request prefix alone, but the next turn's\n // adjacency sweep re-derives each candidate's hash through its OWN position — which for\n // the second reasoning item includes the first reasoning item and its paired message. The\n // hashes could not match, so every item after the first was dropped as stale.\n precedingReplayItems: OpenAIResponsesInputItem[] = []\n ): Promise<void> => {\n const content = slot.reasoningText.length > 0 ? slot.reasoningText : slot.summaryText\n let payload: OpenAIResponsesReasoningReplayPayload | undefined\n if (merged.reasoningReplay !== 'off') {\n const item: OpenAIResponsesReasoningItem = {\n type: 'reasoning',\n id: normalizeOpenAIResponsesItemId(slot.itemId, 'rs'),\n summary:\n slot.summaryText.length > 0 ? [{ type: 'summary_text', text: slot.summaryText }] : [],\n ...(slot.reasoningText.length > 0\n ? { content: [{ type: 'reasoning_text', text: slot.reasoningText }] }\n : {}),\n ...(slot.encryptedContent ? { encrypted_content: slot.encryptedContent } : {}),\n }\n const prefixFingerprint = await resolvedHelpers.fingerprintOpenAIResponsesPrefix({\n model: merged.model,\n instructions: assembled.instructions,\n // Pass `assembled.tools` THROUGH, without an `?? []` fallback: the next turn's\n // adjacency sweep re-derives this hash against the same `undefined`-when-empty shape.\n // Coercing to `[]` here hashes different bytes than the sweep does and drops every\n // replayed reasoning item as stale whenever no tools are registered.\n tools: assembled.tools,\n // Hash the sweep-visible request prefix PLUS whatever this same response already\n // contributed ahead of this item (see `precedingReplayItems`). On the next turn the\n // sweep hashes exactly this sequence when it reaches this item's position.\n //\n // `throughItem` is the length of that combined array: the sweep-visible region of the\n // request (a trailing-bucket item is appended AFTER the sweep runs, so it is absent\n // from every prefix the sweep hashes — including it here would guarantee a mismatch\n // whenever `bucketOrder` puts a non-empty bucket after `'timeline'`) plus the\n // preceding items from this response.\n input: [\n ...assembled.input.slice(0, assembled.fingerprintableLength),\n ...precedingReplayItems,\n ],\n throughItem: assembled.fingerprintableLength + precedingReplayItems.length,\n })\n payload = {\n variant: 'responses-reasoning',\n item,\n pairedItemId,\n prefixFingerprint,\n }\n }\n await ctx.storeThought(\n new Thought({\n id: slot.itemId,\n content,\n identity: selfIdentity,\n payload,\n replayCompatibility: payload ? 'openai-responses-reasoning-v1' : undefined,\n createdAt: stamp,\n updatedAt: stamp,\n })\n )\n }\n\n // ── Step 8: streaming path ────────────────────────────────────────────\n if (stream) {\n if (!response.body) {\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR(['response has no body']))\n return\n }\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n const slotMachine = resolvedHelpers.createResponsesOutputSlotMachine()\n const streamId = dispatchStreamId\n\n let buffer = ''\n let idleTimer: ReturnType<typeof setTimeout> | undefined\n let stalled = false\n let terminalSeen = false\n let terminalStatus: OpenAIResponsesResponseObject['status'] | undefined\n let incompleteReason: string | undefined\n let finalUsage: OpenAIResponsesResponseObject['usage'] | undefined\n let finalModel: string | undefined\n let finalRaw: Record<string, unknown> = {}\n const collectedToolCalls: Array<{ id: string; name: string; args: string }> = []\n let sawMessageDelta = false\n\n const idleMs = merged.streamIdleTimeoutMs ?? 0\n const armIdleTimer = (): void => {\n if (idleMs <= 0) return\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(() => {\n stalled = true\n helpers.log.warn({\n kind: 'stream-idle-timeout',\n message: `SSE stream went idle for ${idleMs}ms; cancelling`,\n payload: { idleMs },\n })\n reader.cancel().catch(() => {\n /* swallow */\n })\n }, idleMs)\n }\n const clearIdleTimer = (): void => {\n if (idleTimer) {\n clearTimeout(idleTimer)\n idleTimer = undefined\n }\n }\n\n const drainAndPersist = async (): Promise<void> => {\n // Persist every open text / thinking slot.\n const orderedIndices = Array.from(slotMachine.slots().keys()).sort((a, b) => a - b)\n // Timestamps are derived MONOTONICALLY from each slot's position in output-index order,\n // never from independent `nowIso()` calls. Two back-to-back `nowIso()` calls return an\n // identical ISO string ~998 times in 1000, and `buildOpenAIResponsesInput` pushes\n // messages into the timeline before thoughts and then stable-sorts by `createdAt` — so\n // on a tie the assistant message sorted AHEAD of its own reasoning item, leaving that\n // item last with nothing after it, and the adjacency sweep dropped it as unpaired. That\n // made reasoning replay fail most of the time even under the default configuration.\n const drainBaseMs = DateTime.now().toMillis()\n // Same multi-reasoning accumulator as the non-streaming path: items from THIS response\n // that will precede a later reasoning item once the whole response replays next turn.\n const replayedSoFar: OpenAIResponsesInputItem[] = []\n const stampFor = (pos: number): string =>\n DateTime.fromMillis(drainBaseMs + pos).toISO() ??\n new Date(drainBaseMs + pos).toISOString()\n for (const [pos, idx] of orderedIndices.entries()) {\n const slot = slotMachine.getSlot(idx)\n if (!slot) continue\n if (slot.kind === 'text') {\n if (slot.text.length > 0 || slot.refusal.length > 0) {\n sawMessageDelta = true\n const text = slot.refusal.length > 0 ? slot.refusal : slot.text\n helpers.reportMessage(slot.itemId || streamId, '', { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: slot.itemId || streamId,\n role: 'assistant',\n content: text,\n identity: selfIdentity,\n createdAt: stampFor(pos),\n updatedAt: stampFor(pos),\n })\n )\n replayedSoFar.push({\n type: 'message',\n role: 'assistant',\n status: 'completed',\n id: slot.itemId || streamId,\n content: [{ type: 'output_text', text, annotations: [] }],\n })\n }\n } else if (slot.kind === 'thinking') {\n helpers.reportThought(slot.itemId || streamId, '', { isComplete: true })\n // `pairedItemId` records the id of the item that FOLLOWS this reasoning item on the\n // wire (per its own contract in types.ts) — look ahead to the next slot in output-index\n // order, not back at whatever slot preceded this one.\n const nextIdx = orderedIndices[pos + 1]\n const nextSlot = nextIdx !== undefined ? slotMachine.getSlot(nextIdx) : undefined\n const pairedItemId = nextSlot?.itemId\n await persistThought(slot, pairedItemId, stampFor(pos), [...replayedSoFar])\n replayedSoFar.push(replayShapeOf(slot))\n } else if (slot.kind === 'toolCall') {\n collectedToolCalls.push({\n id: `${slot.callId}|${slot.itemId}`,\n name: slot.name,\n args: slot.args,\n })\n }\n }\n\n if (finalUsage !== undefined || terminalStatus !== undefined) {\n const calls = collectedToolCalls.length > 0\n helpers.reportGenerationStats(\n extractGenerationStats({\n model: finalModel ?? merged.model,\n usage: finalUsage,\n finishReason: mapStopReason(terminalStatus, incompleteReason, calls),\n raw:\n Object.keys(finalRaw).length > 0\n ? finalRaw\n : { usage: finalUsage, status: terminalStatus },\n })\n )\n }\n\n const nativeCalls = collectedToolCalls\n const combinedText = Array.from(slotMachine.slots().values())\n .filter((s): s is Extract<typeof s, { kind: 'text' }> => s.kind === 'text')\n .map((s) => (s.refusal.length > 0 ? s.refusal : s.text))\n .join('')\n const calls = nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(combinedText)\n\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: combinedText,\n cleanedText: combinedText,\n reasoning: Array.from(slotMachine.slots().values())\n .filter(\n (s): s is Extract<typeof s, { kind: 'thinking' }> => s.kind === 'thinking'\n )\n .map((s) => (s.reasoningText.length > 0 ? s.reasoningText : s.summaryText)),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n helpers.log.debug({\n kind: 'stream-finalised',\n message: `Stream finalised: ${calls.length} tool call(s), message=${sawMessageDelta}`,\n payload: { toolCallCount: calls.length, sawMessageDelta, terminalSeen },\n })\n\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n\n // Processes one SSE frame's `data:` lines. Returns `'stop'` once a terminal event (or a\n // fatal stream-level error) has been handled — the caller must stop reading and return\n // immediately — or `'continue'` otherwise. Extracted so the SAME logic can run once more\n // on whatever is left in `buffer` after EOF (Known finding: a final frame lacking its\n // trailing blank-line separator was previously left unprocessed and silently dropped).\n const processFrame = async (frame: string): Promise<'stop' | 'continue'> => {\n // Per the SSE spec an event's `data:` FIELDS are concatenated (newline-separated) and the\n // result parsed ONCE — a single JSON value may legally be split across several `data:`\n // lines. Parsing each line independently produced two invalid JSON fragments and silently\n // skipped both, losing the whole event. OpenAI does not split events today, but an\n // intermediary may, exactly as one already forced the CRLF handling above.\n //\n // Concatenating per frame is a superset of the previous behaviour for the single-line\n // case (one field joins to itself), so nothing that parsed before stops parsing.\n const dataLines = frame\n .split('\\n')\n .filter((line) => line.startsWith('data:'))\n .map((line) => line.slice(5).trim())\n for (const data of dataLines.length > 1 ? [dataLines.join('\\n')] : dataLines) {\n if (data.length === 0) continue\n let payload: OpenAIResponsesStreamEvent\n try {\n payload = JSON.parse(data) as OpenAIResponsesStreamEvent\n } catch {\n helpers.log.trace({\n kind: 'sse-parse-failure',\n message: 'Failed to parse SSE chunk as JSON; skipping',\n payload: { dataPreview: data.slice(0, 256) },\n })\n continue\n }\n // The union's structural fallback member (`OpenAIResponsesStreamEventBase &\n // Record<string, unknown>`, covering every event type this battery does not act\n // on) carries a loose `type: string`, which prevents TypeScript from narrowing the\n // discriminant inside a `switch` the way it would for a \"closed\" union — the same\n // issue documented in `helpers.ts`'s output-slot-machine `openSlot`/`finalizeSlot`.\n // Cast to the specific event type inside each case rather than rely on narrowing.\n switch (payload.type) {\n case 'response.output_item.added': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.output_item.added' }\n >\n const slot = slotMachine.openSlot(ev.output_index, ev.item)\n if (!slot) {\n helpers.log.debug({\n kind: 'unhandled-output-item',\n message: `No slot opened for output item type \"${ev.item.type}\" at index ${ev.output_index}`,\n payload: { itemType: ev.item.type, outputIndex: ev.output_index },\n })\n }\n break\n }\n case 'response.output_text.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.output_text.delta' }\n >\n slotMachine.appendText(ev.output_index, ev.delta)\n sawMessageDelta = true\n helpers.reportMessage(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.refusal.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.refusal.delta' }\n >\n slotMachine.appendRefusal(ev.output_index, ev.delta)\n sawMessageDelta = true\n helpers.reportMessage(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.reasoning_summary_text.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.reasoning_summary_text.delta' }\n >\n slotMachine.appendReasoningSummary(ev.output_index, ev.delta)\n helpers.reportThought(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.reasoning_text.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.reasoning_text.delta' }\n >\n slotMachine.appendReasoningText(ev.output_index, ev.delta)\n helpers.reportThought(String(ev.item_id || streamId), ev.delta)\n break\n }\n case 'response.function_call_arguments.delta': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.function_call_arguments.delta' }\n >\n slotMachine.appendFunctionCallArgumentsDelta(ev.output_index, ev.delta)\n break\n }\n case 'response.function_call_arguments.done': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.function_call_arguments.done' }\n >\n slotMachine.setFunctionCallArgumentsDone(ev.output_index, ev.arguments)\n break\n }\n case 'response.output_item.done': {\n // The ONLY point at which a reasoning item's encrypted_content is captured\n // (Known Gotcha #3) — never at `.added`, before it's populated.\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.output_item.done' }\n >\n slotMachine.finalizeSlot(ev.output_index, ev.item)\n break\n }\n case 'response.completed':\n case 'response.incomplete': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.completed' | 'response.incomplete' }\n >\n terminalSeen = true\n terminalStatus = ev.response.status\n incompleteReason = ev.response.incomplete_details?.reason ?? undefined\n finalUsage = ev.response.usage\n finalModel = ev.response.model\n finalRaw = { ...ev.response } as unknown as Record<string, unknown>\n // Backfill `encrypted_content` from the terminal event's own `response.output`\n // for any reasoning item whose `.done` event omitted it.\n const output = ev.response.output ?? []\n for (const [i, item] of output.entries()) {\n if (item && item.type === 'reasoning') {\n const reasoningItem = item as OpenAIResponsesReasoningItem\n if (reasoningItem.encrypted_content) {\n slotMachine.backfillEncryptedContent(i, reasoningItem.encrypted_content)\n }\n }\n }\n clearIdleTimer()\n await drainAndPersist()\n return 'stop'\n }\n case 'response.failed': {\n const ev = payload as Extract<\n OpenAIResponsesStreamEvent,\n { type: 'response.failed' }\n >\n terminalSeen = true\n clearIdleTimer()\n const msg = ev.response.error?.message ?? 'response.failed'\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([msg]))\n return 'stop'\n }\n case 'error': {\n const ev = payload as Extract<OpenAIResponsesStreamEvent, { type: 'error' }>\n terminalSeen = true\n clearIdleTimer()\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([ev.message]))\n return 'stop'\n }\n default:\n // Every other event type (response.created, .in_progress,\n // content_part.added/.done, hosted-tool progress events, etc.) — not acted on.\n break\n }\n }\n return 'continue'\n }\n\n // `requestTimeoutMs` bounds the COMPLETE HTTP exchange, not just the headers. The\n // per-attempt timer above is cleared as soon as `fetch` resolves — which happens on\n // headers — so without this a response whose BODY then stalls waits forever whenever\n // `streamIdleTimeoutMs` is unset (verified: with `requestTimeoutMs: 300` and a body that\n // never yields a byte, the dispatch hung indefinitely). The deadline is measured from the\n // START OF THE ATTEMPT (not from when headers arrived) and races every `reader.read()`,\n // so slow headers and a slow body share one budget rather than getting one each.\n const bodyTimeoutMs = merged.requestTimeoutMs ?? 0\n const bodyDeadline = bodyTimeoutMs > 0 ? attemptStartedAtMs + bodyTimeoutMs : undefined\n const readWithDeadline = async (): Promise<\n ReadableStreamReadResult<Uint8Array> | 'timeout'\n > => {\n if (bodyDeadline === undefined) return reader.read()\n const remaining = bodyDeadline - Date.now()\n if (remaining <= 0) return 'timeout'\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n reader.read(),\n new Promise<'timeout'>((resolve) => {\n timer = setTimeout(() => resolve('timeout'), remaining)\n }),\n ])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n }\n\n try {\n armIdleTimer()\n while (true) {\n const read = await readWithDeadline()\n if (read === 'timeout') {\n clearIdleTimer()\n reader.cancel().catch(() => {\n /* swallow */\n })\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Response body exceeded requestTimeoutMs (${bodyTimeoutMs}ms) while streaming`,\n payload: { requestTimeoutMs: bodyTimeoutMs },\n })\n ctx.nack(new E_OPENAI_RESPONSES_REQUEST_TIMEOUT([bodyTimeoutMs]))\n return\n }\n const { done, value } = read\n if (done) break\n armIdleTimer()\n if (ctx.abortSignal.aborted) {\n clearIdleTimer()\n return\n }\n buffer += decoder.decode(value, { stream: true })\n let sepMatch = SSE_FRAME_SEPARATOR.exec(buffer)\n while (sepMatch !== null) {\n const frame = buffer.slice(0, sepMatch.index)\n buffer = buffer.slice(sepMatch.index + sepMatch[0].length)\n if ((await processFrame(frame)) === 'stop') return\n sepMatch = SSE_FRAME_SEPARATOR.exec(buffer)\n }\n }\n // EOF: flush the decoder's own internal state (a dangling multi-byte UTF-8 sequence split\n // across the last two chunks) and process whatever is left in `buffer` as one final frame\n // even without its own trailing blank-line separator — a terminal event (or any other\n // event) arriving as the very last bytes of the stream, with no `\\n\\n` after it, was\n // previously left sitting in `buffer` and silently dropped when the loop broke.\n buffer += decoder.decode()\n if (buffer.trim().length > 0) {\n const finalFrame = buffer\n buffer = ''\n if ((await processFrame(finalFrame)) === 'stop') return\n }\n clearIdleTimer()\n if (stalled) {\n // DELIBERATE ASYMMETRY with the EOF path below: a stall DISCARDS accumulated state\n // rather than draining it, even though both arrive here holding the same partial slots.\n //\n // The difference is what the two conditions tell you about the stream. EOF means the\n // provider CLOSED it — the turn is over and whatever arrived is all there will ever be,\n // so draining preserves a complete-if-short answer. A stall means the connection is\n // still OPEN and simply quiet: more content may well be in flight, and the reader is\n // being cancelled underneath it. Persisting a mid-sentence fragment as though it were\n // the model's answer would put text into history that the model never finished, which\n // the next turn would then treat as a completed assistant turn.\n //\n // The nack is therefore the whole outcome: the caller retries the turn rather than\n // inheriting a truncated answer. Same treatment in `openai_chat_completions` and\n // `anthropic_messages` — the convention was previously undocumented in all three,\n // which reads as an oversight rather than a choice, so it is stated here.\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_STALLED([idleMs]))\n return\n }\n if (!terminalSeen) {\n helpers.log.warn({\n kind: 'sse-eof-without-terminal-event',\n message:\n 'SSE stream ended without a terminal event (response.completed/.incomplete/.failed); draining accumulated state',\n })\n await drainAndPersist()\n }\n } catch (err) {\n clearIdleTimer()\n if (ctx.abortSignal.aborted) return\n if (stalled) {\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_STALLED([idleMs]))\n return\n }\n helpers.log.error({\n kind: 'stream-error',\n message: `SSE stream failed: ${isError(err) ? err.message : String(err)}`,\n payload: { detail: isError(err) ? err.message : String(err) },\n })\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n return\n }\n\n // ── Step 9: non-streaming path ────────────────────────────────────────\n let parsed: OpenAIResponsesResponseObject\n try {\n // `response.json()` consumes the BODY, and the per-attempt timer was cleared the moment\n // `fetch` resolved (which happens on headers) — so a response whose body then stalls hung\n // forever here despite a configured `requestTimeoutMs`. Verified before fixing: with\n // `requestTimeoutMs: 200` and a body that never yields a byte, the dispatch never returned.\n //\n // Bounded by the SAME whole-exchange deadline the streaming path uses (measured from\n // `attemptStartedAtMs`, not from when headers arrived), so slow headers and a slow body\n // share one budget rather than getting one each.\n const jsonTimeoutMs = merged.requestTimeoutMs ?? 0\n if (jsonTimeoutMs > 0) {\n const remaining = attemptStartedAtMs + jsonTimeoutMs - Date.now()\n let timer: ReturnType<typeof setTimeout> | undefined\n const timedOut = Symbol('timeout')\n const raced = await Promise.race([\n response.json(),\n new Promise<typeof timedOut>((resolve) => {\n timer = setTimeout(() => resolve(timedOut), Math.max(0, remaining))\n }),\n ]).finally(() => {\n if (timer !== undefined) clearTimeout(timer)\n })\n if (raced === timedOut) {\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Response body exceeded requestTimeoutMs (${jsonTimeoutMs}ms) while parsing`,\n payload: { requestTimeoutMs: jsonTimeoutMs },\n })\n ctx.nack(new E_OPENAI_RESPONSES_REQUEST_TIMEOUT([jsonTimeoutMs]))\n return\n }\n parsed = raced as OpenAIResponsesResponseObject\n } else {\n parsed = (await response.json()) as OpenAIResponsesResponseObject\n }\n } catch (err) {\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n const output = parsed.output ?? []\n const responseId = parsed.id ?? uuidv6()\n\n const nativeCalls: Array<{ id: string; name: string; args: string }> = []\n let combinedText = ''\n // Same monotonic-timestamp scheme as the streaming drain: derive each persisted record's\n // stamp from its position in `output` rather than calling `nowIso()` per item. Independent\n // calls collide on the same millisecond ~998 times in 1000, and a tie lets the assistant\n // message sort ahead of its own reasoning item (messages are pushed into the timeline before\n // thoughts, then stable-sorted), orphaning it so the adjacency sweep drops it.\n const outputBaseMs = DateTime.now().toMillis()\n const stampAt = (pos: number): string =>\n DateTime.fromMillis(outputBaseMs + pos).toISO() ??\n new Date(outputBaseMs + pos).toISOString()\n // Deliberately does NOT include `function_call`/`function_call_output` items from this\n // response, despite a review finding asking for them. A `ToolCall` is stamped with\n // `createdAt = completedAt` at EXECUTION time — after every item in the response that\n // requested it — and `buildOpenAIResponsesInput` orders the timeline by `createdAt`. So an\n // in-response tool call sorts AFTER the reasoning item, not before it. Verified on the wire:\n // turn 2 assembled as `role:user | message | function_call | function_call_output`, with the\n // tool call last. Adding it to the prefix would corrupt a hash that currently matches.\n // Items from THIS response that will precede the next reasoning item once the whole response\n // is replayed next turn, in the same wire shapes `buildOpenAIResponsesInput` emits: a\n // replayed reasoning item verbatim, and own-assistant text as the OUTPUT-message shape\n // (`renderOwnAssistantOutputItem`). Passed to `persistThought` so each item's fingerprint\n // covers the prefix the adjacency sweep will actually see at its position — without it, only\n // the first reasoning item in a multi-reasoning response ever replayed.\n const replayedSoFar: OpenAIResponsesInputItem[] = []\n for (const [i, item] of output.entries()) {\n if (!item) continue\n if (item.type === 'message') {\n const msgItem = item as Extract<typeof item, { type: 'message' }>\n const parts: string[] = []\n let refusal = ''\n for (const part of msgItem.content) {\n if (part.type === 'output_text') parts.push(part.text)\n else if (part.type === 'refusal') refusal = part.refusal\n }\n const text = refusal.length > 0 ? refusal : parts.join('')\n combinedText += text\n if (text.length > 0) {\n const messageId = msgItem.id ?? `${responseId}:message:${i}`\n helpers.reportMessage(messageId, text, { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: messageId,\n role: 'assistant',\n content: text,\n identity: selfIdentity,\n createdAt: stampAt(i),\n updatedAt: stampAt(i),\n })\n )\n // Own-assistant text replays as the OUTPUT-message shape, so record it in that exact\n // form for any later reasoning item's fingerprint prefix.\n replayedSoFar.push({\n type: 'message',\n role: 'assistant',\n status: 'completed',\n id: messageId,\n content: [{ type: 'output_text', text, annotations: [] }],\n })\n }\n } else if (item.type === 'reasoning') {\n const reasoningItem = item as OpenAIResponsesReasoningItem\n const summaryText = (reasoningItem.summary ?? []).map((s) => s.text).join('\\n\\n')\n const reasoningText = (reasoningItem.content ?? []).map((c) => c.text).join('\\n\\n')\n const thoughtId = reasoningItem.id\n helpers.reportThought(thoughtId, reasoningText.length > 0 ? reasoningText : summaryText, {\n isComplete: true,\n })\n // `pairedItemId` records the id of the item that FOLLOWS this reasoning item on the wire\n // (per its own contract in types.ts) — look ahead to the next output entry, not back at\n // whatever preceded this one.\n // `output[i + 1]` may be NULL, not merely undefined — the array is provider-supplied and\n // its element type is nullable, which is exactly why the loop head guards with\n // `if (!item) continue`. That guard does not cover this LOOKAHEAD: `'id' in null` throws\n // `TypeError: Cannot use 'in' operator to search for 'id' in null`, killing the whole\n // dispatch (no message persisted, no thought persisted, turn lost) whenever a null sits\n // between a reasoning item and its paired output item. A truthiness check covers null and\n // undefined together.\n const nextItem = output[i + 1]\n const pairedItemId = nextItem && 'id' in nextItem ? nextItem.id : undefined\n await persistThought(\n {\n itemId: reasoningItem.id,\n summaryText,\n reasoningText,\n ...(reasoningItem.encrypted_content\n ? { encryptedContent: reasoningItem.encrypted_content }\n : {}),\n },\n pairedItemId,\n stampAt(i),\n [...replayedSoFar]\n )\n // This item will itself precede any LATER reasoning item on replay.\n replayedSoFar.push(\n replayShapeOf({\n itemId: reasoningItem.id,\n summaryText,\n reasoningText,\n ...(reasoningItem.encrypted_content\n ? { encryptedContent: reasoningItem.encrypted_content }\n : {}),\n })\n )\n } else if (item.type === 'function_call') {\n const fcItem = item as OpenAIResponsesFunctionCallItem\n nativeCalls.push({\n id: fcItem.id ? `${fcItem.call_id}|${fcItem.id}` : fcItem.call_id,\n name: fcItem.name,\n args: fcItem.arguments,\n })\n } else {\n // Hosted/unrecognized output item type — never replayed, debug-log only.\n helpers.log.debug({\n kind: 'unhandled-output-item',\n message: `Unhandled output item type \"${item.type}\" at index ${i}`,\n payload: { itemType: item.type, index: i },\n })\n }\n }\n\n if (isObject(parsed.usage) || typeof parsed.status === 'string') {\n helpers.reportGenerationStats(\n extractGenerationStats({\n model: parsed.model ?? merged.model,\n usage: parsed.usage,\n finishReason: mapStopReason(\n parsed.status,\n parsed.incomplete_details?.reason ?? undefined,\n nativeCalls.length > 0\n ),\n raw: { ...parsed } as unknown as Record<string, unknown>,\n })\n )\n }\n\n if (parsed.status === 'failed' || parsed.status === 'cancelled') {\n const msg = parsed.error?.message ?? `response ${parsed.status}`\n ctx.nack(new E_OPENAI_RESPONSES_STREAM_ERROR([msg]))\n return\n }\n\n const calls = nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(combinedText)\n\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: combinedText,\n cleanedText: combinedText,\n reasoning: output\n .filter((i): i is OpenAIResponsesReasoningItem => i?.type === 'reasoning')\n .map(\n (i) =>\n (i.content ?? []).map((c) => c.text).join('\\n\\n') ||\n (i.summary ?? []).map((s) => s.text).join('\\n\\n')\n ),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: false,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n }\n\n /**\n * Returns `true` when `value` is an {@link OpenAIResponsesAdapter} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is an `OpenAIResponsesAdapter` instance.\n */\n public static isOpenAIResponsesAdapter(value: unknown): value is OpenAIResponsesAdapter {\n return isInstanceOf(value, 'OpenAIResponsesAdapter', OpenAIResponsesAdapter)\n }\n}\n"],"mappings":"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"}