jeopi-ai 16.2.13

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 (598) hide show
  1. package/CHANGELOG.md +4347 -0
  2. package/README.md +1193 -0
  3. package/dist/types/api-registry.d.ts +30 -0
  4. package/dist/types/auth-broker/client.d.ts +73 -0
  5. package/dist/types/auth-broker/discover.d.ts +35 -0
  6. package/dist/types/auth-broker/index.d.ts +7 -0
  7. package/dist/types/auth-broker/refresher.d.ts +25 -0
  8. package/dist/types/auth-broker/remote-store.d.ts +102 -0
  9. package/dist/types/auth-broker/server.d.ts +43 -0
  10. package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
  11. package/dist/types/auth-broker/types.d.ts +107 -0
  12. package/dist/types/auth-broker/wire-schemas.d.ts +411 -0
  13. package/dist/types/auth-gateway/http.d.ts +39 -0
  14. package/dist/types/auth-gateway/index.d.ts +3 -0
  15. package/dist/types/auth-gateway/server.d.ts +36 -0
  16. package/dist/types/auth-gateway/types.d.ts +123 -0
  17. package/dist/types/auth-retry.d.ts +124 -0
  18. package/dist/types/auth-storage.d.ts +1026 -0
  19. package/dist/types/dialect/anthropic.d.ts +15 -0
  20. package/dist/types/dialect/catalog.d.ts +3 -0
  21. package/dist/types/dialect/coercion.d.ts +23 -0
  22. package/dist/types/dialect/deepseek.d.ts +14 -0
  23. package/dist/types/dialect/demotion.d.ts +23 -0
  24. package/dist/types/dialect/examples.d.ts +2 -0
  25. package/dist/types/dialect/factory.d.ts +3 -0
  26. package/dist/types/dialect/fenced-thinking.d.ts +53 -0
  27. package/dist/types/dialect/gemini.d.ts +17 -0
  28. package/dist/types/dialect/gemma.d.ts +15 -0
  29. package/dist/types/dialect/glm.d.ts +9 -0
  30. package/dist/types/dialect/harmony.d.ts +8 -0
  31. package/dist/types/dialect/hermes.d.ts +9 -0
  32. package/dist/types/dialect/history.d.ts +3 -0
  33. package/dist/types/dialect/index.d.ts +11 -0
  34. package/dist/types/dialect/inventory.d.ts +12 -0
  35. package/dist/types/dialect/kimi.d.ts +14 -0
  36. package/dist/types/dialect/minimax.d.ts +3 -0
  37. package/dist/types/dialect/owned-stream.d.ts +4 -0
  38. package/dist/types/dialect/qwen3.d.ts +9 -0
  39. package/dist/types/dialect/rendering.d.ts +45 -0
  40. package/dist/types/dialect/thinking.d.ts +6 -0
  41. package/dist/types/dialect/types.d.ts +69 -0
  42. package/dist/types/dialect/xml.d.ts +9 -0
  43. package/dist/types/error/abort.d.ts +14 -0
  44. package/dist/types/error/auth-classify.d.ts +16 -0
  45. package/dist/types/error/auth.d.ts +27 -0
  46. package/dist/types/error/aws.d.ts +23 -0
  47. package/dist/types/error/classes.d.ts +102 -0
  48. package/dist/types/error/finalize.d.ts +39 -0
  49. package/dist/types/error/flags.d.ts +79 -0
  50. package/dist/types/error/format.d.ts +20 -0
  51. package/dist/types/error/gateway.d.ts +20 -0
  52. package/dist/types/error/index.d.ts +13 -0
  53. package/dist/types/error/oauth.d.ts +43 -0
  54. package/dist/types/error/provider.d.ts +42 -0
  55. package/dist/types/error/rate-limit.d.ts +59 -0
  56. package/dist/types/error/retryable.d.ts +27 -0
  57. package/dist/types/error/validation.d.ts +32 -0
  58. package/dist/types/index.d.ts +49 -0
  59. package/dist/types/provider-details.d.ts +24 -0
  60. package/dist/types/providers/__tests__/google-auth.test.d.ts +1 -0
  61. package/dist/types/providers/__tests__/kimi-code-thinking.test.d.ts +1 -0
  62. package/dist/types/providers/__tests__/openai-codex-error.test.d.ts +1 -0
  63. package/dist/types/providers/amazon-bedrock.d.ts +39 -0
  64. package/dist/types/providers/anthropic-client.d.ts +94 -0
  65. package/dist/types/providers/anthropic-messages-server-schema.d.ts +497 -0
  66. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  67. package/dist/types/providers/anthropic-wire.d.ts +318 -0
  68. package/dist/types/providers/anthropic.d.ts +248 -0
  69. package/dist/types/providers/aws-credentials.d.ts +53 -0
  70. package/dist/types/providers/aws-eventstream.d.ts +39 -0
  71. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  72. package/dist/types/providers/azure-openai-responses.d.ts +16 -0
  73. package/dist/types/providers/cursor.d.ts +91 -0
  74. package/dist/types/providers/devin.d.ts +12 -0
  75. package/dist/types/providers/error-message.d.ts +27 -0
  76. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  77. package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
  78. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  79. package/dist/types/providers/google-auth.d.ts +32 -0
  80. package/dist/types/providers/google-gemini-cli.d.ts +118 -0
  81. package/dist/types/providers/google-interactions.d.ts +65 -0
  82. package/dist/types/providers/google-shared.d.ts +203 -0
  83. package/dist/types/providers/google-types.d.ts +155 -0
  84. package/dist/types/providers/google-vertex.d.ts +7 -0
  85. package/dist/types/providers/google.d.ts +4 -0
  86. package/dist/types/providers/grammar.d.ts +1 -0
  87. package/dist/types/providers/kimi.d.ts +27 -0
  88. package/dist/types/providers/mock.d.ts +178 -0
  89. package/dist/types/providers/ollama.d.ts +7 -0
  90. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  91. package/dist/types/providers/openai-chat-server-schema.d.ts +695 -0
  92. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  93. package/dist/types/providers/openai-chat-wire.d.ts +644 -0
  94. package/dist/types/providers/openai-codex/request-transformer.d.ts +54 -0
  95. package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
  96. package/dist/types/providers/openai-codex-responses.d.ts +108 -0
  97. package/dist/types/providers/openai-completions.d.ts +45 -0
  98. package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
  99. package/dist/types/providers/openai-responses-server-schema.d.ts +349 -0
  100. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  101. package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
  102. package/dist/types/providers/openai-responses.d.ts +126 -0
  103. package/dist/types/providers/openai-shared.d.ts +506 -0
  104. package/dist/types/providers/pi-native-client.d.ts +13 -0
  105. package/dist/types/providers/pi-native-server.d.ts +69 -0
  106. package/dist/types/providers/register-builtins.d.ts +32 -0
  107. package/dist/types/providers/synthetic.d.ts +26 -0
  108. package/dist/types/providers/transform-messages.d.ts +11 -0
  109. package/dist/types/providers/vision-guard.d.ts +20 -0
  110. package/dist/types/registry/aimlapi.d.ts +4 -0
  111. package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
  112. package/dist/types/registry/amazon-bedrock.d.ts +5 -0
  113. package/dist/types/registry/anthropic.d.ts +10 -0
  114. package/dist/types/registry/api-key-login.d.ts +42 -0
  115. package/dist/types/registry/api-key-validation.d.ts +43 -0
  116. package/dist/types/registry/azure.d.ts +4 -0
  117. package/dist/types/registry/cerebras.d.ts +7 -0
  118. package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
  119. package/dist/types/registry/coreweave.d.ts +7 -0
  120. package/dist/types/registry/cursor.d.ts +7 -0
  121. package/dist/types/registry/deepseek.d.ts +8 -0
  122. package/dist/types/registry/derived.d.ts +5 -0
  123. package/dist/types/registry/devin.d.ts +8 -0
  124. package/dist/types/registry/firepass.d.ts +16 -0
  125. package/dist/types/registry/fireworks.d.ts +7 -0
  126. package/dist/types/registry/github-copilot.d.ts +7 -0
  127. package/dist/types/registry/gitlab-duo-workflow.d.ts +10 -0
  128. package/dist/types/registry/gitlab-duo.d.ts +9 -0
  129. package/dist/types/registry/google-antigravity.d.ts +9 -0
  130. package/dist/types/registry/google-gemini-cli.d.ts +9 -0
  131. package/dist/types/registry/google-vertex.d.ts +5 -0
  132. package/dist/types/registry/google.d.ts +4 -0
  133. package/dist/types/registry/groq.d.ts +4 -0
  134. package/dist/types/registry/huggingface.d.ts +7 -0
  135. package/dist/types/registry/index.d.ts +4 -0
  136. package/dist/types/registry/kagi.d.ts +14 -0
  137. package/dist/types/registry/kilo.d.ts +7 -0
  138. package/dist/types/registry/kimi-code.d.ts +7 -0
  139. package/dist/types/registry/litellm.d.ts +13 -0
  140. package/dist/types/registry/llama-cpp.d.ts +8 -0
  141. package/dist/types/registry/lm-studio.d.ts +8 -0
  142. package/dist/types/registry/minimax-code-cn.d.ts +6 -0
  143. package/dist/types/registry/minimax-code.d.ts +6 -0
  144. package/dist/types/registry/minimax.d.ts +4 -0
  145. package/dist/types/registry/mistral.d.ts +4 -0
  146. package/dist/types/registry/moonshot.d.ts +7 -0
  147. package/dist/types/registry/nanogpt.d.ts +7 -0
  148. package/dist/types/registry/nvidia.d.ts +7 -0
  149. package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  150. package/dist/types/registry/oauth/anthropic.d.ts +23 -0
  151. package/dist/types/registry/oauth/callback-server.d.ts +72 -0
  152. package/dist/types/registry/oauth/cursor.d.ts +15 -0
  153. package/dist/types/registry/oauth/devin.d.ts +5 -0
  154. package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
  155. package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
  156. package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
  157. package/dist/types/registry/oauth/google-antigravity.d.ts +11 -0
  158. package/dist/types/registry/oauth/google-gemini-cli.d.ts +10 -0
  159. package/dist/types/registry/oauth/google-oauth-shared.d.ts +22 -0
  160. package/dist/types/registry/oauth/index.d.ts +64 -0
  161. package/dist/types/registry/oauth/kimi.d.ts +21 -0
  162. package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
  163. package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
  164. package/dist/types/registry/oauth/opencode.d.ts +18 -0
  165. package/dist/types/registry/oauth/perplexity.d.ts +9 -0
  166. package/dist/types/registry/oauth/pkce.d.ts +8 -0
  167. package/dist/types/registry/oauth/types.d.ts +56 -0
  168. package/dist/types/registry/oauth/wafer.d.ts +1 -0
  169. package/dist/types/registry/oauth/xai-oauth.d.ts +52 -0
  170. package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
  171. package/dist/types/registry/ollama-cloud.d.ts +7 -0
  172. package/dist/types/registry/ollama.d.ts +12 -0
  173. package/dist/types/registry/openai-codex-device.d.ts +8 -0
  174. package/dist/types/registry/openai-codex.d.ts +9 -0
  175. package/dist/types/registry/openai.d.ts +4 -0
  176. package/dist/types/registry/opencode-go.d.ts +6 -0
  177. package/dist/types/registry/opencode-zen.d.ts +6 -0
  178. package/dist/types/registry/openrouter.d.ts +13 -0
  179. package/dist/types/registry/parallel.d.ts +14 -0
  180. package/dist/types/registry/perplexity.d.ts +7 -0
  181. package/dist/types/registry/qianfan.d.ts +7 -0
  182. package/dist/types/registry/qwen-portal.d.ts +7 -0
  183. package/dist/types/registry/registry.d.ts +303 -0
  184. package/dist/types/registry/sakana.d.ts +7 -0
  185. package/dist/types/registry/synthetic.d.ts +6 -0
  186. package/dist/types/registry/tavily.d.ts +14 -0
  187. package/dist/types/registry/together.d.ts +6 -0
  188. package/dist/types/registry/types.d.ts +51 -0
  189. package/dist/types/registry/umans.d.ts +7 -0
  190. package/dist/types/registry/venice.d.ts +13 -0
  191. package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
  192. package/dist/types/registry/vllm.d.ts +7 -0
  193. package/dist/types/registry/wafer-serverless.d.ts +6 -0
  194. package/dist/types/registry/xai-oauth.d.ts +7 -0
  195. package/dist/types/registry/xai.d.ts +4 -0
  196. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
  197. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
  198. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
  199. package/dist/types/registry/xiaomi.d.ts +6 -0
  200. package/dist/types/registry/zai.d.ts +7 -0
  201. package/dist/types/registry/zenmux.d.ts +7 -0
  202. package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
  203. package/dist/types/stream.d.ts +44 -0
  204. package/dist/types/types.d.ts +715 -0
  205. package/dist/types/usage/claude.d.ts +4 -0
  206. package/dist/types/usage/gemini.d.ts +2 -0
  207. package/dist/types/usage/github-copilot.d.ts +7 -0
  208. package/dist/types/usage/google-antigravity.d.ts +15 -0
  209. package/dist/types/usage/kimi.d.ts +2 -0
  210. package/dist/types/usage/minimax-code.d.ts +2 -0
  211. package/dist/types/usage/ollama.d.ts +5 -0
  212. package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
  213. package/dist/types/usage/openai-codex-reset.d.ts +79 -0
  214. package/dist/types/usage/openai-codex.d.ts +3 -0
  215. package/dist/types/usage/opencode-go.d.ts +2 -0
  216. package/dist/types/usage/shared.d.ts +1 -0
  217. package/dist/types/usage/zai.d.ts +2 -0
  218. package/dist/types/usage.d.ts +346 -0
  219. package/dist/types/utils/abort.d.ts +25 -0
  220. package/dist/types/utils/anthropic-auth.d.ts +35 -0
  221. package/dist/types/utils/block-symbols.d.ts +20 -0
  222. package/dist/types/utils/deterministic-id.d.ts +16 -0
  223. package/dist/types/utils/empty-completion-retry.d.ts +21 -0
  224. package/dist/types/utils/event-stream.d.ts +30 -0
  225. package/dist/types/utils/foundry.d.ts +1 -0
  226. package/dist/types/utils/google-validation.d.ts +2 -0
  227. package/dist/types/utils/harmony-leak.d.ts +118 -0
  228. package/dist/types/utils/http-inspector.d.ts +30 -0
  229. package/dist/types/utils/idle-iterator.d.ts +137 -0
  230. package/dist/types/utils/leaked-thinking-stream.d.ts +29 -0
  231. package/dist/types/utils/openai-http.d.ts +54 -0
  232. package/dist/types/utils/openrouter-headers.d.ts +1 -0
  233. package/dist/types/utils/parse-bind.d.ts +23 -0
  234. package/dist/types/utils/provider-response.d.ts +3 -0
  235. package/dist/types/utils/proxy.d.ts +29 -0
  236. package/dist/types/utils/request-debug.d.ts +29 -0
  237. package/dist/types/utils/retry-after.d.ts +4 -0
  238. package/dist/types/utils/retry.d.ts +14 -0
  239. package/dist/types/utils/schema/adapt.d.ts +24 -0
  240. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  241. package/dist/types/utils/schema/dereference.d.ts +11 -0
  242. package/dist/types/utils/schema/draft.d.ts +10 -0
  243. package/dist/types/utils/schema/equality.d.ts +4 -0
  244. package/dist/types/utils/schema/fields.d.ts +54 -0
  245. package/dist/types/utils/schema/index.d.ts +15 -0
  246. package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
  247. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  248. package/dist/types/utils/schema/normalize.d.ts +124 -0
  249. package/dist/types/utils/schema/spill.d.ts +8 -0
  250. package/dist/types/utils/schema/stamps.d.ts +17 -0
  251. package/dist/types/utils/schema/strict-tool-validation.d.ts +16 -0
  252. package/dist/types/utils/schema/types.d.ts +4 -0
  253. package/dist/types/utils/schema/typescript.d.ts +18 -0
  254. package/dist/types/utils/schema/wire.d.ts +92 -0
  255. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  256. package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
  257. package/dist/types/utils/sse-debug.d.ts +5 -0
  258. package/dist/types/utils/stream-markup-healing.d.ts +87 -0
  259. package/dist/types/utils/thinking-loop.d.ts +102 -0
  260. package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
  261. package/dist/types/utils/tool-choice.d.ts +50 -0
  262. package/dist/types/utils/validation.d.ts +42 -0
  263. package/dist/types/utils.d.ts +24 -0
  264. package/package.json +139 -0
  265. package/src/api-registry.ts +109 -0
  266. package/src/auth-broker/client.ts +359 -0
  267. package/src/auth-broker/discover.ts +222 -0
  268. package/src/auth-broker/index.ts +7 -0
  269. package/src/auth-broker/refresher.ts +117 -0
  270. package/src/auth-broker/remote-store.ts +657 -0
  271. package/src/auth-broker/server.ts +646 -0
  272. package/src/auth-broker/snapshot-cache.ts +191 -0
  273. package/src/auth-broker/types.ts +130 -0
  274. package/src/auth-broker/wire-schemas.ts +249 -0
  275. package/src/auth-gateway/http.ts +194 -0
  276. package/src/auth-gateway/index.ts +3 -0
  277. package/src/auth-gateway/server.ts +802 -0
  278. package/src/auth-gateway/types.ts +151 -0
  279. package/src/auth-retry.ts +250 -0
  280. package/src/auth-storage.ts +5576 -0
  281. package/src/dialect/anthropic.md +31 -0
  282. package/src/dialect/anthropic.ts +608 -0
  283. package/src/dialect/catalog.ts +29 -0
  284. package/src/dialect/coercion.ts +136 -0
  285. package/src/dialect/deepseek.md +24 -0
  286. package/src/dialect/deepseek.ts +609 -0
  287. package/src/dialect/demotion.ts +36 -0
  288. package/src/dialect/examples.ts +33 -0
  289. package/src/dialect/factory.ts +34 -0
  290. package/src/dialect/fenced-thinking.ts +184 -0
  291. package/src/dialect/gemini.md +44 -0
  292. package/src/dialect/gemini.ts +597 -0
  293. package/src/dialect/gemma.md +33 -0
  294. package/src/dialect/gemma.ts +387 -0
  295. package/src/dialect/glm.md +32 -0
  296. package/src/dialect/glm.ts +456 -0
  297. package/src/dialect/harmony.md +31 -0
  298. package/src/dialect/harmony.ts +346 -0
  299. package/src/dialect/hermes.md +25 -0
  300. package/src/dialect/hermes.ts +206 -0
  301. package/src/dialect/history.ts +81 -0
  302. package/src/dialect/index.ts +15 -0
  303. package/src/dialect/inventory.ts +73 -0
  304. package/src/dialect/kimi.md +24 -0
  305. package/src/dialect/kimi.ts +340 -0
  306. package/src/dialect/minimax.md +31 -0
  307. package/src/dialect/minimax.ts +95 -0
  308. package/src/dialect/owned-stream.ts +470 -0
  309. package/src/dialect/prompt-template.md +12 -0
  310. package/src/dialect/qwen3.md +28 -0
  311. package/src/dialect/qwen3.ts +240 -0
  312. package/src/dialect/rendering.ts +249 -0
  313. package/src/dialect/thinking.ts +122 -0
  314. package/src/dialect/types.ts +57 -0
  315. package/src/dialect/xml.md +22 -0
  316. package/src/dialect/xml.ts +90 -0
  317. package/src/error/abort.ts +18 -0
  318. package/src/error/auth-classify.ts +30 -0
  319. package/src/error/auth.ts +48 -0
  320. package/src/error/aws.ts +31 -0
  321. package/src/error/classes.ts +186 -0
  322. package/src/error/finalize.ts +69 -0
  323. package/src/error/flags.ts +506 -0
  324. package/src/error/format.ts +45 -0
  325. package/src/error/gateway.ts +96 -0
  326. package/src/error/index.ts +13 -0
  327. package/src/error/oauth.ts +58 -0
  328. package/src/error/provider.ts +62 -0
  329. package/src/error/rate-limit.ts +161 -0
  330. package/src/error/retryable.ts +70 -0
  331. package/src/error/validation.ts +44 -0
  332. package/src/index.ts +49 -0
  333. package/src/provider-details.ts +90 -0
  334. package/src/providers/__tests__/google-auth.test.ts +144 -0
  335. package/src/providers/__tests__/kimi-code-thinking.test.ts +112 -0
  336. package/src/providers/__tests__/openai-codex-error.test.ts +84 -0
  337. package/src/providers/amazon-bedrock.ts +1042 -0
  338. package/src/providers/anthropic-client.ts +295 -0
  339. package/src/providers/anthropic-messages-server-schema.ts +252 -0
  340. package/src/providers/anthropic-messages-server.ts +756 -0
  341. package/src/providers/anthropic-wire.ts +318 -0
  342. package/src/providers/anthropic.ts +4078 -0
  343. package/src/providers/aws-credentials.ts +586 -0
  344. package/src/providers/aws-eventstream.ts +181 -0
  345. package/src/providers/aws-sigv4.ts +218 -0
  346. package/src/providers/azure-openai-responses.ts +382 -0
  347. package/src/providers/cursor/proto/agent.proto +3526 -0
  348. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  349. package/src/providers/cursor/proto/buf.yaml +17 -0
  350. package/src/providers/cursor.ts +2695 -0
  351. package/src/providers/devin/proto/buf/validate/validate.proto +468 -0
  352. package/src/providers/devin/proto/buf.gen.yaml +33 -0
  353. package/src/providers/devin/proto/buf.yaml +17 -0
  354. package/src/providers/devin/proto/cel/expr/checked.proto +103 -0
  355. package/src/providers/devin/proto/cel/expr/eval.proto +38 -0
  356. package/src/providers/devin/proto/cel/expr/explain.proto +15 -0
  357. package/src/providers/devin/proto/cel/expr/syntax.proto +113 -0
  358. package/src/providers/devin/proto/cel/expr/value.proto +41 -0
  359. package/src/providers/devin/proto/connectext/grpc/status/v1/status.proto +11 -0
  360. package/src/providers/devin/proto/errorspb/errors.proto +56 -0
  361. package/src/providers/devin/proto/errorspb/hintdetail.proto +7 -0
  362. package/src/providers/devin/proto/errorspb/markers.proto +10 -0
  363. package/src/providers/devin/proto/errorspb/tags.proto +12 -0
  364. package/src/providers/devin/proto/errorspb/testing.proto +6 -0
  365. package/src/providers/devin/proto/exa/analytics_pb/analytics.proto +188 -0
  366. package/src/providers/devin/proto/exa/api_server_pb/api_server.proto +2461 -0
  367. package/src/providers/devin/proto/exa/auth_pb/auth.proto +19 -0
  368. package/src/providers/devin/proto/exa/auto_cascade_common_pb/auto_cascade_common.proto +79 -0
  369. package/src/providers/devin/proto/exa/browser_preview_pb/browser_preview.proto +32 -0
  370. package/src/providers/devin/proto/exa/bug_checker_pb/bug_checker.proto +22 -0
  371. package/src/providers/devin/proto/exa/cascade_plugins_pb/cascade_plugins.proto +262 -0
  372. package/src/providers/devin/proto/exa/chat_client_server_pb/chat_client_server.proto +57 -0
  373. package/src/providers/devin/proto/exa/chat_pb/chat.proto +449 -0
  374. package/src/providers/devin/proto/exa/code_edit/code_edit_pb/code_edit.proto +186 -0
  375. package/src/providers/devin/proto/exa/codeium_common_pb/codeium_common.proto +4157 -0
  376. package/src/providers/devin/proto/exa/context_module_pb/context_module.proto +175 -0
  377. package/src/providers/devin/proto/exa/cortex_pb/cortex.proto +3268 -0
  378. package/src/providers/devin/proto/exa/dev_pb/dev.proto +26 -0
  379. package/src/providers/devin/proto/exa/diff_action_pb/diff_action.proto +75 -0
  380. package/src/providers/devin/proto/exa/eval/pr_eval/datasets_pb/datasets.proto +103 -0
  381. package/src/providers/devin/proto/exa/eval_pb/eval.proto +1315 -0
  382. package/src/providers/devin/proto/exa/extension_server_pb/extension_server.proto +556 -0
  383. package/src/providers/devin/proto/exa/file_system_provider_pb/file_system_provider.proto +75 -0
  384. package/src/providers/devin/proto/exa/index_pb/index.proto +461 -0
  385. package/src/providers/devin/proto/exa/knowledge_base_pb/knowledge_base.proto +144 -0
  386. package/src/providers/devin/proto/exa/language_server_pb/language_server.proto +2385 -0
  387. package/src/providers/devin/proto/exa/model_management_pb/model_management.proto +186 -0
  388. package/src/providers/devin/proto/exa/opensearch_clients_pb/opensearch_clients.proto +503 -0
  389. package/src/providers/devin/proto/exa/product_analytics_pb/product_analytics.proto +37 -0
  390. package/src/providers/devin/proto/exa/prompt_pb/prompt.proto +92 -0
  391. package/src/providers/devin/proto/exa/reactive_component_pb/reactive_component.proto +96 -0
  392. package/src/providers/devin/proto/exa/seat_management_pb/seat_management.proto +2680 -0
  393. package/src/providers/devin/proto/exa/tokenizer_pb/tokenizer.proto +37 -0
  394. package/src/providers/devin/proto/exa/trainer_pb/config.proto +647 -0
  395. package/src/providers/devin/proto/exa/tree_sitter/language_data_pb/language_data.proto +14 -0
  396. package/src/providers/devin/proto/exa/trust_pb/trust.proto +157 -0
  397. package/src/providers/devin/proto/exa/user_analytics_pb/user_analytics.proto +519 -0
  398. package/src/providers/devin/proto/google.golang.org/appengine/internal/base/api_base.proto +28 -0
  399. package/src/providers/devin/proto/google.golang.org/appengine/internal/datastore/datastore_v3.proto +484 -0
  400. package/src/providers/devin/proto/google.golang.org/appengine/internal/log/log_service.proto +136 -0
  401. package/src/providers/devin/proto/google.golang.org/appengine/internal/remote_api/remote_api.proto +42 -0
  402. package/src/providers/devin/proto/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +61 -0
  403. package/src/providers/devin/proto/grpc/binlog/v1/binarylog.proto +84 -0
  404. package/src/providers/devin/proto/io/prometheus/client/metrics.proto +98 -0
  405. package/src/providers/devin.ts +577 -0
  406. package/src/providers/error-message.ts +21 -0
  407. package/src/providers/github-copilot-headers.ts +141 -0
  408. package/src/providers/gitlab-duo-workflow-chatml-note.md +1 -0
  409. package/src/providers/gitlab-duo-workflow.ts +3058 -0
  410. package/src/providers/gitlab-duo.ts +395 -0
  411. package/src/providers/google-auth.ts +350 -0
  412. package/src/providers/google-gemini-cli.ts +1362 -0
  413. package/src/providers/google-interactions.ts +753 -0
  414. package/src/providers/google-shared.ts +1103 -0
  415. package/src/providers/google-types.ts +180 -0
  416. package/src/providers/google-vertex.ts +183 -0
  417. package/src/providers/google.ts +87 -0
  418. package/src/providers/grammar.ts +70 -0
  419. package/src/providers/kimi.ts +52 -0
  420. package/src/providers/mock.ts +507 -0
  421. package/src/providers/ollama.ts +773 -0
  422. package/src/providers/openai-anthropic-shim.ts +152 -0
  423. package/src/providers/openai-chat-server-schema.ts +242 -0
  424. package/src/providers/openai-chat-server.ts +715 -0
  425. package/src/providers/openai-chat-wire.ts +847 -0
  426. package/src/providers/openai-codex/request-transformer.ts +295 -0
  427. package/src/providers/openai-codex/response-handler.ts +102 -0
  428. package/src/providers/openai-codex-responses.ts +3468 -0
  429. package/src/providers/openai-completions.ts +2173 -0
  430. package/src/providers/openai-reasoning-fallback.ts +269 -0
  431. package/src/providers/openai-responses-reasoning-suppression.md +1 -0
  432. package/src/providers/openai-responses-server-schema.ts +282 -0
  433. package/src/providers/openai-responses-server.ts +1280 -0
  434. package/src/providers/openai-responses-wire.ts +6391 -0
  435. package/src/providers/openai-responses.ts +1022 -0
  436. package/src/providers/openai-shared.ts +2648 -0
  437. package/src/providers/pi-native-client.ts +266 -0
  438. package/src/providers/pi-native-server.ts +242 -0
  439. package/src/providers/register-builtins.ts +475 -0
  440. package/src/providers/synthetic.ts +50 -0
  441. package/src/providers/transform-messages.ts +787 -0
  442. package/src/providers/vision-guard.ts +54 -0
  443. package/src/registry/aimlapi.ts +6 -0
  444. package/src/registry/alibaba-coding-plan.ts +95 -0
  445. package/src/registry/amazon-bedrock.ts +22 -0
  446. package/src/registry/anthropic.ts +26 -0
  447. package/src/registry/api-key-login.ts +112 -0
  448. package/src/registry/api-key-validation.ts +161 -0
  449. package/src/registry/azure.ts +6 -0
  450. package/src/registry/cerebras.ts +23 -0
  451. package/src/registry/cloudflare-ai-gateway.ts +45 -0
  452. package/src/registry/coreweave.ts +40 -0
  453. package/src/registry/cursor.ts +20 -0
  454. package/src/registry/deepseek.ts +46 -0
  455. package/src/registry/derived.ts +9 -0
  456. package/src/registry/devin.ts +15 -0
  457. package/src/registry/firepass.ts +32 -0
  458. package/src/registry/fireworks.ts +28 -0
  459. package/src/registry/github-copilot.ts +22 -0
  460. package/src/registry/gitlab-duo-workflow.ts +20 -0
  461. package/src/registry/gitlab-duo.ts +19 -0
  462. package/src/registry/google-antigravity.ts +22 -0
  463. package/src/registry/google-gemini-cli.ts +22 -0
  464. package/src/registry/google-vertex.ts +38 -0
  465. package/src/registry/google.ts +6 -0
  466. package/src/registry/groq.ts +6 -0
  467. package/src/registry/huggingface.ts +29 -0
  468. package/src/registry/index.ts +4 -0
  469. package/src/registry/kagi.ts +46 -0
  470. package/src/registry/kilo.ts +114 -0
  471. package/src/registry/kimi-code.ts +17 -0
  472. package/src/registry/litellm.ts +45 -0
  473. package/src/registry/llama-cpp.ts +35 -0
  474. package/src/registry/lm-studio.ts +31 -0
  475. package/src/registry/minimax-code-cn.ts +12 -0
  476. package/src/registry/minimax-code.ts +12 -0
  477. package/src/registry/minimax.ts +6 -0
  478. package/src/registry/mistral.ts +6 -0
  479. package/src/registry/moonshot.ts +22 -0
  480. package/src/registry/nanogpt.ts +22 -0
  481. package/src/registry/nvidia.ts +61 -0
  482. package/src/registry/oauth/__tests__/xai-oauth.test.ts +104 -0
  483. package/src/registry/oauth/anthropic.ts +311 -0
  484. package/src/registry/oauth/callback-server.ts +315 -0
  485. package/src/registry/oauth/cursor.ts +171 -0
  486. package/src/registry/oauth/devin.ts +124 -0
  487. package/src/registry/oauth/github-copilot.ts +369 -0
  488. package/src/registry/oauth/gitlab-duo-workflow.ts +146 -0
  489. package/src/registry/oauth/gitlab-duo.ts +222 -0
  490. package/src/registry/oauth/google-antigravity.ts +209 -0
  491. package/src/registry/oauth/google-gemini-cli.ts +273 -0
  492. package/src/registry/oauth/google-oauth-shared.ts +125 -0
  493. package/src/registry/oauth/index.ts +269 -0
  494. package/src/registry/oauth/kimi.ts +289 -0
  495. package/src/registry/oauth/minimax-code.ts +53 -0
  496. package/src/registry/oauth/oauth.html +311 -0
  497. package/src/registry/oauth/openai-codex.ts +364 -0
  498. package/src/registry/oauth/opencode.ts +50 -0
  499. package/src/registry/oauth/perplexity.ts +228 -0
  500. package/src/registry/oauth/pkce.ts +18 -0
  501. package/src/registry/oauth/types.ts +65 -0
  502. package/src/registry/oauth/wafer.ts +24 -0
  503. package/src/registry/oauth/xai-oauth.ts +394 -0
  504. package/src/registry/oauth/xiaomi.ts +211 -0
  505. package/src/registry/ollama-cloud.ts +36 -0
  506. package/src/registry/ollama.ts +43 -0
  507. package/src/registry/openai-codex-device.ts +18 -0
  508. package/src/registry/openai-codex.ts +19 -0
  509. package/src/registry/openai.ts +6 -0
  510. package/src/registry/opencode-go.ts +12 -0
  511. package/src/registry/opencode-zen.ts +12 -0
  512. package/src/registry/openrouter.ts +28 -0
  513. package/src/registry/parallel.ts +45 -0
  514. package/src/registry/perplexity.ts +13 -0
  515. package/src/registry/qianfan.ts +27 -0
  516. package/src/registry/qwen-portal.ts +50 -0
  517. package/src/registry/registry.ts +161 -0
  518. package/src/registry/sakana.ts +22 -0
  519. package/src/registry/synthetic.ts +21 -0
  520. package/src/registry/tavily.ts +45 -0
  521. package/src/registry/together.ts +22 -0
  522. package/src/registry/types.ts +56 -0
  523. package/src/registry/umans.ts +23 -0
  524. package/src/registry/venice.ts +33 -0
  525. package/src/registry/vercel-ai-gateway.ts +38 -0
  526. package/src/registry/vllm.ts +34 -0
  527. package/src/registry/wafer-serverless.ts +12 -0
  528. package/src/registry/xai-oauth.ts +17 -0
  529. package/src/registry/xai.ts +6 -0
  530. package/src/registry/xiaomi-token-plan-ams.ts +12 -0
  531. package/src/registry/xiaomi-token-plan-cn.ts +12 -0
  532. package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
  533. package/src/registry/xiaomi.ts +12 -0
  534. package/src/registry/zai.ts +27 -0
  535. package/src/registry/zenmux.ts +22 -0
  536. package/src/registry/zhipu-coding-plan.ts +27 -0
  537. package/src/stream.ts +1778 -0
  538. package/src/types.ts +856 -0
  539. package/src/usage/claude.ts +485 -0
  540. package/src/usage/gemini.ts +258 -0
  541. package/src/usage/github-copilot.ts +424 -0
  542. package/src/usage/google-antigravity.ts +497 -0
  543. package/src/usage/kimi.ts +271 -0
  544. package/src/usage/minimax-code.ts +30 -0
  545. package/src/usage/ollama.ts +41 -0
  546. package/src/usage/openai-codex-base-url.ts +35 -0
  547. package/src/usage/openai-codex-reset.ts +174 -0
  548. package/src/usage/openai-codex.ts +535 -0
  549. package/src/usage/opencode-go.ts +89 -0
  550. package/src/usage/shared.ts +10 -0
  551. package/src/usage/zai.ts +321 -0
  552. package/src/usage.ts +333 -0
  553. package/src/utils/abort.ts +67 -0
  554. package/src/utils/anthropic-auth.ts +93 -0
  555. package/src/utils/block-symbols.ts +32 -0
  556. package/src/utils/deterministic-id.ts +20 -0
  557. package/src/utils/empty-completion-retry.ts +159 -0
  558. package/src/utils/event-stream.ts +171 -0
  559. package/src/utils/foundry.ts +8 -0
  560. package/src/utils/google-validation.ts +25 -0
  561. package/src/utils/harmony-leak.ts +456 -0
  562. package/src/utils/http-inspector.ts +168 -0
  563. package/src/utils/idle-iterator.ts +473 -0
  564. package/src/utils/leaked-thinking-stream.ts +294 -0
  565. package/src/utils/openai-http.ts +122 -0
  566. package/src/utils/openrouter-headers.ts +12 -0
  567. package/src/utils/parse-bind.ts +56 -0
  568. package/src/utils/provider-response.ts +30 -0
  569. package/src/utils/proxy.ts +240 -0
  570. package/src/utils/request-debug.ts +351 -0
  571. package/src/utils/retry-after.ts +110 -0
  572. package/src/utils/retry.ts +59 -0
  573. package/src/utils/schema/CONSTRAINTS.md +166 -0
  574. package/src/utils/schema/adapt.ts +36 -0
  575. package/src/utils/schema/compatibility.ts +435 -0
  576. package/src/utils/schema/dereference.ts +98 -0
  577. package/src/utils/schema/draft.ts +341 -0
  578. package/src/utils/schema/equality.ts +97 -0
  579. package/src/utils/schema/fields.ts +207 -0
  580. package/src/utils/schema/index.ts +15 -0
  581. package/src/utils/schema/json-schema-validator.ts +595 -0
  582. package/src/utils/schema/meta-validator.ts +167 -0
  583. package/src/utils/schema/normalize.ts +1901 -0
  584. package/src/utils/schema/spill.ts +43 -0
  585. package/src/utils/schema/stamps.ts +109 -0
  586. package/src/utils/schema/strict-tool-validation.ts +117 -0
  587. package/src/utils/schema/types.ts +10 -0
  588. package/src/utils/schema/typescript.ts +198 -0
  589. package/src/utils/schema/wire.ts +789 -0
  590. package/src/utils/schema/zod-decontaminate.ts +331 -0
  591. package/src/utils/sdk-stream-timeout.ts +43 -0
  592. package/src/utils/sse-debug.ts +18 -0
  593. package/src/utils/stream-markup-healing.ts +247 -0
  594. package/src/utils/thinking-loop.ts +552 -0
  595. package/src/utils/tool-call-loop-guard.ts +107 -0
  596. package/src/utils/tool-choice.ts +99 -0
  597. package/src/utils/validation.ts +1507 -0
  598. package/src/utils.ts +171 -0
