@openrouter/sdk 0.9.11 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (608) hide show
  1. package/FUNCTIONS.md +3 -2
  2. package/_speakeasy/.github/action-inputs-config.json +4 -0
  3. package/esm/funcs/analyticsGetUserActivity.js +2 -1
  4. package/esm/funcs/apiKeysCreate.js +2 -1
  5. package/esm/funcs/apiKeysDelete.js +2 -1
  6. package/esm/funcs/apiKeysGet.js +2 -1
  7. package/esm/funcs/apiKeysGetCurrentKeyMetadata.js +2 -1
  8. package/esm/funcs/apiKeysList.js +2 -1
  9. package/esm/funcs/apiKeysUpdate.js +2 -1
  10. package/esm/funcs/betaResponsesSend.d.ts +4 -4
  11. package/esm/funcs/betaResponsesSend.js +4 -5
  12. package/esm/funcs/call-model.d.ts +20 -71
  13. package/esm/funcs/call-model.js +30 -72
  14. package/esm/funcs/chatSend.d.ts +4 -4
  15. package/esm/funcs/chatSend.js +4 -5
  16. package/esm/funcs/creditsCreateCoinbaseCharge.js +2 -1
  17. package/esm/funcs/creditsGetCredits.js +2 -1
  18. package/esm/funcs/embeddingsGenerate.js +2 -1
  19. package/esm/funcs/embeddingsListModels.js +2 -1
  20. package/esm/funcs/endpointsList.js +2 -1
  21. package/esm/funcs/endpointsListZdrEndpoints.js +2 -1
  22. package/esm/funcs/generationsGetGeneration.js +2 -1
  23. package/esm/funcs/guardrailsBulkAssignKeys.js +2 -1
  24. package/esm/funcs/guardrailsBulkAssignMembers.js +2 -1
  25. package/esm/funcs/guardrailsBulkUnassignKeys.js +2 -1
  26. package/esm/funcs/guardrailsBulkUnassignMembers.js +2 -1
  27. package/esm/funcs/guardrailsCreate.js +2 -1
  28. package/esm/funcs/guardrailsDelete.js +2 -1
  29. package/esm/funcs/guardrailsGet.js +2 -1
  30. package/esm/funcs/guardrailsList.js +2 -1
  31. package/esm/funcs/guardrailsListGuardrailKeyAssignments.js +2 -1
  32. package/esm/funcs/guardrailsListGuardrailMemberAssignments.js +2 -1
  33. package/esm/funcs/guardrailsListKeyAssignments.js +2 -1
  34. package/esm/funcs/guardrailsListMemberAssignments.js +2 -1
  35. package/esm/funcs/guardrailsUpdate.js +2 -1
  36. package/esm/funcs/modelsCount.d.ts +1 -1
  37. package/esm/funcs/modelsCount.js +9 -4
  38. package/esm/funcs/modelsList.js +3 -1
  39. package/esm/funcs/modelsListForUser.js +2 -1
  40. package/esm/funcs/oAuthCreateAuthCode.d.ts +1 -1
  41. package/esm/funcs/oAuthCreateAuthCode.js +4 -3
  42. package/esm/funcs/oAuthExchangeAuthCodeForAPIKey.js +2 -1
  43. package/esm/funcs/providersList.js +2 -1
  44. package/esm/index.d.ts +5 -23
  45. package/esm/index.js +5 -25
  46. package/esm/lib/anthropic-compat.d.ts +3 -2
  47. package/esm/lib/anthropic-compat.js +10 -11
  48. package/esm/lib/anthropic-compat.test.js +2 -1
  49. package/esm/lib/async-params.d.ts +21 -7
  50. package/esm/lib/async-params.js +5 -1
  51. package/esm/lib/chat-compat.d.ts +2 -2
  52. package/esm/lib/chat-compat.js +9 -10
  53. package/esm/lib/chat-compat.test.js +3 -2
  54. package/esm/lib/claude-type-guards.d.ts +2 -2
  55. package/esm/lib/config.d.ts +9 -11
  56. package/esm/lib/config.js +3 -3
  57. package/esm/lib/conversation-state.d.ts +4 -4
  58. package/esm/lib/conversation-state.js +35 -32
  59. package/esm/lib/encodings.js +20 -5
  60. package/esm/lib/env.d.ts +6 -2
  61. package/esm/lib/env.js +7 -3
  62. package/esm/lib/event-streams.d.ts +11 -4
  63. package/esm/lib/event-streams.js +44 -22
  64. package/esm/lib/files.d.ts +13 -0
  65. package/esm/lib/files.js +18 -0
  66. package/esm/lib/matchers.js +0 -1
  67. package/esm/lib/model-result.d.ts +79 -28
  68. package/esm/lib/model-result.js +386 -167
  69. package/esm/lib/next-turn-params.d.ts +4 -4
  70. package/esm/lib/next-turn-params.js +1 -1
  71. package/esm/lib/sdks.d.ts +1 -1
  72. package/esm/lib/sdks.js +18 -34
  73. package/esm/lib/security.d.ts +1 -1
  74. package/esm/lib/security.js +20 -10
  75. package/esm/lib/stream-transformers.d.ts +45 -21
  76. package/esm/lib/stream-transformers.js +33 -38
  77. package/esm/lib/stream-type-guards.d.ts +15 -15
  78. package/esm/lib/stream-type-guards.js +8 -32
  79. package/esm/lib/tool-context.d.ts +68 -0
  80. package/esm/lib/tool-context.js +175 -0
  81. package/esm/lib/tool-executor.d.ts +9 -5
  82. package/esm/lib/tool-executor.js +26 -16
  83. package/esm/lib/tool-orchestrator.d.ts +4 -4
  84. package/esm/lib/tool-orchestrator.js +1 -1
  85. package/esm/lib/tool-types.d.ts +123 -22
  86. package/esm/lib/tool-types.js +23 -0
  87. package/esm/lib/tool.d.ts +49 -60
  88. package/esm/lib/tool.js +15 -19
  89. package/esm/lib/turn-context.d.ts +3 -3
  90. package/esm/lib/turn-context.js +1 -1
  91. package/esm/lib/url.js +4 -2
  92. package/esm/models/annotationaddedevent.d.ts +20 -0
  93. package/esm/models/annotationaddedevent.js +30 -0
  94. package/esm/models/applypatchservertool.d.ts +20 -0
  95. package/esm/models/applypatchservertool.js +21 -0
  96. package/esm/models/baseinputsunion.d.ts +185 -0
  97. package/esm/models/baseinputsunion.js +274 -0
  98. package/esm/models/basereasoningconfig.d.ts +13 -0
  99. package/esm/models/basereasoningconfig.js +17 -0
  100. package/esm/models/chatassistantimages.d.ts +33 -0
  101. package/esm/models/chatassistantimages.js +44 -0
  102. package/esm/models/chatassistantmessage.d.ts +86 -0
  103. package/esm/models/chatassistantmessage.js +70 -0
  104. package/esm/models/chataudiooutput.d.ts +38 -0
  105. package/esm/models/chataudiooutput.js +36 -0
  106. package/esm/models/chatchoice.d.ts +27 -0
  107. package/esm/models/chatchoice.js +25 -0
  108. package/esm/models/chatcontentaudio.d.ts +52 -0
  109. package/esm/models/chatcontentaudio.js +55 -0
  110. package/esm/models/chatcontentcachecontrol.d.ts +40 -0
  111. package/esm/models/chatcontentcachecontrol.js +39 -0
  112. package/esm/models/chatcontentfile.d.ts +57 -0
  113. package/esm/models/chatcontentfile.js +59 -0
  114. package/esm/models/chatcontentimage.d.ts +68 -0
  115. package/esm/models/chatcontentimage.js +68 -0
  116. package/esm/models/chatcontentitems.d.ts +31 -0
  117. package/esm/models/chatcontentitems.js +57 -0
  118. package/esm/models/chatcontenttext.d.ts +37 -0
  119. package/esm/models/chatcontenttext.js +42 -0
  120. package/esm/models/chatcontentvideo.d.ts +26 -0
  121. package/esm/models/chatcontentvideo.js +33 -0
  122. package/esm/models/chatcontentvideoinput.d.ts +23 -0
  123. package/esm/models/chatcontentvideoinput.js +21 -0
  124. package/esm/models/{debugoptions.d.ts → chatdebugoptions.d.ts} +5 -5
  125. package/esm/models/{debugoptions.js → chatdebugoptions.js} +5 -5
  126. package/esm/models/chatdevelopermessage.d.ts +35 -0
  127. package/esm/models/chatdevelopermessage.js +21 -0
  128. package/esm/models/chatfinishreasonenum.d.ts +13 -0
  129. package/esm/models/{chatcompletionfinishreason.js → chatfinishreasonenum.js} +4 -4
  130. package/esm/models/chatformatgrammarconfig.d.ts +20 -0
  131. package/esm/models/chatformatgrammarconfig.js +14 -0
  132. package/esm/models/chatformatjsonschemaconfig.d.ts +21 -0
  133. package/esm/models/chatformatjsonschemaconfig.js +20 -0
  134. package/esm/models/chatformatpythonconfig.d.ts +15 -0
  135. package/esm/models/chatformatpythonconfig.js +13 -0
  136. package/esm/models/chatformattextconfig.d.ts +15 -0
  137. package/esm/models/chatformattextconfig.js +13 -0
  138. package/esm/models/chatfunctiontool.d.ts +77 -0
  139. package/esm/models/chatfunctiontool.js +49 -0
  140. package/esm/models/{jsonschemaconfig.d.ts → chatjsonschemaconfig.d.ts} +5 -5
  141. package/esm/models/{jsonschemaconfig.js → chatjsonschemaconfig.js} +5 -5
  142. package/esm/models/chatmessages.d.ts +20 -0
  143. package/esm/models/chatmessages.js +22 -0
  144. package/esm/models/chatnamedtoolchoice.d.ts +37 -0
  145. package/esm/models/chatnamedtoolchoice.js +26 -0
  146. package/esm/models/chatreasoningsummaryverbosityenum.d.ts +11 -0
  147. package/esm/models/chatreasoningsummaryverbosityenum.js +13 -0
  148. package/esm/models/{chatgenerationparams.d.ts → chatrequest.d.ts} +213 -120
  149. package/esm/models/chatrequest.js +426 -0
  150. package/esm/models/chatresult.d.ts +50 -0
  151. package/esm/models/chatresult.js +35 -0
  152. package/esm/models/chatstreamchoice.d.ts +27 -0
  153. package/esm/models/chatstreamchoice.js +24 -0
  154. package/esm/models/{chatstreamingresponsechunk.d.ts → chatstreamchunk.d.ts} +17 -13
  155. package/esm/models/chatstreamchunk.js +43 -0
  156. package/esm/models/{chatstreamingmessagechunk.d.ts → chatstreamdelta.d.ts} +12 -10
  157. package/esm/models/chatstreamdelta.js +37 -0
  158. package/esm/models/chatstreamtoolcall.d.ts +57 -0
  159. package/esm/models/chatstreamtoolcall.js +33 -0
  160. package/esm/models/chatsystemmessage.d.ts +35 -0
  161. package/esm/models/chatsystemmessage.js +21 -0
  162. package/esm/models/chattokenlogprob.d.ts +36 -0
  163. package/esm/models/chattokenlogprob.js +31 -0
  164. package/esm/models/chattokenlogprobs.d.ts +21 -0
  165. package/esm/models/chattokenlogprobs.js +16 -0
  166. package/esm/models/chattoolcall.d.ts +57 -0
  167. package/esm/models/chattoolcall.js +49 -0
  168. package/esm/models/chattoolchoice.d.ts +31 -0
  169. package/esm/models/chattoolchoice.js +32 -0
  170. package/esm/models/chattoolmessage.d.ts +35 -0
  171. package/esm/models/chattoolmessage.js +26 -0
  172. package/esm/models/{chatgenerationtokenusage.d.ts → chatusage.d.ts} +4 -4
  173. package/esm/models/{chatgenerationtokenusage.js → chatusage.js} +5 -5
  174. package/esm/models/chatusermessage.d.ts +35 -0
  175. package/esm/models/chatusermessage.js +21 -0
  176. package/esm/models/chatwebsearchservertool.d.ts +124 -0
  177. package/esm/models/chatwebsearchservertool.js +84 -0
  178. package/esm/models/chatwebsearchshorthand.d.ts +219 -0
  179. package/esm/models/chatwebsearchshorthand.js +141 -0
  180. package/esm/models/codeinterpreterservertool.d.ts +68 -0
  181. package/esm/models/codeinterpreterservertool.js +85 -0
  182. package/esm/models/codexlocalshelltool.d.ts +20 -0
  183. package/esm/models/codexlocalshelltool.js +21 -0
  184. package/esm/models/compoundfilter.d.ts +36 -0
  185. package/esm/models/compoundfilter.js +32 -0
  186. package/esm/models/computeruseservertool.d.ts +39 -0
  187. package/esm/models/computeruseservertool.js +50 -0
  188. package/esm/models/conflictresponseerrordata.d.ts +17 -0
  189. package/esm/models/conflictresponseerrordata.js +16 -0
  190. package/esm/models/contentpartaddedevent.d.ts +29 -0
  191. package/esm/models/contentpartaddedevent.js +43 -0
  192. package/esm/models/contentpartdoneevent.d.ts +29 -0
  193. package/esm/models/contentpartdoneevent.js +43 -0
  194. package/esm/models/contextcompressionengine.d.ts +15 -0
  195. package/esm/models/contextcompressionengine.js +14 -0
  196. package/esm/models/customtool.d.ts +75 -0
  197. package/esm/models/customtool.js +96 -0
  198. package/esm/models/datetimeservertool.d.ts +37 -0
  199. package/esm/models/datetimeservertool.js +27 -0
  200. package/esm/models/defaultparameters.d.ts +3 -0
  201. package/esm/models/defaultparameters.js +6 -0
  202. package/esm/models/easyinputmessage.d.ts +120 -0
  203. package/esm/models/easyinputmessage.js +141 -0
  204. package/esm/models/{openresponseserrorevent.d.ts → errorevent.d.ts} +4 -4
  205. package/esm/models/{openresponseserrorevent.js → errorevent.js} +6 -5
  206. package/esm/models/errors/conflictresponseerror.d.ts +33 -0
  207. package/esm/models/errors/conflictresponseerror.js +42 -0
  208. package/esm/models/errors/index.d.ts +1 -0
  209. package/esm/models/errors/index.js +1 -0
  210. package/esm/models/filesearchservertool.d.ts +111 -0
  211. package/esm/models/filesearchservertool.js +180 -0
  212. package/esm/models/formatjsonobjectconfig.d.ts +20 -0
  213. package/esm/models/formatjsonobjectconfig.js +21 -0
  214. package/esm/models/formatjsonschemaconfig.d.ts +32 -0
  215. package/esm/models/formatjsonschemaconfig.js +29 -0
  216. package/esm/models/formats.d.ts +19 -0
  217. package/esm/models/formats.js +29 -0
  218. package/esm/models/formattextconfig.d.ts +20 -0
  219. package/esm/models/formattextconfig.js +21 -0
  220. package/esm/models/functioncallargsdeltaevent.d.ts +17 -0
  221. package/esm/models/functioncallargsdeltaevent.js +25 -0
  222. package/esm/models/functioncallargsdoneevent.d.ts +18 -0
  223. package/esm/models/functioncallargsdoneevent.js +26 -0
  224. package/esm/models/functioncallitem.d.ts +33 -0
  225. package/esm/models/functioncallitem.js +29 -0
  226. package/esm/models/functioncalloutputitem.d.ts +70 -0
  227. package/esm/models/functioncalloutputitem.js +79 -0
  228. package/esm/models/imagegencallcompletedevent.d.ts +16 -0
  229. package/esm/models/{openresponsesimagegencallcompleted.js → imagegencallcompletedevent.js} +5 -5
  230. package/esm/models/imagegencallgeneratingevent.d.ts +16 -0
  231. package/esm/models/{openresponsesimagegencallgenerating.js → imagegencallgeneratingevent.js} +5 -5
  232. package/esm/models/imagegencallinprogressevent.d.ts +16 -0
  233. package/esm/models/{openresponsesimagegencallinprogress.js → imagegencallinprogressevent.js} +5 -5
  234. package/esm/models/{openresponsesimagegencallpartialimage.d.ts → imagegencallpartialimageevent.d.ts} +4 -4
  235. package/esm/models/{openresponsesimagegencallpartialimage.js → imagegencallpartialimageevent.js} +5 -5
  236. package/esm/models/imagegenerationservertool.d.ts +125 -0
  237. package/esm/models/imagegenerationservertool.js +153 -0
  238. package/esm/models/{openairesponsesincompletedetails.d.ts → incompletedetails.d.ts} +4 -4
  239. package/esm/models/{openairesponsesincompletedetails.js → incompletedetails.js} +5 -5
  240. package/esm/models/index.d.ts +126 -95
  241. package/esm/models/index.js +126 -95
  242. package/esm/models/inputaudio.d.ts +47 -0
  243. package/esm/models/inputaudio.js +58 -0
  244. package/esm/models/{responseinputfile.d.ts → inputfile.d.ts} +7 -7
  245. package/esm/models/{responseinputfile.js → inputfile.js} +8 -8
  246. package/esm/models/inputimage.d.ts +43 -0
  247. package/esm/models/inputimage.js +52 -0
  248. package/esm/models/inputmessageitem.d.ts +84 -0
  249. package/esm/models/inputmessageitem.js +92 -0
  250. package/esm/models/inputsunion.d.ts +208 -0
  251. package/esm/models/inputsunion.js +228 -0
  252. package/esm/models/inputtext.d.ts +22 -0
  253. package/esm/models/inputtext.js +23 -0
  254. package/esm/models/inputvideo.d.ts +20 -0
  255. package/esm/models/{responseinputvideo.js → inputvideo.js} +5 -5
  256. package/esm/models/legacychatcontentvideo.d.ts +28 -0
  257. package/esm/models/legacychatcontentvideo.js +33 -0
  258. package/esm/models/legacywebsearchservertool.d.ts +78 -0
  259. package/esm/models/legacywebsearchservertool.js +87 -0
  260. package/esm/models/mcpservertool.d.ts +128 -0
  261. package/esm/models/mcpservertool.js +174 -0
  262. package/esm/models/model.d.ts +4 -0
  263. package/esm/models/model.js +2 -0
  264. package/esm/models/openairesponsestruncation.d.ts +1 -1
  265. package/esm/models/openairesponsestruncation.js +1 -1
  266. package/esm/models/openresponsesresult.d.ts +110 -0
  267. package/esm/models/openresponsesresult.js +142 -0
  268. package/esm/models/operations/bulkassignkeystoguardrail.d.ts +16 -3
  269. package/esm/models/operations/bulkassignkeystoguardrail.js +2 -2
  270. package/esm/models/operations/bulkassignmemberstoguardrail.d.ts +16 -3
  271. package/esm/models/operations/bulkassignmemberstoguardrail.js +2 -2
  272. package/esm/models/operations/bulkunassignkeysfromguardrail.d.ts +16 -3
  273. package/esm/models/operations/bulkunassignkeysfromguardrail.js +2 -2
  274. package/esm/models/operations/bulkunassignmembersfromguardrail.d.ts +16 -3
  275. package/esm/models/operations/bulkunassignmembersfromguardrail.js +2 -2
  276. package/esm/models/operations/createauthkeyscode.d.ts +16 -3
  277. package/esm/models/operations/createauthkeyscode.js +2 -2
  278. package/esm/models/operations/createcoinbasecharge.d.ts +16 -3
  279. package/esm/models/operations/createcoinbasecharge.js +2 -2
  280. package/esm/models/operations/createembeddings.d.ts +16 -3
  281. package/esm/models/operations/createembeddings.js +2 -2
  282. package/esm/models/operations/createguardrail.d.ts +25 -3
  283. package/esm/models/operations/createguardrail.js +6 -2
  284. package/esm/models/operations/createkeys.d.ts +20 -3
  285. package/esm/models/operations/createkeys.js +4 -2
  286. package/esm/models/operations/createresponses.d.ts +20 -7
  287. package/esm/models/operations/createresponses.js +8 -7
  288. package/esm/models/operations/deleteguardrail.d.ts +16 -3
  289. package/esm/models/operations/deleteguardrail.js +2 -2
  290. package/esm/models/operations/deletekeys.d.ts +16 -3
  291. package/esm/models/operations/deletekeys.js +2 -2
  292. package/esm/models/operations/exchangeauthcodeforapikey.d.ts +16 -3
  293. package/esm/models/operations/exchangeauthcodeforapikey.js +2 -2
  294. package/esm/models/operations/getcredits.d.ts +16 -3
  295. package/esm/models/operations/getcredits.js +2 -2
  296. package/esm/models/operations/getcurrentkey.d.ts +20 -3
  297. package/esm/models/operations/getcurrentkey.js +4 -2
  298. package/esm/models/operations/getgeneration.d.ts +27 -3
  299. package/esm/models/operations/getgeneration.js +9 -2
  300. package/esm/models/operations/getguardrail.d.ts +20 -3
  301. package/esm/models/operations/getguardrail.js +4 -2
  302. package/esm/models/operations/getkey.d.ts +20 -3
  303. package/esm/models/operations/getkey.js +4 -2
  304. package/esm/models/operations/getmodels.d.ts +21 -3
  305. package/esm/models/operations/getmodels.js +4 -2
  306. package/esm/models/operations/getuseractivity.d.ts +16 -3
  307. package/esm/models/operations/getuseractivity.js +2 -2
  308. package/esm/models/operations/list.d.ts +20 -3
  309. package/esm/models/operations/list.js +4 -2
  310. package/esm/models/operations/listembeddingsmodels.d.ts +16 -3
  311. package/esm/models/operations/listembeddingsmodels.js +2 -2
  312. package/esm/models/operations/listendpoints.d.ts +16 -3
  313. package/esm/models/operations/listendpoints.js +2 -2
  314. package/esm/models/operations/listendpointszdr.d.ts +16 -3
  315. package/esm/models/operations/listendpointszdr.js +2 -2
  316. package/esm/models/operations/listguardrailkeyassignments.d.ts +16 -3
  317. package/esm/models/operations/listguardrailkeyassignments.js +2 -2
  318. package/esm/models/operations/listguardrailmemberassignments.d.ts +16 -3
  319. package/esm/models/operations/listguardrailmemberassignments.js +2 -2
  320. package/esm/models/operations/listguardrails.d.ts +20 -3
  321. package/esm/models/operations/listguardrails.js +4 -2
  322. package/esm/models/operations/listkeyassignments.d.ts +16 -3
  323. package/esm/models/operations/listkeyassignments.js +2 -2
  324. package/esm/models/operations/listmemberassignments.d.ts +16 -3
  325. package/esm/models/operations/listmemberassignments.js +2 -2
  326. package/esm/models/operations/listmodelscount.d.ts +21 -3
  327. package/esm/models/operations/listmodelscount.js +4 -2
  328. package/esm/models/operations/listmodelsuser.d.ts +16 -3
  329. package/esm/models/operations/listmodelsuser.js +2 -2
  330. package/esm/models/operations/listproviders.d.ts +539 -3
  331. package/esm/models/operations/listproviders.js +514 -2
  332. package/esm/models/operations/sendchatcompletionrequest.d.ts +20 -7
  333. package/esm/models/operations/sendchatcompletionrequest.js +8 -7
  334. package/esm/models/operations/updateguardrail.d.ts +25 -3
  335. package/esm/models/operations/updateguardrail.js +6 -2
  336. package/esm/models/operations/updatekeys.d.ts +20 -3
  337. package/esm/models/operations/updatekeys.js +4 -2
  338. package/esm/models/outputdatetimeitem.d.ts +44 -0
  339. package/esm/models/outputdatetimeitem.js +30 -0
  340. package/esm/models/outputfilesearchcallitem.d.ts +33 -0
  341. package/esm/models/outputfilesearchcallitem.js +35 -0
  342. package/esm/models/outputfunctioncallitem.d.ts +69 -0
  343. package/esm/models/outputfunctioncallitem.js +94 -0
  344. package/esm/models/outputimagegenerationcallitem.d.ts +33 -0
  345. package/esm/models/outputimagegenerationcallitem.js +35 -0
  346. package/esm/models/outputitems.d.ts +18 -0
  347. package/esm/models/outputitems.js +28 -0
  348. package/esm/models/outputmessage.d.ts +23 -0
  349. package/esm/models/outputmessage.js +24 -0
  350. package/esm/models/outputmessageitem.d.ts +81 -0
  351. package/esm/models/outputmessageitem.js +93 -0
  352. package/esm/models/outputmodality.d.ts +1 -0
  353. package/esm/models/outputmodality.js +1 -0
  354. package/esm/models/outputmodalityenum.d.ts +10 -0
  355. package/esm/models/outputmodalityenum.js +12 -0
  356. package/esm/models/outputreasoningitem.d.ts +74 -0
  357. package/esm/models/outputreasoningitem.js +75 -0
  358. package/esm/models/outputservertoolitem.d.ts +42 -0
  359. package/esm/models/outputservertoolitem.js +44 -0
  360. package/esm/models/outputwebsearchcallitem.d.ts +116 -0
  361. package/esm/models/outputwebsearchcallitem.js +141 -0
  362. package/esm/models/pdfparserengine.d.ts +18 -9
  363. package/esm/models/pdfparserengine.js +17 -6
  364. package/esm/models/pdfparseroptions.d.ts +3 -3
  365. package/esm/models/preview20250311websearchservertool.d.ts +75 -0
  366. package/esm/models/preview20250311websearchservertool.js +89 -0
  367. package/esm/models/previewwebsearchservertool.d.ts +75 -0
  368. package/esm/models/previewwebsearchservertool.js +89 -0
  369. package/esm/models/previewwebsearchuserlocation.d.ts +34 -0
  370. package/esm/models/previewwebsearchuserlocation.js +36 -0
  371. package/esm/models/providername.d.ts +2 -0
  372. package/esm/models/providername.js +2 -0
  373. package/esm/models/providerpreferences.d.ts +7 -0
  374. package/esm/models/providerpreferences.js +4 -0
  375. package/esm/models/providersort.d.ts +1 -0
  376. package/esm/models/providersort.js +1 -0
  377. package/esm/models/providersortconfig.d.ts +1 -0
  378. package/esm/models/providersortconfig.js +1 -0
  379. package/esm/models/reasoningconfig.d.ts +23 -0
  380. package/esm/models/reasoningconfig.js +23 -0
  381. package/esm/models/{openresponsesreasoningdeltaevent.d.ts → reasoningdeltaevent.d.ts} +4 -4
  382. package/esm/models/{openresponsesreasoningdeltaevent.js → reasoningdeltaevent.js} +5 -5
  383. package/esm/models/{openresponsesreasoningdoneevent.d.ts → reasoningdoneevent.d.ts} +4 -4
  384. package/esm/models/{openresponsesreasoningdoneevent.js → reasoningdoneevent.js} +5 -5
  385. package/esm/models/reasoningeffortenum.d.ts +16 -0
  386. package/esm/models/reasoningeffortenum.js +18 -0
  387. package/esm/models/reasoningitem.d.ts +73 -0
  388. package/esm/models/reasoningitem.js +71 -0
  389. package/esm/models/{openresponsesreasoningsummarypartaddedevent.d.ts → reasoningsummarypartaddedevent.d.ts} +4 -4
  390. package/esm/models/{openresponsesreasoningsummarypartaddedevent.js → reasoningsummarypartaddedevent.js} +5 -5
  391. package/esm/models/reasoningsummarypartdoneevent.d.ts +19 -0
  392. package/esm/models/reasoningsummarypartdoneevent.js +28 -0
  393. package/esm/models/reasoningsummarytextdeltaevent.d.ts +18 -0
  394. package/esm/models/{openresponsesreasoningsummarytextdeltaevent.js → reasoningsummarytextdeltaevent.js} +5 -5
  395. package/esm/models/reasoningsummarytextdoneevent.d.ts +18 -0
  396. package/esm/models/{openresponsesreasoningsummarytextdoneevent.js → reasoningsummarytextdoneevent.js} +5 -5
  397. package/esm/models/reasoningsummaryverbosityenum.d.ts +13 -0
  398. package/esm/models/reasoningsummaryverbosityenum.js +15 -0
  399. package/esm/models/refusaldeltaevent.d.ts +18 -0
  400. package/esm/models/refusaldeltaevent.js +27 -0
  401. package/esm/models/refusaldoneevent.d.ts +18 -0
  402. package/esm/models/refusaldoneevent.js +27 -0
  403. package/esm/models/{openairesponsesincludable.d.ts → responseincludesenum.d.ts} +4 -4
  404. package/esm/models/{openairesponsesincludable.js → responseincludesenum.js} +4 -4
  405. package/esm/models/responseoutputtext.d.ts +8 -8
  406. package/esm/models/responseoutputtext.js +10 -9
  407. package/esm/models/responsesrequest.d.ts +499 -0
  408. package/esm/models/responsesrequest.js +347 -0
  409. package/esm/models/searchcontextsizeenum.d.ts +19 -0
  410. package/esm/models/searchcontextsizeenum.js +18 -0
  411. package/esm/models/shellservertool.d.ts +20 -0
  412. package/esm/models/shellservertool.js +21 -0
  413. package/esm/models/storedprompttemplate.d.ts +35 -0
  414. package/esm/models/storedprompttemplate.js +56 -0
  415. package/esm/models/streamevents.d.ts +136 -0
  416. package/esm/models/streamevents.js +165 -0
  417. package/esm/models/textconfig.d.ts +27 -0
  418. package/esm/models/textconfig.js +25 -0
  419. package/esm/models/textdeltaevent.d.ts +42 -0
  420. package/esm/models/textdeltaevent.js +52 -0
  421. package/esm/models/textdoneevent.d.ts +42 -0
  422. package/esm/models/textdoneevent.js +53 -0
  423. package/esm/models/textextendedconfig.d.ts +30 -0
  424. package/esm/models/textextendedconfig.js +23 -0
  425. package/esm/models/toolcallstatusenum.d.ts +13 -0
  426. package/esm/models/toolcallstatusenum.js +15 -0
  427. package/esm/models/truncationenum.d.ts +10 -0
  428. package/esm/models/truncationenum.js +12 -0
  429. package/esm/models/{openresponsesusage.d.ts → usage.d.ts} +4 -4
  430. package/esm/models/{openresponsesusage.js → usage.js} +5 -5
  431. package/esm/models/websearchcallcompletedevent.d.ts +16 -0
  432. package/esm/models/websearchcallcompletedevent.js +24 -0
  433. package/esm/models/websearchcallinprogressevent.d.ts +16 -0
  434. package/esm/models/websearchcallinprogressevent.js +24 -0
  435. package/esm/models/websearchcallsearchingevent.d.ts +16 -0
  436. package/esm/models/websearchcallsearchingevent.js +24 -0
  437. package/esm/models/websearchengine.d.ts +2 -0
  438. package/esm/models/websearchengine.js +2 -0
  439. package/esm/models/websearchservertool.d.ts +78 -0
  440. package/esm/models/websearchservertool.js +89 -0
  441. package/esm/models/websearchservertoolopenrouter.d.ts +35 -0
  442. package/esm/models/websearchservertoolopenrouter.js +28 -0
  443. package/esm/models/websearchuserlocation.d.ts +37 -0
  444. package/esm/models/websearchuserlocation.js +36 -0
  445. package/esm/sdk/chat.d.ts +4 -4
  446. package/esm/sdk/responses.d.ts +4 -4
  447. package/esm/sdk/sdk.d.ts +4 -1
  448. package/esm/sdk/sdk.js +0 -1
  449. package/esm/types/index.d.ts +0 -2
  450. package/esm/types/index.js +0 -1
  451. package/jsr.json +1 -1
  452. package/package.json +11 -11
  453. package/tsconfig.json +3 -1
  454. package/turbo.json +10 -0
  455. package/esm/models/assistantmessage.d.ts +0 -80
  456. package/esm/models/assistantmessage.js +0 -83
  457. package/esm/models/assistantmessageimages.d.ts +0 -33
  458. package/esm/models/assistantmessageimages.js +0 -44
  459. package/esm/models/chatcompletionfinishreason.d.ts +0 -13
  460. package/esm/models/chatgenerationparams.js +0 -371
  461. package/esm/models/chatmessagecontentitem.d.ts +0 -30
  462. package/esm/models/chatmessagecontentitem.js +0 -54
  463. package/esm/models/chatmessagecontentitemaudio.d.ts +0 -52
  464. package/esm/models/chatmessagecontentitemaudio.js +0 -55
  465. package/esm/models/chatmessagecontentitemcachecontrol.d.ts +0 -40
  466. package/esm/models/chatmessagecontentitemcachecontrol.js +0 -41
  467. package/esm/models/chatmessagecontentitemimage.d.ts +0 -68
  468. package/esm/models/chatmessagecontentitemimage.js +0 -68
  469. package/esm/models/chatmessagecontentitemtext.d.ts +0 -37
  470. package/esm/models/chatmessagecontentitemtext.js +0 -42
  471. package/esm/models/chatmessagecontentitemvideo.d.ts +0 -26
  472. package/esm/models/chatmessagecontentitemvideo.js +0 -33
  473. package/esm/models/chatmessagecontentitemvideolegacy.d.ts +0 -28
  474. package/esm/models/chatmessagecontentitemvideolegacy.js +0 -33
  475. package/esm/models/chatmessagetokenlogprob.d.ts +0 -36
  476. package/esm/models/chatmessagetokenlogprob.js +0 -31
  477. package/esm/models/chatmessagetokenlogprobs.d.ts +0 -21
  478. package/esm/models/chatmessagetokenlogprobs.js +0 -16
  479. package/esm/models/chatmessagetoolcall.d.ts +0 -57
  480. package/esm/models/chatmessagetoolcall.js +0 -48
  481. package/esm/models/chatresponse.d.ts +0 -46
  482. package/esm/models/chatresponse.js +0 -33
  483. package/esm/models/chatresponsechoice.d.ts +0 -27
  484. package/esm/models/chatresponsechoice.js +0 -24
  485. package/esm/models/chatstreamingchoice.d.ts +0 -27
  486. package/esm/models/chatstreamingchoice.js +0 -24
  487. package/esm/models/chatstreamingmessagechunk.js +0 -35
  488. package/esm/models/chatstreamingmessagetoolcall.d.ts +0 -57
  489. package/esm/models/chatstreamingmessagetoolcall.js +0 -34
  490. package/esm/models/chatstreamingresponsechunk.js +0 -41
  491. package/esm/models/developermessage.d.ts +0 -35
  492. package/esm/models/developermessage.js +0 -24
  493. package/esm/models/message.d.ts +0 -20
  494. package/esm/models/message.js +0 -23
  495. package/esm/models/namedtoolchoice.d.ts +0 -37
  496. package/esm/models/namedtoolchoice.js +0 -26
  497. package/esm/models/openairesponsesinputunion.d.ts +0 -154
  498. package/esm/models/openairesponsesinputunion.js +0 -222
  499. package/esm/models/openairesponsesprompt.d.ts +0 -35
  500. package/esm/models/openairesponsesprompt.js +0 -56
  501. package/esm/models/openairesponsesreasoningconfig.d.ts +0 -13
  502. package/esm/models/openairesponsesreasoningconfig.js +0 -17
  503. package/esm/models/openairesponsesreasoningeffort.d.ts +0 -16
  504. package/esm/models/openairesponsesreasoningeffort.js +0 -18
  505. package/esm/models/openairesponsesservicetier.d.ts +0 -13
  506. package/esm/models/openairesponsesservicetier.js +0 -15
  507. package/esm/models/openresponseseasyinputmessage.d.ts +0 -94
  508. package/esm/models/openresponseseasyinputmessage.js +0 -115
  509. package/esm/models/openresponsesfunctioncalloutput.d.ts +0 -31
  510. package/esm/models/openresponsesfunctioncalloutput.js +0 -28
  511. package/esm/models/openresponsesfunctiontoolcall.d.ts +0 -33
  512. package/esm/models/openresponsesfunctiontoolcall.js +0 -29
  513. package/esm/models/openresponsesimagegencallcompleted.d.ts +0 -16
  514. package/esm/models/openresponsesimagegencallgenerating.d.ts +0 -16
  515. package/esm/models/openresponsesimagegencallinprogress.d.ts +0 -16
  516. package/esm/models/openresponsesinput.d.ts +0 -28
  517. package/esm/models/openresponsesinput.js +0 -54
  518. package/esm/models/openresponsesinputmessageitem.d.ts +0 -84
  519. package/esm/models/openresponsesinputmessageitem.js +0 -92
  520. package/esm/models/openresponseslogprobs.d.ts +0 -16
  521. package/esm/models/openresponseslogprobs.js +0 -22
  522. package/esm/models/openresponsesnonstreamingresponse.d.ts +0 -102
  523. package/esm/models/openresponsesnonstreamingresponse.js +0 -117
  524. package/esm/models/openresponsesreasoning.d.ts +0 -73
  525. package/esm/models/openresponsesreasoning.js +0 -71
  526. package/esm/models/openresponsesreasoningconfig.d.ts +0 -23
  527. package/esm/models/openresponsesreasoningconfig.js +0 -23
  528. package/esm/models/openresponsesreasoningsummarytextdeltaevent.d.ts +0 -18
  529. package/esm/models/openresponsesreasoningsummarytextdoneevent.d.ts +0 -18
  530. package/esm/models/openresponsesrequest.d.ts +0 -451
  531. package/esm/models/openresponsesrequest.js +0 -300
  532. package/esm/models/openresponsesresponsetext.d.ts +0 -30
  533. package/esm/models/openresponsesresponsetext.js +0 -24
  534. package/esm/models/openresponsesstreamevent.d.ts +0 -287
  535. package/esm/models/openresponsesstreamevent.js +0 -379
  536. package/esm/models/openresponsestoplogprobs.d.ts +0 -14
  537. package/esm/models/openresponsestoplogprobs.js +0 -15
  538. package/esm/models/openresponseswebsearch20250826tool.d.ts +0 -47
  539. package/esm/models/openresponseswebsearch20250826tool.js +0 -64
  540. package/esm/models/openresponseswebsearchpreview20250311tool.d.ts +0 -29
  541. package/esm/models/openresponseswebsearchpreview20250311tool.js +0 -40
  542. package/esm/models/openresponseswebsearchpreviewtool.d.ts +0 -29
  543. package/esm/models/openresponseswebsearchpreviewtool.js +0 -40
  544. package/esm/models/openresponseswebsearchtool.d.ts +0 -47
  545. package/esm/models/openresponseswebsearchtool.js +0 -64
  546. package/esm/models/reasoningsummaryverbosity.d.ts +0 -13
  547. package/esm/models/reasoningsummaryverbosity.js +0 -15
  548. package/esm/models/responseformatjsonobject.d.ts +0 -20
  549. package/esm/models/responseformatjsonobject.js +0 -21
  550. package/esm/models/responseformatjsonschema.d.ts +0 -21
  551. package/esm/models/responseformatjsonschema.js +0 -20
  552. package/esm/models/responseformattext.d.ts +0 -15
  553. package/esm/models/responseformattext.js +0 -13
  554. package/esm/models/responseformattextconfig.d.ts +0 -19
  555. package/esm/models/responseformattextconfig.js +0 -28
  556. package/esm/models/responseformattextgrammar.d.ts +0 -20
  557. package/esm/models/responseformattextgrammar.js +0 -14
  558. package/esm/models/responseformattextpython.d.ts +0 -15
  559. package/esm/models/responseformattextpython.js +0 -13
  560. package/esm/models/responseinputaudio.d.ts +0 -47
  561. package/esm/models/responseinputaudio.js +0 -57
  562. package/esm/models/responseinputimage.d.ts +0 -43
  563. package/esm/models/responseinputimage.js +0 -51
  564. package/esm/models/responseinputtext.d.ts +0 -22
  565. package/esm/models/responseinputtext.js +0 -23
  566. package/esm/models/responseinputvideo.d.ts +0 -20
  567. package/esm/models/responsesformattext.d.ts +0 -20
  568. package/esm/models/responsesformattext.js +0 -21
  569. package/esm/models/responsesformattextjsonschemaconfig.d.ts +0 -32
  570. package/esm/models/responsesformattextjsonschemaconfig.js +0 -29
  571. package/esm/models/responsesimagegenerationcall.d.ts +0 -33
  572. package/esm/models/responsesimagegenerationcall.js +0 -35
  573. package/esm/models/responsesoutputitem.d.ts +0 -29
  574. package/esm/models/responsesoutputitem.js +0 -25
  575. package/esm/models/responsesoutputitemfilesearchcall.d.ts +0 -33
  576. package/esm/models/responsesoutputitemfilesearchcall.js +0 -35
  577. package/esm/models/responsesoutputitemfunctioncall.d.ts +0 -69
  578. package/esm/models/responsesoutputitemfunctioncall.js +0 -94
  579. package/esm/models/responsesoutputitemreasoning.d.ts +0 -103
  580. package/esm/models/responsesoutputitemreasoning.js +0 -118
  581. package/esm/models/responsesoutputmessage.d.ts +0 -89
  582. package/esm/models/responsesoutputmessage.js +0 -114
  583. package/esm/models/responsesoutputmodality.d.ts +0 -10
  584. package/esm/models/responsesoutputmodality.js +0 -12
  585. package/esm/models/responsessearchcontextsize.d.ts +0 -19
  586. package/esm/models/responsessearchcontextsize.js +0 -18
  587. package/esm/models/responseswebsearchcalloutput.d.ts +0 -31
  588. package/esm/models/responseswebsearchcalloutput.js +0 -33
  589. package/esm/models/responseswebsearchuserlocation.d.ts +0 -37
  590. package/esm/models/responseswebsearchuserlocation.js +0 -36
  591. package/esm/models/responsetextconfig.d.ts +0 -27
  592. package/esm/models/responsetextconfig.js +0 -24
  593. package/esm/models/systemmessage.d.ts +0 -35
  594. package/esm/models/systemmessage.js +0 -24
  595. package/esm/models/toolcallstatus.d.ts +0 -13
  596. package/esm/models/toolcallstatus.js +0 -15
  597. package/esm/models/toolchoiceoption.d.ts +0 -31
  598. package/esm/models/toolchoiceoption.js +0 -32
  599. package/esm/models/tooldefinitionjson.d.ts +0 -68
  600. package/esm/models/tooldefinitionjson.js +0 -36
  601. package/esm/models/toolresponsemessage.d.ts +0 -35
  602. package/esm/models/toolresponsemessage.js +0 -29
  603. package/esm/models/usermessage.d.ts +0 -35
  604. package/esm/models/usermessage.js +0 -24
  605. package/esm/models/videoinput.d.ts +0 -23
  606. package/esm/models/videoinput.js +0 -22
  607. package/esm/models/websearchpreviewtooluserlocation.d.ts +0 -34
  608. package/esm/models/websearchpreviewtooluserlocation.js +0 -36
