@vib-rato/ai 0.16.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 (525) hide show
  1. package/CHANGELOG.md +3354 -0
  2. package/README.md +1194 -0
  3. package/dist/types/adapter-internals/provider-safety-stop.d.ts +45 -0
  4. package/dist/types/api-registry.d.ts +30 -0
  5. package/dist/types/auth-broker/client.d.ts +80 -0
  6. package/dist/types/auth-broker/index.d.ts +5 -0
  7. package/dist/types/auth-broker/redact.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 +153 -0
  10. package/dist/types/auth-broker/server.d.ts +32 -0
  11. package/dist/types/auth-broker/types.d.ts +132 -0
  12. package/dist/types/auth-broker/wire-schemas.d.ts +555 -0
  13. package/dist/types/auth-gateway/http.d.ts +40 -0
  14. package/dist/types/auth-gateway/index.d.ts +3 -0
  15. package/dist/types/auth-gateway/server.d.ts +70 -0
  16. package/dist/types/auth-gateway/types.d.ts +129 -0
  17. package/dist/types/auth-storage.d.ts +1074 -0
  18. package/dist/types/cli.d.ts +2 -0
  19. package/dist/types/codex-tools.d.ts +4 -0
  20. package/dist/types/context-cap-policy.d.ts +68 -0
  21. package/dist/types/core.d.ts +35 -0
  22. package/dist/types/index.d.ts +55 -0
  23. package/dist/types/model-cache.d.ts +24 -0
  24. package/dist/types/model-manager.d.ts +77 -0
  25. package/dist/types/model-pricing.d.ts +3 -0
  26. package/dist/types/model-retirements.d.ts +6 -0
  27. package/dist/types/model-thinking.d.ts +100 -0
  28. package/dist/types/models.d.ts +21 -0
  29. package/dist/types/openai-completions-compat.d.ts +34 -0
  30. package/dist/types/provider-details.d.ts +24 -0
  31. package/dist/types/provider-models/bundled-references.d.ts +4 -0
  32. package/dist/types/provider-models/descriptors.d.ts +48 -0
  33. package/dist/types/provider-models/google.d.ts +20 -0
  34. package/dist/types/provider-models/index.d.ts +5 -0
  35. package/dist/types/provider-models/ollama.d.ts +7 -0
  36. package/dist/types/provider-models/openai-compat.d.ts +293 -0
  37. package/dist/types/provider-models/special.d.ts +29 -0
  38. package/dist/types/providers/amazon-bedrock.d.ts +60 -0
  39. package/dist/types/providers/anthropic-messages-server-schema.d.ts +450 -0
  40. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  41. package/dist/types/providers/anthropic.d.ts +280 -0
  42. package/dist/types/providers/aws-credential-config.d.ts +19 -0
  43. package/dist/types/providers/aws-credentials.d.ts +43 -0
  44. package/dist/types/providers/aws-eventstream.d.ts +38 -0
  45. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  46. package/dist/types/providers/azure-openai-responses.d.ts +22 -0
  47. package/dist/types/providers/composer-discipline.d.ts +32 -0
  48. package/dist/types/providers/cursor/client-version.d.ts +10 -0
  49. package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
  50. package/dist/types/providers/cursor/gen/agent_pb.d.ts +16769 -0
  51. package/dist/types/providers/cursor-pi-args.d.ts +119 -0
  52. package/dist/types/providers/cursor.d.ts +72 -0
  53. package/dist/types/providers/dashscope-token-plan-headers.d.ts +57 -0
  54. package/dist/types/providers/error-message.d.ts +27 -0
  55. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  56. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  57. package/dist/types/providers/google-auth.d.ts +26 -0
  58. package/dist/types/providers/google-gemini-cli.d.ts +75 -0
  59. package/dist/types/providers/google-gemini-headers.d.ts +43 -0
  60. package/dist/types/providers/google-shared.d.ts +183 -0
  61. package/dist/types/providers/google-types.d.ts +138 -0
  62. package/dist/types/providers/google-vertex.d.ts +11 -0
  63. package/dist/types/providers/google.d.ts +4 -0
  64. package/dist/types/providers/grammar.d.ts +1 -0
  65. package/dist/types/providers/kimi.d.ts +27 -0
  66. package/dist/types/providers/kiro-api-key.d.ts +50 -0
  67. package/dist/types/providers/kiro-codewhisperer.d.ts +11 -0
  68. package/dist/types/providers/mock.d.ts +189 -0
  69. package/dist/types/providers/ollama.d.ts +41 -0
  70. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  71. package/dist/types/providers/openai-bounded-rate-limits.d.ts +3 -0
  72. package/dist/types/providers/openai-chat-server-schema.d.ts +1733 -0
  73. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  74. package/dist/types/providers/openai-codex/constants.d.ts +26 -0
  75. package/dist/types/providers/openai-codex/request-transformer.d.ts +50 -0
  76. package/dist/types/providers/openai-codex/response-handler.d.ts +18 -0
  77. package/dist/types/providers/openai-codex-responses.d.ts +71 -0
  78. package/dist/types/providers/openai-completions-compat.d.ts +6 -0
  79. package/dist/types/providers/openai-completions.d.ts +35 -0
  80. package/dist/types/providers/openai-opencodex-responses.d.ts +10 -0
  81. package/dist/types/providers/openai-request-transform.d.ts +4 -0
  82. package/dist/types/providers/openai-responses-server-schema.d.ts +392 -0
  83. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  84. package/dist/types/providers/openai-responses-shared.d.ts +106 -0
  85. package/dist/types/providers/openai-responses.d.ts +37 -0
  86. package/dist/types/providers/pi-native-client.d.ts +29 -0
  87. package/dist/types/providers/pi-native-server.d.ts +60 -0
  88. package/dist/types/providers/register-builtins.d.ts +59 -0
  89. package/dist/types/providers/synthetic.d.ts +26 -0
  90. package/dist/types/providers/transform-messages.d.ts +33 -0
  91. package/dist/types/providers/vision-guard.d.ts +8 -0
  92. package/dist/types/rate-limit-utils.d.ts +19 -0
  93. package/dist/types/stream.d.ts +45 -0
  94. package/dist/types/types.d.ts +1073 -0
  95. package/dist/types/usage/claude.d.ts +3 -0
  96. package/dist/types/usage/gemini.d.ts +2 -0
  97. package/dist/types/usage/github-copilot.d.ts +7 -0
  98. package/dist/types/usage/google-antigravity.d.ts +2 -0
  99. package/dist/types/usage/grok-cli.d.ts +17 -0
  100. package/dist/types/usage/kimi.d.ts +4 -0
  101. package/dist/types/usage/minimax-code.d.ts +2 -0
  102. package/dist/types/usage/openai-codex.d.ts +3 -0
  103. package/dist/types/usage/shared.d.ts +1 -0
  104. package/dist/types/usage/zai.d.ts +2 -0
  105. package/dist/types/usage.d.ts +264 -0
  106. package/dist/types/utils/abort.d.ts +19 -0
  107. package/dist/types/utils/anthropic-auth.d.ts +39 -0
  108. package/dist/types/utils/block-symbols.d.ts +6 -0
  109. package/dist/types/utils/discovery/antigravity.d.ts +67 -0
  110. package/dist/types/utils/discovery/codex.d.ts +38 -0
  111. package/dist/types/utils/discovery/cursor.d.ts +49 -0
  112. package/dist/types/utils/discovery/gemini.d.ts +25 -0
  113. package/dist/types/utils/discovery/index.d.ts +4 -0
  114. package/dist/types/utils/discovery/openai-compatible.d.ts +81 -0
  115. package/dist/types/utils/event-stream.d.ts +41 -0
  116. package/dist/types/utils/fallback-transport.d.ts +110 -0
  117. package/dist/types/utils/fireworks-model-id.d.ts +10 -0
  118. package/dist/types/utils/foundry.d.ts +11 -0
  119. package/dist/types/utils/h2-fetch.d.ts +22 -0
  120. package/dist/types/utils/http-inspector.d.ts +59 -0
  121. package/dist/types/utils/idle-iterator.d.ts +122 -0
  122. package/dist/types/utils/json-parse.d.ts +98 -0
  123. package/dist/types/utils/oauth/alibaba-token-plan.d.ts +19 -0
  124. package/dist/types/utils/oauth/anthropic.d.ts +41 -0
  125. package/dist/types/utils/oauth/api-key-login.d.ts +38 -0
  126. package/dist/types/utils/oauth/api-key-validation.d.ts +39 -0
  127. package/dist/types/utils/oauth/bizrouter.d.ts +1 -0
  128. package/dist/types/utils/oauth/callback-server.d.ts +80 -0
  129. package/dist/types/utils/oauth/cerebras.d.ts +1 -0
  130. package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +18 -0
  131. package/dist/types/utils/oauth/commandcode.d.ts +1 -0
  132. package/dist/types/utils/oauth/cursor.d.ts +15 -0
  133. package/dist/types/utils/oauth/deepinfra.d.ts +1 -0
  134. package/dist/types/utils/oauth/deepseek.d.ts +10 -0
  135. package/dist/types/utils/oauth/firepass.d.ts +1 -0
  136. package/dist/types/utils/oauth/fireworks.d.ts +1 -0
  137. package/dist/types/utils/oauth/fugu.d.ts +1 -0
  138. package/dist/types/utils/oauth/github-copilot.d.ts +38 -0
  139. package/dist/types/utils/oauth/gitlab-duo.d.ts +3 -0
  140. package/dist/types/utils/oauth/glm-zcode.d.ts +71 -0
  141. package/dist/types/utils/oauth/google-antigravity.d.ts +11 -0
  142. package/dist/types/utils/oauth/google-gemini-cli.d.ts +10 -0
  143. package/dist/types/utils/oauth/google-oauth-shared.d.ts +28 -0
  144. package/dist/types/utils/oauth/huggingface.d.ts +19 -0
  145. package/dist/types/utils/oauth/index.d.ts +39 -0
  146. package/dist/types/utils/oauth/kagi.d.ts +17 -0
  147. package/dist/types/utils/oauth/kilo.d.ts +5 -0
  148. package/dist/types/utils/oauth/kimi.d.ts +17 -0
  149. package/dist/types/utils/oauth/kiro.d.ts +71 -0
  150. package/dist/types/utils/oauth/litellm.d.ts +18 -0
  151. package/dist/types/utils/oauth/lm-studio.d.ts +17 -0
  152. package/dist/types/utils/oauth/mara.d.ts +1 -0
  153. package/dist/types/utils/oauth/minimax-code.d.ts +28 -0
  154. package/dist/types/utils/oauth/moonshot.d.ts +1 -0
  155. package/dist/types/utils/oauth/nanogpt.d.ts +1 -0
  156. package/dist/types/utils/oauth/nvidia.d.ts +18 -0
  157. package/dist/types/utils/oauth/ollama-cloud.d.ts +2 -0
  158. package/dist/types/utils/oauth/ollama.d.ts +18 -0
  159. package/dist/types/utils/oauth/openai-codex.d.ts +21 -0
  160. package/dist/types/utils/oauth/opencode.d.ts +18 -0
  161. package/dist/types/utils/oauth/opengateway.d.ts +1 -0
  162. package/dist/types/utils/oauth/openrouter.d.ts +1 -0
  163. package/dist/types/utils/oauth/parallel.d.ts +17 -0
  164. package/dist/types/utils/oauth/perplexity.d.ts +4 -0
  165. package/dist/types/utils/oauth/pkce.d.ts +8 -0
  166. package/dist/types/utils/oauth/qianfan.d.ts +17 -0
  167. package/dist/types/utils/oauth/qwen-portal.d.ts +19 -0
  168. package/dist/types/utils/oauth/sglang.d.ts +16 -0
  169. package/dist/types/utils/oauth/synthetic.d.ts +1 -0
  170. package/dist/types/utils/oauth/tavily.d.ts +17 -0
  171. package/dist/types/utils/oauth/together.d.ts +1 -0
  172. package/dist/types/utils/oauth/types.d.ts +56 -0
  173. package/dist/types/utils/oauth/venice.d.ts +18 -0
  174. package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +18 -0
  175. package/dist/types/utils/oauth/vllm.d.ts +16 -0
  176. package/dist/types/utils/oauth/xai.d.ts +30 -0
  177. package/dist/types/utils/oauth/xiaomi.d.ts +25 -0
  178. package/dist/types/utils/oauth/zai.d.ts +18 -0
  179. package/dist/types/utils/oauth/zenmux.d.ts +1 -0
  180. package/dist/types/utils/overflow.d.ts +14 -0
  181. package/dist/types/utils/parse-bind.d.ts +26 -0
  182. package/dist/types/utils/provider-response.d.ts +6 -0
  183. package/dist/types/utils/provider-safety-stop.d.ts +8 -0
  184. package/dist/types/utils/proxy.d.ts +7 -0
  185. package/dist/types/utils/retry-after.d.ts +3 -0
  186. package/dist/types/utils/retry-budget.d.ts +1 -0
  187. package/dist/types/utils/retry.d.ts +29 -0
  188. package/dist/types/utils/schema/adapt.d.ts +24 -0
  189. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  190. package/dist/types/utils/schema/dereference.d.ts +11 -0
  191. package/dist/types/utils/schema/draft.d.ts +10 -0
  192. package/dist/types/utils/schema/equality.d.ts +4 -0
  193. package/dist/types/utils/schema/fields.d.ts +49 -0
  194. package/dist/types/utils/schema/index.d.ts +14 -0
  195. package/dist/types/utils/schema/json-schema-validator.d.ts +12 -0
  196. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  197. package/dist/types/utils/schema/normalize.d.ts +93 -0
  198. package/dist/types/utils/schema/root-combinator.d.ts +12 -0
  199. package/dist/types/utils/schema/spill.d.ts +8 -0
  200. package/dist/types/utils/schema/stamps.d.ts +25 -0
  201. package/dist/types/utils/schema/types.d.ts +4 -0
  202. package/dist/types/utils/schema/wire.d.ts +54 -0
  203. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  204. package/dist/types/utils/sse-debug.d.ts +10 -0
  205. package/dist/types/utils/tool-call-healing.d.ts +80 -0
  206. package/dist/types/utils/tool-choice-capability.d.ts +57 -0
  207. package/dist/types/utils/tool-choice.d.ts +50 -0
  208. package/dist/types/utils/validation.d.ts +17 -0
  209. package/dist/types/utils.d.ts +117 -0
  210. package/package.json +152 -0
  211. package/src/adapter-internals/provider-safety-stop.d.ts +45 -0
  212. package/src/adapter-internals/provider-safety-stop.ts +156 -0
  213. package/src/api-registry.d.ts +30 -0
  214. package/src/api-registry.ts +96 -0
  215. package/src/auth-broker/client.ts +444 -0
  216. package/src/auth-broker/index.ts +5 -0
  217. package/src/auth-broker/redact.ts +39 -0
  218. package/src/auth-broker/refresher.ts +130 -0
  219. package/src/auth-broker/remote-store.ts +1576 -0
  220. package/src/auth-broker/server.ts +764 -0
  221. package/src/auth-broker/types.ts +164 -0
  222. package/src/auth-broker/wire-schemas.ts +261 -0
  223. package/src/auth-gateway/http.ts +198 -0
  224. package/src/auth-gateway/index.ts +3 -0
  225. package/src/auth-gateway/server.ts +1315 -0
  226. package/src/auth-gateway/types.ts +160 -0
  227. package/src/auth-storage.ts +7312 -0
  228. package/src/cli.ts +269 -0
  229. package/src/codex-tools.d.ts +4 -0
  230. package/src/codex-tools.ts +24 -0
  231. package/src/context-cap-policy.d.ts +68 -0
  232. package/src/context-cap-policy.ts +123 -0
  233. package/src/core.ts +44 -0
  234. package/src/index.ts +61 -0
  235. package/src/model-cache.ts +236 -0
  236. package/src/model-manager.ts +744 -0
  237. package/src/model-pricing.d.ts +3 -0
  238. package/src/model-pricing.ts +68 -0
  239. package/src/model-retirements.d.ts +6 -0
  240. package/src/model-retirements.ts +19 -0
  241. package/src/model-thinking.d.ts +100 -0
  242. package/src/model-thinking.ts +1054 -0
  243. package/src/models.d.ts +21 -0
  244. package/src/models.json +94672 -0
  245. package/src/models.json.d.ts +9 -0
  246. package/src/models.ts +126 -0
  247. package/src/openai-completions-compat.d.ts +34 -0
  248. package/src/openai-completions-compat.ts +383 -0
  249. package/src/prompts/composer-bash-policy-recovery.md +1 -0
  250. package/src/prompts/cursor-composer-bash-policy-recovery.md +1 -0
  251. package/src/prompts/cursor-composer-edit-discipline.md +7 -0
  252. package/src/prompts/turn-aborted-guidance.md +4 -0
  253. package/src/provider-details.ts +90 -0
  254. package/src/provider-models/bundled-references.ts +38 -0
  255. package/src/provider-models/descriptors.ts +392 -0
  256. package/src/provider-models/google.ts +92 -0
  257. package/src/provider-models/index.ts +5 -0
  258. package/src/provider-models/ollama.ts +159 -0
  259. package/src/provider-models/openai-compat.ts +2920 -0
  260. package/src/provider-models/special.ts +185 -0
  261. package/src/providers/amazon-bedrock.d.ts +60 -0
  262. package/src/providers/amazon-bedrock.ts +939 -0
  263. package/src/providers/anthropic-messages-server-schema.ts +229 -0
  264. package/src/providers/anthropic-messages-server.ts +839 -0
  265. package/src/providers/anthropic.d.ts +280 -0
  266. package/src/providers/anthropic.ts +4421 -0
  267. package/src/providers/aws-credential-config.d.ts +19 -0
  268. package/src/providers/aws-credential-config.ts +179 -0
  269. package/src/providers/aws-credentials.d.ts +43 -0
  270. package/src/providers/aws-credentials.ts +457 -0
  271. package/src/providers/aws-eventstream.d.ts +38 -0
  272. package/src/providers/aws-eventstream.ts +185 -0
  273. package/src/providers/aws-sigv4.d.ts +55 -0
  274. package/src/providers/aws-sigv4.ts +218 -0
  275. package/src/providers/azure-openai-responses.d.ts +22 -0
  276. package/src/providers/azure-openai-responses.ts +447 -0
  277. package/src/providers/composer-discipline.d.ts +32 -0
  278. package/src/providers/composer-discipline.ts +95 -0
  279. package/src/providers/cursor/client-version.d.ts +10 -0
  280. package/src/providers/cursor/client-version.ts +10 -0
  281. package/src/providers/cursor/exec-modern.d.ts +98 -0
  282. package/src/providers/cursor/exec-modern.ts +497 -0
  283. package/src/providers/cursor/gen/agent_pb.d.ts +16769 -0
  284. package/src/providers/cursor/gen/agent_pb.ts +19780 -0
  285. package/src/providers/cursor/proto/agent.proto +4533 -0
  286. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  287. package/src/providers/cursor/proto/buf.yaml +17 -0
  288. package/src/providers/cursor-pi-args.d.ts +119 -0
  289. package/src/providers/cursor-pi-args.ts +187 -0
  290. package/src/providers/cursor.d.ts +72 -0
  291. package/src/providers/cursor.ts +3396 -0
  292. package/src/providers/dashscope-token-plan-headers.d.ts +57 -0
  293. package/src/providers/dashscope-token-plan-headers.ts +84 -0
  294. package/src/providers/error-message.d.ts +27 -0
  295. package/src/providers/error-message.ts +21 -0
  296. package/src/providers/github-copilot-headers.d.ts +40 -0
  297. package/src/providers/github-copilot-headers.ts +140 -0
  298. package/src/providers/gitlab-duo.d.ts +27 -0
  299. package/src/providers/gitlab-duo.ts +393 -0
  300. package/src/providers/google-auth.d.ts +26 -0
  301. package/src/providers/google-auth.ts +262 -0
  302. package/src/providers/google-gemini-cli.d.ts +75 -0
  303. package/src/providers/google-gemini-cli.ts +969 -0
  304. package/src/providers/google-gemini-headers.d.ts +43 -0
  305. package/src/providers/google-gemini-headers.ts +100 -0
  306. package/src/providers/google-shared.d.ts +183 -0
  307. package/src/providers/google-shared.ts +1105 -0
  308. package/src/providers/google-types.d.ts +138 -0
  309. package/src/providers/google-types.ts +167 -0
  310. package/src/providers/google-vertex.d.ts +11 -0
  311. package/src/providers/google-vertex.ts +124 -0
  312. package/src/providers/google.d.ts +4 -0
  313. package/src/providers/google.ts +41 -0
  314. package/src/providers/grammar.d.ts +1 -0
  315. package/src/providers/grammar.ts +70 -0
  316. package/src/providers/kimi.d.ts +27 -0
  317. package/src/providers/kimi.ts +52 -0
  318. package/src/providers/kiro-api-key.d.ts +50 -0
  319. package/src/providers/kiro-api-key.ts +786 -0
  320. package/src/providers/kiro-codewhisperer.d.ts +11 -0
  321. package/src/providers/kiro-codewhisperer.ts +600 -0
  322. package/src/providers/mock.ts +526 -0
  323. package/src/providers/ollama.d.ts +41 -0
  324. package/src/providers/ollama.ts +645 -0
  325. package/src/providers/openai-anthropic-shim.d.ts +31 -0
  326. package/src/providers/openai-anthropic-shim.ts +156 -0
  327. package/src/providers/openai-bounded-rate-limits.d.ts +3 -0
  328. package/src/providers/openai-bounded-rate-limits.ts +57 -0
  329. package/src/providers/openai-chat-server-schema.ts +254 -0
  330. package/src/providers/openai-chat-server.ts +724 -0
  331. package/src/providers/openai-codex/constants.d.ts +26 -0
  332. package/src/providers/openai-codex/constants.ts +43 -0
  333. package/src/providers/openai-codex/request-transformer.d.ts +50 -0
  334. package/src/providers/openai-codex/request-transformer.ts +219 -0
  335. package/src/providers/openai-codex/response-handler.d.ts +18 -0
  336. package/src/providers/openai-codex/response-handler.ts +111 -0
  337. package/src/providers/openai-codex-responses.d.ts +71 -0
  338. package/src/providers/openai-codex-responses.ts +3288 -0
  339. package/src/providers/openai-completions-compat.d.ts +6 -0
  340. package/src/providers/openai-completions-compat.ts +6 -0
  341. package/src/providers/openai-completions.d.ts +35 -0
  342. package/src/providers/openai-completions.ts +2294 -0
  343. package/src/providers/openai-opencodex-responses.ts +174 -0
  344. package/src/providers/openai-request-transform.d.ts +4 -0
  345. package/src/providers/openai-request-transform.ts +136 -0
  346. package/src/providers/openai-responses-server-schema.ts +290 -0
  347. package/src/providers/openai-responses-server.ts +1268 -0
  348. package/src/providers/openai-responses-shared.d.ts +106 -0
  349. package/src/providers/openai-responses-shared.ts +1253 -0
  350. package/src/providers/openai-responses.d.ts +37 -0
  351. package/src/providers/openai-responses.ts +989 -0
  352. package/src/providers/pi-native-client.d.ts +29 -0
  353. package/src/providers/pi-native-client.ts +243 -0
  354. package/src/providers/pi-native-server.ts +488 -0
  355. package/src/providers/register-builtins.d.ts +59 -0
  356. package/src/providers/register-builtins.ts +544 -0
  357. package/src/providers/synthetic.d.ts +26 -0
  358. package/src/providers/synthetic.ts +50 -0
  359. package/src/providers/transform-messages.d.ts +33 -0
  360. package/src/providers/transform-messages.ts +408 -0
  361. package/src/providers/vision-guard.d.ts +8 -0
  362. package/src/providers/vision-guard.ts +31 -0
  363. package/src/rate-limit-utils.d.ts +19 -0
  364. package/src/rate-limit-utils.ts +102 -0
  365. package/src/stream.d.ts +45 -0
  366. package/src/stream.ts +1306 -0
  367. package/src/types.d.ts +1073 -0
  368. package/src/types.ts +1305 -0
  369. package/src/usage/claude.ts +449 -0
  370. package/src/usage/gemini.ts +250 -0
  371. package/src/usage/github-copilot.ts +421 -0
  372. package/src/usage/google-antigravity.ts +201 -0
  373. package/src/usage/grok-cli.ts +259 -0
  374. package/src/usage/kimi.ts +285 -0
  375. package/src/usage/minimax-code.ts +31 -0
  376. package/src/usage/openai-codex.ts +503 -0
  377. package/src/usage/shared.ts +10 -0
  378. package/src/usage/zai.ts +247 -0
  379. package/src/usage.ts +190 -0
  380. package/src/utils/abort.d.ts +19 -0
  381. package/src/utils/abort.ts +51 -0
  382. package/src/utils/anthropic-auth.ts +95 -0
  383. package/src/utils/block-symbols.d.ts +6 -0
  384. package/src/utils/block-symbols.ts +11 -0
  385. package/src/utils/discovery/antigravity.ts +275 -0
  386. package/src/utils/discovery/codex.ts +362 -0
  387. package/src/utils/discovery/cursor.ts +388 -0
  388. package/src/utils/discovery/gemini.ts +248 -0
  389. package/src/utils/discovery/index.ts +4 -0
  390. package/src/utils/discovery/openai-compatible.ts +379 -0
  391. package/src/utils/event-stream.d.ts +41 -0
  392. package/src/utils/event-stream.ts +269 -0
  393. package/src/utils/fallback-transport.d.ts +110 -0
  394. package/src/utils/fallback-transport.ts +411 -0
  395. package/src/utils/fireworks-model-id.d.ts +10 -0
  396. package/src/utils/fireworks-model-id.ts +30 -0
  397. package/src/utils/foundry.d.ts +11 -0
  398. package/src/utils/foundry.ts +18 -0
  399. package/src/utils/h2-fetch.ts +60 -0
  400. package/src/utils/http-inspector.d.ts +59 -0
  401. package/src/utils/http-inspector.ts +380 -0
  402. package/src/utils/idle-iterator.d.ts +122 -0
  403. package/src/utils/idle-iterator.ts +410 -0
  404. package/src/utils/json-parse.d.ts +98 -0
  405. package/src/utils/json-parse.ts +607 -0
  406. package/src/utils/oauth/alibaba-token-plan.ts +60 -0
  407. package/src/utils/oauth/anthropic.ts +233 -0
  408. package/src/utils/oauth/api-key-login.ts +98 -0
  409. package/src/utils/oauth/api-key-validation.ts +344 -0
  410. package/src/utils/oauth/bizrouter.ts +15 -0
  411. package/src/utils/oauth/callback-server.d.ts +80 -0
  412. package/src/utils/oauth/callback-server.ts +359 -0
  413. package/src/utils/oauth/cerebras.ts +16 -0
  414. package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
  415. package/src/utils/oauth/commandcode.ts +17 -0
  416. package/src/utils/oauth/cursor.ts +157 -0
  417. package/src/utils/oauth/deepinfra.ts +15 -0
  418. package/src/utils/oauth/deepseek.ts +53 -0
  419. package/src/utils/oauth/firepass.ts +24 -0
  420. package/src/utils/oauth/fireworks.ts +15 -0
  421. package/src/utils/oauth/fugu.ts +15 -0
  422. package/src/utils/oauth/github-copilot.d.ts +38 -0
  423. package/src/utils/oauth/github-copilot.ts +362 -0
  424. package/src/utils/oauth/gitlab-duo.ts +123 -0
  425. package/src/utils/oauth/glm-zcode.d.ts +71 -0
  426. package/src/utils/oauth/glm-zcode.ts +433 -0
  427. package/src/utils/oauth/google-antigravity.ts +200 -0
  428. package/src/utils/oauth/google-gemini-cli.ts +256 -0
  429. package/src/utils/oauth/google-oauth-shared.ts +110 -0
  430. package/src/utils/oauth/huggingface.ts +62 -0
  431. package/src/utils/oauth/index.ts +558 -0
  432. package/src/utils/oauth/kagi.ts +47 -0
  433. package/src/utils/oauth/kilo.ts +87 -0
  434. package/src/utils/oauth/kimi.d.ts +17 -0
  435. package/src/utils/oauth/kimi.ts +275 -0
  436. package/src/utils/oauth/kiro.ts +448 -0
  437. package/src/utils/oauth/litellm.ts +47 -0
  438. package/src/utils/oauth/lm-studio.ts +38 -0
  439. package/src/utils/oauth/mara.ts +16 -0
  440. package/src/utils/oauth/minimax-code.ts +78 -0
  441. package/src/utils/oauth/moonshot.ts +16 -0
  442. package/src/utils/oauth/nanogpt.ts +15 -0
  443. package/src/utils/oauth/nvidia.ts +70 -0
  444. package/src/utils/oauth/oauth.html +199 -0
  445. package/src/utils/oauth/ollama-cloud.ts +28 -0
  446. package/src/utils/oauth/ollama.ts +47 -0
  447. package/src/utils/oauth/openai-codex.ts +299 -0
  448. package/src/utils/oauth/opencode.ts +49 -0
  449. package/src/utils/oauth/opengateway.ts +15 -0
  450. package/src/utils/oauth/openrouter.ts +16 -0
  451. package/src/utils/oauth/parallel.ts +46 -0
  452. package/src/utils/oauth/perplexity.ts +225 -0
  453. package/src/utils/oauth/pkce.ts +18 -0
  454. package/src/utils/oauth/qianfan.ts +58 -0
  455. package/src/utils/oauth/qwen-portal.ts +60 -0
  456. package/src/utils/oauth/sglang.ts +42 -0
  457. package/src/utils/oauth/synthetic.ts +15 -0
  458. package/src/utils/oauth/tavily.ts +46 -0
  459. package/src/utils/oauth/together.ts +16 -0
  460. package/src/utils/oauth/types.d.ts +56 -0
  461. package/src/utils/oauth/types.ts +122 -0
  462. package/src/utils/oauth/venice.ts +59 -0
  463. package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
  464. package/src/utils/oauth/vllm.ts +42 -0
  465. package/src/utils/oauth/xai.ts +246 -0
  466. package/src/utils/oauth/xiaomi.ts +199 -0
  467. package/src/utils/oauth/zai.ts +60 -0
  468. package/src/utils/oauth/zenmux.ts +15 -0
  469. package/src/utils/overflow.ts +275 -0
  470. package/src/utils/parse-bind.ts +81 -0
  471. package/src/utils/provider-response.d.ts +6 -0
  472. package/src/utils/provider-response.ts +30 -0
  473. package/src/utils/provider-safety-stop.ts +8 -0
  474. package/src/utils/proxy.d.ts +7 -0
  475. package/src/utils/proxy.ts +652 -0
  476. package/src/utils/retry-after.d.ts +3 -0
  477. package/src/utils/retry-after.ts +110 -0
  478. package/src/utils/retry-budget.d.ts +1 -0
  479. package/src/utils/retry-budget.ts +4 -0
  480. package/src/utils/retry.d.ts +29 -0
  481. package/src/utils/retry.ts +67 -0
  482. package/src/utils/schema/CONSTRAINTS.md +164 -0
  483. package/src/utils/schema/adapt.d.ts +24 -0
  484. package/src/utils/schema/adapt.ts +36 -0
  485. package/src/utils/schema/compatibility.d.ts +30 -0
  486. package/src/utils/schema/compatibility.ts +435 -0
  487. package/src/utils/schema/dereference.d.ts +11 -0
  488. package/src/utils/schema/dereference.ts +98 -0
  489. package/src/utils/schema/draft.d.ts +10 -0
  490. package/src/utils/schema/draft.ts +341 -0
  491. package/src/utils/schema/equality.d.ts +4 -0
  492. package/src/utils/schema/equality.ts +97 -0
  493. package/src/utils/schema/fields.d.ts +49 -0
  494. package/src/utils/schema/fields.ts +190 -0
  495. package/src/utils/schema/index.d.ts +14 -0
  496. package/src/utils/schema/index.ts +14 -0
  497. package/src/utils/schema/json-schema-validator.d.ts +12 -0
  498. package/src/utils/schema/json-schema-validator.ts +577 -0
  499. package/src/utils/schema/meta-validator.d.ts +2 -0
  500. package/src/utils/schema/meta-validator.ts +167 -0
  501. package/src/utils/schema/normalize.d.ts +93 -0
  502. package/src/utils/schema/normalize.ts +1588 -0
  503. package/src/utils/schema/root-combinator.d.ts +12 -0
  504. package/src/utils/schema/root-combinator.ts +143 -0
  505. package/src/utils/schema/spill.d.ts +8 -0
  506. package/src/utils/schema/spill.ts +43 -0
  507. package/src/utils/schema/stamps.d.ts +25 -0
  508. package/src/utils/schema/stamps.ts +97 -0
  509. package/src/utils/schema/types.d.ts +4 -0
  510. package/src/utils/schema/types.ts +11 -0
  511. package/src/utils/schema/wire.d.ts +54 -0
  512. package/src/utils/schema/wire.ts +213 -0
  513. package/src/utils/schema/zod-decontaminate.d.ts +31 -0
  514. package/src/utils/schema/zod-decontaminate.ts +331 -0
  515. package/src/utils/sse-debug.d.ts +10 -0
  516. package/src/utils/sse-debug.ts +289 -0
  517. package/src/utils/tool-call-healing.d.ts +80 -0
  518. package/src/utils/tool-call-healing.ts +298 -0
  519. package/src/utils/tool-choice-capability.d.ts +57 -0
  520. package/src/utils/tool-choice-capability.ts +633 -0
  521. package/src/utils/tool-choice.d.ts +50 -0
  522. package/src/utils/tool-choice.ts +99 -0
  523. package/src/utils/validation.ts +1080 -0
  524. package/src/utils.d.ts +117 -0
  525. package/src/utils.ts +523 -0