@@ -0,0 +1,473 @@
1
+ import { $env } from "jeopi-utils";
2
+ import * as AIError from "../error";
3
+
4
+ const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 120_000;
5
+ const DEFAULT_STREAM_FIRST_EVENT_TIMEOUT_MS = 100_000;
6
+ /** Re-mint persistent race promises every N iterations (see hoisted-racer comment). */
7
+ const RACER_REMINT_INTERVAL = 1024;
8
+
9
+ function normalizeIdleTimeoutMs(value: string | undefined, fallback: number): number | undefined {
10
+ if (value === undefined) return fallback;
11
+ const parsed = Number(value);
12
+ if (!Number.isFinite(parsed)) return fallback;
13
+ if (parsed <= 0) return undefined;
14
+ return Math.trunc(parsed);
15
+ }
16
+
17
+ /**
18
+ * Returns the idle timeout used for provider streaming transports.
19
+ *
20
+ * `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS` is accepted as a backward-compatible alias.
21
+ * Set `PI_STREAM_IDLE_TIMEOUT_MS=0` to disable the watchdog.
22
+ *
23
+ * Providers that legitimately stream much slower than the global default can pass
24
+ * `fallbackMs` to widen the floor used when neither env var nor caller option is set.
25
+ * Caller options still take precedence; env overrides still trump the fallback.
26
+ */
27
+ export function getStreamIdleTimeoutMs(fallbackMs: number = DEFAULT_STREAM_IDLE_TIMEOUT_MS): number | undefined {
28
+ return normalizeIdleTimeoutMs($env.PI_STREAM_IDLE_TIMEOUT_MS ?? $env.PI_OPENAI_STREAM_IDLE_TIMEOUT_MS, fallbackMs);
29
+ }
30
+
31
+ /**
32
+ * Returns the idle timeout used for OpenAI-family streaming transports.
33
+ *
34
+ * `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS` takes precedence over the generic
35
+ * `PI_STREAM_IDLE_TIMEOUT_MS` because some deployments tune OpenAI-compatible
36
+ * backends separately from Anthropic/Gemini-style transports.
37
+ *
38
+ * Set `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS=0` to disable the watchdog.
39
+ */
40
+ export function getOpenAIStreamIdleTimeoutMs(fallbackMs: number = DEFAULT_STREAM_IDLE_TIMEOUT_MS): number | undefined {
41
+ return normalizeIdleTimeoutMs($env.PI_OPENAI_STREAM_IDLE_TIMEOUT_MS ?? $env.PI_STREAM_IDLE_TIMEOUT_MS, fallbackMs);
42
+ }
43
+
44
+ /**
45
+ * Returns the timeout used while waiting for the first stream event.
46
+ * The first token can legitimately take longer than later inter-event gaps,
47
+ * so the default never undershoots the steady-state idle timeout.
48
+ *
49
+ * Set `PI_STREAM_FIRST_EVENT_TIMEOUT_MS=0` to disable the watchdog.
50
+ *
51
+ * Providers whose first response can legitimately take longer (heavy reasoning,
52
+ * slow cold-start proxies) can pass `fallbackMs` to widen the floor used when
53
+ * neither env var nor caller option is set. Caller options still take precedence;
54
+ * env overrides still trump the fallback.
55
+ */
56
+ export function getStreamFirstEventTimeoutMs(
57
+ idleTimeoutMs?: number,
58
+ fallbackMs: number = DEFAULT_STREAM_FIRST_EVENT_TIMEOUT_MS,
59
+ ): number | undefined {
60
+ const fallback = idleTimeoutMs === undefined ? fallbackMs : Math.max(fallbackMs, idleTimeoutMs);
61
+ return normalizeIdleTimeoutMs($env.PI_STREAM_FIRST_EVENT_TIMEOUT_MS, fallback);
62
+ }
63
+
64
+ /**
65
+ * Returns the first-event timeout used for OpenAI-family streaming transports.
66
+ *
67
+ * Precedence: explicit `PI_OPENAI_STREAM_FIRST_EVENT_TIMEOUT_MS` (including a
68
+ * `"0"` disable) wins outright. Otherwise the resolved idle (caller-supplied
69
+ * `idleTimeoutMs` — which itself already encompasses per-call
70
+ * `streamIdleTimeoutMs` or `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS` resolved
71
+ * upstream) floors the first-event budget so slow local OpenAI-compatible
72
+ * servers are not undercut by a shorter `PI_STREAM_FIRST_EVENT_TIMEOUT_MS`
73
+ * or the global default during prompt processing.
74
+ *
75
+ * Returns `undefined` when an explicit env knob disables the watchdog.
76
+ */
77
+ export function getOpenAIStreamFirstEventTimeoutMs(
78
+ idleTimeoutMs?: number,
79
+ fallbackMs: number = DEFAULT_STREAM_FIRST_EVENT_TIMEOUT_MS,
80
+ ): number | undefined {
81
+ const openAIFirstEventRaw = $env.PI_OPENAI_STREAM_FIRST_EVENT_TIMEOUT_MS;
82
+ if (openAIFirstEventRaw !== undefined) {
83
+ return normalizeIdleTimeoutMs(openAIFirstEventRaw, fallbackMs);
84
+ }
85
+ const base = normalizeIdleTimeoutMs($env.PI_STREAM_FIRST_EVENT_TIMEOUT_MS, fallbackMs);
86
+ if (base === undefined) return undefined;
87
+ if (idleTimeoutMs === undefined || idleTimeoutMs <= 0) return base;
88
+ return Math.max(base, idleTimeoutMs);
89
+ }
90
+
91
+ /**
92
+ * Arms a clearable pre-response (time-to-first-byte) abort guard for a streaming
93
+ * fetch, combined with the caller's signal.
94
+ *
95
+ * `AbortSignal.timeout(ms)` is an *absolute* wall-clock deadline: once handed to
96
+ * `fetch` it keeps governing the request after the response headers arrive, so
97
+ * it aborts an actively-streaming body the moment it fires — not just a stalled
98
+ * pre-response request (issue #2422 regression: large `write` tool-call streams
99
+ * died at the budget with `TimeoutError: The operation timed out.` despite
100
+ * deltas actively flowing). This arms a `clearTimeout`-able timer instead;
101
+ * callers MUST `clear()` as soon as `fetchWithRetry` resolves (headers in) so
102
+ * the body stream is left to the iterator-level idle watchdog. The timer aborts
103
+ * with a `TimeoutError` matching `AbortSignal.timeout`, so a genuine pre-response
104
+ * stall behaves exactly as the prior code did — `fetchWithRetry` normalizes the
105
+ * abort to "Request was aborted" either way (only a post-headers abort ever
106
+ * surfaced the raw `"The operation timed out."`, which clearing now prevents).
107
+ *
108
+ * Returns the caller signal unchanged (and a no-op `clear`) when no positive
109
+ * timeout is configured.
110
+ */
111
+ export function armPreResponseTimeout(
112
+ callerSignal: AbortSignal | undefined,
113
+ timeoutMs: number | undefined,
114
+ ): { signal: AbortSignal | undefined; clear: () => void } {
115
+ if (timeoutMs === undefined || timeoutMs <= 0) return { signal: callerSignal, clear: () => {} };
116
+ const controller = new AbortController();
117
+ const timer = setTimeout(() => {
118
+ controller.abort(new DOMException("The operation timed out.", "TimeoutError"));
119
+ }, timeoutMs);
120
+ timer.unref?.();
121
+ const signal = callerSignal ? AbortSignal.any([callerSignal, controller.signal]) : controller.signal;
122
+ return { signal, clear: () => clearTimeout(timer) };
123
+ }
124
+
125
+ export interface IdleTimeoutIteratorOptions {
126
+ idleTimeoutMs?: number;
127
+ firstItemTimeoutMs?: number;
128
+ errorMessage: string;
129
+ firstItemErrorMessage?: string;
130
+ onIdle?: () => void;
131
+ onFirstItemTimeout?: () => void;
132
+ /**
133
+ * Optional semantic-progress predicate. Non-progress items are still yielded,
134
+ * but they do not reset the idle deadline. This prevents provider
135
+ * keepalive/no-op events from keeping a stalled tool call alive forever.
136
+ */
137
+ isProgressItem?: (item: unknown) => boolean;
138
+ /**
139
+ * Cancel iteration as soon as this signal aborts. Required for caller-driven
140
+ * cancellation (ESC) when the underlying transport does not surface signal
141
+ * aborts to the iterator (HTTP/2 proxies, native sockets, mocked fetch).
142
+ * Without this, the consumer sleeps on iterator.next() until the idle/first
143
+ * -event watchdog fires — observable as the issue #912 "Working… forever"
144
+ * symptom on the github-copilot provider.
145
+ */
146
+ abortSignal?: AbortSignal;
147
+ }
148
+
149
+ /**
150
+ * Yields items from an async iterable while enforcing a maximum idle gap between items.
151
+ *
152
+ * The first item may use a shorter timeout so stuck requests can be aborted and retried
153
+ * before any user-visible content has streamed.
154
+ */
155
+ export async function* iterateWithIdleTimeout<T>(
156
+ iterable: AsyncIterable<T>,
157
+ options: IdleTimeoutIteratorOptions,
158
+ ): AsyncGenerator<T> {
159
+ const firstItemTimeoutMs = options.firstItemTimeoutMs ?? options.idleTimeoutMs;
160
+ const firstItemDeadlineMs =
161
+ firstItemTimeoutMs !== undefined && firstItemTimeoutMs > 0 ? Date.now() + firstItemTimeoutMs : undefined;
162
+ const abortSignal = options.abortSignal;
163
+ const iterator = iterable[Symbol.asyncIterator]();
164
+ let iteratorClosed = false;
165
+
166
+ const closeIterator = (): void => {
167
+ if (iteratorClosed) return;
168
+ iteratorClosed = true;
169
+ const returnPromise = iterator.return?.();
170
+ if (returnPromise) {
171
+ void returnPromise.catch(() => {});
172
+ }
173
+ };
174
+
175
+ if (abortSignal?.aborted) {
176
+ closeIterator();
177
+ throw abortReason(abortSignal);
178
+ }
179
+
180
+ const withRacy = <T>(promise: Promise<T>) =>
181
+ promise.then(
182
+ result => ({ kind: "next" as const, result }),
183
+ error => ({ kind: "error" as const, error }),
184
+ );
185
+
186
+ let awaitingFirstItem = true;
187
+ const markFirstItemReceived = () => {
188
+ awaitingFirstItem = false;
189
+ };
190
+ const isProgressItem = (item: T): boolean => {
191
+ if (!options.isProgressItem) return true;
192
+ try {
193
+ return options.isProgressItem(item);
194
+ } catch {
195
+ return true;
196
+ }
197
+ };
198
+ let lastProgressAt = Date.now();
199
+
200
+ const noTimeoutEnforced =
201
+ (firstItemTimeoutMs === undefined || firstItemTimeoutMs <= 0) &&
202
+ (options.idleTimeoutMs === undefined || options.idleTimeoutMs <= 0);
203
+
204
+ // Persistent racers, hoisted out of the per-item loop. The abort promise can
205
+ // only ever resolve once (abort latches), and a timeout resolution always
206
+ // precedes a throw — so neither needs per-item re-creation. This keeps the
207
+ // token hot path free of timer create/destroy and listener churn.
208
+ //
209
+ // Each Promise.race() call still attaches a reaction record to every pending
210
+ // racer, and those records live until the racer settles — so a never-firing
211
+ // abort/timeout promise would accumulate one record per streamed item for
212
+ // the stream's whole life. The loop re-mints both promises every
213
+ // RACER_REMINT_INTERVAL iterations to keep that retention bounded; the
214
+ // listener and timer callbacks resolve through late-bound variables so a
215
+ // re-mint never strands them.
216
+ let abortPromise: Promise<{ kind: "abort" }> | undefined;
217
+ let abortListener: (() => void) | undefined;
218
+ let resolveAbort: ((value: { kind: "abort" }) => void) | undefined;
219
+ if (abortSignal) {
220
+ const { promise, resolve } = Promise.withResolvers<{ kind: "abort" }>();
221
+ resolveAbort = resolve;
222
+ abortListener = () => resolveAbort?.({ kind: "abort" });
223
+ abortSignal.addEventListener("abort", abortListener, { once: true });
224
+ abortPromise = promise;
225
+ }
226
+
227
+ let timeoutPromise: Promise<{ kind: "timeout" }> | undefined;
228
+ let resolveTimeout: ((value: { kind: "timeout" }) => void) | undefined;
229
+ let timeoutFired = false;
230
+ let timer: NodeJS.Timeout | undefined;
231
+ let timerFireAtMs = Infinity;
232
+
233
+ const currentDeadlineMs = (): number | undefined => {
234
+ if (awaitingFirstItem) return firstItemDeadlineMs;
235
+ if (options.idleTimeoutMs !== undefined && options.idleTimeoutMs > 0) {
236
+ return lastProgressAt + options.idleTimeoutMs;
237
+ }
238
+ return undefined;
239
+ };
240
+ const onTimerFire = (): void => {
241
+ timer = undefined;
242
+ timerFireAtMs = Infinity;
243
+ const deadlineMs = currentDeadlineMs();
244
+ if (deadlineMs === undefined) return;
245
+ const remainingMs = deadlineMs - Date.now();
246
+ if (remainingMs > 0) {
247
+ // Progress moved the deadline since this timer was armed — re-arm for
248
+ // the remainder. One stale wake per idle period, not one per item.
249
+ timerFireAtMs = deadlineMs;
250
+ timer = setTimeout(onTimerFire, remainingMs);
251
+ return;
252
+ }
253
+ timeoutFired = true;
254
+ resolveTimeout?.({ kind: "timeout" });
255
+ };
256
+ const armTimer = (deadlineMs: number): void => {
257
+ if (timeoutPromise === undefined || timeoutFired) {
258
+ // A fired-but-unconsumed resolution (the item won the same race) is
259
+ // stale — racing it again would fake a timeout, so mint a fresh one.
260
+ const { promise, resolve } = Promise.withResolvers<{ kind: "timeout" }>();
261
+ timeoutPromise = promise;
262
+ resolveTimeout = resolve;
263
+ timeoutFired = false;
264
+ }
265
+ if (timer !== undefined) {
266
+ // An armed timer firing at or before the new deadline re-arms itself.
267
+ if (timerFireAtMs <= deadlineMs) return;
268
+ clearTimeout(timer);
269
+ }
270
+ timerFireAtMs = deadlineMs;
271
+ timer = setTimeout(onTimerFire, Math.max(0, deadlineMs - Date.now()));
272
+ };
273
+
274
+ try {
275
+ let raceCount = 0;
276
+ while (true) {
277
+ if (++raceCount % RACER_REMINT_INTERVAL === 0) {
278
+ if (abortPromise !== undefined && !abortSignal!.aborted) {
279
+ const { promise, resolve } = Promise.withResolvers<{ kind: "abort" }>();
280
+ resolveAbort = resolve;
281
+ abortPromise = promise;
282
+ }
283
+ if (timeoutPromise !== undefined && !timeoutFired) {
284
+ const { promise, resolve } = Promise.withResolvers<{ kind: "timeout" }>();
285
+ resolveTimeout = resolve;
286
+ timeoutPromise = promise;
287
+ }
288
+ }
289
+ let activeTimeoutMs: number | undefined;
290
+ if (awaitingFirstItem) {
291
+ if (firstItemDeadlineMs !== undefined) {
292
+ activeTimeoutMs = firstItemDeadlineMs - Date.now();
293
+ if (activeTimeoutMs <= 0) {
294
+ options.onFirstItemTimeout?.();
295
+ closeIterator();
296
+ throw new AIError.StreamTimeoutError(options.firstItemErrorMessage ?? options.errorMessage);
297
+ }
298
+ }
299
+ } else if (options.idleTimeoutMs !== undefined && options.idleTimeoutMs > 0) {
300
+ activeTimeoutMs = options.idleTimeoutMs - (Date.now() - lastProgressAt);
301
+ if (activeTimeoutMs <= 0) {
302
+ options.onIdle?.();
303
+ closeIterator();
304
+ throw new AIError.StreamTimeoutError(options.errorMessage);
305
+ }
306
+ }
307
+
308
+ const nextResultPromise = withRacy(iterator.next());
309
+
310
+ const racers: Array<
311
+ Promise<
312
+ | { kind: "next"; result: IteratorResult<T> }
313
+ | { kind: "error"; error: unknown }
314
+ | { kind: "timeout" }
315
+ | { kind: "abort" }
316
+ >
317
+ > = [nextResultPromise];
318
+
319
+ const enforceTimeout = !noTimeoutEnforced && activeTimeoutMs !== undefined && activeTimeoutMs > 0;
320
+ if (enforceTimeout) {
321
+ armTimer(Date.now() + activeTimeoutMs!);
322
+ racers.push(timeoutPromise!);
323
+ }
324
+ if (abortPromise) {
325
+ racers.push(abortPromise);
326
+ }
327
+
328
+ // Tracks whether this iteration handed an item to the consumer and resumed
329
+ // normally. Any other exit — internal throw, `done` return, or the consumer
330
+ // abandoning us via `.return()`/`.throw()` at the `yield` below — must close
331
+ // the upstream iterator so the underlying SSE body / SDK stream (and its
332
+ // socket) is released instead of being left suspended.
333
+ let continuing = false;
334
+ try {
335
+ const outcome = await Promise.race(racers);
336
+ if (outcome.kind === "abort") {
337
+ closeIterator();
338
+ throw abortReason(abortSignal!);
339
+ }
340
+ if (outcome.kind === "timeout") {
341
+ if (!awaitingFirstItem) {
342
+ options.onIdle?.();
343
+ } else {
344
+ options.onFirstItemTimeout?.();
345
+ }
346
+ closeIterator();
347
+ throw new AIError.StreamTimeoutError(
348
+ !awaitingFirstItem ? options.errorMessage : (options.firstItemErrorMessage ?? options.errorMessage),
349
+ );
350
+ }
351
+ if (outcome.kind === "error") {
352
+ throw outcome.error;
353
+ }
354
+ if (outcome.result.done) {
355
+ markFirstItemReceived();
356
+ return;
357
+ }
358
+ const item = outcome.result.value;
359
+ // Non-progress items (e.g. provider keepalives, synthetic `start` events that
360
+ // arrive before the model has produced any tokens) MUST NOT flip us out of
361
+ // `awaitingFirstItem`. Otherwise the next iteration switches from the (longer)
362
+ // first-item watchdog to the (shorter) idle watchdog while we're still waiting
363
+ // on the model's first real output.
364
+ if (isProgressItem(item)) {
365
+ markFirstItemReceived();
366
+ lastProgressAt = Date.now();
367
+ }
368
+ yield item;
369
+ continuing = true;
370
+ } finally {
371
+ if (!continuing) closeIterator();
372
+ }
373
+ }
374
+ } finally {
375
+ if (timer !== undefined) clearTimeout(timer);
376
+ // Settle the persistent racers so the final Promise.race releases them.
377
+ resolveTimeout?.({ kind: "timeout" });
378
+ if (abortListener && abortSignal) {
379
+ abortSignal.removeEventListener("abort", abortListener);
380
+ }
381
+ resolveAbort?.({ kind: "abort" });
382
+ }
383
+ }
384
+
385
+ export interface TerminalGraceIteratorOptions {
386
+ /**
387
+ * Epoch-ms timestamp at which the consumer observed a logically terminal
388
+ * item (e.g. a chat-completions chunk carrying `finish_reason`), or
389
+ * `undefined` while the stream is still mid-response. Read before every
390
+ * pull, so the consumer can flip it between yields.
391
+ */
392
+ finishedAtMs: () => number | undefined;
393
+ /**
394
+ * Post-terminal budget: how long after `finishedAtMs()` to keep draining
395
+ * trailing items (e.g. a usage-only chunk or the `[DONE]` sentinel) before
396
+ * ending the iteration cleanly. The deadline is fixed at
397
+ * `finishedAtMs() + graceMs`; trailing items do not extend it, so
398
+ * keepalive-only servers cannot hold the stream open.
399
+ */
400
+ graceMs: number;
401
+ /**
402
+ * Invoked when the grace window closes with the source still open. Use it
403
+ * to abort the underlying request: the source generator is typically parked
404
+ * mid-`next()` (not at a yield), so a queued `.return()` alone cannot reach
405
+ * the transport until that pending read settles.
406
+ */
407
+ onGraceEnd?: () => void;
408
+ }
409
+
410
+ /**
411
+ * Yields items from an async iterable until the consumer marks the stream
412
+ * logically finished AND the source stays silent past a short grace window.
413
+ *
414
+ * Misbehaving OpenAI-compatible servers deliver the terminal chunk but never
415
+ * send `[DONE]` nor close the connection; without this guard the consumer
416
+ * hangs on `iterator.next()` until the idle watchdog converts an
417
+ * already-successful turn into a timeout error. Grace expiry is a clean end
418
+ * of iteration, never an error.
419
+ */
420
+ export async function* iterateWithTerminalGrace<T>(
421
+ iterable: AsyncIterable<T>,
422
+ options: TerminalGraceIteratorOptions,
423
+ ): AsyncGenerator<T> {
424
+ const iterator = iterable[Symbol.asyncIterator]();
425
+ try {
426
+ while (true) {
427
+ const finishedAtMs = options.finishedAtMs();
428
+ if (finishedAtMs === undefined) {
429
+ const result = await iterator.next();
430
+ if (result.done) return;
431
+ yield result.value;
432
+ continue;
433
+ }
434
+ const remainingMs = finishedAtMs + options.graceMs - Date.now();
435
+ if (remainingMs <= 0) {
436
+ options.onGraceEnd?.();
437
+ return;
438
+ }
439
+ const nextPromise = iterator.next();
440
+ let timer: NodeJS.Timeout | undefined;
441
+ const timeoutPromise = new Promise<"timeout">(resolve => {
442
+ timer = setTimeout(() => resolve("timeout"), remainingMs);
443
+ });
444
+ try {
445
+ const outcome = await Promise.race([nextPromise, timeoutPromise]);
446
+ if (outcome === "timeout") {
447
+ // The abandoned read settles (likely rejects) once onGraceEnd
448
+ // aborts the transport — mark it handled so it cannot surface
449
+ // as an unhandled rejection.
450
+ nextPromise.catch(() => {});
451
+ options.onGraceEnd?.();
452
+ return;
453
+ }
454
+ if (outcome.done) return;
455
+ yield outcome.value;
456
+ } finally {
457
+ if (timer !== undefined) clearTimeout(timer);
458
+ }
459
+ }
460
+ } finally {
461
+ const returnPromise = iterator.return?.();
462
+ if (returnPromise) {
463
+ void Promise.resolve(returnPromise).catch(() => {});
464
+ }
465
+ }
466
+ }
467
+
468
+ function abortReason(signal: AbortSignal): Error {
469
+ const reason = signal.reason;
470
+ if (reason instanceof Error) return reason;
471
+ if (typeof reason === "string") return new AIError.AbortError(reason);
472
+ return new AIError.AbortError();
473
+ }