@linxiraos/pi-ai 1.0.0

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