package/src/utils.d.ts ADDED
@@ -0,0 +1,117 @@
1
+ import type { ResponseInput } from "openai/resources/responses/responses";
2
+ import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types";
3
+ export { isRecord } from "@vib-rato/utils";
4
+ export declare function normalizeSystemPrompts(systemPrompt: readonly string[] | string | undefined | null): string[];
5
+ export declare function sanitizeJsonStrings(value: unknown): unknown;
6
+ export declare function toNumber(value: unknown): number | undefined;
7
+ export declare function toPositiveNumber(value: unknown, fallback: number): number;
8
+ export declare function toBoolean(value: unknown): boolean | undefined;
9
+ export declare function normalizeToolCallId(id: string): string;
10
+ type ResponsesToolItemIdPrefix = "fc" | "ctc";
11
+ export declare function normalizeResponsesToolCallId(id: string, itemPrefix?: ResponsesToolItemIdPrefix): {
12
+ callId: string;
13
+ itemId: string;
14
+ };
15
+ /**
16
+ * Truncate an OpenAI Responses API item ID to 64 characters.
17
+ * IDs exceeding the limit are replaced with a hash-based ID using the given prefix.
18
+ */
19
+ export declare function truncateResponseItemId(id: string, prefix: string): string;
20
+ export declare function sanitizeOpenAIResponsesHistoryItemsForReplay(items: Array<Record<string, unknown>>): ResponseInput;
21
+ /**
22
+ * Neutralize leaked OpenAI Harmony / control tokens (`<|channel|>`, `<|message|>`,
23
+ * `<|call|>`, `<|constrain|>`, `<|recipient|>`, `<|content|>`, ...) in replayed
24
+ * history text. A subagent whose tool-call channel degenerates can dump raw
25
+ * control-token scaffolding into its reply text; once that poisoned text lands in
26
+ * history the Codex / Responses endpoint rejects every subsequent request with
27
+ * `Request blocked (code=invalid_prompt)`, permanently wedging the session because
28
+ * the offending item is re-sent on each turn. Insert a zero-width space after `<`
29
+ * so the delimiter can no longer be tokenized as a reserved control token while the
30
+ * text stays human-readable.
31
+ *
32
+ * The pattern matches the two control-token shapes only, so ordinary text and pipe
33
+ * syntax is left untouched:
34
+ * - simple form `<|ident|>` — a leading run of identifier chars then `|>`; and
35
+ * - header form `<|role to=recipient|>` — a known Harmony role
36
+ * (`system`/`developer`/`user`/`assistant`/`tool`) followed by a single
37
+ * recipient assignment `to=<recipient>` whose value is an unbounded run of
38
+ * non-delimiter, non-whitespace chars (so long MCP/custom tool recipients like
39
+ * `to=functions.<long.name>` are covered).
40
+ * The header branch is deliberately scoped to the known role + `to=` recipient
41
+ * grammar rather than an arbitrary `key=value`, so request-boundary sanitization
42
+ * never rewrites non-control delimiter text such as `<|foo bar=baz|>`. A single-line
43
+ * body (no `\n`) and the required leading identifier char also leave compact
44
+ * pipe/operator syntax alone — e.g. F# `value <| f |> g` (space after `<|`),
45
+ * `sum<|a+b|>c` (punctuation body), and `<|foo bar|>` (no assignment) never match.
46
+ * The simple branch is a strict superset of the original identifier-only pattern:
47
+ * every marker the old regex caught still matches.
48
+ */
49
+ export declare function neutralizeReservedControlTokens(text: string): string;
50
+ /**
51
+ * Shape-tolerant classifier for the poisoned-history rejection that wedges
52
+ * gpt-5.6 sessions: `Request blocked (code=invalid_prompt)`. Accepts a raw
53
+ * provider error, an assistant message, or any object carrying a
54
+ * `providerCode` / `transportFailure` / `errorMessage` field, and returns true
55
+ * when the failure is the deterministic `invalid_prompt` content fault rather
56
+ * than a transient upstream error. This is the single shared contract the
57
+ * provider transports and the session-level circuit breaker key on so the
58
+ * classification is explicit (not inferred from a catch-all bucket) and
59
+ * uniformly testable across transports.
60
+ */
61
+ export declare function isInvalidPromptError(input: unknown): boolean;
62
+ /**
63
+ * Shape-tolerant classifier for the DeepSeek-family reasoning-content replay
64
+ * rejection: "The `reasoning_content` in the thinking mode must be passed back
65
+ * to the API." DeepSeek V4 (and reasoning-capable siblings reached through any
66
+ * OpenAI-compatible proxy) 400 every follow-up turn once a prior assistant turn
67
+ * carried reasoning the proxy stripped to an empty `encrypted_content` /
68
+ * `reasoning_content`. Resending the identical history re-triggers it, so naive
69
+ * session auto-retry just burns the budget — it needs the same bounded
70
+ * repair-and-resend contract as the `invalid_prompt` poisoned-history breaker.
71
+ *
72
+ * Accepts a raw provider error, an assistant message, or any object carrying an
73
+ * `errorMessage` field (the agent-loop circuit breaker keys on this).
74
+ */
75
+ export declare function isReasoningContentReplayError(input: unknown): boolean;
76
+ /**
77
+ * Remove Responses-API `reasoning` items whose `encrypted_content` is missing or
78
+ * empty from an outgoing history payload. DeepSeek rejects replay of reasoning
79
+ * whose encrypted blob a proxy stripped to `""`; dropping those items lets the
80
+ * model re-reason on the next turn instead of re-triggering a deterministic 400.
81
+ * Non-reasoning items (text, function_call, function_call_output, ...) are kept
82
+ * verbatim so tool-use pairing and message order are preserved. Returns whether
83
+ * any item was actually removed — the circuit breaker uses this to decide
84
+ * between a single repaired resend (removed) and immediate fail-fast (unchanged).
85
+ */
86
+ export declare function stripUnusableReasoningItems(items: Array<Record<string, unknown>>): {
87
+ result: Array<Record<string, unknown>>;
88
+ removed: number;
89
+ };
90
+ /**
91
+ * Neutralize leaked reserved control tokens across every string in an outgoing
92
+ * Responses `input` array. This is the request-boundary complement to the
93
+ * replay-history sanitizer: leaked Harmony markers (`<|channel|>analysis`, ...)
94
+ * can enter the payload from assistant reasoning summaries, live-converted
95
+ * message/tool-output text, or user-authored content — not just replayed
96
+ * history — and every gpt-5.6 request that carries one is rejected with
97
+ * `Request blocked (code=invalid_prompt)`. Walking every string (rather than an
98
+ * item-type allowlist) guarantees no leak source is missed as item shapes
99
+ * evolve; the zero-width-space insertion is idempotent (`<\u200b|` no longer
100
+ * matches `<|`) and keeps the text human-readable.
101
+ */
102
+ export declare function neutralizeResponsesInputControlTokens<T>(items: readonly T[]): T[];
103
+ export declare function createOpenAIResponsesHistoryPayload(provider: string, items: Array<Record<string, unknown>>, incremental?: boolean): OpenAIResponsesHistoryPayload;
104
+ export declare function getOpenAIResponsesHistoryPayload(providerPayload: ProviderPayload | undefined, currentProvider: string, fallbackProvider?: string): OpenAIResponsesHistoryPayload | undefined;
105
+ export declare function getOpenAIResponsesHistoryItems(providerPayload: ProviderPayload | undefined, currentProvider: string, fallbackProvider?: string): Array<Record<string, unknown>> | undefined;
106
+ /**
107
+ * Resolve cache retention preference.
108
+ *
109
+ * Resolution order: explicit request value → `VIB_CACHE_RETENTION` →
110
+ * legacy `PI_CACHE_RETENTION` → `fallback`. Both env vars act as explicit
111
+ * opt-in (`"long"`) or opt-out (any other value) so a provider-specific
112
+ * `fallback` only applies when nothing else is configured. `fallback`
113
+ * defaults to `"short"` to preserve the historical behaviour for callers
114
+ * that don't pass one.
115
+ */
116
+ export declare function resolveCacheRetention(cacheRetention?: CacheRetention, fallback?: CacheRetention): CacheRetention;
117
+ export declare function isAnthropicOAuthToken(key: string): boolean;
package/src/utils.ts ADDED
@@ -0,0 +1,523 @@
1
+ import { $env } from "@vib-rato/utils";
2
+ import type { ResponseInput } from "openai/resources/responses/responses";
3
+ import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types";
4
+
5
+ type OpenAIResponsesReplayItem = ResponseInput[number];
6
+
7
+ export { isRecord } from "@vib-rato/utils";
8
+ export function normalizeSystemPrompts(systemPrompt: readonly string[] | string | undefined | null): string[] {
9
+ if (systemPrompt === undefined || systemPrompt === null) return [];
10
+ const prompts = Array.isArray(systemPrompt) ? systemPrompt : typeof systemPrompt === "string" ? [systemPrompt] : [];
11
+ return prompts.map(prompt => prompt.toWellFormed()).filter(prompt => prompt.length > 0);
12
+ }
13
+
14
+ export function sanitizeJsonStrings(value: unknown): unknown {
15
+ return sanitizeJsonStringsInner(value, new WeakMap<object, unknown>());
16
+ }
17
+
18
+ function sanitizeJsonStringsInner(value: unknown, seen: WeakMap<object, unknown>): unknown {
19
+ if (typeof value === "string") return value.toWellFormed();
20
+ if (!value || typeof value !== "object") return value;
21
+
22
+ const cached = seen.get(value);
23
+ if (cached !== undefined) return cached;
24
+
25
+ if (Array.isArray(value)) {
26
+ const sanitized: unknown[] = [];
27
+ seen.set(value, sanitized);
28
+ for (const item of value) {
29
+ sanitized.push(sanitizeJsonStringsInner(item, seen));
30
+ }
31
+ return sanitized;
32
+ }
33
+
34
+ const sanitized: Record<string, unknown> = {};
35
+ seen.set(value, sanitized);
36
+ for (const [key, nestedValue] of Object.entries(value)) {
37
+ sanitized[key.toWellFormed()] = sanitizeJsonStringsInner(nestedValue, seen);
38
+ }
39
+ return sanitized;
40
+ }
41
+
42
+ export function toNumber(value: unknown): number | undefined {
43
+ if (typeof value === "number" && Number.isFinite(value)) return value;
44
+ if (typeof value === "string" && value.trim()) {
45
+ const parsed = Number(value);
46
+ return Number.isFinite(parsed) ? parsed : undefined;
47
+ }
48
+ return undefined;
49
+ }
50
+
51
+ export function toPositiveNumber(value: unknown, fallback: number): number {
52
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
53
+ return fallback;
54
+ }
55
+ return value;
56
+ }
57
+
58
+ export function toBoolean(value: unknown): boolean | undefined {
59
+ return typeof value === "boolean" ? value : undefined;
60
+ }
61
+
62
+ export function normalizeToolCallId(id: string): string {
63
+ const sanitized = id.replace(/[^a-zA-Z0-9_-]/g, "_");
64
+ return sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized;
65
+ }
66
+
67
+ type ResponsesToolItemIdPrefix = "fc" | "ctc";
68
+
69
+ export function normalizeResponsesToolCallId(
70
+ id: string,
71
+ itemPrefix: ResponsesToolItemIdPrefix = "fc",
72
+ ): { callId: string; itemId: string } {
73
+ const [callId, itemId] = id.split("|");
74
+ if (callId && itemId) {
75
+ const normalizedCallId = truncateResponseItemId(callId, getIdPrefix(callId, "call"));
76
+ const normalizedItemId = normalizeResponsesItemId(itemId, itemPrefix);
77
+ return { callId: normalizedCallId, itemId: normalizedItemId };
78
+ }
79
+ const hash = Bun.hash(id).toString(36);
80
+ const normalizedCallId = id.startsWith("call_") ? truncateResponseItemId(id, "call") : `call_${hash}`;
81
+ return { callId: normalizedCallId, itemId: `${itemPrefix}_${hash}` };
82
+ }
83
+
84
+ function getIdPrefix(id: string, fallback: string): string {
85
+ const prefix = id.match(/^([a-zA-Z][a-zA-Z0-9]*)_/)?.[1];
86
+ return prefix || fallback;
87
+ }
88
+
89
+ function getExplicitIdPrefix(id: string): string | undefined {
90
+ return id.match(/^([a-zA-Z][a-zA-Z0-9]*)_/)?.[1];
91
+ }
92
+
93
+ function normalizeResponsesItemId(itemId: string, fallbackPrefix: ResponsesToolItemIdPrefix): string {
94
+ const prefix = getExplicitIdPrefix(itemId);
95
+ const isAllowedPrefix = prefix
96
+ ? fallbackPrefix === "ctc"
97
+ ? prefix === "ctc"
98
+ : prefix === "fc" || prefix === "fcr"
99
+ : false;
100
+ if (!prefix || !isAllowedPrefix) {
101
+ return `${fallbackPrefix}_${Bun.hash(itemId).toString(36)}`;
102
+ }
103
+ return truncateResponseItemId(itemId, prefix);
104
+ }
105
+
106
+ /**
107
+ * Truncate an OpenAI Responses API item ID to 64 characters.
108
+ * IDs exceeding the limit are replaced with a hash-based ID using the given prefix.
109
+ */
110
+ export function truncateResponseItemId(id: string, prefix: string): string {
111
+ if (id.length <= 64) return id;
112
+ return `${prefix}_${Bun.hash(id).toString(36)}`;
113
+ }
114
+
115
+ export function sanitizeOpenAIResponsesHistoryItemsForReplay(items: Array<Record<string, unknown>>): ResponseInput {
116
+ const normalizedCallIds = new Map<string, string>();
117
+ return items.flatMap(item => {
118
+ const sanitized = sanitizeOpenAIResponsesHistoryItemForReplay(item, normalizedCallIds);
119
+ return sanitized ? [sanitized] : [];
120
+ });
121
+ }
122
+ const RESERVED_CONTROL_TOKEN_RE =
123
+ /<\|(?=(?:[A-Za-z0-9_]+|(?:system|developer|user|assistant|tool)[ \t]+to=[^\s<>|]+)\|>)/g;
124
+ /**
125
+ * Neutralize leaked OpenAI Harmony / control tokens (`<|channel|>`, `<|message|>`,
126
+ * `<|call|>`, `<|constrain|>`, `<|recipient|>`, `<|content|>`, ...) in replayed
127
+ * history text. A subagent whose tool-call channel degenerates can dump raw
128
+ * control-token scaffolding into its reply text; once that poisoned text lands in
129
+ * history the Codex / Responses endpoint rejects every subsequent request with
130
+ * `Request blocked (code=invalid_prompt)`, permanently wedging the session because
131
+ * the offending item is re-sent on each turn. Insert a zero-width space after `<`
132
+ * so the delimiter can no longer be tokenized as a reserved control token while the
133
+ * text stays human-readable.
134
+ *
135
+ * The pattern matches the two control-token shapes only, so ordinary text and pipe
136
+ * syntax is left untouched:
137
+ * - simple form `<|ident|>` — a leading run of identifier chars then `|>`; and
138
+ * - header form `<|role to=recipient|>` — a known Harmony role
139
+ * (`system`/`developer`/`user`/`assistant`/`tool`) followed by a single
140
+ * recipient assignment `to=<recipient>` whose value is an unbounded run of
141
+ * non-delimiter, non-whitespace chars (so long MCP/custom tool recipients like
142
+ * `to=functions.<long.name>` are covered).
143
+ * The header branch is deliberately scoped to the known role + `to=` recipient
144
+ * grammar rather than an arbitrary `key=value`, so request-boundary sanitization
145
+ * never rewrites non-control delimiter text such as `<|foo bar=baz|>`. A single-line
146
+ * body (no `\n`) and the required leading identifier char also leave compact
147
+ * pipe/operator syntax alone — e.g. F# `value <| f |> g` (space after `<|`),
148
+ * `sum<|a+b|>c` (punctuation body), and `<|foo bar|>` (no assignment) never match.
149
+ * The simple branch is a strict superset of the original identifier-only pattern:
150
+ * every marker the old regex caught still matches.
151
+ */
152
+ export function neutralizeReservedControlTokens(text: string): string {
153
+ if (!text.includes("<|")) return text;
154
+ return text.replace(RESERVED_CONTROL_TOKEN_RE, "<\u200b|");
155
+ }
156
+
157
+ /**
158
+ * Shape-tolerant classifier for the poisoned-history rejection that wedges
159
+ * gpt-5.6 sessions: `Request blocked (code=invalid_prompt)`. Accepts a raw
160
+ * provider error, an assistant message, or any object carrying a
161
+ * `providerCode` / `transportFailure` / `errorMessage` field, and returns true
162
+ * when the failure is the deterministic `invalid_prompt` content fault rather
163
+ * than a transient upstream error. This is the single shared contract the
164
+ * provider transports and the session-level circuit breaker key on so the
165
+ * classification is explicit (not inferred from a catch-all bucket) and
166
+ * uniformly testable across transports.
167
+ */
168
+ export function isInvalidPromptError(input: unknown): boolean {
169
+ if (!input) return false;
170
+ if (typeof input === "string") return INVALID_PROMPT_MESSAGE_RE.test(input);
171
+ if (typeof input !== "object") return false;
172
+ const value = input as {
173
+ providerCode?: unknown;
174
+ code?: unknown;
175
+ errorMessage?: unknown;
176
+ message?: unknown;
177
+ transportFailure?: { providerCode?: unknown; code?: unknown };
178
+ error?: { code?: unknown };
179
+ };
180
+ const code =
181
+ asLowerString(value.providerCode) ??
182
+ asLowerString(value.code) ??
183
+ asLowerString(value.transportFailure?.providerCode) ??
184
+ asLowerString(value.transportFailure?.code) ??
185
+ asLowerString(value.error?.code);
186
+ if (code === "invalid_prompt") return true;
187
+ const message =
188
+ typeof value.errorMessage === "string"
189
+ ? value.errorMessage
190
+ : typeof value.message === "string"
191
+ ? value.message
192
+ : undefined;
193
+ return message !== undefined && INVALID_PROMPT_MESSAGE_RE.test(message);
194
+ }
195
+
196
+ const INVALID_PROMPT_MESSAGE_RE = /code=invalid[_ -]prompt|request blocked[^\n]*invalid[_ -]prompt/i;
197
+
198
+ function asLowerString(value: unknown): string | undefined {
199
+ return typeof value === "string" ? value.toLowerCase() : undefined;
200
+ }
201
+
202
+ /**
203
+ * Shape-tolerant classifier for the DeepSeek-family reasoning-content replay
204
+ * rejection: "The `reasoning_content` in the thinking mode must be passed back
205
+ * to the API." DeepSeek V4 (and reasoning-capable siblings reached through any
206
+ * OpenAI-compatible proxy) 400 every follow-up turn once a prior assistant turn
207
+ * carried reasoning the proxy stripped to an empty `encrypted_content` /
208
+ * `reasoning_content`. Resending the identical history re-triggers it, so naive
209
+ * session auto-retry just burns the budget — it needs the same bounded
210
+ * repair-and-resend contract as the `invalid_prompt` poisoned-history breaker.
211
+ *
212
+ * Accepts a raw provider error, an assistant message, or any object carrying an
213
+ * `errorMessage` field (the agent-loop circuit breaker keys on this).
214
+ */
215
+ export function isReasoningContentReplayError(input: unknown): boolean {
216
+ if (!input) return false;
217
+ const message =
218
+ typeof input === "string"
219
+ ? input
220
+ : input && typeof input === "object"
221
+ ? ((input as { errorMessage?: unknown; message?: unknown }).errorMessage ??
222
+ (input as { message?: unknown }).message)
223
+ : undefined;
224
+ return typeof message === "string" && REASONING_CONTENT_REPLAY_MESSAGE_RE.test(message);
225
+ }
226
+
227
+ const REASONING_CONTENT_REPLAY_MESSAGE_RE =
228
+ /reasoning_content[\s\S]*must be passed back to the API|reasoning content[\s\S]*must be passed back to the API/i;
229
+
230
+ /**
231
+ * Remove Responses-API `reasoning` items whose `encrypted_content` is missing or
232
+ * empty from an outgoing history payload. DeepSeek rejects replay of reasoning
233
+ * whose encrypted blob a proxy stripped to `""`; dropping those items lets the
234
+ * model re-reason on the next turn instead of re-triggering a deterministic 400.
235
+ * Non-reasoning items (text, function_call, function_call_output, ...) are kept
236
+ * verbatim so tool-use pairing and message order are preserved. Returns whether
237
+ * any item was actually removed — the circuit breaker uses this to decide
238
+ * between a single repaired resend (removed) and immediate fail-fast (unchanged).
239
+ */
240
+ export function stripUnusableReasoningItems(items: Array<Record<string, unknown>>): {
241
+ result: Array<Record<string, unknown>>;
242
+ removed: number;
243
+ } {
244
+ let removed = 0;
245
+ const result: Array<Record<string, unknown>> = [];
246
+ for (const item of items) {
247
+ if (item?.type === "reasoning") {
248
+ const encrypted = item.encrypted_content;
249
+ if (encrypted === undefined || encrypted === null || encrypted === "") {
250
+ removed++;
251
+ continue;
252
+ }
253
+ }
254
+ result.push(item);
255
+ }
256
+ return { result, removed };
257
+ }
258
+ /**
259
+ * Neutralize leaked reserved control tokens across every string in an outgoing
260
+ * Responses `input` array. This is the request-boundary complement to the
261
+ * replay-history sanitizer: leaked Harmony markers (`<|channel|>analysis`, ...)
262
+ * can enter the payload from assistant reasoning summaries, live-converted
263
+ * message/tool-output text, or user-authored content — not just replayed
264
+ * history — and every gpt-5.6 request that carries one is rejected with
265
+ * `Request blocked (code=invalid_prompt)`. Walking every string (rather than an
266
+ * item-type allowlist) guarantees no leak source is missed as item shapes
267
+ * evolve; the zero-width-space insertion is idempotent (`<\u200b|` no longer
268
+ * matches `<|`) and keeps the text human-readable.
269
+ */
270
+ export function neutralizeResponsesInputControlTokens<T>(items: readonly T[]): T[] {
271
+ return items.map(item => deepNeutralizeReservedControlTokens(item) as T);
272
+ }
273
+
274
+ function deepNeutralizeReservedControlTokens(value: unknown): unknown {
275
+ if (typeof value === "string") return neutralizeReservedControlTokens(value);
276
+ if (Array.isArray(value)) return value.map(deepNeutralizeReservedControlTokens);
277
+ if (value && typeof value === "object") {
278
+ const out: Record<string, unknown> = {};
279
+ for (const [key, nested] of Object.entries(value)) {
280
+ out[key] = deepNeutralizeReservedControlTokens(nested);
281
+ }
282
+ return out;
283
+ }
284
+ return value;
285
+ }
286
+
287
+ function stringifyResponsesStringParamForReplay(value: unknown): string {
288
+ if (typeof value === "string") return neutralizeReservedControlTokens(value.toWellFormed());
289
+ try {
290
+ const encoded = JSON.stringify(value);
291
+ if (typeof encoded === "string") return neutralizeReservedControlTokens(encoded.toWellFormed());
292
+ } catch {
293
+ // Fall through to String().
294
+ }
295
+ return neutralizeReservedControlTokens(String(value ?? "").toWellFormed());
296
+ }
297
+
298
+ function normalizeResponsesMessageTextForReplay(value: unknown): string {
299
+ if (typeof value === "string") return neutralizeReservedControlTokens(value.toWellFormed());
300
+ if (value && typeof value === "object") {
301
+ const nestedText = (value as { text?: unknown }).text;
302
+ if (typeof nestedText === "string") return neutralizeReservedControlTokens(nestedText.toWellFormed());
303
+ }
304
+ return stringifyResponsesStringParamForReplay(value);
305
+ }
306
+
307
+ type ResponsesImageDetail = "auto" | "low" | "high";
308
+
309
+ interface NormalizedResponsesImageUrl {
310
+ readonly imageUrl: string;
311
+ readonly detail?: ResponsesImageDetail;
312
+ }
313
+
314
+ function isResponsesImageDetail(value: unknown): value is ResponsesImageDetail {
315
+ return value === "auto" || value === "low" || value === "high";
316
+ }
317
+
318
+ function normalizeResponsesImageUrlForReplay(value: unknown): NormalizedResponsesImageUrl {
319
+ if (typeof value === "string") return { imageUrl: value.toWellFormed() };
320
+ if (value && typeof value === "object" && "url" in value && typeof value.url === "string") {
321
+ const detail = "detail" in value && isResponsesImageDetail(value.detail) ? value.detail : undefined;
322
+ return {
323
+ imageUrl: value.url.toWellFormed(),
324
+ ...(detail ? { detail } : {}),
325
+ };
326
+ }
327
+ return { imageUrl: stringifyResponsesStringParamForReplay(value) };
328
+ }
329
+
330
+ /**
331
+ * OpenAI Responses `input_image.image_url` must be a fetchable HTTP(S) URL or an
332
+ * image data URI. Session resident-blob materialization may leave a human-readable
333
+ * placeholder like `[Session resident imageUrl blob missing: sha256:…; …]` in this
334
+ * field; replaying that string as `image_url` makes Codex reject the entire turn
335
+ * with `invalid_value` (#2924).
336
+ */
337
+ function isProviderSafeResponsesImageUrl(value: string): boolean {
338
+ const url = value.trim();
339
+ if (url.length === 0) return false;
340
+ if (url.startsWith("https://") || url.startsWith("http://")) return true;
341
+ // Accept only image data URIs — other data: schemes are not valid image inputs.
342
+ if (url.startsWith("data:image/")) return true;
343
+ return false;
344
+ }
345
+
346
+ function hasNonEmptyResponsesFileId(part: Record<string, unknown>): boolean {
347
+ return typeof part.file_id === "string" && part.file_id.trim().length > 0;
348
+ }
349
+
350
+ function sanitizeResponsesMessageContentForReplay(content: unknown): unknown {
351
+ if (typeof content === "string") return neutralizeReservedControlTokens(content.toWellFormed());
352
+ if (!Array.isArray(content)) return content;
353
+ const sanitizedContent: unknown[] = [];
354
+ for (const part of content) {
355
+ if (!part || typeof part !== "object") {
356
+ sanitizedContent.push(part);
357
+ continue;
358
+ }
359
+ const sanitizedPart = { ...(part as Record<string, unknown>) };
360
+ if ("text" in sanitizedPart) {
361
+ sanitizedPart.text = normalizeResponsesMessageTextForReplay(sanitizedPart.text);
362
+ }
363
+ if ("image_url" in sanitizedPart) {
364
+ const normalizedImageUrl = normalizeResponsesImageUrlForReplay(sanitizedPart.image_url);
365
+ if (!isProviderSafeResponsesImageUrl(normalizedImageUrl.imageUrl)) {
366
+ // Keep the part when a provider file_id can stand alone; otherwise drop
367
+ // only this image part so neighboring text/history still replays.
368
+ if (!hasNonEmptyResponsesFileId(sanitizedPart)) continue;
369
+ delete sanitizedPart.image_url;
370
+ if (sanitizedPart.type === "image_url") sanitizedPart.type = "input_image";
371
+ if ("detail" in sanitizedPart && !isResponsesImageDetail(sanitizedPart.detail)) {
372
+ delete sanitizedPart.detail;
373
+ }
374
+ sanitizedContent.push(sanitizedPart);
375
+ continue;
376
+ }
377
+ sanitizedPart.image_url = normalizedImageUrl.imageUrl;
378
+ if (sanitizedPart.type === "image_url") {
379
+ sanitizedPart.type = "input_image";
380
+ }
381
+ if (normalizedImageUrl.detail) {
382
+ sanitizedPart.detail = normalizedImageUrl.detail;
383
+ } else if ("detail" in sanitizedPart && !isResponsesImageDetail(sanitizedPart.detail)) {
384
+ delete sanitizedPart.detail;
385
+ }
386
+ }
387
+ sanitizedContent.push(sanitizedPart);
388
+ }
389
+ return sanitizedContent;
390
+ }
391
+
392
+ function sanitizeResponsesStringFieldsForReplay(item: Record<string, unknown>): void {
393
+ if (item.type === "message") {
394
+ item.content = sanitizeResponsesMessageContentForReplay(item.content);
395
+ }
396
+ if (item.type === "function_call" && "arguments" in item && typeof item.arguments !== "string") {
397
+ item.arguments = stringifyResponsesStringParamForReplay(item.arguments);
398
+ }
399
+ if (item.type === "custom_tool_call" && "input" in item && typeof item.input !== "string") {
400
+ item.input = stringifyResponsesStringParamForReplay(item.input);
401
+ }
402
+ if ((item.type === "function_call_output" || item.type === "custom_tool_call_output") && "output" in item) {
403
+ item.output =
404
+ typeof item.output === "string"
405
+ ? neutralizeReservedControlTokens(item.output.toWellFormed())
406
+ : stringifyResponsesStringParamForReplay(item.output);
407
+ }
408
+ }
409
+
410
+ function sanitizeOpenAIResponsesHistoryItemForReplay(
411
+ item: Record<string, unknown>,
412
+ normalizedCallIds: Map<string, string>,
413
+ ): OpenAIResponsesReplayItem | undefined {
414
+ if (item.type === "item_reference") return undefined;
415
+
416
+ // providerPayload stores raw output items; replay strips fields that are output-only.
417
+ const { id: _id, ...itemWithoutId } = item;
418
+ const sanitizedItem =
419
+ item.type === "computer_call"
420
+ ? sanitizeComputerCallForResponsesInput(itemWithoutId)
421
+ : item.type === "image_generation_call"
422
+ ? sanitizeImageGenerationCallForResponsesInput(itemWithoutId)
423
+ : itemWithoutId;
424
+ if (typeof item.call_id === "string") {
425
+ sanitizedItem.call_id = normalizeReplayedResponsesHistoryCallId(item.call_id, normalizedCallIds);
426
+ }
427
+ sanitizeResponsesStringFieldsForReplay(sanitizedItem);
428
+
429
+ return sanitizedItem as unknown as OpenAIResponsesReplayItem;
430
+ }
431
+
432
+ function sanitizeComputerCallForResponsesInput(item: Record<string, unknown>): Record<string, unknown> {
433
+ // The Responses stream includes the performed computer action on output items,
434
+ // but the create input accepts only the call identity/status fields on replay.
435
+ const { action: _action, actions: _actions, ...inputSafeItem } = item;
436
+ return inputSafeItem;
437
+ }
438
+
439
+ function sanitizeImageGenerationCallForResponsesInput(item: Record<string, unknown>): Record<string, unknown> {
440
+ // Image generation output items include request-time knobs that are not part of
441
+ // the Responses input replay schema. Replaying them verbatim makes OpenAI-compatible
442
+ // endpoints reject the next turn, e.g. `Unknown parameter: input[n].action`.
443
+ const {
444
+ action: _action,
445
+ background: _background,
446
+ output_format: _outputFormat,
447
+ quality: _quality,
448
+ revised_prompt: _revisedPrompt,
449
+ size: _size,
450
+ ...inputSafeItem
451
+ } = item;
452
+ return inputSafeItem;
453
+ }
454
+
455
+ function normalizeReplayedResponsesHistoryCallId(value: string, normalizedValues: Map<string, string>): string {
456
+ const normalized = normalizedValues.get(value);
457
+ if (normalized) return normalized;
458
+ const next = truncateResponseItemId(value, getIdPrefix(value, "call"));
459
+ normalizedValues.set(value, next);
460
+ return next;
461
+ }
462
+
463
+ export function createOpenAIResponsesHistoryPayload(
464
+ provider: string,
465
+ items: Array<Record<string, unknown>>,
466
+ incremental = true,
467
+ ): OpenAIResponsesHistoryPayload {
468
+ return {
469
+ type: "openaiResponsesHistory",
470
+ provider,
471
+ ...(incremental ? { dt: true } : {}),
472
+ items,
473
+ };
474
+ }
475
+
476
+ export function getOpenAIResponsesHistoryPayload(
477
+ providerPayload: ProviderPayload | undefined,
478
+ currentProvider: string,
479
+ fallbackProvider?: string,
480
+ ): OpenAIResponsesHistoryPayload | undefined {
481
+ if (providerPayload?.type !== "openaiResponsesHistory" || !Array.isArray(providerPayload.items)) {
482
+ return undefined;
483
+ }
484
+ const payloadProvider = providerPayload.provider ?? fallbackProvider;
485
+ if (!payloadProvider || payloadProvider !== currentProvider) {
486
+ return undefined;
487
+ }
488
+ return { ...providerPayload, provider: payloadProvider };
489
+ }
490
+
491
+ export function getOpenAIResponsesHistoryItems(
492
+ providerPayload: ProviderPayload | undefined,
493
+ currentProvider: string,
494
+ fallbackProvider?: string,
495
+ ): Array<Record<string, unknown>> | undefined {
496
+ return getOpenAIResponsesHistoryPayload(providerPayload, currentProvider, fallbackProvider)?.items;
497
+ }
498
+
499
+ /**
500
+ * Resolve cache retention preference.
501
+ *
502
+ * Resolution order: explicit request value → `VIB_CACHE_RETENTION` →
503
+ * legacy `PI_CACHE_RETENTION` → `fallback`. Both env vars act as explicit
504
+ * opt-in (`"long"`) or opt-out (any other value) so a provider-specific
505
+ * `fallback` only applies when nothing else is configured. `fallback`
506
+ * defaults to `"short"` to preserve the historical behaviour for callers
507
+ * that don't pass one.
508
+ */
509
+ export function resolveCacheRetention(
510
+ cacheRetention?: CacheRetention,
511
+ fallback: CacheRetention = "short",
512
+ ): CacheRetention {
513
+ if (cacheRetention) return cacheRetention;
514
+ if ($env.VIB_CACHE_RETENTION === "long") return "long";
515
+ if ($env.VIB_CACHE_RETENTION !== undefined) return "short";
516
+ if ($env.PI_CACHE_RETENTION === "long") return "long";
517
+ if ($env.PI_CACHE_RETENTION !== undefined) return "short";
518
+ return fallback;
519
+ }
520
+
521
+ export function isAnthropicOAuthToken(key: string): boolean {
522
+ return key.includes("sk-ant-oat");
523
+ }