@openrouter/sdk 0.8.0 → 0.10.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 (360) hide show
  1. package/FUNCTIONS.md +2 -1
  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.js +2 -1
  11. package/esm/funcs/call-model.d.ts +19 -70
  12. package/esm/funcs/call-model.js +29 -71
  13. package/esm/funcs/chatSend.d.ts +3 -3
  14. package/esm/funcs/chatSend.js +20 -3
  15. package/esm/funcs/creditsCreateCoinbaseCharge.js +2 -1
  16. package/esm/funcs/creditsGetCredits.js +2 -1
  17. package/esm/funcs/embeddingsGenerate.js +2 -1
  18. package/esm/funcs/embeddingsListModels.js +2 -1
  19. package/esm/funcs/endpointsList.js +2 -1
  20. package/esm/funcs/endpointsListZdrEndpoints.js +2 -1
  21. package/esm/funcs/generationsGetGeneration.js +2 -1
  22. package/esm/funcs/guardrailsBulkAssignKeys.js +2 -1
  23. package/esm/funcs/guardrailsBulkAssignMembers.js +2 -1
  24. package/esm/funcs/guardrailsBulkUnassignKeys.js +2 -1
  25. package/esm/funcs/guardrailsBulkUnassignMembers.js +2 -1
  26. package/esm/funcs/guardrailsCreate.js +2 -1
  27. package/esm/funcs/guardrailsDelete.js +2 -1
  28. package/esm/funcs/guardrailsGet.js +2 -1
  29. package/esm/funcs/guardrailsList.js +2 -1
  30. package/esm/funcs/guardrailsListGuardrailKeyAssignments.js +2 -1
  31. package/esm/funcs/guardrailsListGuardrailMemberAssignments.js +2 -1
  32. package/esm/funcs/guardrailsListKeyAssignments.js +2 -1
  33. package/esm/funcs/guardrailsListMemberAssignments.js +2 -1
  34. package/esm/funcs/guardrailsUpdate.js +2 -1
  35. package/esm/funcs/modelsCount.d.ts +1 -1
  36. package/esm/funcs/modelsCount.js +9 -4
  37. package/esm/funcs/modelsList.js +3 -1
  38. package/esm/funcs/modelsListForUser.js +2 -1
  39. package/esm/funcs/oAuthCreateAuthCode.d.ts +1 -1
  40. package/esm/funcs/oAuthCreateAuthCode.js +4 -3
  41. package/esm/funcs/oAuthExchangeAuthCodeForAPIKey.js +2 -1
  42. package/esm/funcs/providersList.js +2 -1
  43. package/esm/index.d.ts +22 -23
  44. package/esm/index.js +20 -17
  45. package/esm/lib/anthropic-compat.d.ts +2 -1
  46. package/esm/lib/anthropic-compat.js +1 -2
  47. package/esm/lib/async-params.d.ts +19 -5
  48. package/esm/lib/async-params.js +5 -1
  49. package/esm/lib/chat-compat.d.ts +1 -1
  50. package/esm/lib/chat-compat.js +1 -2
  51. package/esm/lib/claude-type-guards.d.ts +2 -2
  52. package/esm/lib/config.d.ts +8 -10
  53. package/esm/lib/config.js +2 -2
  54. package/esm/lib/conversation-state.d.ts +1 -1
  55. package/esm/lib/conversation-state.js +35 -32
  56. package/esm/lib/env.d.ts +6 -2
  57. package/esm/lib/env.js +7 -3
  58. package/esm/lib/model-result.d.ts +73 -17
  59. package/esm/lib/model-result.js +329 -125
  60. package/esm/lib/sdks.d.ts +1 -1
  61. package/esm/lib/sdks.js +8 -28
  62. package/esm/lib/stream-transformers.d.ts +5 -4
  63. package/esm/lib/stream-transformers.js +24 -29
  64. package/esm/lib/stream-type-guards.js +8 -32
  65. package/esm/lib/tool-context.d.ts +68 -0
  66. package/esm/lib/tool-context.js +175 -0
  67. package/esm/lib/tool-executor.d.ts +9 -5
  68. package/esm/lib/tool-executor.js +26 -16
  69. package/esm/lib/tool-orchestrator.d.ts +2 -2
  70. package/esm/lib/tool-types.d.ts +101 -14
  71. package/esm/lib/tool-types.js +17 -0
  72. package/esm/lib/tool.d.ts +49 -60
  73. package/esm/lib/tool.js +15 -19
  74. package/esm/lib/turn-context.d.ts +1 -1
  75. package/esm/models/assistantmessage.d.ts +53 -36
  76. package/esm/models/assistantmessage.js +38 -47
  77. package/esm/models/assistantmessageimages.d.ts +33 -0
  78. package/esm/models/assistantmessageimages.js +44 -0
  79. package/esm/models/chatcompletionaudiooutput.d.ts +38 -0
  80. package/esm/models/chatcompletionaudiooutput.js +36 -0
  81. package/esm/models/chatgenerationparams.d.ts +527 -131
  82. package/esm/models/chatgenerationparams.js +280 -97
  83. package/esm/models/chatgenerationtokenusage.d.ts +48 -0
  84. package/esm/models/chatmessagecontentitem.d.ts +16 -10
  85. package/esm/models/chatmessagecontentitem.js +28 -4
  86. package/esm/models/chatmessagecontentitemaudio.d.ts +20 -2
  87. package/esm/models/chatmessagecontentitemaudio.js +9 -2
  88. package/esm/models/chatmessagecontentitemcachecontrol.d.ts +19 -8
  89. package/esm/models/chatmessagecontentitemcachecontrol.js +14 -9
  90. package/esm/models/chatmessagecontentitemfile.d.ts +57 -0
  91. package/esm/models/chatmessagecontentitemfile.js +59 -0
  92. package/esm/models/chatmessagecontentitemimage.d.ts +26 -3
  93. package/esm/models/chatmessagecontentitemimage.js +12 -2
  94. package/esm/models/chatmessagecontentitemtext.d.ts +17 -2
  95. package/esm/models/chatmessagecontentitemtext.js +9 -2
  96. package/esm/models/chatmessagecontentitemvideo.d.ts +12 -55
  97. package/esm/models/chatmessagecontentitemvideo.js +5 -72
  98. package/esm/models/chatmessagecontentitemvideolegacy.d.ts +28 -0
  99. package/esm/models/chatmessagecontentitemvideolegacy.js +33 -0
  100. package/esm/models/chatmessagetokenlogprob.d.ts +15 -0
  101. package/esm/models/chatmessagetokenlogprobs.d.ts +10 -1
  102. package/esm/models/chatmessagetokenlogprobs.js +2 -1
  103. package/esm/models/chatmessagetoolcall.d.ts +23 -2
  104. package/esm/models/chatmessagetoolcall.js +9 -2
  105. package/esm/models/chatresponse.d.ts +30 -2
  106. package/esm/models/chatresponse.js +7 -2
  107. package/esm/models/chatresponsechoice.d.ts +13 -2
  108. package/esm/models/chatresponsechoice.js +1 -2
  109. package/esm/models/chatstreamingchoice.d.ts +13 -2
  110. package/esm/models/chatstreamingchoice.js +1 -2
  111. package/esm/models/chatstreamingmessagechunk.d.ts +31 -2
  112. package/esm/models/chatstreamingmessagechunk.js +7 -2
  113. package/esm/models/chatstreamingmessagetoolcall.d.ts +38 -1
  114. package/esm/models/chatstreamingmessagetoolcall.js +9 -1
  115. package/esm/models/chatstreamingresponsechunk.d.ts +46 -12
  116. package/esm/models/chatstreamingresponsechunk.js +12 -26
  117. package/esm/models/chatstreamoptions.d.ts +8 -0
  118. package/esm/models/compoundfilter.d.ts +36 -0
  119. package/esm/models/compoundfilter.js +32 -0
  120. package/esm/models/conflictresponseerrordata.d.ts +17 -0
  121. package/esm/models/conflictresponseerrordata.js +16 -0
  122. package/esm/models/contextcompressionengine.d.ts +15 -0
  123. package/esm/models/contextcompressionengine.js +14 -0
  124. package/esm/models/datetimeservertool.d.ts +30 -0
  125. package/esm/models/datetimeservertool.js +22 -0
  126. package/esm/models/debugoptions.d.ts +18 -0
  127. package/esm/models/debugoptions.js +18 -0
  128. package/esm/models/defaultparameters.d.ts +3 -0
  129. package/esm/models/defaultparameters.js +6 -0
  130. package/esm/models/developermessage.d.ts +12 -0
  131. package/esm/models/errors/conflictresponseerror.d.ts +33 -0
  132. package/esm/models/errors/{chaterror.js → conflictresponseerror.js} +17 -7
  133. package/esm/models/errors/index.d.ts +1 -1
  134. package/esm/models/errors/index.js +1 -1
  135. package/esm/models/index.d.ts +35 -12
  136. package/esm/models/index.js +35 -12
  137. package/esm/models/jsonschemaconfig.d.ts +17 -2
  138. package/esm/models/jsonschemaconfig.js +1 -1
  139. package/esm/models/message.d.ts +9 -2
  140. package/esm/models/message.js +1 -1
  141. package/esm/models/modelscountresponse.d.ts +4 -4
  142. package/esm/models/modelscountresponse.js +4 -4
  143. package/esm/models/namedtoolchoice.d.ts +15 -2
  144. package/esm/models/namedtoolchoice.js +6 -1
  145. package/esm/models/openairesponsesinputunion.d.ts +32 -1
  146. package/esm/models/openairesponsesinputunion.js +53 -1
  147. package/esm/models/openairesponsesreasoningconfig.d.ts +1 -1
  148. package/esm/models/openairesponsesreasoningconfig.js +1 -1
  149. package/esm/models/openresponsesapplypatchtool.d.ts +20 -0
  150. package/esm/models/openresponsesapplypatchtool.js +21 -0
  151. package/esm/models/openresponsescodeinterpretertool.d.ts +68 -0
  152. package/esm/models/openresponsescodeinterpretertool.js +85 -0
  153. package/esm/models/openresponsescomputertool.d.ts +39 -0
  154. package/esm/models/openresponsescomputertool.js +50 -0
  155. package/esm/models/openresponsescustomtool.d.ts +75 -0
  156. package/esm/models/openresponsescustomtool.js +95 -0
  157. package/esm/models/openresponseseasyinputmessage.d.ts +30 -4
  158. package/esm/models/openresponseseasyinputmessage.js +28 -2
  159. package/esm/models/openresponsesfilesearchtool.d.ts +111 -0
  160. package/esm/models/openresponsesfilesearchtool.js +180 -0
  161. package/esm/models/openresponsesfunctioncalloutput.d.ts +46 -7
  162. package/esm/models/openresponsesfunctioncalloutput.js +56 -4
  163. package/esm/models/openresponsesfunctionshelltool.d.ts +20 -0
  164. package/esm/models/openresponsesfunctionshelltool.js +21 -0
  165. package/esm/models/openresponsesimagegenerationtool.d.ts +125 -0
  166. package/esm/models/openresponsesimagegenerationtool.js +153 -0
  167. package/esm/models/openresponsesinputmessageitem.d.ts +2 -2
  168. package/esm/models/openresponsesinputmessageitem.js +2 -2
  169. package/esm/models/openresponsesinputunion.d.ts +207 -0
  170. package/esm/models/openresponsesinputunion.js +225 -0
  171. package/esm/models/openresponseslocalshelltool.d.ts +20 -0
  172. package/esm/models/openresponseslocalshelltool.js +21 -0
  173. package/esm/models/openresponsesmcptool.d.ts +128 -0
  174. package/esm/models/openresponsesmcptool.js +173 -0
  175. package/esm/models/openresponsesnonstreamingresponse.d.ts +15 -6
  176. package/esm/models/openresponsesnonstreamingresponse.js +30 -3
  177. package/esm/models/openresponsesreasoning.d.ts +2 -2
  178. package/esm/models/openresponsesreasoning.js +1 -1
  179. package/esm/models/openresponsesreasoningconfig.d.ts +2 -2
  180. package/esm/models/openresponsesreasoningconfig.js +1 -1
  181. package/esm/models/openresponsesrequest.d.ts +111 -39
  182. package/esm/models/openresponsesrequest.js +112 -38
  183. package/esm/models/openresponsesstreamevent.d.ts +52 -4
  184. package/esm/models/openresponsesstreamevent.js +54 -3
  185. package/esm/models/openresponseswebsearch20250826tool.d.ts +29 -0
  186. package/esm/models/openresponseswebsearch20250826tool.js +23 -0
  187. package/esm/models/openresponseswebsearchcallcompleted.d.ts +16 -0
  188. package/esm/models/openresponseswebsearchcallcompleted.js +24 -0
  189. package/esm/models/openresponseswebsearchcallinprogress.d.ts +16 -0
  190. package/esm/models/openresponseswebsearchcallinprogress.js +24 -0
  191. package/esm/models/openresponseswebsearchcallsearching.d.ts +16 -0
  192. package/esm/models/openresponseswebsearchcallsearching.js +24 -0
  193. package/esm/models/openresponseswebsearchpreview20250311tool.d.ts +44 -0
  194. package/esm/models/openresponseswebsearchpreview20250311tool.js +51 -0
  195. package/esm/models/openresponseswebsearchpreviewtool.d.ts +44 -0
  196. package/esm/models/openresponseswebsearchpreviewtool.js +47 -0
  197. package/esm/models/openresponseswebsearchtool.d.ts +29 -0
  198. package/esm/models/openresponseswebsearchtool.js +23 -0
  199. package/esm/models/operations/bulkassignkeystoguardrail.d.ts +16 -3
  200. package/esm/models/operations/bulkassignkeystoguardrail.js +2 -2
  201. package/esm/models/operations/bulkassignmemberstoguardrail.d.ts +16 -3
  202. package/esm/models/operations/bulkassignmemberstoguardrail.js +2 -2
  203. package/esm/models/operations/bulkunassignkeysfromguardrail.d.ts +16 -3
  204. package/esm/models/operations/bulkunassignkeysfromguardrail.js +2 -2
  205. package/esm/models/operations/bulkunassignmembersfromguardrail.d.ts +16 -3
  206. package/esm/models/operations/bulkunassignmembersfromguardrail.js +2 -2
  207. package/esm/models/operations/createauthkeyscode.d.ts +40 -3
  208. package/esm/models/operations/createauthkeyscode.js +16 -2
  209. package/esm/models/operations/createcoinbasecharge.d.ts +16 -3
  210. package/esm/models/operations/createcoinbasecharge.js +2 -2
  211. package/esm/models/operations/createembeddings.d.ts +16 -3
  212. package/esm/models/operations/createembeddings.js +2 -2
  213. package/esm/models/operations/createguardrail.d.ts +25 -3
  214. package/esm/models/operations/createguardrail.js +6 -2
  215. package/esm/models/operations/createkeys.d.ts +16 -3
  216. package/esm/models/operations/createkeys.js +2 -2
  217. package/esm/models/operations/createresponses.d.ts +16 -3
  218. package/esm/models/operations/createresponses.js +2 -2
  219. package/esm/models/operations/deleteguardrail.d.ts +16 -3
  220. package/esm/models/operations/deleteguardrail.js +2 -2
  221. package/esm/models/operations/deletekeys.d.ts +16 -3
  222. package/esm/models/operations/deletekeys.js +2 -2
  223. package/esm/models/operations/exchangeauthcodeforapikey.d.ts +16 -3
  224. package/esm/models/operations/exchangeauthcodeforapikey.js +2 -2
  225. package/esm/models/operations/getcredits.d.ts +16 -3
  226. package/esm/models/operations/getcredits.js +2 -2
  227. package/esm/models/operations/getcurrentkey.d.ts +16 -3
  228. package/esm/models/operations/getcurrentkey.js +2 -2
  229. package/esm/models/operations/getgeneration.d.ts +27 -3
  230. package/esm/models/operations/getgeneration.js +9 -2
  231. package/esm/models/operations/getguardrail.d.ts +20 -3
  232. package/esm/models/operations/getguardrail.js +4 -2
  233. package/esm/models/operations/getkey.d.ts +16 -3
  234. package/esm/models/operations/getkey.js +2 -2
  235. package/esm/models/operations/getmodels.d.ts +21 -3
  236. package/esm/models/operations/getmodels.js +4 -2
  237. package/esm/models/operations/getuseractivity.d.ts +16 -3
  238. package/esm/models/operations/getuseractivity.js +2 -2
  239. package/esm/models/operations/list.d.ts +16 -3
  240. package/esm/models/operations/list.js +2 -2
  241. package/esm/models/operations/listembeddingsmodels.d.ts +16 -3
  242. package/esm/models/operations/listembeddingsmodels.js +2 -2
  243. package/esm/models/operations/listendpoints.d.ts +16 -3
  244. package/esm/models/operations/listendpoints.js +2 -2
  245. package/esm/models/operations/listendpointszdr.d.ts +16 -3
  246. package/esm/models/operations/listendpointszdr.js +2 -2
  247. package/esm/models/operations/listguardrailkeyassignments.d.ts +16 -3
  248. package/esm/models/operations/listguardrailkeyassignments.js +2 -2
  249. package/esm/models/operations/listguardrailmemberassignments.d.ts +16 -3
  250. package/esm/models/operations/listguardrailmemberassignments.js +2 -2
  251. package/esm/models/operations/listguardrails.d.ts +20 -3
  252. package/esm/models/operations/listguardrails.js +4 -2
  253. package/esm/models/operations/listkeyassignments.d.ts +16 -3
  254. package/esm/models/operations/listkeyassignments.js +2 -2
  255. package/esm/models/operations/listmemberassignments.d.ts +16 -3
  256. package/esm/models/operations/listmemberassignments.js +2 -2
  257. package/esm/models/operations/listmodelscount.d.ts +21 -3
  258. package/esm/models/operations/listmodelscount.js +4 -2
  259. package/esm/models/operations/listmodelsuser.d.ts +16 -3
  260. package/esm/models/operations/listmodelsuser.js +2 -2
  261. package/esm/models/operations/listproviders.d.ts +16 -3
  262. package/esm/models/operations/listproviders.js +2 -2
  263. package/esm/models/operations/sendchatcompletionrequest.d.ts +27 -5
  264. package/esm/models/operations/sendchatcompletionrequest.js +22 -4
  265. package/esm/models/operations/updateguardrail.d.ts +25 -3
  266. package/esm/models/operations/updateguardrail.js +6 -2
  267. package/esm/models/operations/updatekeys.d.ts +16 -3
  268. package/esm/models/operations/updatekeys.js +2 -2
  269. package/esm/models/outputmessage.d.ts +23 -0
  270. package/esm/models/outputmessage.js +24 -0
  271. package/esm/models/outputmodality.d.ts +1 -0
  272. package/esm/models/outputmodality.js +1 -0
  273. package/esm/models/providername.d.ts +3 -0
  274. package/esm/models/providername.js +3 -0
  275. package/esm/models/providerpreferences.d.ts +49 -14
  276. package/esm/models/providerpreferences.js +33 -15
  277. package/esm/models/providersort.d.ts +7 -0
  278. package/esm/models/providersort.js +4 -0
  279. package/esm/models/providersortconfig.d.ts +31 -2
  280. package/esm/models/providersortconfig.js +16 -2
  281. package/esm/models/reasoningdetailencrypted.d.ts +42 -0
  282. package/esm/models/reasoningdetailencrypted.js +42 -0
  283. package/esm/models/reasoningdetailsummary.d.ts +42 -0
  284. package/esm/models/reasoningdetailsummary.js +42 -0
  285. package/esm/models/reasoningdetailtext.d.ts +44 -0
  286. package/esm/models/reasoningdetailtext.js +44 -0
  287. package/esm/models/reasoningdetailunion.d.ts +19 -0
  288. package/esm/models/reasoningdetailunion.js +28 -0
  289. package/esm/models/responseformatjsonobject.d.ts +20 -0
  290. package/esm/models/responseformatjsonobject.js +21 -0
  291. package/esm/models/responseformatjsonschema.d.ts +6 -0
  292. package/esm/models/responseformattext.d.ts +15 -0
  293. package/esm/models/responseformattext.js +13 -0
  294. package/esm/models/responseformattextconfig.d.ts +3 -3
  295. package/esm/models/responseformattextconfig.js +3 -3
  296. package/esm/models/responseformattextgrammar.d.ts +6 -0
  297. package/esm/models/responseformattextpython.d.ts +15 -0
  298. package/esm/models/responseformattextpython.js +13 -0
  299. package/esm/models/responseoutputtext.d.ts +8 -8
  300. package/esm/models/responseoutputtext.js +10 -9
  301. package/esm/models/responseserrorfield.d.ts +4 -4
  302. package/esm/models/responseserrorfield.js +4 -4
  303. package/esm/models/responsesoutputitem.d.ts +2 -13
  304. package/esm/models/responsesoutputitem.js +8 -6
  305. package/esm/models/responsesoutputitemreasoning.d.ts +3 -32
  306. package/esm/models/responsesoutputitemreasoning.js +3 -45
  307. package/esm/models/responsesoutputmessage.d.ts +24 -32
  308. package/esm/models/responsesoutputmessage.js +26 -47
  309. package/esm/models/responsesservertooloutput.d.ts +42 -0
  310. package/esm/models/responsesservertooloutput.js +44 -0
  311. package/esm/models/responseswebsearchcalloutput.d.ts +90 -5
  312. package/esm/models/responseswebsearchcalloutput.js +113 -5
  313. package/esm/models/responseswebsearchservertool.d.ts +35 -0
  314. package/esm/models/responseswebsearchservertool.js +28 -0
  315. package/esm/models/systemmessage.d.ts +12 -0
  316. package/esm/models/toolchoiceoption.d.ts +31 -0
  317. package/esm/models/toolchoiceoption.js +32 -0
  318. package/esm/models/tooldefinitionjson.d.ts +62 -10
  319. package/esm/models/tooldefinitionjson.js +29 -6
  320. package/esm/models/toolresponsemessage.d.ts +12 -0
  321. package/esm/models/usermessage.d.ts +12 -0
  322. package/esm/models/videoinput.d.ts +23 -0
  323. package/esm/models/videoinput.js +22 -0
  324. package/esm/models/websearchengine.d.ts +2 -0
  325. package/esm/models/websearchengine.js +2 -0
  326. package/esm/models/websearchservertool.d.ts +116 -0
  327. package/esm/models/websearchservertool.js +77 -0
  328. package/esm/models/websearchshorthand.d.ts +215 -0
  329. package/esm/models/websearchshorthand.js +138 -0
  330. package/esm/sdk/chat.d.ts +1 -1
  331. package/esm/sdk/sdk.d.ts +6 -3
  332. package/esm/sdk/sdk.js +3 -4
  333. package/esm/types/index.d.ts +0 -2
  334. package/esm/types/index.js +0 -1
  335. package/jsr.json +1 -1
  336. package/package.json +11 -6
  337. package/turbo.json +10 -0
  338. package/esm/models/chaterror.d.ts +0 -17
  339. package/esm/models/chaterror.js +0 -25
  340. package/esm/models/errors/chaterror.d.ts +0 -19
  341. package/esm/models/openresponsesinput.d.ts +0 -28
  342. package/esm/models/openresponsesinput.js +0 -54
  343. package/esm/models/openresponseslogprobs.d.ts +0 -16
  344. package/esm/models/openresponseslogprobs.js +0 -22
  345. package/esm/models/openresponsestoplogprobs.d.ts +0 -14
  346. package/esm/models/openresponsestoplogprobs.js +0 -15
  347. package/esm/models/providersortunion.d.ts +0 -10
  348. package/esm/models/providersortunion.js +0 -13
  349. package/esm/models/responsesformatjsonobject.d.ts +0 -20
  350. package/esm/models/responsesformatjsonobject.js +0 -21
  351. package/esm/models/schema10.d.ts +0 -33
  352. package/esm/models/schema10.js +0 -30
  353. package/esm/models/schema14.d.ts +0 -8
  354. package/esm/models/schema14.js +0 -12
  355. package/esm/models/schema17.d.ts +0 -102
  356. package/esm/models/schema17.js +0 -95
  357. package/esm/models/schema19.d.ts +0 -92
  358. package/esm/models/schema19.js +0 -109
  359. package/esm/models/schema5.d.ts +0 -86
  360. package/esm/models/schema5.js +0 -89