@@ -1,14 +1,15 @@
1
1
  import { ToolEventBroadcaster } from './tool-event-broadcaster.js';
2
+ import { ToolContextStore, resolveContext } from './tool-context.js';
2
3
  import { betaResponsesSend } from '../funcs/betaResponsesSend.js';
3
4
  import { hasAsyncFunctions, resolveAsyncFunctions, } from './async-params.js';
4
5
  import { appendToMessages, createInitialState, createRejectedResult, createUnsentResult, extractTextFromResponse as extractTextFromResponseState, partitionToolCalls, unsentResultsToAPIFormat, updateState, } from './conversation-state.js';
5
6
  import { ReusableReadableStream } from './reusable-stream.js';
6
- import { buildItemsStream, buildResponsesMessageStream, buildToolCallStream, consumeStreamForCompletion, extractReasoningDeltas, extractResponsesMessageFromResponse, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, } from './stream-transformers.js';
7
+ import { buildItemsStream, buildResponsesMessageStream, buildToolCallStream, consumeStreamForCompletion, extractReasoningDeltas, extractResponsesMessageFromResponse, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, itemsStreamHandlers, streamTerminationEvents, } from './stream-transformers.js';
7
8
  import { executeTool } from './tool-executor.js';
8
9
  import { executeNextTurnParamsFunctions, applyNextTurnParamsToRequest } from './next-turn-params.js';
