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,240 @@
1
+ import * as net from "node:net";
2
+ import * as tls from "node:tls";
3
+ import * as AIError from "../error";
4
+ import type { FetchImpl } from "../types";
5
+
6
+ /**
7
+ * Checks if a host is local or cloud metadata, which should always bypass the proxy
8
+ * (e.g. localhost, 127/8, ::1, 169.254.169.254, metadata.google.internal).
9
+ */
10
+ export function isLocalOrMetadataHost(host: string): boolean {
11
+ const lowerHost = host.toLowerCase();
12
+
13
+ // Hostnames: localhost and the cloud metadata service.
14
+ if (lowerHost === "localhost" || lowerHost.endsWith(".localhost") || lowerHost === "metadata.google.internal") {
15
+ return true;
16
+ }
17
+
18
+ // Strip IPv6 brackets before numeric checks.
19
+ const ip = lowerHost.replace(/^\[|\]$/g, "");
20
+
21
+ // IPv4 loopback (127/8), unspecified (0/8), RFC1918 private (10/8, 172.16/12,
22
+ // 192.168/16) and link-local (169.254/16 — covers IMDS 169.254.169.254 and
23
+ // ECS credentials 169.254.170.2). None are reachable through a remote egress
24
+ // proxy, and credential/metadata probes must never leak to one.
25
+ const v4 = ip.match(/^(\d{1,3})\.(\d{1,3})\.\d{1,3}\.\d{1,3}$/);
26
+ if (v4) {
27
+ const a = Number(v4[1]);
28
+ const b = Number(v4[2]);
29
+ if (a === 127 || a === 10 || a === 0) return true;
30
+ if (a === 169 && b === 254) return true;
31
+ if (a === 192 && b === 168) return true;
32
+ if (a === 172 && b >= 16 && b <= 31) return true;
33
+ return false;
34
+ }
35
+
36
+ // IPv6 loopback (::1), unspecified (::), link-local (fe80::/10) and
37
+ // unique-local (fc00::/7 — covers EC2 IPv6 IMDS fd00:ec2::254).
38
+ if (ip === "::1" || ip === "::") return true;
39
+ if (/^fe[89ab][0-9a-f]:/.test(ip)) return true;
40
+ if (/^f[cd][0-9a-f]{2}:/.test(ip)) return true;
41
+
42
+ return false;
43
+ }
44
+
45
+ /**
46
+ * Check if the url should bypass the proxy due to hard-coded localhost/metadata checks
47
+ * or custom NO_PROXY/no_proxy environment variables rules.
48
+ */
49
+ export function shouldBypassProxy(urlObj: URL): boolean {
50
+ if (isLocalOrMetadataHost(urlObj.hostname)) {
51
+ return true;
52
+ }
53
+
54
+ const noProxyVal = Bun.env.NO_PROXY || Bun.env.no_proxy;
55
+ if (!noProxyVal) {
56
+ return false;
57
+ }
58
+
59
+ const rules = noProxyVal
60
+ .split(/[,\s]+/)
61
+ .map(r => r.trim())
62
+ .filter(Boolean);
63
+ const targetHost = urlObj.hostname.toLowerCase();
64
+ const targetPort = urlObj.port || (urlObj.protocol === "https:" ? "443" : "80");
65
+
66
+ for (const rule of rules) {
67
+ if (rule === "*") {
68
+ return true;
69
+ }
70
+
71
+ let ruleHost = rule.toLowerCase();
72
+ let rulePort: string | undefined;
73
+
74
+ if (ruleHost.includes("]:")) {
75
+ const lastColon = ruleHost.lastIndexOf(":");
76
+ rulePort = ruleHost.slice(lastColon + 1);
77
+ ruleHost = ruleHost.slice(0, lastColon);
78
+ } else if (!ruleHost.includes("]") && ruleHost.includes(":")) {
79
+ const lastColon = ruleHost.lastIndexOf(":");
80
+ rulePort = ruleHost.slice(lastColon + 1);
81
+ ruleHost = ruleHost.slice(0, lastColon);
82
+ }
83
+
84
+ // Strip IPv6 brackets
85
+ ruleHost = ruleHost.replace(/^\[|\]$/g, "");
86
+
87
+ if (rulePort && rulePort !== targetPort) {
88
+ continue;
89
+ }
90
+
91
+ // Match host part
92
+ if (ruleHost.startsWith(".")) {
93
+ const suffix = ruleHost;
94
+ const cleanRule = ruleHost.slice(1);
95
+ if (targetHost === cleanRule || targetHost.endsWith(suffix)) {
96
+ return true;
97
+ }
98
+ } else {
99
+ if (targetHost === ruleHost || targetHost.endsWith(`.${ruleHost}`)) {
100
+ return true;
101
+ }
102
+ }
103
+ }
104
+
105
+ return false;
106
+ }
107
+
108
+ const proxyCache = new Map<string, string | undefined>();
109
+
110
+ /** Test seam: clears the provider proxy cache. */
111
+ export function __resetProxyCache(): void {
112
+ proxyCache.clear();
113
+ }
114
+
115
+ /**
116
+ * Normalizes provider id (e.g. github-copilot -> PI_PROXY_GITHUB_COPILOT) and looks it up.
117
+ * If not found, falls back to PI_PROXY. Results are memoized because env values are static
118
+ * for the lifetime of the process and this function is called for every outgoing request.
119
+ */
120
+ export function getProxyForProvider(provider: string): string | undefined {
121
+ if (proxyCache.has(provider)) {
122
+ return proxyCache.get(provider);
123
+ }
124
+
125
+ const normalized = provider.toUpperCase().replace(/[^A-Z0-9]/g, "_");
126
+ const envKey = `PI_PROXY_${normalized}`;
127
+ const value = Bun.env[envKey] || Bun.env.PI_PROXY;
128
+ proxyCache.set(provider, value);
129
+ return value;
130
+ }
131
+
132
+ /**
133
+ * Wraps a fetch implementation to inject proxy options for non-local hosts.
134
+ */
135
+ export function wrapFetchForProxy(fetchImpl: FetchImpl, provider: string): FetchImpl {
136
+ const proxyUrl = getProxyForProvider(provider);
137
+ if (!proxyUrl) {
138
+ return fetchImpl;
139
+ }
140
+
141
+ const wrapped = async (input: string | URL | Request, init?: RequestInit): Promise<Response> => {
142
+ const urlStr = input instanceof Request ? input.url : input.toString();
143
+ let urlObj: URL;
144
+ try {
145
+ urlObj = new URL(urlStr);
146
+ } catch {
147
+ // Fallback to calling fetch unmodified if URL is unparseable
148
+ return fetchImpl(input, init);
149
+ }
150
+
151
+ if (shouldBypassProxy(urlObj)) {
152
+ return fetchImpl(input, init);
153
+ }
154
+
155
+ const mergedInit = { ...(init ?? {}), proxy: proxyUrl };
156
+ return fetchImpl(input, mergedInit);
157
+ };
158
+
159
+ if (fetchImpl.preconnect) {
160
+ wrapped.preconnect = fetchImpl.preconnect;
161
+ }
162
+ return wrapped;
163
+ }
164
+
165
+ /**
166
+ * Tunnel a socket connection through an HTTP CONNECT proxy.
167
+ * This is used specifically to wrap Node's `http2.connect(baseUrl, { createConnection })` for Cursor.
168
+ */
169
+ export async function connectProxiedSocket(proxyUrlStr: string, targetUrlStr: string): Promise<tls.TLSSocket> {
170
+ const proxyUrl = new URL(proxyUrlStr);
171
+ const targetUrl = new URL(targetUrlStr);
172
+
173
+ const useProxySsl = proxyUrl.protocol === "https:";
174
+ const proxyPort = proxyUrl.port ? parseInt(proxyUrl.port, 10) : useProxySsl ? 443 : 80;
175
+ const proxyHost = proxyUrl.hostname;
176
+
177
+ const targetPort = targetUrl.port ? parseInt(targetUrl.port, 10) : 443;
178
+ const targetHost = targetUrl.hostname;
179
+
180
+ const { promise, resolve, reject } = Promise.withResolvers<tls.TLSSocket>();
181
+
182
+ let rawSocket: net.Socket;
183
+ if (useProxySsl) {
184
+ rawSocket = tls.connect({
185
+ host: proxyHost,
186
+ port: proxyPort,
187
+ });
188
+ } else {
189
+ rawSocket = net.connect({
190
+ host: proxyHost,
191
+ port: proxyPort,
192
+ });
193
+ }
194
+
195
+ rawSocket.once("error", reject);
196
+
197
+ const readyEvent = useProxySsl ? "secureConnect" : "connect";
198
+ rawSocket.once(readyEvent, () => {
199
+ let connectReq = `CONNECT ${targetHost}:${targetPort} HTTP/1.1\r\n` + `Host: ${targetHost}:${targetPort}\r\n`;
200
+
201
+ if (proxyUrl.username || proxyUrl.password) {
202
+ const creds = Buffer.from(
203
+ `${decodeURIComponent(proxyUrl.username)}:${decodeURIComponent(proxyUrl.password)}`,
204
+ ).toString("base64");
205
+ connectReq += `Proxy-Authorization: Basic ${creds}\r\n`;
206
+ }
207
+ connectReq += "\r\n";
208
+
209
+ rawSocket.write(connectReq);
210
+
211
+ let responseData = "";
212
+ const onData = (chunk: Buffer) => {
213
+ responseData += chunk.toString("binary");
214
+ if (responseData.includes("\r\n\r\n")) {
215
+ rawSocket.off("data", onData);
216
+ rawSocket.off("error", reject);
217
+
218
+ const firstLine = responseData.split("\r\n")[0];
219
+ if (firstLine.includes(" 200 ")) {
220
+ const tlsSocket = tls.connect({
221
+ socket: rawSocket,
222
+ servername: targetHost,
223
+ ALPNProtocols: ["h2"],
224
+ });
225
+
226
+ tlsSocket.once("secureConnect", () => {
227
+ resolve(tlsSocket);
228
+ });
229
+ tlsSocket.once("error", reject);
230
+ } else {
231
+ rawSocket.destroy();
232
+ reject(new AIError.ValidationError(`Proxy tunnel failed: ${firstLine}`));
233
+ }
234
+ }
235
+ };
236
+ rawSocket.on("data", onData);
237
+ });
238
+
239
+ return promise;
240
+ }
@@ -0,0 +1,351 @@
1
+ import { Buffer } from "node:buffer";
2
+ import * as fs from "node:fs/promises";
3
+ import type { FetchImpl } from "../types";
4
+
5
+ const REQUEST_DEBUG_ENV = "PI_REQ_DEBUG";
6
+ const DEBUG_FETCH_MARKER = Symbol("omp.requestDebugFetch");
7
+ const textEncoder = new TextEncoder();
8
+ const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
9
+
10
+ let nextSessionId = 1;
11
+
12
+ type DebugFetch = FetchImpl & { [DEBUG_FETCH_MARKER]?: true };
13
+ type RequestBodyInit = NonNullable<RequestInit["body"]>;
14
+
15
+ type RequestDebugBody = { body: unknown } | { bodyText: string } | { bodyBase64: string } | { bodyUnavailable: string };
16
+
17
+ export type RequestDebugHeaders = Headers | Record<string, string | string[] | number | undefined | null> | undefined;
18
+
19
+ export interface RequestDebugPayload {
20
+ method: string;
21
+ url: string;
22
+ headers?: RequestDebugHeaders;
23
+ body?: unknown;
24
+ bodyText?: string;
25
+ bodyBase64?: string;
26
+ bodyUnavailable?: string;
27
+ protocol?: string;
28
+ }
29
+
30
+ interface ReservedRequestDebugFile {
31
+ id: number;
32
+ requestPath: string;
33
+ responsePath: string;
34
+ handle: fs.FileHandle;
35
+ overwrite: boolean;
36
+ }
37
+
38
+ export interface RequestDebugResponseLog {
39
+ write(chunk: Uint8Array | string): void;
40
+ close(): Promise<void>;
41
+ }
42
+
43
+ export interface RequestDebugSession {
44
+ readonly id: number;
45
+ readonly requestPath: string;
46
+ readonly responsePath: string;
47
+ openResponseLog(statusLine: string, headers?: RequestDebugHeaders): Promise<RequestDebugResponseLog>;
48
+ wrapResponse(response: Response): Promise<Response>;
49
+ }
50
+
51
+ function isRequestDebugEnvEnabled(): boolean {
52
+ return Bun.env[REQUEST_DEBUG_ENV] === "1";
53
+ }
54
+
55
+ export function isRequestDebugEnabled(): boolean {
56
+ return isRequestDebugEnvEnabled();
57
+ }
58
+
59
+ export function wrapFetchForRequestDebug(fetchImpl: FetchImpl): FetchImpl {
60
+ if (!isRequestDebugEnabled()) return fetchImpl;
61
+ const maybeWrapped = fetchImpl as DebugFetch;
62
+ if (maybeWrapped[DEBUG_FETCH_MARKER]) return fetchImpl;
63
+
64
+ const wrapped = Object.assign(
65
+ async (input: string | URL | Request, init?: RequestInit): Promise<Response> => {
66
+ if (!isRequestDebugEnabled()) return fetchImpl(input, init);
67
+ const session = await createFetchRequestDebugSession(input, init);
68
+ const response = await fetchImpl(input, init);
69
+ return session.wrapResponse(response);
70
+ },
71
+ fetchImpl.preconnect ? { preconnect: fetchImpl.preconnect } : {},
72
+ { [DEBUG_FETCH_MARKER]: true as const },
73
+ );
74
+ return wrapped;
75
+ }
76
+
77
+ export function withRequestDebugFetch<T extends { fetch?: FetchImpl } | undefined>(options: T): T {
78
+ if (!isRequestDebugEnabled()) return options;
79
+ const fetchImpl = options?.fetch ?? (globalThis.fetch as FetchImpl);
80
+ const wrapped = wrapFetchForRequestDebug(fetchImpl);
81
+ return { ...(options ?? {}), fetch: wrapped } as T;
82
+ }
83
+
84
+ export async function createRequestDebugSession(payload: RequestDebugPayload): Promise<RequestDebugSession> {
85
+ const { id, requestPath, responsePath, handle, overwrite } = await reserveRequestDebugFile();
86
+ const requestDump: Record<string, unknown> = {
87
+ id,
88
+ protocol: payload.protocol ?? "http",
89
+ method: payload.method,
90
+ url: payload.url,
91
+ };
92
+ const headers = headersToRecord(payload.headers);
93
+ if (headers) requestDump.headers = headers;
94
+ if (payload.body !== undefined) requestDump.body = payload.body;
95
+ if (payload.bodyText !== undefined) requestDump.bodyText = payload.bodyText;
96
+ if (payload.bodyBase64 !== undefined) requestDump.bodyBase64 = payload.bodyBase64;
97
+ if (payload.bodyUnavailable !== undefined) requestDump.bodyUnavailable = payload.bodyUnavailable;
98
+
99
+ try {
100
+ await handle.writeFile(`${JSON.stringify(requestDump, null, 2)}\n`, "utf8");
101
+ } finally {
102
+ await handle.close();
103
+ }
104
+
105
+ return new FileRequestDebugSession(id, requestPath, responsePath, overwrite);
106
+ }
107
+
108
+ async function createFetchRequestDebugSession(
109
+ input: string | URL | Request,
110
+ init: RequestInit | undefined,
111
+ ): Promise<RequestDebugSession> {
112
+ const headers = resolveRequestHeaders(input, init);
113
+ const body = await snapshotRequestBody(input, init, headers.get("content-type"));
114
+ return createRequestDebugSession({
115
+ method: resolveRequestMethod(input, init),
116
+ url: resolveRequestUrl(input),
117
+ headers,
118
+ ...body,
119
+ });
120
+ }
121
+
122
+ class FileRequestDebugSession implements RequestDebugSession {
123
+ readonly id: number;
124
+ readonly requestPath: string;
125
+ readonly responsePath: string;
126
+ readonly #overwriteResponseLog: boolean;
127
+
128
+ constructor(id: number, requestPath: string, responsePath: string, overwriteResponseLog: boolean) {
129
+ this.id = id;
130
+ this.requestPath = requestPath;
131
+ this.responsePath = responsePath;
132
+ this.#overwriteResponseLog = overwriteResponseLog;
133
+ }
134
+
135
+ async openResponseLog(statusLine: string, headers?: RequestDebugHeaders): Promise<RequestDebugResponseLog> {
136
+ const handle = await fs.open(this.responsePath, this.#overwriteResponseLog ? "w" : "wx");
137
+ const headerBlock = formatResponseHeaderBlock(statusLine, headers);
138
+ await handle.write(textEncoder.encode(headerBlock));
139
+ return new FileRequestDebugResponseLog(handle);
140
+ }
141
+
142
+ async wrapResponse(response: Response): Promise<Response> {
143
+ const log = await this.openResponseLog(`HTTP ${response.status} ${response.statusText}`.trim(), response.headers);
144
+ if (!response.body) {
145
+ await log.close();
146
+ return response;
147
+ }
148
+
149
+ const reader = response.body.getReader();
150
+ const teed = new ReadableStream<Uint8Array>({
151
+ async pull(controller) {
152
+ try {
153
+ const { done, value } = await reader.read();
154
+ if (done) {
155
+ await log.close();
156
+ controller.close();
157
+ return;
158
+ }
159
+ log.write(value);
160
+ controller.enqueue(value);
161
+ } catch (error) {
162
+ await log.close().catch(() => undefined);
163
+ controller.error(error);
164
+ }
165
+ },
166
+ async cancel(reason) {
167
+ try {
168
+ await reader.cancel(reason);
169
+ } finally {
170
+ await log.close();
171
+ }
172
+ },
173
+ });
174
+
175
+ const wrapped = new Response(teed, {
176
+ status: response.status,
177
+ statusText: response.statusText,
178
+ headers: response.headers,
179
+ });
180
+ copyResponseMetadata(wrapped, response);
181
+ return wrapped;
182
+ }
183
+ }
184
+
185
+ class FileRequestDebugResponseLog implements RequestDebugResponseLog {
186
+ #handle: fs.FileHandle | undefined;
187
+ #pending: Promise<void> = Promise.resolve();
188
+ #closed: Promise<void> | undefined;
189
+
190
+ constructor(handle: fs.FileHandle) {
191
+ this.#handle = handle;
192
+ }
193
+
194
+ write(chunk: Uint8Array | string): void {
195
+ const handle = this.#handle;
196
+ if (!handle) return;
197
+ const bytes = typeof chunk === "string" ? textEncoder.encode(chunk) : chunk.slice();
198
+ this.#pending = this.#pending.then(async () => {
199
+ await handle.write(bytes);
200
+ });
201
+ }
202
+
203
+ close(): Promise<void> {
204
+ if (this.#closed) return this.#closed;
205
+ const handle = this.#handle;
206
+ if (!handle) return Promise.resolve();
207
+ this.#handle = undefined;
208
+ this.#closed = (async () => {
209
+ try {
210
+ await this.#pending;
211
+ } finally {
212
+ await handle.close();
213
+ }
214
+ })();
215
+ return this.#closed;
216
+ }
217
+ }
218
+
219
+ function copyResponseMetadata(target: Response, source: Response): void {
220
+ const sourceUrl = source.url;
221
+ if (!sourceUrl) return;
222
+ try {
223
+ Object.defineProperty(target, "url", { value: sourceUrl, configurable: true });
224
+ } catch {
225
+ // Some runtimes may expose Response.url as non-configurable. The body
226
+ // capture remains correct; callers that need url already tolerate the
227
+ // platform default on other response wrappers in this package.
228
+ }
229
+ }
230
+
231
+ async function reserveRequestDebugFile(): Promise<ReservedRequestDebugFile> {
232
+ for (;;) {
233
+ const id = nextSessionId++;
234
+ const requestPath = `rr-session-${id}.json`;
235
+ try {
236
+ const handle = await fs.open(requestPath, "wx");
237
+ return { id, requestPath, responsePath: `rr-session-${id}.res.log`, handle, overwrite: false };
238
+ } catch (error) {
239
+ if (isFileExistsError(error)) continue;
240
+ throw error;
241
+ }
242
+ }
243
+ }
244
+
245
+ function resolveRequestMethod(input: string | URL | Request, init: RequestInit | undefined): string {
246
+ return (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
247
+ }
248
+
249
+ function resolveRequestUrl(input: string | URL | Request): string {
250
+ return input instanceof Request ? input.url : input.toString();
251
+ }
252
+
253
+ function resolveRequestHeaders(input: string | URL | Request, init: RequestInit | undefined): Headers {
254
+ if (init?.headers) return new Headers(init.headers);
255
+ return input instanceof Request ? new Headers(input.headers) : new Headers();
256
+ }
257
+
258
+ async function snapshotRequestBody(
259
+ input: string | URL | Request,
260
+ init: RequestInit | undefined,
261
+ contentType: string | null,
262
+ ): Promise<RequestDebugBody | undefined> {
263
+ if (init?.body !== undefined && init.body !== null) return snapshotBodyInit(init.body, contentType);
264
+ if (input instanceof Request && input.body) {
265
+ return snapshotBytes(new Uint8Array(await input.clone().arrayBuffer()), contentType);
266
+ }
267
+ return undefined;
268
+ }
269
+
270
+ async function snapshotBodyInit(body: RequestBodyInit, contentType: string | null): Promise<RequestDebugBody> {
271
+ if (typeof body === "string") return snapshotText(body, contentType);
272
+ if (body instanceof URLSearchParams) return { bodyText: body.toString() };
273
+ if (body instanceof FormData) return { bodyUnavailable: "FormData" };
274
+ if (body instanceof Blob) return snapshotBytes(new Uint8Array(await body.arrayBuffer()), body.type || contentType);
275
+ if (body instanceof ArrayBuffer) return snapshotBytes(new Uint8Array(body), contentType);
276
+ if (ArrayBuffer.isView(body)) {
277
+ return snapshotBytes(new Uint8Array(body.buffer, body.byteOffset, body.byteLength), contentType);
278
+ }
279
+ if (body instanceof ReadableStream) return { bodyUnavailable: "ReadableStream" };
280
+ return { bodyText: String(body) };
281
+ }
282
+
283
+ function snapshotBytes(bytes: Uint8Array, contentType: string | null): RequestDebugBody {
284
+ try {
285
+ return snapshotText(utf8Decoder.decode(bytes), contentType);
286
+ } catch {
287
+ return { bodyBase64: Buffer.from(bytes).toString("base64") };
288
+ }
289
+ }
290
+
291
+ function snapshotText(text: string, contentType: string | null): RequestDebugBody {
292
+ if (isJsonContentType(contentType) || looksLikeJson(text)) {
293
+ try {
294
+ return { body: JSON.parse(text) };
295
+ } catch {
296
+ // Fall through to bodyText: malformed JSON is still useful as raw text.
297
+ }
298
+ }
299
+ return { bodyText: text };
300
+ }
301
+
302
+ function isJsonContentType(contentType: string | null): boolean {
303
+ if (!contentType) return false;
304
+ const lower = contentType.toLowerCase();
305
+ return lower.includes("application/json") || lower.includes("+json");
306
+ }
307
+
308
+ function looksLikeJson(text: string): boolean {
309
+ const trimmed = text.trimStart();
310
+ return trimmed.startsWith("{") || trimmed.startsWith("[");
311
+ }
312
+
313
+ function formatResponseHeaderBlock(statusLine: string, headers?: RequestDebugHeaders): string {
314
+ const lines = [statusLine];
315
+ const record = headersToRecord(headers);
316
+ if (record) {
317
+ for (const name in record) {
318
+ const value = record[name];
319
+ if (Array.isArray(value)) {
320
+ for (const item of value) lines.push(`${name}: ${item}`);
321
+ } else {
322
+ lines.push(`${name}: ${value}`);
323
+ }
324
+ }
325
+ }
326
+ return `${lines.join("\r\n")}\r\n\r\n`;
327
+ }
328
+
329
+ function headersToRecord(headers: RequestDebugHeaders): Record<string, string | string[]> | undefined {
330
+ if (!headers) return undefined;
331
+ const record: Record<string, string | string[]> = {};
332
+ let hasHeaders = false;
333
+ if (headers instanceof Headers) {
334
+ headers.forEach((value, key) => {
335
+ hasHeaders = true;
336
+ record[key] = value;
337
+ });
338
+ } else {
339
+ for (const key in headers) {
340
+ const value = headers[key];
341
+ if (value === undefined || value === null) continue;
342
+ hasHeaders = true;
343
+ record[key] = Array.isArray(value) ? value.map(String) : String(value);
344
+ }
345
+ }
346
+ return hasHeaders ? record : undefined;
347
+ }
348
+
349
+ function isFileExistsError(error: unknown): boolean {
350
+ return typeof error === "object" && error !== null && (error as { code?: unknown }).code === "EEXIST";
351
+ }
@@ -0,0 +1,110 @@
1
+ export type HeadersLike = Headers | Record<string, string | undefined> | undefined | null;
2
+
3
+ const RETRY_AFTER_HINT = "retry-after-ms=";
4
+
5
+ export function formatErrorMessageWithRetryAfter(error: unknown, headers?: HeadersLike): string {
6
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
7
+ if (message.includes(RETRY_AFTER_HINT)) {
8
+ return message;
9
+ }
10
+
11
+ const retryAfterMs = getRetryAfterMsFromHeaders(headers ?? getHeadersFromError(error));
12
+ if (retryAfterMs === undefined) {
13
+ return message;
14
+ }
15
+
16
+ return `${message} ${RETRY_AFTER_HINT}${retryAfterMs}`;
17
+ }
18
+
19
+ export function getRetryAfterMsFromHeaders(headers: HeadersLike): number | undefined {
20
+ if (!headers) return undefined;
21
+
22
+ const retryAfter = parseRetryAfterHeader(getHeaderValue(headers, "retry-after"));
23
+ const resetMs = parseResetHeader(getHeaderValue(headers, "x-ratelimit-reset-ms"), "ms");
24
+ const resetSeconds = parseResetHeader(getHeaderValue(headers, "x-ratelimit-reset"), "s");
25
+
26
+ const candidates = [retryAfter, resetMs, resetSeconds].filter((value): value is number => value !== undefined);
27
+ if (candidates.length === 0) return undefined;
28
+ return Math.max(...candidates);
29
+ }
30
+
31
+ export function getHeadersFromError(error: unknown): HeadersLike {
32
+ if (!error || typeof error !== "object") return undefined;
33
+ const record = error as { headers?: unknown; response?: { headers?: unknown }; cause?: unknown };
34
+ const direct = extractHeaders(record.headers) ?? extractHeaders(record.response?.headers);
35
+ if (direct) return direct;
36
+ if (record.cause) return getHeadersFromError(record.cause);
37
+ return undefined;
38
+ }
39
+
40
+ function extractHeaders(value: unknown): HeadersLike {
41
+ if (!value) return undefined;
42
+ if (value instanceof Headers) return value;
43
+ if (typeof value === "object") return value as Record<string, string | undefined>;
44
+ return undefined;
45
+ }
46
+
47
+ function getHeaderValue(headers: Headers | Record<string, string | undefined>, name: string): string | undefined {
48
+ if (headers instanceof Headers) {
49
+ const value = headers.get(name);
50
+ return value ?? undefined;
51
+ }
52
+
53
+ const target = name.toLowerCase();
54
+ for (const [key, value] of Object.entries(headers)) {
55
+ if (key.toLowerCase() === target && typeof value === "string") {
56
+ return value;
57
+ }
58
+ }
59
+ return undefined;
60
+ }
61
+
62
+ function parseRetryAfterHeader(value: string | undefined): number | undefined {
63
+ if (!value) return undefined;
64
+ const trimmed = value.trim();
65
+ if (!trimmed) return undefined;
66
+
67
+ const numeric = Number(trimmed);
68
+ if (Number.isFinite(numeric)) {
69
+ if (numeric <= 0) return undefined;
70
+ return Math.ceil(numeric * 1000);
71
+ }
72
+
73
+ const dateMs = Date.parse(trimmed);
74
+ if (!Number.isNaN(dateMs)) {
75
+ const delay = dateMs - Date.now();
76
+ return delay > 0 ? Math.ceil(delay) : undefined;
77
+ }
78
+
79
+ return undefined;
80
+ }
81
+
82
+ function parseResetHeader(value: string | undefined, unit: "ms" | "s"): number | undefined {
83
+ if (!value) return undefined;
84
+ const numeric = Number(value);
85
+ if (!Number.isFinite(numeric) || numeric <= 0) return undefined;
86
+
87
+ const nowMs = Date.now();
88
+ let targetMs: number | undefined;
89
+
90
+ if (unit === "ms") {
91
+ if (numeric > 1e12) {
92
+ targetMs = numeric;
93
+ } else if (numeric > 1e9) {
94
+ targetMs = numeric * 1000;
95
+ } else {
96
+ return Math.ceil(numeric);
97
+ }
98
+ } else {
99
+ if (numeric > 1e12) {
100
+ targetMs = numeric;
101
+ } else if (numeric > 1e9) {
102
+ targetMs = numeric * 1000;
103
+ } else {
104
+ return Math.ceil(numeric * 1000);
105
+ }
106
+ }
107
+
108
+ if (targetMs <= nowMs) return undefined;
109
+ return Math.ceil(targetMs - nowMs);
110
+ }