@prometheus-ai/ai 0.5.4 → 0.5.8

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 (377) hide show
  1. package/dist/types/auth-broker/remote-store.d.ts +2 -1
  2. package/dist/types/auth-broker/wire-schemas.d.ts +4 -1
  3. package/dist/types/auth-gateway/server.d.ts +19 -0
  4. package/dist/types/auth-gateway/types.d.ts +9 -3
  5. package/dist/types/auth-retry.d.ts +119 -0
  6. package/dist/types/auth-storage.d.ts +217 -8
  7. package/dist/types/errors.d.ts +24 -0
  8. package/dist/types/index.d.ts +5 -9
  9. package/dist/types/provider-details.d.ts +1 -1
  10. package/dist/types/providers/amazon-bedrock.d.ts +12 -6
  11. package/dist/types/providers/anthropic-client.d.ts +10 -3
  12. package/dist/types/providers/anthropic-messages-server-schema.d.ts +2 -2
  13. package/dist/types/providers/anthropic-messages-server.d.ts +3 -3
  14. package/dist/types/providers/anthropic-wire.d.ts +3 -3
  15. package/dist/types/providers/anthropic.d.ts +41 -34
  16. package/dist/types/providers/aws-credentials.d.ts +8 -0
  17. package/dist/types/providers/azure-openai-responses.d.ts +1 -0
  18. package/dist/types/providers/google-gemini-cli.d.ts +22 -1
  19. package/dist/types/providers/google-shared.d.ts +22 -0
  20. package/dist/types/providers/google-types.d.ts +13 -1
  21. package/dist/types/providers/mock.d.ts +8 -3
  22. package/dist/types/providers/ollama.d.ts +6 -0
  23. package/dist/types/providers/openai-chat-server-schema.d.ts +6 -3
  24. package/dist/types/providers/openai-chat-server.d.ts +3 -3
  25. package/dist/types/providers/openai-chat-wire.d.ts +644 -0
  26. package/dist/types/providers/openai-codex/request-transformer.d.ts +8 -0
  27. package/dist/types/providers/openai-codex/response-handler.d.ts +9 -0
  28. package/dist/types/providers/openai-codex-responses.d.ts +31 -2
  29. package/dist/types/providers/openai-completions-compat.d.ts +2 -25
  30. package/dist/types/providers/openai-completions.d.ts +2 -10
  31. package/dist/types/providers/openai-responses-server-schema.d.ts +4 -4
  32. package/dist/types/providers/openai-responses-server.d.ts +2 -2
  33. package/dist/types/providers/openai-responses-shared.d.ts +49 -9
  34. package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
  35. package/dist/types/providers/openai-responses.d.ts +13 -4
  36. package/dist/types/providers/prometheus-native-client.d.ts +9 -0
  37. package/dist/types/providers/prometheus-native-server.d.ts +4 -3
  38. package/dist/types/providers/transform-messages.d.ts +1 -2
  39. package/dist/types/rate-limit-utils.d.ts +3 -2
  40. package/dist/types/registry/aimlapi.d.ts +4 -0
  41. package/dist/types/registry/alibaba-coding-plan.d.ts +7 -0
  42. package/dist/types/registry/amazon-bedrock.d.ts +5 -0
  43. package/dist/types/registry/anthropic.d.ts +10 -0
  44. package/dist/types/{utils/oauth → registry}/api-key-login.d.ts +8 -2
  45. package/dist/types/{utils/oauth → registry}/api-key-validation.d.ts +15 -0
  46. package/dist/types/registry/cerebras.d.ts +7 -0
  47. package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
  48. package/dist/types/registry/cursor.d.ts +7 -0
  49. package/dist/types/registry/deepseek.d.ts +8 -0
  50. package/dist/types/registry/derived.d.ts +5 -0
  51. package/dist/types/registry/firepass.d.ts +16 -0
  52. package/dist/types/registry/fireworks.d.ts +7 -0
  53. package/dist/types/registry/github-copilot.d.ts +7 -0
  54. package/dist/types/registry/gitlab-duo.d.ts +9 -0
  55. package/dist/types/registry/google-antigravity.d.ts +9 -0
  56. package/dist/types/registry/google-gemini-cli.d.ts +9 -0
  57. package/dist/types/registry/google-vertex.d.ts +5 -0
  58. package/dist/types/registry/google.d.ts +4 -0
  59. package/dist/types/registry/groq.d.ts +4 -0
  60. package/dist/types/registry/huggingface.d.ts +7 -0
  61. package/dist/types/registry/index.d.ts +4 -0
  62. package/dist/types/registry/kagi.d.ts +14 -0
  63. package/dist/types/registry/kilo.d.ts +7 -0
  64. package/dist/types/registry/kimi-code.d.ts +7 -0
  65. package/dist/types/registry/litellm.d.ts +13 -0
  66. package/dist/types/registry/lm-studio.d.ts +8 -0
  67. package/dist/types/registry/minimax-code-cn.d.ts +6 -0
  68. package/dist/types/registry/minimax-code.d.ts +6 -0
  69. package/dist/types/registry/minimax.d.ts +4 -0
  70. package/dist/types/registry/mistral.d.ts +4 -0
  71. package/dist/types/registry/moonshot.d.ts +7 -0
  72. package/dist/types/registry/nanogpt.d.ts +7 -0
  73. package/dist/types/registry/nvidia.d.ts +7 -0
  74. package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  75. package/dist/types/{utils → registry}/oauth/anthropic.d.ts +2 -1
  76. package/dist/types/{utils → registry}/oauth/github-copilot.d.ts +15 -23
  77. package/dist/types/{utils → registry}/oauth/index.d.ts +1 -0
  78. package/dist/types/{utils → registry}/oauth/minimax-code.d.ts +5 -5
  79. package/dist/types/{utils → registry}/oauth/types.d.ts +6 -1
  80. package/dist/types/{utils → registry}/oauth/xai-oauth.d.ts +2 -1
  81. package/dist/types/registry/ollama-cloud.d.ts +7 -0
  82. package/dist/types/registry/ollama.d.ts +12 -0
  83. package/dist/types/registry/openai-codex-device.d.ts +8 -0
  84. package/dist/types/registry/openai-codex.d.ts +9 -0
  85. package/dist/types/registry/openai.d.ts +4 -0
  86. package/dist/types/registry/opencode-go.d.ts +6 -0
  87. package/dist/types/registry/opencode-zen.d.ts +6 -0
  88. package/dist/types/registry/openrouter.d.ts +13 -0
  89. package/dist/types/registry/parallel.d.ts +14 -0
  90. package/dist/types/registry/perplexity.d.ts +7 -0
  91. package/dist/types/registry/qianfan.d.ts +7 -0
  92. package/dist/types/registry/qwen-portal.d.ts +7 -0
  93. package/dist/types/registry/registry.d.ts +272 -0
  94. package/dist/types/registry/synthetic.d.ts +6 -0
  95. package/dist/types/registry/tavily.d.ts +14 -0
  96. package/dist/types/registry/together.d.ts +6 -0
  97. package/dist/types/registry/types.d.ts +51 -0
  98. package/dist/types/registry/venice.d.ts +13 -0
  99. package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
  100. package/dist/types/registry/vllm.d.ts +7 -0
  101. package/dist/types/registry/wafer-pass.d.ts +6 -0
  102. package/dist/types/registry/wafer-serverless.d.ts +6 -0
  103. package/dist/types/registry/xai-oauth.d.ts +7 -0
  104. package/dist/types/registry/xai.d.ts +4 -0
  105. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
  106. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
  107. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
  108. package/dist/types/registry/xiaomi.d.ts +6 -0
  109. package/dist/types/registry/zai.d.ts +7 -0
  110. package/dist/types/registry/zenmux.d.ts +7 -0
  111. package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
  112. package/dist/types/stream.d.ts +9 -1
  113. package/dist/types/types.d.ts +56 -295
  114. package/dist/types/usage/google-antigravity.d.ts +15 -1
  115. package/dist/types/usage/openai-codex-reset.d.ts +79 -0
  116. package/dist/types/usage/openai-codex.d.ts +1 -0
  117. package/dist/types/usage.d.ts +77 -4
  118. package/dist/types/utils/abort.d.ts +6 -0
  119. package/dist/types/utils/event-stream.d.ts +2 -0
  120. package/dist/types/utils/http-inspector.d.ts +0 -1
  121. package/dist/types/utils/idle-iterator.d.ts +35 -0
  122. package/dist/types/utils/openai-http.d.ts +58 -0
  123. package/dist/types/utils/request-debug.d.ts +3 -0
  124. package/dist/types/utils/retry-after.d.ts +1 -0
  125. package/dist/types/utils/schema/fields.d.ts +5 -0
  126. package/dist/types/utils/schema/json-schema-validator.d.ts +8 -0
  127. package/dist/types/utils/schema/stamps.d.ts +7 -15
  128. package/dist/types/utils/sse-debug.d.ts +0 -5
  129. package/dist/types/utils/stream-markup-healing.d.ts +2 -0
  130. package/dist/types/utils.d.ts +1 -5
  131. package/package.json +17 -29
  132. package/src/auth-broker/remote-store.ts +10 -1
  133. package/src/auth-broker/snapshot-cache.ts +1 -1
  134. package/src/auth-broker/wire-schemas.ts +1 -1
  135. package/src/auth-gateway/http.ts +1 -1
  136. package/src/auth-gateway/server.ts +95 -30
  137. package/src/auth-gateway/types.ts +10 -2
  138. package/src/auth-retry.ts +238 -0
  139. package/src/auth-storage.ts +935 -430
  140. package/src/errors.ts +32 -0
  141. package/src/index.ts +9 -14
  142. package/src/provider-details.ts +1 -1
  143. package/src/providers/__tests__/google-auth.test.ts +144 -0
  144. package/src/providers/amazon-bedrock.ts +70 -40
  145. package/src/providers/anthropic-client.ts +15 -13
  146. package/src/providers/anthropic-messages-server-schema.ts +17 -7
  147. package/src/providers/anthropic-messages-server.ts +88 -20
  148. package/src/providers/anthropic-wire.ts +4 -3
  149. package/src/providers/anthropic.ts +1234 -621
  150. package/src/providers/aws-credentials.ts +47 -5
  151. package/src/providers/aws-eventstream.ts +5 -0
  152. package/src/providers/azure-openai-responses.ts +117 -67
  153. package/src/providers/cursor.ts +30 -30
  154. package/src/providers/github-copilot-headers.ts +1 -1
  155. package/src/providers/gitlab-duo.ts +36 -29
  156. package/src/providers/google-auth.ts +71 -8
  157. package/src/providers/google-gemini-cli.ts +118 -22
  158. package/src/providers/google-shared.ts +163 -43
  159. package/src/providers/google-types.ts +10 -1
  160. package/src/providers/kimi.ts +1 -1
  161. package/src/providers/mock.ts +11 -3
  162. package/src/providers/ollama.ts +64 -7
  163. package/src/providers/openai-anthropic-shim.ts +17 -8
  164. package/src/providers/openai-chat-server-schema.ts +9 -3
  165. package/src/providers/openai-chat-server.ts +82 -16
  166. package/src/providers/openai-chat-wire.ts +847 -0
  167. package/src/providers/openai-codex/request-transformer.ts +129 -34
  168. package/src/providers/openai-codex/response-handler.ts +22 -1
  169. package/src/providers/openai-codex-responses.ts +699 -247
  170. package/src/providers/openai-completions-compat.ts +8 -308
  171. package/src/providers/openai-completions.ts +416 -267
  172. package/src/providers/openai-responses-server-schema.ts +15 -9
  173. package/src/providers/openai-responses-server.ts +162 -114
  174. package/src/providers/openai-responses-shared.ts +320 -82
  175. package/src/providers/openai-responses-wire.ts +6391 -0
  176. package/src/providers/openai-responses.ts +382 -176
  177. package/src/providers/prometheus-native-client.ts +27 -11
  178. package/src/providers/prometheus-native-server.ts +44 -17
  179. package/src/providers/transform-messages.ts +311 -120
  180. package/src/providers/vision-guard.ts +5 -3
  181. package/src/rate-limit-utils.ts +13 -3
  182. package/src/registry/aimlapi.ts +6 -0
  183. package/src/{utils/oauth → registry}/alibaba-coding-plan.ts +8 -18
  184. package/src/registry/amazon-bedrock.ts +22 -0
  185. package/src/registry/anthropic.ts +26 -0
  186. package/src/{utils/oauth → registry}/api-key-login.ts +25 -3
  187. package/src/{utils/oauth → registry}/api-key-validation.ts +62 -2
  188. package/src/{utils/oauth → registry}/cerebras.ts +8 -1
  189. package/src/{utils/oauth → registry}/cloudflare-ai-gateway.ts +8 -12
  190. package/src/registry/cursor.ts +20 -0
  191. package/src/{utils/oauth → registry}/deepseek.ts +9 -17
  192. package/src/registry/derived.ts +9 -0
  193. package/src/{utils/oauth → registry}/firepass.ts +10 -2
  194. package/src/{utils/oauth → registry}/fireworks.ts +8 -1
  195. package/src/registry/github-copilot.ts +22 -0
  196. package/src/registry/gitlab-duo.ts +19 -0
  197. package/src/registry/google-antigravity.ts +21 -0
  198. package/src/registry/google-gemini-cli.ts +21 -0
  199. package/src/registry/google-vertex.ts +38 -0
  200. package/src/registry/google.ts +6 -0
  201. package/src/registry/groq.ts +6 -0
  202. package/src/{utils/oauth → registry}/huggingface.ts +8 -19
  203. package/src/registry/index.ts +4 -0
  204. package/src/{utils/oauth → registry}/kagi.ts +9 -11
  205. package/src/{utils/oauth → registry}/kilo.ts +11 -6
  206. package/src/registry/kimi-code.ts +17 -0
  207. package/src/{utils/oauth → registry}/litellm.ts +8 -12
  208. package/src/{utils/oauth → registry}/lm-studio.ts +9 -17
  209. package/src/registry/minimax-code-cn.ts +12 -0
  210. package/src/registry/minimax-code.ts +12 -0
  211. package/src/registry/minimax.ts +6 -0
  212. package/src/registry/mistral.ts +6 -0
  213. package/src/{utils/oauth → registry}/moonshot.ts +8 -9
  214. package/src/{utils/oauth → registry}/nanogpt.ts +8 -1
  215. package/src/{utils/oauth → registry}/nvidia.ts +8 -18
  216. package/src/{utils → registry}/oauth/__tests__/xai-oauth.test.ts +4 -7
  217. package/src/{utils → registry}/oauth/anthropic.ts +38 -17
  218. package/src/{utils → registry}/oauth/github-copilot.ts +79 -115
  219. package/src/registry/oauth/gitlab-duo.ts +198 -0
  220. package/src/{utils → registry}/oauth/google-antigravity.ts +1 -4
  221. package/src/{utils → registry}/oauth/google-gemini-cli.ts +1 -4
  222. package/src/registry/oauth/index.ts +164 -0
  223. package/src/{utils → registry}/oauth/minimax-code.ts +16 -14
  224. package/src/{utils → registry}/oauth/types.ts +7 -51
  225. package/src/{utils → registry}/oauth/wafer.ts +1 -1
  226. package/src/{utils → registry}/oauth/xai-oauth.ts +16 -8
  227. package/src/{utils → registry}/oauth/xiaomi.ts +9 -4
  228. package/src/{utils/oauth → registry}/ollama-cloud.ts +8 -1
  229. package/src/{utils/oauth → registry}/ollama.ts +8 -13
  230. package/src/registry/openai-codex-device.ts +18 -0
  231. package/src/registry/openai-codex.ts +19 -0
  232. package/src/registry/openai.ts +6 -0
  233. package/src/registry/opencode-go.ts +12 -0
  234. package/src/registry/opencode-zen.ts +12 -0
  235. package/src/{utils/oauth → registry}/openrouter.ts +10 -2
  236. package/src/{utils/oauth → registry}/parallel.ts +9 -11
  237. package/src/registry/perplexity.ts +13 -0
  238. package/src/{utils/oauth → registry}/qianfan.ts +8 -17
  239. package/src/{utils/oauth → registry}/qwen-portal.ts +8 -19
  240. package/src/registry/registry.ts +149 -0
  241. package/src/{utils/oauth → registry}/synthetic.ts +7 -1
  242. package/src/{utils/oauth → registry}/tavily.ts +10 -12
  243. package/src/{utils/oauth → registry}/together.ts +7 -1
  244. package/src/registry/types.ts +56 -0
  245. package/src/{utils/oauth → registry}/venice.ts +8 -12
  246. package/src/{utils/oauth → registry}/vercel-ai-gateway.ts +8 -18
  247. package/src/{utils/oauth → registry}/vllm.ts +9 -16
  248. package/src/registry/wafer-pass.ts +12 -0
  249. package/src/registry/wafer-serverless.ts +12 -0
  250. package/src/registry/xai-oauth.ts +17 -0
  251. package/src/registry/xai.ts +6 -0
  252. package/src/registry/xiaomi-token-plan-ams.ts +12 -0
  253. package/src/registry/xiaomi-token-plan-cn.ts +12 -0
  254. package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
  255. package/src/registry/xiaomi.ts +12 -0
  256. package/src/{utils/oauth → registry}/zai.ts +10 -22
  257. package/src/{utils/oauth → registry}/zenmux.ts +8 -1
  258. package/src/{utils/oauth/zhipu.ts → registry/zhipu-coding-plan.ts} +9 -21
  259. package/src/stream.ts +229 -199
  260. package/src/types.ts +63 -384
  261. package/src/usage/claude.ts +4 -2
  262. package/src/usage/github-copilot.ts +4 -2
  263. package/src/usage/google-antigravity.ts +196 -28
  264. package/src/usage/kimi.ts +1 -1
  265. package/src/usage/minimax-code.ts +5 -6
  266. package/src/usage/openai-codex-reset.ts +174 -0
  267. package/src/usage/openai-codex.ts +19 -2
  268. package/src/usage/zai.ts +2 -1
  269. package/src/usage.ts +93 -4
  270. package/src/utils/abort.ts +14 -0
  271. package/src/utils/event-stream.ts +17 -0
  272. package/src/utils/http-inspector.ts +4 -12
  273. package/src/utils/idle-iterator.ts +250 -79
  274. package/src/utils/openai-http.ts +157 -0
  275. package/src/utils/request-debug.ts +67 -19
  276. package/src/utils/retry-after.ts +1 -1
  277. package/src/utils/retry.ts +23 -2
  278. package/src/utils/schema/CONSTRAINTS.md +4 -2
  279. package/src/utils/schema/fields.ts +16 -0
  280. package/src/utils/schema/json-schema-validator.ts +19 -1
  281. package/src/utils/schema/normalize.ts +80 -8
  282. package/src/utils/schema/stamps.ts +22 -10
  283. package/src/utils/schema/wire.ts +2 -2
  284. package/src/utils/sse-debug.ts +0 -271
  285. package/src/utils/stream-markup-healing.ts +50 -8
  286. package/src/utils/validation.ts +49 -13
  287. package/src/utils.ts +2 -26
  288. package/dist/types/model-cache.d.ts +0 -17
  289. package/dist/types/model-manager.d.ts +0 -64
  290. package/dist/types/model-thinking.d.ts +0 -100
  291. package/dist/types/models.d.ts +0 -12
  292. package/dist/types/provider-models/bundled-references.d.ts +0 -4
  293. package/dist/types/provider-models/descriptors.d.ts +0 -50
  294. package/dist/types/provider-models/google.d.ts +0 -24
  295. package/dist/types/provider-models/index.d.ts +0 -5
  296. package/dist/types/provider-models/ollama.d.ts +0 -7
  297. package/dist/types/provider-models/openai-compat.d.ts +0 -323
  298. package/dist/types/provider-models/special.d.ts +0 -16
  299. package/dist/types/utils/discovery/antigravity.d.ts +0 -61
  300. package/dist/types/utils/discovery/codex.d.ts +0 -38
  301. package/dist/types/utils/discovery/cursor.d.ts +0 -23
  302. package/dist/types/utils/discovery/gemini.d.ts +0 -25
  303. package/dist/types/utils/discovery/index.d.ts +0 -4
  304. package/dist/types/utils/discovery/openai-compatible.d.ts +0 -72
  305. package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +0 -18
  306. package/dist/types/utils/oauth/cerebras.d.ts +0 -1
  307. package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +0 -18
  308. package/dist/types/utils/oauth/deepseek.d.ts +0 -10
  309. package/dist/types/utils/oauth/firepass.d.ts +0 -1
  310. package/dist/types/utils/oauth/fireworks.d.ts +0 -1
  311. package/dist/types/utils/oauth/huggingface.d.ts +0 -19
  312. package/dist/types/utils/oauth/kagi.d.ts +0 -17
  313. package/dist/types/utils/oauth/kilo.d.ts +0 -5
  314. package/dist/types/utils/oauth/litellm.d.ts +0 -18
  315. package/dist/types/utils/oauth/lm-studio.d.ts +0 -17
  316. package/dist/types/utils/oauth/moonshot.d.ts +0 -1
  317. package/dist/types/utils/oauth/nanogpt.d.ts +0 -1
  318. package/dist/types/utils/oauth/nvidia.d.ts +0 -18
  319. package/dist/types/utils/oauth/ollama-cloud.d.ts +0 -2
  320. package/dist/types/utils/oauth/ollama.d.ts +0 -18
  321. package/dist/types/utils/oauth/openrouter.d.ts +0 -1
  322. package/dist/types/utils/oauth/parallel.d.ts +0 -17
  323. package/dist/types/utils/oauth/qianfan.d.ts +0 -17
  324. package/dist/types/utils/oauth/qwen-portal.d.ts +0 -19
  325. package/dist/types/utils/oauth/synthetic.d.ts +0 -1
  326. package/dist/types/utils/oauth/tavily.d.ts +0 -17
  327. package/dist/types/utils/oauth/together.d.ts +0 -1
  328. package/dist/types/utils/oauth/venice.d.ts +0 -18
  329. package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +0 -18
  330. package/dist/types/utils/oauth/vllm.d.ts +0 -16
  331. package/dist/types/utils/oauth/zai.d.ts +0 -18
  332. package/dist/types/utils/oauth/zenmux.d.ts +0 -1
  333. package/dist/types/utils/oauth/zhipu.d.ts +0 -18
  334. package/src/model-cache.ts +0 -129
  335. package/src/model-manager.ts +0 -469
  336. package/src/model-thinking.ts +0 -756
  337. package/src/models.json +0 -60287
  338. package/src/models.json.d.ts +0 -9
  339. package/src/models.ts +0 -56
  340. package/src/provider-models/bundled-references.ts +0 -38
  341. package/src/provider-models/descriptors.ts +0 -364
  342. package/src/provider-models/google.ts +0 -88
  343. package/src/provider-models/index.ts +0 -5
  344. package/src/provider-models/ollama.ts +0 -153
  345. package/src/provider-models/openai-compat.ts +0 -2904
  346. package/src/provider-models/special.ts +0 -67
  347. package/src/utils/discovery/antigravity.ts +0 -261
  348. package/src/utils/discovery/codex.ts +0 -371
  349. package/src/utils/discovery/cursor.ts +0 -306
  350. package/src/utils/discovery/gemini.ts +0 -248
  351. package/src/utils/discovery/index.ts +0 -4
  352. package/src/utils/discovery/openai-compatible.ts +0 -224
  353. package/src/utils/oauth/gitlab-duo.ts +0 -123
  354. package/src/utils/oauth/index.ts +0 -502
  355. /package/dist/types/{utils/oauth/__tests__/xai-oauth.test.d.ts → providers/__tests__/google-auth.test.d.ts} +0 -0
  356. /package/dist/types/{utils → registry}/oauth/callback-server.d.ts +0 -0
  357. /package/dist/types/{utils → registry}/oauth/cursor.d.ts +0 -0
  358. /package/dist/types/{utils → registry}/oauth/gitlab-duo.d.ts +0 -0
  359. /package/dist/types/{utils → registry}/oauth/google-antigravity.d.ts +0 -0
  360. /package/dist/types/{utils → registry}/oauth/google-gemini-cli.d.ts +0 -0
  361. /package/dist/types/{utils → registry}/oauth/google-oauth-shared.d.ts +0 -0
  362. /package/dist/types/{utils → registry}/oauth/kimi.d.ts +0 -0
  363. /package/dist/types/{utils → registry}/oauth/openai-codex.d.ts +0 -0
  364. /package/dist/types/{utils → registry}/oauth/opencode.d.ts +0 -0
  365. /package/dist/types/{utils → registry}/oauth/perplexity.d.ts +0 -0
  366. /package/dist/types/{utils → registry}/oauth/pkce.d.ts +0 -0
  367. /package/dist/types/{utils → registry}/oauth/wafer.d.ts +0 -0
  368. /package/dist/types/{utils → registry}/oauth/xiaomi.d.ts +0 -0
  369. /package/src/{utils → registry}/oauth/callback-server.ts +0 -0
  370. /package/src/{utils → registry}/oauth/cursor.ts +0 -0
  371. /package/src/{utils → registry}/oauth/google-oauth-shared.ts +0 -0
  372. /package/src/{utils → registry}/oauth/kimi.ts +0 -0
  373. /package/src/{utils → registry}/oauth/oauth.html +0 -0
  374. /package/src/{utils → registry}/oauth/openai-codex.ts +0 -0
  375. /package/src/{utils → registry}/oauth/opencode.ts +0 -0
  376. /package/src/{utils → registry}/oauth/perplexity.ts +0 -0
  377. /package/src/{utils → registry}/oauth/pkce.ts +0 -0