9
- import { hasExecuteFunction } from './tool-types.js';
10
+ import { hasExecuteFunction, isToolCallOutputEvent } from './tool-types.js';
10
11
  import { isStopConditionMet, stepCountIs } from './stop-conditions.js';
11
- import { isOutputMessage, isFunctionCallItem, isReasoningOutputItem, isWebSearchCallOutputItem, isFileSearchCallOutputItem, isImageGenerationCallOutputItem, hasTypeProperty, } from './stream-type-guards.js';
12
+ import { isFunctionCallItem, isResponseCompletedEvent, isResponseFailedEvent, isResponseIncompleteEvent, isOutputTextDeltaEvent, isReasoningDeltaEvent, hasTypeProperty, } from './stream-type-guards.js';
12
13
  /**
13
14
  * Default maximum number of tool execution steps if no stopWhen is specified.
14
15
  * This prevents infinite loops in tool execution.
@@ -38,7 +39,7 @@ function isEventStream(value) {
38
39
  * - `await result.getText()` - Get just the text
39
40
  * - `await result.getResponse()` - Get the full response object
40
41
  * - `for await (const delta of result.getTextStream())` - Stream text deltas
41
- * - `for await (const msg of result.getNewMessagesStream())` - Stream incremental message updates
42
+ * - `for await (const msg of result.getNewMessagesStream())` - Stream cumulative message snapshots
42
43
  * - `for await (const event of result.getFullResponsesStream())` - Stream all response events
43
44
  *
44
45
  * For message format conversion, use the helper functions:
@@ -49,6 +50,7 @@ function isEventStream(value) {
49
50
  * ReusableReadableStream implementation.
50
51
  *
51
52
  * @template TTools - The tools array type to enable typed tool calls and results
53
+ * @template TShared - The shape of the shared context (inferred from sharedContextSchema)
52
54
  */