@@ -1,4 +1,5 @@
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';
@@ -8,7 +9,7 @@ import { executeTool } from './tool-executor.js';
8
9
  import { executeNextTurnParamsFunctions, applyNextTurnParamsToRequest } from './next-turn-params.js';
9
10
  import { hasExecuteFunction } 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 { isOutputMessage, isFunctionCallItem, isReasoningOutputItem, isWebSearchCallOutputItem, isFileSearchCallOutputItem, isImageGenerationCallOutputItem, 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.
@@ -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,13 +502,7 @@ 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
- }
505
+ this.broadcastToolResult(originalToolCall.id, { error: errorMessage });
386
506
  toolResults.push({
387
507
  type: 'function_call_output',
388
508
  id: `output_${originalToolCall.id}`,
@@ -398,18 +518,10 @@ export class ModelResult {
398
518
  toolResults.push(value.output);
399
519
  continue;
400
520
  }
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
- }),
411
- });
412
- }
521
+ const toolResult = (value.result.error
522
+ ? { error: value.result.error.message }
523
+ : value.result.result);
524
+ this.broadcastToolResult(value.toolCall.id, toolResult, value.preliminaryResultsForCall.length > 0 ? value.preliminaryResultsForCall : undefined);
413
525
  toolResults.push({
414
526
  type: 'function_call_output',
415
527
  id: `output_${value.toolCall.id}`,
@@ -432,9 +544,10 @@ export class ModelResult {
432
544
  const resolved = await resolveAsyncFunctions(this.options.request, turnContext);
433
545
  // Preserve accumulated input from previous turns
434
546
  const preservedInput = this.resolvedRequest?.input;
547
+ const preservedStream = this.resolvedRequest?.stream;
435
548
  this.resolvedRequest = {
436
549
  ...resolved,
437
- stream: false,
550
+ stream: preservedStream ?? true,
438
551
  ...(preservedInput !== undefined && { input: preservedInput }),
439
552
  };
440
553
  }
@@ -456,13 +569,14 @@ export class ModelResult {
456
569
  }
457
570
  /**
458
571
  * Make a follow-up API request with tool results.
459
- * Continues the conversation after tool execution.
572
+ * Uses streaming and pipes events through the turn broadcaster when available.
460
573
  *
461
574
  * @param currentResponse - The response that contained tool calls
462
575
  * @param toolResults - The results from executing those tools
576
+ * @param turnNumber - The turn number for this follow-up request
463
577
  * @returns The new response from the API
464
578
  */
465
- async makeFollowupRequest(currentResponse, toolResults) {
579
+ async makeFollowupRequest(currentResponse, toolResults, turnNumber) {
466
580
  // Build new input preserving original conversation + tool results
467
581
  const originalInput = this.resolvedRequest?.input;
468
582
  const normalizedOriginalInput = Array.isArray(originalInput)
@@ -487,7 +601,7 @@ export class ModelResult {
487
601
  };
488
602
  const newRequest = {
489
603
  ...this.resolvedRequest,
490
- stream: false,
604
+ stream: true,
491
605
  };
492
606
  const newResult = await betaResponsesSend(this.options.client, { openResponsesRequest: newRequest }, this.options.options);
493
607
  if (!newResult.ok) {
@@ -496,8 +610,11 @@ export class ModelResult {
496
610
  // Handle streaming or non-streaming response
497
611
  const value = newResult.value;
498
612
  if (isEventStream(value)) {
499
- const stream = new ReusableReadableStream(value);
500
- return consumeStreamForCompletion(stream);
613
+ const followUpStream = new ReusableReadableStream(value);
614
+ if (this.turnBroadcaster) {
615
+ return this.pipeAndConsumeStream(followUpStream, turnNumber);
616
+ }
617
+ return consumeStreamForCompletion(followUpStream);
501
618
  }
502
619
  else if (this.isNonStreamingResponse(value)) {
503
620
  return value;
@@ -533,7 +650,7 @@ export class ModelResult {
533
650
  }
534
651
  // Already resolved, extract non-function fields
535
652
  // 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;
653
+ const { stopWhen: _, state: _s, requireApproval: _r, approveToolCalls: _a, rejectToolCalls: _rj, context: _c, ...rest } = this.options.request;
537
654
  return rest;
538
655
  }
539
656
  /**
@@ -590,6 +707,12 @@ export class ModelResult {
590
707
  // Check if we're resuming from awaiting_approval with decisions
591
708
  if (loadedState.status === 'awaiting_approval' &&
592
709
  (this.approvedToolCalls.length > 0 || this.rejectedToolCalls.length > 0)) {
710
+ // Initialize context store before resuming so tools have access
711
+ if (this.options.context !== undefined) {
712
+ const approvalContext = { numberOfTurns: 0 };
713
+ const resolvedCtx = await resolveContext(this.options.context, approvalContext);
714
+ this.contextStore = new ToolContextStore(resolvedCtx);
715
+ }
593
716
  this.isResumingFromApproval = true;
594
717
  await this.processApprovalDecisions();
595
718
  return; // Skip normal initialization, we're resuming
@@ -610,9 +733,12 @@ export class ModelResult {
610
733
  }
611
734
  // Resolve async functions before initial request
612
735
  // Build initial turn context (turn 0 for initial request)
613
- const initialContext = {
614
- numberOfTurns: 0,
615
- };
736
+ const initialContext = { numberOfTurns: 0 };
737
+ // Initialize context store from the context option
738
+ if (this.options.context !== undefined) {
739
+ const resolvedCtx = await resolveContext(this.options.context, initialContext);
740
+ this.contextStore = new ToolContextStore(resolvedCtx);
741
+ }
616
742
  // Resolve any async functions first
617
743
  let baseRequest = await this.resolveRequestForContext(initialContext);
618
744
  // If we have state with existing messages, use those as input
@@ -673,6 +799,7 @@ export class ModelResult {
673
799
  // Build turn context - numberOfTurns represents the current turn (1-indexed after initial)
674
800
  const turnContext = {
675
801
  numberOfTurns: this.allToolExecutionRounds.length + 1,
802
+ // context is handled via contextStore, not on TurnContext
676
803
  };
677
804
  // Process approvals - execute the approved tools
678
805
  for (const callId of this.approvedToolCalls) {
@@ -685,7 +812,7 @@ export class ModelResult {
685
812
  unsentResults.push(createRejectedResult(callId, String(toolCall.name), 'Tool not found or not executable'));
686
813
  continue;
687
814
  }
688
- const result = await executeTool(tool, toolCall, turnContext);
815
+ const result = await executeTool(tool, toolCall, turnContext, undefined, this.contextStore ?? undefined, this.options.sharedContextSchema);
689
816
  if (result.error) {
690
817
  unsentResults.push(createRejectedResult(callId, String(toolCall.name), result.error.message));
691
818
  }
@@ -839,7 +966,9 @@ export class ModelResult {
839
966
  break;
840
967
  }
841
968
  // Build turn context
842
- const turnContext = { numberOfTurns: currentRound + 1 };
969
+ const turnNumber = currentRound + 1;
970
+ const turnContext = { numberOfTurns: turnNumber };
971
+ await this.options.onTurnStart?.(turnContext);
843
972
  // Resolve async functions for this turn
844
973
  await this.resolveAsyncFunctionsForTurn(turnContext);
845
974
  // Execute tools
@@ -855,8 +984,8 @@ export class ModelResult {
855
984
  await this.saveToolResultsToState(toolResults);
856
985
  // Apply nextTurnParams
857
986
  await this.applyNextTurnParams(currentToolCalls);
858
- // Make follow-up request
859
- currentResponse = await this.makeFollowupRequest(currentResponse, toolResults);
987
+ currentResponse = await this.makeFollowupRequest(currentResponse, toolResults, turnNumber);
988
+ await this.options.onTurnEnd?.(turnContext, currentResponse);
860
989
  // Save new response to state
861
990
  await this.saveResponseToState(currentResponse);
862
991
  currentRound++;
@@ -902,63 +1031,56 @@ export class ModelResult {
902
1031
  return this.finalResponse;
903
1032
  }
904
1033
  /**
905
- * Stream all response events as they arrive.
1034
+ * Stream all response events as they arrive across all turns.
906
1035
  * Multiple consumers can iterate over this stream concurrently.
907
- * Preliminary tool results and tool results are streamed in REAL-TIME as generator tools yield.
1036
+ * Includes API events, tool events, and turn.start/turn.end delimiters.
908
1037
  */
909
1038
  getFullResponsesStream() {
910
1039
  return async function* () {
911
1040
  await this.initStream();
912
- if (!this.reusableStream) {
1041
+ if (!this.reusableStream && !this.finalResponse) {
913
1042
  throw new Error('Stream not initialized');
914
1043
  }
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
1044
+ if (!this.options.tools?.length) {
1045
+ if (this.reusableStream) {
1046
+ const consumer = this.reusableStream.createConsumer();
1047
+ for await (const event of consumer) {
1048
+ yield event;
1049
+ }
1050
+ }
1051
+ return;
1052
+ }
1053
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
924
1054
  for await (const event of consumer) {
925
1055
  yield event;
926
1056
  }
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
1057
  await executionPromise;
949
1058
  }.call(this);
950
1059
  }
951
1060
  /**
952
- * Stream only text deltas as they arrive.
953
- * This filters the full event stream to only yield text content.
1061
+ * Stream only text deltas as they arrive from all turns.
1062
+ * This filters the full event stream to only yield text content,
1063
+ * including text from follow-up responses in multi-turn tool loops.
954
1064
  */
955
1065
  getTextStream() {
956
1066
  return async function* () {
957
1067
  await this.initStream();
958
- if (!this.reusableStream) {
1068
+ if (!this.reusableStream && !this.finalResponse) {
959
1069
  throw new Error('Stream not initialized');
960
1070
  }
961
- yield* extractTextDeltas(this.reusableStream);
1071
+ if (!this.options.tools?.length) {
1072
+ if (this.reusableStream) {
1073
+ yield* extractTextDeltas(this.reusableStream);
1074
+ }
1075
+ return;
1076
+ }
1077
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1078
+ for await (const event of consumer) {
1079
+ if (isOutputTextDeltaEvent(event)) {
1080
+ yield event.delta;
1081
+ }
1082
+ }
1083
+ await executionPromise;
962
1084
  }.call(this);
963
1085
  }
964
1086
  /**
@@ -978,11 +1100,13 @@ export class ModelResult {
978
1100
  getItemsStream() {
979
1101
  return async function* () {
980
1102
  await this.initStream();
981
- if (!this.reusableStream) {
1103
+ if (!this.reusableStream && !this.finalResponse) {
982
1104
  throw new Error('Stream not initialized');
983
1105
  }
984
1106
  // Stream all items from the API response cumulatively
985
- yield* buildItemsStream(this.reusableStream);
1107
+ if (this.reusableStream) {
1108
+ yield* buildItemsStream(this.reusableStream);
1109
+ }
986
1110
  // Execute tools if needed
987
1111
  await this.executeToolsIfNeeded();
988
1112
  // Yield function calls and outputs for each tool round
@@ -1028,11 +1152,13 @@ export class ModelResult {
1028
1152
  getNewMessagesStream() {
1029
1153
  return async function* () {
1030
1154
  await this.initStream();
1031
- if (!this.reusableStream) {
1155
+ if (!this.reusableStream && !this.finalResponse) {
1032
1156
  throw new Error('Stream not initialized');
1033
1157
  }
1034
1158
  // First yield messages from the stream in responses format
1035
- yield* buildResponsesMessageStream(this.reusableStream);
1159
+ if (this.reusableStream) {
1160
+ yield* buildResponsesMessageStream(this.reusableStream);
1161
+ }
1036
1162
  // Execute tools if needed
1037
1163
  await this.executeToolsIfNeeded();
1038
1164
  // Yield function calls and their outputs for each executed tool
@@ -1059,20 +1185,33 @@ export class ModelResult {
1059
1185
  }.call(this);
1060
1186
  }
1061
1187
  /**
1062
- * Stream only reasoning deltas as they arrive.
1063
- * This filters the full event stream to only yield reasoning content.
1188
+ * Stream only reasoning deltas as they arrive from all turns.
1189
+ * This filters the full event stream to only yield reasoning content,
1190
+ * including reasoning from follow-up responses in multi-turn tool loops.
1064
1191
  */
1065
1192
  getReasoningStream() {
1066
1193
  return async function* () {
1067
1194
  await this.initStream();
1068
- if (!this.reusableStream) {
1195
+ if (!this.reusableStream && !this.finalResponse) {
1069
1196
  throw new Error('Stream not initialized');
1070
1197
  }
1071
- yield* extractReasoningDeltas(this.reusableStream);
1198
+ if (!this.options.tools?.length) {
1199
+ if (this.reusableStream) {
1200
+ yield* extractReasoningDeltas(this.reusableStream);
1201
+ }
1202
+ return;
1203
+ }
1204
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1205
+ for await (const event of consumer) {
1206
+ if (isReasoningDeltaEvent(event)) {
1207
+ yield event.delta;
1208
+ }
1209
+ }
1210
+ await executionPromise;
1072
1211
  }.call(this);
1073
1212
  }
1074
1213
  /**
1075
- * Stream tool call argument deltas and preliminary results.
1214
+ * Stream tool call argument deltas and preliminary results from all turns.
1076
1215
  * Preliminary results are streamed in REAL-TIME as generator tools yield.
1077
1216
  * - Tool call argument deltas as { type: "delta", content: string }
1078
1217
  * - Preliminary results as { type: "preliminary_result", toolCallId, result }
@@ -1080,30 +1219,31 @@ export class ModelResult {
1080
1219
  getToolStream() {
1081
1220
  return async function* () {
1082
1221
  await this.initStream();
1083
- if (!this.reusableStream) {
1222
+ if (!this.reusableStream && !this.finalResponse) {
1084
1223
  throw new Error('Stream not initialized');
1085
1224
  }
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
- };
1225
+ if (!this.options.tools?.length) {
1226
+ if (this.reusableStream) {
1227
+ for await (const delta of extractToolDeltas(this.reusableStream)) {
1228
+ yield { type: 'delta', content: delta };
1229
+ }
1230
+ }
1231
+ return;
1099
1232
  }
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;
1233
+ const { consumer, executionPromise } = this.startTurnBroadcasterExecution();
1234
+ for await (const event of consumer) {
1235
+ if (event.type === 'response.function_call_arguments.delta') {
1236
+ yield { type: 'delta', content: event.delta };
1237
+ continue;
1238
+ }
1239
+ if (event.type === 'tool.preliminary_result') {
1240
+ yield {
1241
+ type: 'preliminary_result',
1242
+ toolCallId: event.toolCallId,
1243
+ result: event.result,
1244
+ };
1104
1245
  }
1105
1246
  }
1106
- // Ensure execution completed (handles errors)
1107
1247
  await executionPromise;
1108
1248
  }.call(this);
1109
1249
  }
@@ -1132,12 +1272,76 @@ export class ModelResult {
1132
1272
  getToolCallsStream() {
1133
1273
  return async function* () {
1134
1274
  await this.initStream();
1135
- if (!this.reusableStream) {
1275
+ if (!this.reusableStream && !this.finalResponse) {
1136
1276
  throw new Error('Stream not initialized');
1137
1277
  }
1138
- yield* buildToolCallStream(this.reusableStream);
1278
+ if (this.reusableStream) {
1279
+ yield* buildToolCallStream(this.reusableStream);
1280
+ }
1139
1281
  }.call(this);
1140
1282
  }
1283
+ /**
1284
+ * Returns an async iterable that emits a full context snapshot every time
1285
+ * any tool calls ctx.update(). Can be consumed concurrently with getText(),
1286
+ * getToolStream(), etc.
1287
+ *
1288
+ * @example
1289
+ * ```typescript
1290
+ * for await (const snapshot of result.getContextUpdates()) {
1291
+ * console.log('Context changed:', snapshot);
1292
+ * }
1293
+ * ```
1294
+ */
1295
+ async *getContextUpdates() {
1296
+ // Ensure stream is initialized (which creates the context store)
1297
+ await this.initStream();
1298
+ if (!this.contextStore) {
1299
+ return;
1300
+ }
1301
+ const store = this.contextStore;
1302
+ const queue = [];
1303
+ let resolve = null;
1304
+ let done = false;
1305
+ const unsubscribe = store.subscribe((snapshot) => {
1306
+ queue.push(snapshot);
1307
+ if (resolve) {
1308
+ resolve();
1309
+ resolve = null;
1310
+ }
1311
+ });
1312
+ // Signal completion when tool execution finishes
1313
+ this.executeToolsIfNeeded().then(() => {
1314
+ done = true;
1315
+ if (resolve) {
1316
+ resolve();
1317
+ resolve = null;
1318
+ }
1319
+ }, () => {
1320
+ done = true;
1321
+ if (resolve) {
1322
+ resolve();
1323
+ resolve = null;
1324
+ }
1325
+ });
1326
+ try {
1327
+ while (!done) {
1328
+ if (queue.length > 0) {
1329
+ yield queue.shift();
1330
+ }
1331
+ else {
1332
+ // Wait for next update or completion
1333
+ await new Promise((r) => { resolve = r; });
1334
+ }
1335
+ }
1336
+ // Drain any remaining queued snapshots
1337
+ while (queue.length > 0) {
1338
+ yield queue.shift();
1339
+ }
1340
+ }
1341
+ finally {
1342
+ unsubscribe();
1343
+ }
1344
+ }
1141
1345
  /**
1142
1346
  * Cancel the underlying stream and all consumers
1143
1347
  */