@@ -7,6 +7,8 @@
7
7
  * Real clients (codex, openai-python, llm-git) routinely send these and a 400
8
8
  * is a worse outcome than dropping them on the floor.
9
9
  */
10
+
11
+ import { z } from "zod/v4";
10
12
  import type {
11
13
  EasyInputMessage,
12
14
  ResponseCreateParams,
@@ -16,8 +18,7 @@ import type {
16
18
  ResponseOutputMessage,
17
19
  ResponseReasoningItem,
18
20
  Tool as ResponsesTool,
19
- } from "openai/resources/responses/responses";
20
- import * as z from "zod/v4";
21
+ } from "./openai-responses-wire";
21
22
 
22
23
  // ─── Input content blocks ───────────────────────────────────────────────────
23
24
 
@@ -97,12 +98,17 @@ const assistantMessageItemSchema = z.object({
97
98
  content: z.union([z.string(), z.array(outputContentBlockSchema)]).optional(),
98
99
  });
99
100
 
100
- const reasoningItemSchema = z.object({
101
- type: z.literal("reasoning"),
102
- id: z.string().optional(),
103
- summary: z.array(summaryTextSchema).optional(),
104
- content: z.array(reasoningTextSchema).optional(),
105
- });
101
+ const reasoningItemSchema = z
102
+ .object({
103
+ type: z.literal("reasoning"),
104
+ id: z.string().optional(),
105
+ summary: z.array(summaryTextSchema).optional(),
106
+ content: z.array(reasoningTextSchema).optional(),
107
+ })
108
+ // Loose: unknown keys like `encrypted_content` must survive the parse —
109
+ // the outbound encoder replays them verbatim (buildReasoningItem spreads
110
+ // the persisted item to preserve encrypted reasoning round-trips).
111
+ .loose();
106
112
 