53
55
  export class ModelResult {
54
56
  constructor(options) {
@@ -68,6 +70,12 @@ export class ModelResult {
68
70
  this.approvedToolCalls = [];
69
71
  this.rejectedToolCalls = [];
70
72
  this.isResumingFromApproval = false;
73
+ // Unified turn broadcaster for multi-turn streaming
74
+ this.turnBroadcaster = null;
75
+ this.initialStreamPipeStarted = false;
76
+ this.initialPipePromise = null;
77
+ // Context store for typed tool context (persists across turns)
78
+ this.contextStore = null;
71
79
  this.options = options;
72
80
  // Runtime validation: approval decisions require state
73
81
  const hasApprovalDecisions = (options.approveToolCalls && options.approveToolCalls.length > 0) ||
@@ -83,15 +91,139 @@ export class ModelResult {
83
91
  this.rejectedToolCalls = options.rejectToolCalls ?? [];
84
92
  }
85
93
  /**
86
- * Get or create the tool event broadcaster (lazy initialization).
87
- * Ensures only one broadcaster exists for the lifetime of this ModelResult.
88
- * Broadcasts both preliminary results and final tool results.
94
+ * Get or create the unified turn broadcaster (lazy initialization).
95
+ * Broadcasts all API stream events, tool events, and turn delimiters across turns.
89
96
  */
90
- ensureBroadcaster() {
91
- if (!this.toolEventBroadcaster) {
92
- this.toolEventBroadcaster = new ToolEventBroadcaster();
97
+ ensureTurnBroadcaster() {
98
+ if (!this.turnBroadcaster) {
99
+ this.turnBroadcaster = new ToolEventBroadcaster();
93
100
  }
94
- return this.toolEventBroadcaster;
101
+ return this.turnBroadcaster;
102
+ }
103
+ /**
104
+ * Start piping the initial stream into the turn broadcaster.
105
+ * Idempotent — only starts once even if called multiple times.
106
+ * Wraps the initial stream events with turn.start(0) / turn.end(0) delimiters.
107
+ */
108
+ startInitialStreamPipe() {
109
+ if (this.initialStreamPipeStarted)
110
+ return;
111
+ this.initialStreamPipeStarted = true;
112
+ const broadcaster = this.ensureTurnBroadcaster();
113
+ if (!this.reusableStream) {
114
+ return;
115
+ }
116
+ const stream = this.reusableStream;
117
+ this.initialPipePromise = (async () => {
118
+ broadcaster.push({
119
+ type: 'turn.start',
120
+ turnNumber: 0,
121
+ timestamp: Date.now(),
122
+ });
123
+ const consumer = stream.createConsumer();
124
+ for await (const event of consumer) {
125
+ broadcaster.push(event);
126
+ }
127
+ broadcaster.push({
128
+ type: 'turn.end',
129
+ turnNumber: 0,
130
+ timestamp: Date.now(),
131
+ });
132
+ })().catch((error) => {
133
+ broadcaster.complete(error instanceof Error ? error : new Error(String(error)));
134
+ });
135
+ }
136
+ /**
137
+ * Pipe a follow-up stream into the turn broadcaster and capture the completed response.
138
+ * Emits turn.start / turn.end delimiters around the stream events.
139
+ */
140
+ async pipeAndConsumeStream(stream, turnNumber) {
141
+ const broadcaster = this.turnBroadcaster;
142
+ broadcaster.push({
143
+ type: 'turn.start',
144
+ turnNumber,
145
+ timestamp: Date.now(),
146
+ });
147
+ const consumer = stream.createConsumer();
148
+ let completedResponse = null;
149
+ for await (const event of consumer) {
150
+ broadcaster.push(event);
151
+ if (isResponseCompletedEvent(event)) {
152
+ completedResponse = event.response;
153
+ }
154
+ if (isResponseFailedEvent(event)) {
155
+ const errorMsg = 'message' in event ? String(event.message) : 'Response failed';
156
+ throw new Error(errorMsg);
157
+ }
158
+ if (isResponseIncompleteEvent(event)) {
159
+ completedResponse = event.response;
160
+ }
161
+ }
162
+ broadcaster.push({
163
+ type: 'turn.end',
164
+ turnNumber,
165
+ timestamp: Date.now(),
166
+ });
167
+ if (!completedResponse) {
168
+ throw new Error('Follow-up stream ended without a completed response');
169
+ }
170
+ return completedResponse;
171
+ }
172
+ /**
173
+ * Push a tool result event to both the legacy tool event broadcaster
174
+ * and the unified turn broadcaster.
175
+ */
176
+ broadcastToolResult(toolCallId, result, preliminaryResults) {
177
+ this.toolEventBroadcaster?.push({
178
+ type: 'tool_result',
179
+ toolCallId,
180
+ result,
181
+ ...(preliminaryResults?.length && { preliminaryResults }),
182
+ });
183
+ this.turnBroadcaster?.push({
184
+ type: 'tool.result',
185
+ toolCallId,
186
+ result,
187
+ timestamp: Date.now(),
188
+ ...(preliminaryResults?.length && { preliminaryResults }),
189
+ });
190
+ }
191
+ /**
192
+ * Push a preliminary result event to both the legacy tool event broadcaster
193
+ * and the unified turn broadcaster.
194
+ */
195
+ broadcastPreliminaryResult(toolCallId, result) {
196
+ this.toolEventBroadcaster?.push({
197
+ type: 'preliminary_result',
198
+ toolCallId,
199
+ result,
200
+ });
201
+ this.turnBroadcaster?.push({
202
+ type: 'tool.preliminary_result',
203
+ toolCallId,
204
+ result,
205
+ timestamp: Date.now(),
206
+ });
207
+ }
208
+ /**
209
+ * Set up the turn broadcaster with tool execution and return the consumer.
210
+ * Used by stream methods that need to iterate over all turns.
211
+ */
212
+ startTurnBroadcasterExecution() {
213
+ const broadcaster = this.ensureTurnBroadcaster();
214
+ this.startInitialStreamPipe();
215
+ const consumer = broadcaster.createConsumer();
216
+ const executionPromise = this.executeToolsIfNeeded().finally(async () => {
217
+ // Wait for the initial stream pipe to finish pushing all events
218
+ // (including turn.end) before marking the broadcaster as complete.
219
+ // Without this, turn.end can be silently dropped if the pipe hasn't
220
+ // finished when executeToolsIfNeeded completes.
221
+ if (this.initialPipePromise) {
222
+ await this.initialPipePromise;
223
+ }
224
+ broadcaster.complete();
225
+ });
226
+ return { consumer, executionPromise };
95
227
  }
96
228
  /**
97
229
  * Type guard to check if a value is a non-streaming response
@@ -208,7 +340,7 @@ export class ModelResult {
208
340
  toolResults: round.toolResults.map((tr) => ({
209
341
  toolCallId: tr.callId,
210
342
  toolName: round.toolCalls.find((tc) => tc.id === tr.callId)?.name ?? '',
211
- result: JSON.parse(tr.output),
343
+ result: typeof tr.output === 'string' ? JSON.parse(tr.output) : tr.output,
212
344
  })),
213
345
  response: round.response,
214
346
  usage: round.response.usage,
@@ -242,7 +374,7 @@ export class ModelResult {
242
374
  if (!tool || !hasExecuteFunction(tool)) {
243
375
  return null;
244
376
  }
245
- const result = await executeTool(tool, tc, turnContext);
377
+ const result = await executeTool(tool, tc, turnContext, undefined, this.contextStore ?? undefined, this.options.sharedContextSchema);
246
378
  if (result.error) {
247
379
  return createRejectedResult(tc.id, String(tc.name), result.error.message);
248
380
  }
@@ -281,7 +413,10 @@ export class ModelResult {
281
413
  async handleApprovalCheck(toolCalls, currentRound, currentResponse) {
282
414
  if (!this.options.tools)
283
415
  return false;
284
- const turnContext = { numberOfTurns: currentRound };
416
+ const turnContext = {
417
+ numberOfTurns: currentRound,
418
+ // context is handled via contextStore, not on TurnContext
419
+ };
285
420
  const { requiresApproval: needsApproval, autoExecute } = await partitionToolCalls(toolCalls, this.options.tools, turnContext, this.requireApprovalFn ?? undefined);
286
421
  if (needsApproval.length === 0)
287
422
  return false;
@@ -326,13 +461,7 @@ export class ModelResult {
326
461
  const errorMessage = `Failed to parse tool call arguments for "${toolCall.name}": The model provided invalid JSON. ` +
327
462
  `Raw arguments received: "${rawArgs}". ` +
328
463
  `Please provide valid JSON arguments for this tool call.`;
329
- if (this.toolEventBroadcaster) {
330
- this.toolEventBroadcaster.push({
331
- type: 'tool_result',
332
- toolCallId: toolCall.id,
333
- result: { error: errorMessage },
334
- });
335
- }
464
+ this.broadcastToolResult(toolCall.id, { error: errorMessage });
336
465
  return {
337
466
  type: 'parse_error',
338
467
  toolCall,
@@ -345,18 +474,15 @@ export class ModelResult {
345
474
  };
346
475
  }
347
476
  const preliminaryResultsForCall = [];
348
- const onPreliminaryResult = this.toolEventBroadcaster
477
+ const hasBroadcaster = this.toolEventBroadcaster || this.turnBroadcaster;
478
+ const onPreliminaryResult = hasBroadcaster
349
479
  ? (callId, resultValue) => {
350
480
  const typedResult = resultValue;
351
481
  preliminaryResultsForCall.push(typedResult);
352
- this.toolEventBroadcaster?.push({
353
- type: 'preliminary_result',
354
- toolCallId: callId,
355
- result: typedResult,
356
- });
482
+ this.broadcastPreliminaryResult(callId, typedResult);
357
483
  }
358
484
  : undefined;
359
- const result = await executeTool(tool, toolCall, turnContext, onPreliminaryResult);
485
+ const result = await executeTool(tool, toolCall, turnContext, onPreliminaryResult, this.contextStore ?? undefined, this.options.sharedContextSchema);
360
486
  return {
361
487
  type: 'execution',
362
488
  toolCall,
@@ -376,18 +502,18 @@ export class ModelResult {
376
502
  const errorMessage = settled.reason instanceof Error
377
503
  ? settled.reason.message
378
504
  : String(settled.reason);
379
- if (this.toolEventBroadcaster) {
380
- this.toolEventBroadcaster.push({
381
- type: 'tool_result',
382
- toolCallId: originalToolCall.id,
383
- result: { error: errorMessage },
384
- });
385
- }
386
- toolResults.push({
505
+ this.broadcastToolResult(originalToolCall.id, { error: errorMessage });
506
+ const rejectedOutput = {
387
507
  type: 'function_call_output',
388
508
  id: `output_${originalToolCall.id}`,
389
509
  callId: originalToolCall.id,
390
510
  output: JSON.stringify({ error: errorMessage }),
511
+ };
512
+ toolResults.push(rejectedOutput);
513
+ this.turnBroadcaster?.push({
514
+ type: 'tool.call_output',
515
+ output: rejectedOutput,
516
+ timestamp: Date.now(),
391
517
  });
392
518
  continue;
393
519
  }
@@ -396,27 +522,30 @@ export class ModelResult {
396
522
  continue;
397
523
  if (value.type === 'parse_error') {
398
524
  toolResults.push(value.output);
399
- continue;
400
- }
401
- if (this.toolEventBroadcaster) {
402
- this.toolEventBroadcaster.push({
403
- type: 'tool_result',
404
- toolCallId: value.toolCall.id,
405
- result: (value.result.error
406
- ? { error: value.result.error.message }
407
- : value.result.result),
408
- ...(value.preliminaryResultsForCall.length > 0 && {
409
- preliminaryResults: value.preliminaryResultsForCall,
410
- }),
525
+ this.turnBroadcaster?.push({
526
+ type: 'tool.call_output',
527
+ output: value.output,
528
+ timestamp: Date.now(),
411
529
  });
530
+ continue;
412
531
  }
413
- toolResults.push({
532
+ const toolResult = (value.result.error
533
+ ? { error: value.result.error.message }
534
+ : value.result.result);
535
+ this.broadcastToolResult(value.toolCall.id, toolResult, value.preliminaryResultsForCall.length > 0 ? value.preliminaryResultsForCall : undefined);
536
+ const executedOutput = {
414
537
  type: 'function_call_output',
415
538
  id: `output_${value.toolCall.id}`,
416
539
  callId: value.toolCall.id,
417
540
  output: value.result.error
418
541
  ? JSON.stringify({ error: value.result.error.message })
419
542
  : JSON.stringify(value.result.result),
543
+ };
544
+ toolResults.push(executedOutput);
545
+ this.turnBroadcaster?.push({
546
+ type: 'tool.call_output',
547
+ output: executedOutput,
548
+ timestamp: Date.now(),
420
549
  });
421
550
  }
422
551
  return toolResults;
@@ -432,9 +561,10 @@ export class ModelResult {
432
561
  const resolved = await resolveAsyncFunctions(this.options.request, turnContext);
433
562
  // Preserve accumulated input from previous turns
434
563
  const preservedInput = this.resolvedRequest?.input;
564
+ const preservedStream = this.resolvedRequest?.stream;
435
565
  this.resolvedRequest = {
436
566
  ...resolved,
437
- stream: false,
567
+ stream: preservedStream ?? true,
438
568
  ...(preservedInput !== undefined && { input: preservedInput }),
439
569
  };
440
570
  }
@@ -456,14 +586,9 @@ export class ModelResult {
456
586
  }
457
587
  /**
458
588
  * Make a follow-up API request with tool results.
459
- * Continues the conversation after tool execution.
460
- *
461
- * @param currentResponse - The response that contained tool calls
462
- * @param toolResults - The results from executing those tools
463
- * @returns The new response from the API
589
+ * Uses streaming and pipes events through the turn broadcaster when available.
464
590
  */
465
- async makeFollowupRequest(currentResponse, toolResults) {
466
- // Build new input preserving original conversation + tool results
591
+ async makeFollowupRequest(currentResponse, toolResults, turnNumber) {
467
592
  const originalInput = this.resolvedRequest?.input;
468
593
  const normalizedOriginalInput = Array.isArray(originalInput)
469
594
  ? originalInput
@@ -487,17 +612,20 @@ export class ModelResult {
487
612
  };
488
613
  const newRequest = {
489
614
  ...this.resolvedRequest,
490
- stream: false,
615
+ stream: true,
491
616
  };
492
- const newResult = await betaResponsesSend(this.options.client, { openResponsesRequest: newRequest }, this.options.options);
617
+ const newResult = await betaResponsesSend(this.options.client, { responsesRequest: newRequest }, this.options.options);
493
618
  if (!newResult.ok) {
494
619
  throw newResult.error;
495
620
  }
496
621
  // Handle streaming or non-streaming response
497
622
  const value = newResult.value;
498
623
  if (isEventStream(value)) {
499
- const stream = new ReusableReadableStream(value);
500
- return consumeStreamForCompletion(stream);
624
+ const followUpStream = new ReusableReadableStream(value);
625
+ if (this.turnBroadcaster) {
626
+ return this.pipeAndConsumeStream(followUpStream, turnNumber);
627
+ }
628
+ return consumeStreamForCompletion(followUpStream);
501
629
  }
502
630
  else if (this.isNonStreamingResponse(value)) {
503
631
  return value;
@@ -533,7 +661,7 @@ export class ModelResult {
533
661
  }
534
662
  // Already resolved, extract non-function fields
535
663
  // Filter out stopWhen and state-related fields that aren't part of the API request
536
- const { stopWhen: _, state: _s, requireApproval: _r, approveToolCalls: _a, rejectToolCalls: _rj, ...rest } = this.options.request;
664
+ const { stopWhen: _, state: _s, requireApproval: _r, approveToolCalls: _a, rejectToolCalls: _rj, context: _c, ...rest } = this.options.request;
537
665
  return rest;
538
666
  }
539
667
  /**
@@ -590,6 +718,12 @@ export class ModelResult {
590
718
  // Check if we're resuming from awaiting_approval with decisions
591
719
  if (loadedState.status === 'awaiting_approval' &&
592
720
  (this.approvedToolCalls.length > 0 || this.rejectedToolCalls.length > 0)) {
721
+ // Initialize context store before resuming so tools have access
722
+ if (this.options.context !== undefined) {
723
+ const approvalContext = { numberOfTurns: 0 };
724
+ const resolvedCtx = await resolveContext(this.options.context, approvalContext);
725
+ this.contextStore = new ToolContextStore(resolvedCtx);
726
+ }
593
727
  this.isResumingFromApproval = true;
594
728
  await this.processApprovalDecisions();
595
729
  return; // Skip normal initialization, we're resuming
@@ -610,9 +744,12 @@ export class ModelResult {
610
744
  }
611
745
  // Resolve async functions before initial request
612
746
  // Build initial turn context (turn 0 for initial request)
613
- const initialContext = {
614
- numberOfTurns: 0,
615
- };
747
+ const initialContext = { numberOfTurns: 0 };
748
+ // Initialize context store from the context option
749
+ if (this.options.context !== undefined) {
750
+ const resolvedCtx = await resolveContext(this.options.context, initialContext);
751
+ this.contextStore = new ToolContextStore(resolvedCtx);
752
+ }
616
753
  // Resolve any async functions first
617
754
  let baseRequest = await this.resolveRequestForContext(initialContext);
618
755
  // If we have state with existing messages, use those as input
@@ -642,7 +779,7 @@ export class ModelResult {
642
779
  // Force stream mode for initial request
643
780
  const request = this.resolvedRequest;
644
781
  // Make the API request
645
- const apiResult = await betaResponsesSend(this.options.client, { openResponsesRequest: request }, this.options.options);
782
+ const apiResult = await betaResponsesSend(this.options.client, { responsesRequest: request }, this.options.options);
646
783
  if (!apiResult.ok) {
647
784
  throw apiResult.error;
648
785
  }
@@ -673,6 +810,7 @@ export class ModelResult {
673
810
  // Build turn context - numberOfTurns represents the current turn (1-indexed after initial)
674
811
  const turnContext = {
675
812
  numberOfTurns: this.allToolExecutionRounds.length + 1,
813
+ // context is handled via contextStore, not on TurnContext
676
814
  };
677
815
  // Process approvals - execute the approved tools
678
816
  for (const callId of this.approvedToolCalls) {
@@ -685,7 +823,7 @@ export class ModelResult {
685
823
  unsentResults.push(createRejectedResult(callId, String(toolCall.name), 'Tool not found or not executable'));
686
824
  continue;
687
825
  }
688
- const result = await executeTool(tool, toolCall, turnContext);
826
+ const result = await executeTool(tool, toolCall, turnContext, undefined, this.contextStore ?? undefined, this.options.sharedContextSchema);
689
827
  if (result.error) {
690
828
  unsentResults.push(createRejectedResult(callId, String(toolCall.name), result.error.message));
691
829
  }
@@ -765,7 +903,7 @@ export class ModelResult {
765
903
  };
766
904
  this.resolvedRequest = request;
767
905
  // Make the API request
768
- const apiResult = await betaResponsesSend(this.options.client, { openResponsesRequest: request }, this.options.options);
906
+ const apiResult = await betaResponsesSend(this.options.client, { responsesRequest: request }, this.options.options);
769
907
  if (!apiResult.ok) {
770
908
  throw apiResult.error;
771
909
  }
@@ -839,7 +977,9 @@ export class ModelResult {
839
977
  break;
840
978
  }
841
979
  // Build turn context
842
- const turnContext = { numberOfTurns: currentRound + 1 };
980
+ const turnNumber = currentRound + 1;
981
+ const turnContext = { numberOfTurns: turnNumber };
982
+ await this.options.onTurnStart?.(turnContext);
843
983
  // Resolve async functions for this turn
844
984
  await this.resolveAsyncFunctionsForTurn(turnContext);
845
985
  // Execute tools
@@ -855,8 +995,8 @@ export class ModelResult {
855
995
  await this.saveToolResultsToState(toolResults);
856
996
  // Apply nextTurnParams
857
997
  await this.applyNextTurnParams(currentToolCalls);
858
- // Make follow-up request
859
- currentResponse = await this.makeFollowupRequest(currentResponse, toolResults);
998
+ currentResponse = await this.makeFollowupRequest(currentResponse, toolResults, turnNumber);
999
+ await this.options.onTurnEnd?.(turnContext, currentResponse);
860
1000
  // Save new response to state
861
1001
  await this.saveResponseToState(currentResponse);
862
1002
  currentRound++;
@@ -892,7 +1032,7 @@ export class ModelResult {
892
1032
  /**
893
1033
  * Get the complete response object including usage information.
894
1034
  * This will consume the stream until completion and execute any tools.
895
- * Returns the full OpenResponsesNonStreamingResponse with usage data (inputTokens, outputTokens, cachedTokens, etc.)
1035
+ * Returns the full OpenResponsesResult with usage data (inputTokens, outputTokens, cachedTokens, etc.)
896
1036
  */
897
1037
  async getResponse() {
898
1038
  await this.executeToolsIfNeeded();
@@ -902,63 +1042,56 @@ export class ModelResult {
902
1042
  return this.finalResponse;
903
1043
  }
904
1044
  /**
905
- * Stream all response events as they arrive.
1045
+ * Stream all response events as they arrive across all turns.
906
1046
  * Multiple consumers can iterate over this stream concurrently.
907
- * Preliminary tool results and tool results are streamed in REAL-TIME as generator tools yield.
1047
+ * Includes API events, tool events, and turn.start/turn.end delimiters.
908
1048
  */
909
1049
  getFullResponsesStream() {
910
1050
  return async function* () {
911
1051
  await this.initStream();
912
- if (!this.reusableStream) {
1052
+ if (!this.reusableStream && !this.finalResponse) {
913
1053
  throw new Error('Stream not initialized');
914
1054
  }
915
- // Get or create broadcaster for real-time tool events (lazy init prevents race conditions)
916
- const broadcaster = this.ensureBroadcaster();
917
- const toolEventConsumer = broadcaster.createConsumer();
918
- // Start tool execution in background (completes broadcaster when done)
919
- const executionPromise = this.executeToolsIfNeeded().finally(() => {
920
- broadcaster.complete();
921
- });
922
- const consumer = this.reusableStream.createConsumer();
923
- // Yield original API events
1055
+ if (!this.options.tools?.length) {
1056
+ if (this.reusableStream) {
1057
+ const consumer = this.reusableStream.createConsumer();
1058
+ for await (const event of consumer) {
1059
+ yield event;
1060
+ }
1061
+ }
1062
+ return;
1063
+ }
1064
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
924
1065
  for await (const event of consumer) {
925
1066
  yield event;
926
1067
  }
927
- // Yield tool events as they arrive (real-time!)
928
- for await (const event of toolEventConsumer) {
929
- if (event.type === 'preliminary_result') {
930
- yield {
931
- type: 'tool.preliminary_result',
932
- toolCallId: event.toolCallId,
933
- result: event.result,
934
- timestamp: Date.now(),
935
- };
936
- }
937
- else if (event.type === 'tool_result') {
938
- yield {
939
- type: 'tool.result',
940
- toolCallId: event.toolCallId,
941
- result: event.result,
942
- timestamp: Date.now(),
943
- ...(event.preliminaryResults && { preliminaryResults: event.preliminaryResults }),
944
- };
945
- }
946
- }
947
- // Ensure execution completed (handles errors)
948
1068
  await executionPromise;
949
1069
  }.call(this);
950
1070
  }
951
1071
  /**
952
- * Stream only text deltas as they arrive.
953
- * This filters the full event stream to only yield text content.
1072
+ * Stream only text deltas as they arrive from all turns.
1073
+ * This filters the full event stream to only yield text content,
1074
+ * including text from follow-up responses in multi-turn tool loops.
954
1075
  */
955
1076
  getTextStream() {
956
1077
  return async function* () {
957
1078
  await this.initStream();
958
- if (!this.reusableStream) {
1079
+ if (!this.reusableStream && !this.finalResponse) {
959
1080
  throw new Error('Stream not initialized');
960
1081
  }
961
- yield* extractTextDeltas(this.reusableStream);
1082
+ if (!this.options.tools?.length) {
1083
+ if (this.reusableStream) {
1084
+ yield* extractTextDeltas(this.reusableStream);
1085
+ }
1086
+ return;
1087
+ }
1088
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1089
+ for await (const event of consumer) {
1090
+ if (isOutputTextDeltaEvent(event)) {
1091
+ yield event.delta;
1092
+ }
1093
+ }
1094
+ await executionPromise;
962
1095
  }.call(this);
963
1096
  }
964
1097
  /**
@@ -978,40 +1111,46 @@ export class ModelResult {
978
1111
  getItemsStream() {
979
1112
  return async function* () {
980
1113
  await this.initStream();
981
- if (!this.reusableStream) {
1114
+ if (!this.reusableStream && !this.finalResponse) {
982
1115
  throw new Error('Stream not initialized');
983
1116
  }
984
- // Stream all items from the API response cumulatively
985
- yield* buildItemsStream(this.reusableStream);
986
- // Execute tools if needed
987
- await this.executeToolsIfNeeded();
988
- // Yield function calls and outputs for each tool round
989
- for (const round of this.allToolExecutionRounds) {
990
- // Round 0's function_calls already yielded via buildItemsStream
991
- if (round.round > 0) {
992
- for (const item of round.response.output) {
993
- if (isFunctionCallItem(item)) {
994
- yield item;
995
- }
996
- }
997
- }
998
- for (const toolResult of round.toolResults) {
999
- yield toolResult;
1117
+ // No tools stream single turn directly (no broadcaster needed)
1118
+ if (!this.options.tools?.length) {
1119
+ if (this.reusableStream) {
1120
+ yield* buildItemsStream(this.reusableStream);
1000
1121
  }
1122
+ return;
1001
1123
  }
1002
- // If tools were executed, yield all items from the final response
1003
- if (this.finalResponse && this.allToolExecutionRounds.length > 0) {
1004
- for (const item of this.finalResponse.output) {
1005
- if (isOutputMessage(item) ||
1006
- isFunctionCallItem(item) ||
1007
- isReasoningOutputItem(item) ||
1008
- isWebSearchCallOutputItem(item) ||
1009
- isFileSearchCallOutputItem(item) ||
1010
- isImageGenerationCallOutputItem(item)) {
1011
- yield item;
1124
+ // Use turnBroadcaster (same pattern as getTextStream/getFullResponsesStream).
1125
+ // executeToolsIfNeeded() drives tool execution in the background while we
1126
+ // passively consume events from the broadcaster in real-time.
1127
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1128
+ const itemsInProgress = new Map();
1129
+ for await (const event of consumer) {
1130
+ // Tool call outputs → yield directly as function_call_output items
1131
+ if (isToolCallOutputEvent(event)) {
1132
+ yield event.output;
1133
+ continue;
1134
+ }
1135
+ // Stream termination → reset items map for next turn
1136
+ if ('type' in event && streamTerminationEvents.has(event.type)) {
1137
+ itemsInProgress.clear();
1138
+ }
1139
+ // API stream events → dispatch through item handlers
1140
+ // Cast is necessary: TypeScript cannot narrow a union via Record key lookup,
1141
+ // but `event.type in itemsStreamHandlers` guarantees the event is an
1142
+ // StreamEvents whose type matches a handler key.
1143
+ if ('type' in event && event.type in itemsStreamHandlers) {
1144
+ const handler = itemsStreamHandlers[event.type];
1145
+ if (handler) {
1146
+ const result = handler(event, itemsInProgress);
1147
+ if (result) {
1148
+ yield result;
1149
+ }
1012
1150
  }
1013
1151
  }
1014
1152
  }
1153
+ await executionPromise;
1015
1154
  }.call(this);
1016
1155
  }
1017
1156
  /**
@@ -1019,20 +1158,22 @@ export class ModelResult {
1019
1158
  * while `getItemsStream()` streams all output item types (messages, function_calls,
1020
1159
  * reasoning, etc.) with cumulative updates.
1021
1160
  *
1022
- * Stream incremental message updates as content is added in responses format.
1161
+ * Stream cumulative message snapshots as content is added in responses format.
1023
1162
  * Each iteration yields an updated version of the message with new content.
1024
- * Also yields function_call items and OpenResponsesFunctionCallOutput after tool execution completes.
1025
- * Returns ResponsesOutputMessage, ResponsesOutputItemFunctionCall, or OpenResponsesFunctionCallOutput
1163
+ * Also yields function_call items and FunctionCallOutputItem after tool execution completes.
1164
+ * Returns OutputMessage, OutputFunctionCallItem, or FunctionCallOutputItem
1026
1165
  * compatible with OpenAI Responses API format.
1027
1166
  */
1028
1167
  getNewMessagesStream() {
1029
1168
  return async function* () {
1030
1169
  await this.initStream();
1031
- if (!this.reusableStream) {
1170
+ if (!this.reusableStream && !this.finalResponse) {
1032
1171
  throw new Error('Stream not initialized');
1033
1172
  }
1034
1173
  // First yield messages from the stream in responses format
1035
- yield* buildResponsesMessageStream(this.reusableStream);
1174
+ if (this.reusableStream) {
1175
+ yield* buildResponsesMessageStream(this.reusableStream);
1176
+ }
1036
1177
  // Execute tools if needed
1037
1178
  await this.executeToolsIfNeeded();
1038
1179
  // Yield function calls and their outputs for each executed tool
@@ -1059,20 +1200,33 @@ export class ModelResult {
1059
1200
  }.call(this);
1060
1201
  }
1061
1202
  /**
1062
- * Stream only reasoning deltas as they arrive.
1063
- * This filters the full event stream to only yield reasoning content.
1203
+ * Stream only reasoning deltas as they arrive from all turns.
1204
+ * This filters the full event stream to only yield reasoning content,
1205
+ * including reasoning from follow-up responses in multi-turn tool loops.
1064
1206
  */
1065
1207
  getReasoningStream() {
1066
1208
  return async function* () {
1067
1209
  await this.initStream();
1068
- if (!this.reusableStream) {
1210
+ if (!this.reusableStream && !this.finalResponse) {
1069
1211
  throw new Error('Stream not initialized');
1070
1212
  }
1071
- yield* extractReasoningDeltas(this.reusableStream);
1213
+ if (!this.options.tools?.length) {
1214
+ if (this.reusableStream) {
1215
+ yield* extractReasoningDeltas(this.reusableStream);
1216
+ }
1217
+ return;
1218
+ }
1219
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1220
+ for await (const event of consumer) {
1221
+ if (isReasoningDeltaEvent(event)) {
1222
+ yield event.delta;
1223
+ }
1224
+ }
1225
+ await executionPromise;
1072
1226
  }.call(this);
1073
1227
  }
1074
1228
  /**
1075
- * Stream tool call argument deltas and preliminary results.
1229
+ * Stream tool call argument deltas and preliminary results from all turns.
1076
1230
  * Preliminary results are streamed in REAL-TIME as generator tools yield.
1077
1231
  * - Tool call argument deltas as { type: "delta", content: string }
1078
1232
  * - Preliminary results as { type: "preliminary_result", toolCallId, result }
@@ -1080,30 +1234,31 @@ export class ModelResult {
1080
1234
  getToolStream() {
1081
1235
  return async function* () {
1082
1236
  await this.initStream();
1083
- if (!this.reusableStream) {
1237
+ if (!this.reusableStream && !this.finalResponse) {
1084
1238
  throw new Error('Stream not initialized');
1085
1239
  }
1086
- // Get or create broadcaster for real-time tool events (lazy init prevents race conditions)
1087
- const broadcaster = this.ensureBroadcaster();
1088
- const toolEventConsumer = broadcaster.createConsumer();
1089
- // Start tool execution in background (completes broadcaster when done)
1090
- const executionPromise = this.executeToolsIfNeeded().finally(() => {
1091
- broadcaster.complete();
1092
- });
1093
- // Yield tool deltas from API stream
1094
- for await (const delta of extractToolDeltas(this.reusableStream)) {
1095
- yield {
1096
- type: 'delta',
1097
- content: delta,
1098
- };
1240
+ if (!this.options.tools?.length) {
1241
+ if (this.reusableStream) {
1242
+ for await (const delta of extractToolDeltas(this.reusableStream)) {
1243
+ yield { type: 'delta', content: delta };
1244
+ }
1245
+ }
1246
+ return;
1099
1247
  }
1100
- // Yield only preliminary_result events (filter out tool_result events)
1101
- for await (const event of toolEventConsumer) {
1102
- if (event.type === 'preliminary_result') {
1103
- yield event;
1248
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1249
+ for await (const event of consumer) {
1250
+ if (event.type === 'response.function_call_arguments.delta') {
1251
+ yield { type: 'delta', content: event.delta };
1252
+ continue;
1253
+ }
1254
+ if (event.type === 'tool.preliminary_result') {
1255
+ yield {
1256
+ type: 'preliminary_result',
1257
+ toolCallId: event.toolCallId,
1258
+ result: event.result,
1259
+ };
1104
1260
  }
1105
1261
  }
1106
- // Ensure execution completed (handles errors)
1107
1262
  await executionPromise;
1108
1263
  }.call(this);
1109
1264
  }
@@ -1132,12 +1287,76 @@ export class ModelResult {
1132
1287
  getToolCallsStream() {
1133
1288
  return async function* () {
1134
1289
  await this.initStream();
1135
- if (!this.reusableStream) {
1290
+ if (!this.reusableStream && !this.finalResponse) {
1136
1291
  throw new Error('Stream not initialized');
1137
1292
  }
1138
- yield* buildToolCallStream(this.reusableStream);
1293
+ if (this.reusableStream) {
1294
+ yield* buildToolCallStream(this.reusableStream);
1295
+ }
1139
1296
  }.call(this);
1140
1297
  }
1298
+ /**
1299
+ * Returns an async iterable that emits a full context snapshot every time
1300
+ * any tool calls ctx.update(). Can be consumed concurrently with getText(),
1301
+ * getToolStream(), etc.
1302
+ *
1303
+ * @example
1304
+ * ```typescript
1305
+ * for await (const snapshot of result.getContextUpdates()) {
1306
+ * console.log('Context changed:', snapshot);
1307
+ * }
1308
+ * ```
1309
+ */
1310
+ async *getContextUpdates() {
1311
+ // Ensure stream is initialized (which creates the context store)
1312
+ await this.initStream();
1313
+ if (!this.contextStore) {
1314
+ return;
1315
+ }
1316
+ const store = this.contextStore;
1317
+ const queue = [];
1318
+ let resolve = null;
1319
+ let done = false;
1320
+ const unsubscribe = store.subscribe((snapshot) => {
1321
+ queue.push(snapshot);
1322
+ if (resolve) {
1323
+ resolve();
1324
+ resolve = null;
1325
+ }
1326
+ });
1327
+ // Signal completion when tool execution finishes
1328
+ this.executeToolsIfNeeded().then(() => {
1329
+ done = true;
1330
+ if (resolve) {
1331
+ resolve();
1332
+ resolve = null;
1333
+ }
1334
+ }, () => {
1335
+ done = true;
1336
+ if (resolve) {
1337
+ resolve();
1338
+ resolve = null;
1339
+ }
1340
+ });
1341
+ try {
1342
+ while (!done) {
1343
+ if (queue.length > 0) {
1344
+ yield queue.shift();
1345
+ }
1346
+ else {
1347
+ // Wait for next update or completion
1348
+ await new Promise((r) => { resolve = r; });
1349
+ }
1350
+ }
1351
+ // Drain any remaining queued snapshots
1352
+ while (queue.length > 0) {
1353
+ yield queue.shift();
1354
+ }
1355
+ }
1356
+ finally {
1357
+ unsubscribe();
1358
+ }
1359
+ }
1141
1360
  /**
1142
1361
  * Cancel the underlying stream and all consumers
1143
1362
  */