107
113
  const functionCallItemSchema = z.object({
108
114
  type: z.literal("function_call"),
@@ -234,7 +240,7 @@ export const toolChoiceSchema = z.union([
234
240
  export const reasoningConfigSchema = z.object({
235
241
  effort: z.string().optional(),
236
242
  // `none` maps to hideThinkingSummary; auto/concise/detailed mean "show
237
- // summary". @prometheus-ai/ai has no per-level plumbing for the latter — walker logs
243
+ // summary". Prometheus AI has no per-level plumbing for the latter — walker logs
238
244
  // once and treats them as default.
239
245
  summary: z.enum(["auto", "concise", "detailed", "none"]).optional(),
240
246
  });
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { logger } from "@prometheus-ai/utils";
13
13
  import { resolvePromptCacheKey } from "../auth-gateway/http";
14
- import type { AuthGatewayParsedRequest as ParsedRequest } from "../auth-gateway/types";
14
+ import type { AuthGatewayStreamControl, AuthGatewayParsedRequest as ParsedRequest } from "../auth-gateway/types";
15
15
  import type {
16
16
  AssistantMessage,
17
17
  AssistantMessageEventStream,
@@ -102,9 +102,9 @@ type InputBlockUnion =
102
102
  | { type: "input_file"; file_id?: string; filename?: string; file_data?: string };
103
103
 
104
104
  /**
105
- * Walk an input message's content array and produce @prometheus-ai/ai's `TextContent[]`.
105
+ * Walk an input message's content array and produce Prometheus AI's `TextContent[]`.
106
106
  * `input_image`/`input_file` blocks become bracketed text placeholders since
107
- * @prometheus-ai/ai's `ImageContent` only carries inline base64 data and we have no
107
+ * Prometheus AI's `ImageContent` only carries inline base64 data and we have no
108
108
  * resolver for OpenAI `image_url` / `file_id` references. Logs once per kind.
109
109
  */
110
110
  function inputContentParts(blocks: OpenAIResponsesInputContent[] | string | undefined): string | TextContent[] {
@@ -118,17 +118,20 @@ function inputContentParts(blocks: OpenAIResponsesInputContent[] | string | unde
118
118
  } else if (block.type === "input_image") {
119
119
  if (!warnedImageNotSupported) {
120
120
  warnedImageNotSupported = true;
121
- logger.warn("openai-responses-server: input_image dropped (no canonical bridge for image_url/file_id)", {
122
- hasUrl: typeof block.image_url === "string",
123
- hasFileId: typeof block.file_id === "string",
124
- });
121
+ logger.warn(
122
+ "openai-responses-server: input_image dropped (no Prometheus AI bridge for image_url/file_id)",
123
+ {
124
+ hasUrl: typeof block.image_url === "string",
125
+ hasFileId: typeof block.file_id === "string",
126
+ },
127
+ );
125
128
  }
126
129
  const ref = block.image_url ?? block.file_id ?? "?";
127
130
  parts.push({ type: "text", text: `[image: ${ref}]` });
128
131
  } else if (block.type === "input_file") {
129
132
  if (!warnedFileNotSupported) {
130
133
  warnedFileNotSupported = true;
131
- logger.warn("openai-responses-server: input_file dropped (no canonical bridge for file_id/file_data)", {
134
+ logger.warn("openai-responses-server: input_file dropped (no Prometheus AI bridge for file_id/file_data)", {
132
135
  hasFileId: typeof block.file_id === "string",
133
136
  hasFileData: typeof block.file_data === "string",
134
137
  });
@@ -185,10 +188,10 @@ function mapToolChoice(value: ParsedToolChoice | undefined): ParsedRequest["opti
185
188
  if (value === "auto" || value === "none" || value === "required") return value;
186
189
  if ("type" in value) {
187
190
  // `custom` (codex apply_patch) and `function` both resolve to the same
188
- // @prometheus-ai/ai shape: @prometheus-ai/ai's dispatcher matches `Tool.name` AND `customWireName`,
191
+ // Prometheus AI shape: Prometheus AI's dispatcher matches `Tool.name` AND `customWireName`,
189
192
  // so passing the wire name works for either.
190
193
  if (value.type === "function" || value.type === "custom") return { name: value.name };
191
- // Hosted tools + allowed_tools — we don't surface these to @prometheus-ai/ai; fall
194
+ // Hosted tools + allowed_tools — we don't surface these to Prometheus AI; fall
192
195
  // back to letting the model pick a tool freely.
193
196
  return "auto";
194
197
  }
@@ -360,7 +363,7 @@ export function parseRequest(body: unknown, headers?: Headers): ParsedRequest {
360
363
  if (effectiveType === "custom_tool_call") {
361
364
  const call = item as { id?: string; call_id: string; name: string; input: string };
362
365
  // Custom tools carry a raw input string. We stash it in `arguments.input`
363
- // matching @prometheus-ai/ai's openai-responses-shared convention, and tag the call
366
+ // matching Prometheus AI's openai-responses-shared convention, and tag the call
364
367
  // with `customWireName` so encoders re-emit it as `custom_tool_call`.
365
368
  const toolCall: ToolCall = {
366
369
  type: "toolCall",
@@ -428,7 +431,7 @@ export function parseRequest(body: unknown, headers?: Headers): ParsedRequest {
428
431
  options.reasoning = data.reasoning.effort;
429
432
  }
430
433
  // OpenAI summary: `none` → suppress; `auto`/`concise`/`detailed` → request
431
- // visible summary. @prometheus-ai/ai has no per-level plumbing — log once and let the
434
+ // visible summary. Prometheus AI has no per-level plumbing — log once and let the
432
435
  // provider default kick in.
433
436
  if (data.reasoning?.summary === "none") {
434
437
  options.hideThinkingSummary = true;
@@ -573,6 +576,17 @@ function reasoningItemId(part: ThinkingContent): string {
573
576
  return makeReasoningId();
574
577
  }
575
578
 
579
+ /**
580
+ * Prometheus AI responses providers mint composite `"{call_id}|{item_id}"` tool-call
581
+ * ids ({@link encodeResponsesToolCallId}). Only the call_id half belongs on
582
+ * the wire: third-party clients validate the `call_id` charset
583
+ * (`^[a-zA-Z0-9_-]+$`) or echo it to other backends, and `|` fails both.
584
+ */
585
+ function wireCallId(id: string): string {
586
+ const sep = id.indexOf("|");
587
+ return sep >= 0 ? id.slice(0, sep) : id;
588
+ }
589
+
576
590
  /**
577
591
  * Walk the assistant content array and group consecutive TextContent into a
578
592
  * single message item; each ThinkingContent / ToolCall is its own item.
@@ -609,7 +623,7 @@ function buildOutputItems(message: AssistantMessage): OutputItem[] {
609
623
  out.push({
610
624
  type: "custom_tool_call",
611
625
  id: part.thoughtSignature ?? makeCustomCallId(),
612
- call_id: part.id,
626
+ call_id: wireCallId(part.id),
613
627
  name: part.customWireName,
614
628
  input: rawInput,
615
629
  status: "completed",
@@ -618,7 +632,7 @@ function buildOutputItems(message: AssistantMessage): OutputItem[] {
618
632
  out.push({
619
633
  type: "function_call",
620
634
  id: part.thoughtSignature ?? makeFuncCallId(),
621
- call_id: part.id,
635
+ call_id: wireCallId(part.id),
622
636
  name: part.name,
623
637
  arguments: JSON.stringify(part.arguments ?? {}),
624
638
  status: "completed",
@@ -698,6 +712,7 @@ interface OpenFunctionCall {
698
712
  kind: "function_call";
699
713
  itemId: string;
700
714
  outputIndex: number;
715
+ contentIndex: number;
701
716
  callId: string;
702
717
  name: string;
703
718
  argsText: string;
@@ -713,23 +728,35 @@ function sseEvent(name: string, data: unknown): string {
713
728
  export function encodeStream(
714
729
  events: AssistantMessageEventStream,
715
730
  requestedModelId: string,
731
+ _options?: ParsedRequest["options"],
732
+ control?: AuthGatewayStreamControl,
716
733
  ): ReadableStream<Uint8Array> {
717
734
  const encoder = new TextEncoder();
718
735
  const responseId = makeRespId();
719
736
  let sequenceNumber = 0;
737
+ let cancelled = control?.signal?.aborted === true;
738
+ const markCancelled = () => {
739
+ cancelled = true;
740
+ };
741
+ control?.signal?.addEventListener("abort", markCancelled, { once: true });
720
742
  const seq = () => sequenceNumber++;
721
743
 
722
744
  return new ReadableStream<Uint8Array>({
723
745
  async start(controller) {
724
746
  const emit = (name: string, data: Record<string, unknown>) => {
725
- controller.enqueue(encoder.encode(sseEvent(name, { type: name, sequence_number: seq(), ...data })));
747
+ if (!cancelled)
748
+ controller.enqueue(encoder.encode(sseEvent(name, { type: name, sequence_number: seq(), ...data })));
749
+ };
750
+ const emitDone = () => {
751
+ if (!cancelled) controller.enqueue(encoder.encode("data: [DONE]\n\n"));
726
752
  };
727
- const emitDone = () => controller.enqueue(encoder.encode("data: [DONE]\n\n"));
728
753
 
729
754
  let createdAt = Math.floor(Date.now() / 1000);
730
755
  let outputIndex = 0;
731
756
  const state: { open: OpenItem | null } = { open: null };
757
+ const openFunctionCalls = new Map<number, OpenFunctionCall>();
732
758
  const finishedItems: OutputItem[] = [];
759
+ const allocateOutputIndex = (): number => outputIndex++;
733
760
 
734
761
  const responseSnapshot = (status: ResponseStatus, output: OutputItem[] | []) => ({
735
762
  id: responseId,
@@ -742,6 +769,7 @@ export function encodeStream(
742
769
  });
743
770
 
744
771
  const openMessage = (): OpenMessage => {
772
+ const itemOutputIndex = allocateOutputIndex();
745
773
  const itemId = makeMsgId();
746
774
  const item = {
747
775
  type: "message" as const,
@@ -750,11 +778,11 @@ export function encodeStream(
750
778
  role: "assistant" as const,
751
779
  content: [] as Array<{ type: "output_text"; text: string; annotations: never[] }>,
752
780
  };
753
- emit("response.output_item.added", { output_index: outputIndex, item });
781
+ emit("response.output_item.added", { output_index: itemOutputIndex, item });
754
782
  const next: OpenMessage = {
755
783
  kind: "message",
756
784
  itemId,
757
- outputIndex,
785
+ outputIndex: itemOutputIndex,
758
786
  contentIndex: 0,
759
787
  currentPartText: "",
760
788
  content: [],
@@ -764,6 +792,7 @@ export function encodeStream(
764
792
  };
765
793
 
766
794
  const openReasoning = (partial: AssistantMessage, contentIndex: number): OpenReasoning => {
795
+ const itemOutputIndex = allocateOutputIndex();
767
796
  const part = partial.content[contentIndex];
768
797
  const itemId = part && part.type === "thinking" ? reasoningItemId(part) : makeReasoningId();
769
798
  const item = {
@@ -771,22 +800,23 @@ export function encodeStream(
771
800
  id: itemId,
772
801
  summary: [] as Array<{ type: "summary_text"; text: string }>,
773
802
  };
774
- emit("response.output_item.added", { output_index: outputIndex, item });
803
+ emit("response.output_item.added", { output_index: itemOutputIndex, item });
775
804
  // Open the summary part. Real OpenAI streams summary text in the
776
- // canonical `reasoning_summary_*` lifecycle; @prometheus-ai/ai's own decoder
805
+ // canonical `reasoning_summary_*` lifecycle; Prometheus AI's own decoder
777
806
  // reads `summary[].text` from the eventual `output_item.done`.
778
807
  emit("response.reasoning_summary_part.added", {
779
808
  item_id: itemId,
780
- output_index: outputIndex,
809
+ output_index: itemOutputIndex,
781
810
  summary_index: 0,
782
811
  part: { type: "summary_text", text: "" },
783
812
  });
784
- const next: OpenReasoning = { kind: "reasoning", itemId, outputIndex, reasoningText: "" };
813
+ const next: OpenReasoning = { kind: "reasoning", itemId, outputIndex: itemOutputIndex, reasoningText: "" };
785
814
  state.open = next;
786
815
  return next;
787
816
  };
788
817
 
789
818
  const openToolCall = (partial: AssistantMessage, contentIndex: number): OpenFunctionCall => {
819
+ const itemOutputIndex = allocateOutputIndex();
790
820
  const part = partial.content[contentIndex];
791
821
  const tc = part && part.type === "toolCall" ? part : undefined;
792
822
  const customWireName: string | undefined =
@@ -795,7 +825,7 @@ export function encodeStream(
795
825
  : undefined;
796
826
  const isCustom = customWireName !== undefined;
797
827
  const itemId = tc?.thoughtSignature ?? (isCustom ? makeCustomCallId() : makeFuncCallId());
798
- const callId = tc?.id ?? "";
828
+ const callId = wireCallId(tc?.id ?? "");
799
829
  const name = customWireName ?? tc?.name ?? "";
800
830
  const item = isCustom
801
831
  ? {
@@ -814,20 +844,65 @@ export function encodeStream(
814
844
  arguments: "",
815
845
  status: "in_progress",
816
846
  };
817
- emit("response.output_item.added", { output_index: outputIndex, item });
847
+ emit("response.output_item.added", { output_index: itemOutputIndex, item });
818
848
  const next: OpenFunctionCall = {
819
849
  kind: "function_call",
820
850
  itemId,
821
- outputIndex,
851
+ outputIndex: itemOutputIndex,
852
+ contentIndex,
822
853
  callId,
823
854
  name,
824
855
  argsText: "",
825
856
  ...(isCustom ? { customWireName } : {}),
826
857
  };
858
+ openFunctionCalls.set(contentIndex, next);
827
859
  state.open = next;
828
860
  return next;
829
861
  };
830
862
 
863
+ const closeFunctionCall = (call: OpenFunctionCall): void => {
864
+ const text = call.argsText ?? "";
865
+ if (call.customWireName) {
866
+ const item = {
867
+ type: "custom_tool_call",
868
+ id: call.itemId,
869
+ call_id: call.callId ?? "",
870
+ name: call.customWireName,
871
+ input: text,
872
+ status: "completed",
873
+ };
874
+ emit("response.output_item.done", { output_index: call.outputIndex, item });
875
+ finishedItems.push({
876
+ type: "custom_tool_call",
877
+ id: call.itemId,
878
+ call_id: call.callId ?? "",
879
+ name: call.customWireName,
880
+ input: text,
881
+ status: "completed",
882
+ });
883
+ } else {
884
+ const item = {
885
+ type: "function_call",
886
+ id: call.itemId,
887
+ call_id: call.callId ?? "",
888
+ name: call.name ?? "",
889
+ arguments: text,
890
+ status: "completed",
891
+ };
892
+ emit("response.output_item.done", { output_index: call.outputIndex, item });
893
+ finishedItems.push({
894
+ type: "function_call",
895
+ id: call.itemId,
896
+ call_id: call.callId ?? "",
897
+ name: call.name ?? "",
898
+ arguments: text,
899
+ status: "completed",
900
+ });
901
+ }
902
+ openFunctionCalls.delete(call.contentIndex);
903
+ if (state.open === call) state.open = null;
904
+ };
905
+
831
906
  const closeOpen = () => {
832
907
  if (!state.open) return;
833
908
  if (state.open.kind === "message") {
@@ -846,6 +921,7 @@ export function encodeStream(
846
921
  status: "completed",
847
922
  content: state.open.content,
848
923
  });
924
+ state.open = null;
849
925
  } else if (state.open.kind === "reasoning") {
850
926
  const summary = [{ type: "summary_text" as const, text: state.open.reasoningText ?? "" }];
851
927
  const item = {
@@ -859,79 +935,40 @@ export function encodeStream(
859
935
  id: state.open.itemId,
860
936
  summary,
861
937
  });
938
+ state.open = null;
862
939
  } else {
863
- const text = state.open.argsText ?? "";
864
- if (state.open.customWireName) {
865
- const item = {
866
- type: "custom_tool_call",
867
- id: state.open.itemId,
868
- call_id: state.open.callId ?? "",
869
- name: state.open.customWireName,
870
- input: text,
871
- status: "completed",
872
- };
873
- emit("response.output_item.done", { output_index: state.open.outputIndex, item });
874
- finishedItems.push({
875
- type: "custom_tool_call",
876
- id: state.open.itemId,
877
- call_id: state.open.callId ?? "",
878
- name: state.open.customWireName,
879
- input: text,
880
- status: "completed",
881
- });
882
- } else {
883
- const item = {
884
- type: "function_call",
885
- id: state.open.itemId,
886
- call_id: state.open.callId ?? "",
887
- name: state.open.name ?? "",
888
- arguments: text,
889
- status: "completed",
890
- };
891
- emit("response.output_item.done", { output_index: state.open.outputIndex, item });
892
- finishedItems.push({
893
- type: "function_call",
894
- id: state.open.itemId,
895
- call_id: state.open.callId ?? "",
896
- name: state.open.name ?? "",
897
- arguments: text,
898
- status: "completed",
899
- });
900
- }
940
+ closeFunctionCall(state.open);
901
941
  }
902
- outputIndex++;
903
- state.open = null;
904
942
  };
905
943
 
906
- try {
907
- let finalMessage: AssistantMessage | null = null;
908
- let failureMessage: AssistantMessage | null = null;
944
+ const closeOpenFunctionCalls = (): void => {
945
+ for (const call of [...openFunctionCalls.values()]) {
946
+ closeFunctionCall(call);
947
+ }
948
+ };
909
949
 
950
+ const functionCallForEvent = (contentIndex: number): OpenFunctionCall | undefined => {
951
+ const byIndex = openFunctionCalls.get(contentIndex);
952
+ if (byIndex) return byIndex;
953
+ return state.open?.kind === "function_call" ? state.open : undefined;
954
+ };
955
+ let finalMessage: AssistantMessage | undefined;
956
+ let failureMessage: AssistantMessage | undefined;
957
+ try {
958
+ if (cancelled) {
959
+ controller.close();
960
+ return;
961
+ }
910
962
  for await (const ev of events) {
963
+ if (cancelled) return;
911
964
  switch (ev.type) {
912
965
  case "start": {
913
966
  createdAt = Math.floor((ev.partial.timestamp || Date.now()) / 1000);
914
967
  // response.created — initial envelope.
915
- controller.enqueue(
916
- encoder.encode(
917
- sseEvent("response.created", {
918
- type: "response.created",
919
- sequence_number: seq(),
920
- response: responseSnapshot("in_progress", []),
921
- }),
922
- ),
923
- );
968
+ emit("response.created", { response: responseSnapshot("in_progress", []) });
924
969
  // response.in_progress — mirrors real OpenAI; some clients gate
925
970
  // on it before reading items.
926
- controller.enqueue(
927
- encoder.encode(
928
- sseEvent("response.in_progress", {
929
- type: "response.in_progress",
930
- sequence_number: seq(),
931
- response: responseSnapshot("in_progress", []),
932
- }),
933
- ),
934
- );
971
+ emit("response.in_progress", { response: responseSnapshot("in_progress", []) });
935
972
  break;
936
973
  }
937
974
  case "text_start": {
@@ -941,7 +978,7 @@ export function encodeStream(
941
978
  cur = state.open;
942
979
  cur.currentPartText = "";
943
980
  } else {
944
- if (state.open) closeOpen();
981
+ if (state.open && state.open.kind !== "function_call") closeOpen();
945
982
  cur = openMessage();
946
983
  }
947
984
  const part = { type: "output_text", text: "", annotations: [] as never[] };
@@ -964,7 +1001,7 @@ export function encodeStream(
964
1001
  delta: ev.delta,
965
1002
  logprobs: [],
966
1003
  });
967
- // TODO: when @prometheus-ai/ai surfaces output_text annotations
1004
+ // TODO: when Prometheus AI surfaces output_text annotations
968
1005
  // (web_search citations, …), emit
969
1006
  // `response.output_text.annotation.added` here.
970
1007
  break;
@@ -992,7 +1029,7 @@ export function encodeStream(
992
1029
  break;
993
1030
  }
994
1031
  case "thinking_start": {
995
- if (state.open) closeOpen();
1032
+ if (state.open && state.open.kind !== "function_call") closeOpen();
996
1033
  openReasoning(ev.partial, ev.contentIndex);
997
1034
  break;
998
1035
  }
@@ -1029,13 +1066,13 @@ export function encodeStream(
1029
1066
  break;
1030
1067
  }
1031
1068
  case "toolcall_start": {
1032
- if (state.open) closeOpen();
1069
+ if (state.open && state.open.kind !== "function_call") closeOpen();
1033
1070
  openToolCall(ev.partial, ev.contentIndex);
1034
1071
  break;
1035
1072
  }
1036
1073
  case "toolcall_delta": {
1037
- if (state.open?.kind !== "function_call") break;
1038
- const cur: OpenFunctionCall = state.open;
1074
+ const cur = functionCallForEvent(ev.contentIndex);
1075
+ if (!cur) break;
1039
1076
  cur.argsText += ev.delta;
1040
1077
  if (cur.customWireName) {
1041
1078
  emit("response.custom_tool_call_input.delta", {
@@ -1053,8 +1090,8 @@ export function encodeStream(
1053
1090
  break;
1054
1091
  }
1055
1092
  case "toolcall_end": {
1056
- if (state.open?.kind !== "function_call") break;
1057
- const cur: OpenFunctionCall = state.open;
1093
+ const cur = functionCallForEvent(ev.contentIndex);
1094
+ if (!cur) break;
1058
1095
  // Promote possibly-late info from the canonical ToolCall.
1059
1096
  const tc = ev.toolCall;
1060
1097
  if (tc.customWireName && !cur.customWireName) cur.customWireName = tc.customWireName;
@@ -1087,7 +1124,7 @@ export function encodeStream(
1087
1124
  name: cur.name,
1088
1125
  });
1089
1126
  }
1090
- closeOpen();
1127
+ closeFunctionCall(cur);
1091
1128
  break;
1092
1129
  }
1093
1130
  case "done": {
@@ -1102,6 +1139,7 @@ export function encodeStream(
1102
1139
  }
1103
1140
 
1104
1141
  if (failureMessage) {
1142
+ closeOpenFunctionCalls();
1105
1143
  if (state.open) closeOpen();
1106
1144
  controller.enqueue(
1107
1145
  encoder.encode(
@@ -1120,6 +1158,7 @@ export function encodeStream(
1120
1158
  return;
1121
1159
  }
1122
1160
 
1161
+ closeOpenFunctionCalls();
1123
1162
  if (state.open) closeOpen();
1124
1163
  const message = finalMessage ?? ((await events.result().catch(() => null)) as AssistantMessage | null);
1125
1164
 
@@ -1158,26 +1197,35 @@ export function encodeStream(
1158
1197
  emitDone();
1159
1198
  controller.close();
1160
1199
  } catch (err) {
1161
- controller.enqueue(
1162
- encoder.encode(
1163
- sseEvent("response.failed", {
1164
- type: "response.failed",
1165
- sequence_number: seq(),
1166
- response: {
1167
- id: responseId,
1168
- object: "response",
1169
- created_at: Math.floor(Date.now() / 1000),
1170
- status: "failed",
1171
- model: requestedModelId,
1172
- output: [],
1173
- error: { message: err instanceof Error ? err.message : String(err) },
1174
- },
1175
- }),
1176
- ),
1177
- );
1178
- emitDone();
1179
- controller.close();
1200
+ if (!cancelled) {
1201
+ controller.enqueue(
1202
+ encoder.encode(
1203
+ sseEvent("response.failed", {
1204
+ type: "response.failed",
1205
+ sequence_number: seq(),
1206
+ response: {
1207
+ id: responseId,
1208
+ object: "response",
1209
+ created_at: Math.floor(Date.now() / 1000),
1210
+ status: "failed",
1211
+ model: requestedModelId,
1212
+ output: [],
1213
+ error: { message: err instanceof Error ? err.message : String(err) },
1214
+ },
1215
+ }),
1216
+ ),
1217
+ );
1218
+ emitDone();
1219
+ controller.close();
1220
+ }
1221
+ } finally {
1222
+ control?.signal?.removeEventListener("abort", markCancelled);
1180
1223
  }
1181
1224
  },
1225
+ cancel(reason) {
1226
+ cancelled = true;
1227
+ control?.signal?.removeEventListener("abort", markCancelled);
1228
+ control?.onCancel?.(reason);
1229
+ },
1182
1230
  });
1183
1231
  }