@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
@@ -0,0 +1,408 @@
1
+ import turnAbortedGuidance from "../prompts/turn-aborted-guidance.md" with { type: "text" };
2
+ import type {
3
+ Api,
4
+ AssistantMessage,
5
+ DeveloperMessage,
6
+ Message,
7
+ Model,
8
+ ToolCall,
9
+ ToolResultMessage,
10
+ UserMessage,
11
+ } from "../types";
12
+
13
+ const enum ToolCallStatus {
14
+ /** Tool call has received a result (real or synthetic for orphan) */
15
+ Resolved = 1,
16
+ /** Tool call was from an aborted message; synthetic result injected, skip real results */
17
+ Aborted = 2,
18
+ }
19
+
20
+ /**
21
+ * Normalize tool call ID for cross-provider compatibility.
22
+ * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
23
+ * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
24
+ *
25
+ * For aborted/errored turns, this function:
26
+ * - Preserves tool call structure (unlike converting to text summaries)
27
+ * - Injects synthetic "aborted" tool results
28
+ * - Adds a <turn-aborted> guidance marker for the model
29
+ */
30
+ /**
31
+ * Detect directly adjacent private thinking blocks inside one assistant message's
32
+ * content. `thinking` and `redacted_thinking` are one adjacency class: the
33
+ * Anthropic wire contract rejects a replayed assistant turn where two such blocks
34
+ * sit next to each other with no intervening `tool_use`/`text` block (#4416).
35
+ *
36
+ * This is a pure, allocation-free predicate used by defense-in-depth diagnostics
37
+ * (issue #4443): the write-time transcript assertion (coding-agent persistence)
38
+ * and the stream-assembler SSE diagnostic (anthropic stream completion). It never
39
+ * inspects block payloads — only the block-type sequence — so it cannot leak
40
+ * thinking text, signatures, or credentials.
41
+ *
42
+ * Blocks separated by any non-private block (`tool_use`, `text`, …) are ordinary
43
+ * interleaved-thinking shape and return `false`.
44
+ */
45
+ export function hasAdjacentPrivateThinkingBlocks(content: { type: string }[]): boolean {
46
+ let previousWasPrivate = false;
47
+ for (const block of content) {
48
+ const isPrivate = block.type === "thinking" || block.type === "redactedThinking";
49
+ if (isPrivate && previousWasPrivate) return true;
50
+ previousWasPrivate = isPrivate;
51
+ }
52
+ return false;
53
+ }
54
+
55
+ /**
56
+ * Collapse a run of directly adjacent `thinking` blocks inside one assistant message down
57
+ * to its first block.
58
+ *
59
+ * Anthropic accepts a replayed assistant turn carrying a single thinking block, and accepts
60
+ * thinking blocks separated by a `tool_use` (ordinary interleaved-thinking shape), but
61
+ * rejects two directly adjacent `thinking` blocks with
62
+ * `messages.N.content.M: thinking or redacted_thinking blocks in the latest assistant
63
+ * message cannot be modified`, citing the *second* block of the pair. Because the offending
64
+ * message keeps its index as history grows, a single such turn makes every later request in
65
+ * that session fail, and the mutation repair - scoped to the latest assistant message -
66
+ * can never reach it (#4416).
67
+ *
68
+ * `redactedThinking` is not folded in this phase, but the final send-boundary
69
+ * collapse in `convertAnthropicMessages` (#4425) treats `thinking` and
70
+ * `redacted_thinking` as one adjacency class per the API contract.
71
+ */
72
+ function collapseAdjacentThinking<T extends { type: string }>(content: T[]): T[] {
73
+ let previousWasThinking = false;
74
+ let dropped = false;
75
+ const collapsed: T[] = [];
76
+ for (const block of content) {
77
+ const thinking = block.type === "thinking";
78
+ if (thinking && previousWasThinking) {
79
+ dropped = true;
80
+ continue;
81
+ }
82
+ previousWasThinking = thinking;
83
+ collapsed.push(block);
84
+ }
85
+ return dropped ? collapsed : content;
86
+ }
87
+
88
+ export function transformMessages<TApi extends Api>(
89
+ messages: Message[],
90
+ model: Model<TApi>,
91
+ normalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string,
92
+ options?: { repairLatestAssistantThinking?: boolean; repairAllAssistantThinking?: boolean },
93
+ ): Message[] {
94
+ // Build a map of original tool call IDs to normalized IDs
95
+ const toolCallIdMap = new Map<string, string>();
96
+
97
+ const latestAssistantIndex = messages.findLastIndex(msg => msg.role === "assistant");
98
+ // First pass: transform messages (thinking blocks, tool call ID normalization)
99
+ const transformed = messages.map((msg, index) => {
100
+ // User and developer messages pass through unchanged
101
+ if (msg.role === "user" || msg.role === "developer") {
102
+ return msg;
103
+ }
104
+
105
+ // Handle toolResult messages - normalize toolCallId if we have a mapping
106
+ if (msg.role === "toolResult") {
107
+ const normalizedId = toolCallIdMap.get(msg.toolCallId);
108
+ if (normalizedId && normalizedId !== msg.toolCallId) {
109
+ return { ...msg, toolCallId: normalizedId };
110
+ }
111
+ return msg;
112
+ }
113
+
114
+ // Assistant messages need transformation check
115
+ if (msg.role === "assistant") {
116
+ const assistantMsg = msg as AssistantMessage;
117
+ const isSameModel =
118
+ assistantMsg.provider === model.provider &&
119
+ assistantMsg.api === model.api &&
120
+ assistantMsg.model === model.id;
121
+
122
+ const mustPreserveLatestAnthropicThinking =
123
+ index === latestAssistantIndex &&
124
+ model.api === "anthropic-messages" &&
125
+ assistantMsg.api === "anthropic-messages";
126
+ // Aborted/errored messages may contain partially-streamed thinking blocks.
127
+ // Anthropic requires thinking/redacted_thinking bytes in replayed assistant
128
+ // messages to match the original response exactly; stripping a signature,
129
+ // well-forming text, or keeping a partial redacted block would emit a
130
+ // modified thinking sequence. Drop those private blocks instead. Tool calls
131
+ // are kept so the second pass can either preserve real results or synthesize
132
+ // an explicit aborted result without leaving dangling tool_use blocks.
133
+ const hasPartialThinking = assistantMsg.stopReason === "aborted" || assistantMsg.stopReason === "error";
134
+ // One-shot Anthropic replay repair. `repairLatestAssistantThinking` targets the
135
+ // "latest assistant message ... cannot be modified" 400; `repairAllAssistantThinking`
136
+ // targets the "Invalid `signature` in `thinking` block" 400, which can cite a block
137
+ // anywhere in the replayed history (e.g. after compaction/pruning rewrote an earlier
138
+ // turn), so the drop must apply to every assistant message. Within each
139
+ // message only blocks that would replay as native thinking/redacted_thinking
140
+ // are dropped; cross-model reasoning degrades to text and is preserved.
141
+ const dropAssistantThinkingForRepair =
142
+ (options?.repairAllAssistantThinking === true ||
143
+ (options?.repairLatestAssistantThinking === true && index === latestAssistantIndex)) &&
144
+ model.api === "anthropic-messages" &&
145
+ assistantMsg.api === "anthropic-messages";
146
+
147
+ const transformedContent = assistantMsg.content.flatMap(block => {
148
+ if (block.type === "thinking") {
149
+ if (hasPartialThinking) return [];
150
+ const sanitized = block;
151
+ // Repair must only drop blocks that would otherwise replay as native
152
+ // thinking. Cross-model/provider reasoning degrades to unsigned text
153
+ // below and was never replayed as a signed block, so it cannot be the
154
+ // signature failure — dropping it would silently lose valid context.
155
+ const replaysAsNativeThinking = mustPreserveLatestAnthropicThinking || isSameModel;
156
+ if (dropAssistantThinkingForRepair && replaysAsNativeThinking) return [];
157
+ if (mustPreserveLatestAnthropicThinking) return sanitized;
158
+ // For same model: keep thinking blocks with signatures (needed for replay)
159
+ // even if the thinking text is empty — but only for non-Anthropic APIs where
160
+ // the signature represents OpenAI encrypted reasoning. For anthropic-messages,
161
+ // a signed block with empty text means clear_thinking_20251015 stripped the
162
+ // content server-side while the stale signature remained; replaying it
163
+ // produces `thinking ... cannot be modified` 400s on every turn (#4247).
164
+ if (isSameModel && sanitized.thinkingSignature) {
165
+ if (sanitized.thinking.trim() === "" && model.api === "anthropic-messages") return [];
166
+ return sanitized;
167
+ }
168
+ // Skip empty thinking blocks, convert others to plain text
169
+ if (!sanitized.thinking || sanitized.thinking.trim() === "") return [];
170
+ if (isSameModel) return sanitized;
171
+ return {
172
+ type: "text" as const,
173
+ text: sanitized.thinking,
174
+ };
175
+ }
176
+
177
+ if (block.type === "redactedThinking") {
178
+ if (hasPartialThinking) return [];
179
+ // Same restriction as thinking blocks: cross-model/provider redacted
180
+ // blocks already drop below, so repair only needs to cover blocks that
181
+ // would replay as native redacted_thinking.
182
+ if (dropAssistantThinkingForRepair && (mustPreserveLatestAnthropicThinking || isSameModel)) {
183
+ return [];
184
+ }
185
+ if (mustPreserveLatestAnthropicThinking) return block;
186
+ if (isSameModel) return block;
187
+ return [];
188
+ }
189
+
190
+ if (block.type === "text") {
191
+ if (isSameModel) return block;
192
+ return {
193
+ type: "text" as const,
194
+ text: block.text,
195
+ };
196
+ }
197
+
198
+ if (block.type === "toolCall") {
199
+ const toolCall = block as ToolCall;
200
+ let normalizedToolCall: ToolCall = toolCall;
201
+
202
+ if (!isSameModel && toolCall.thoughtSignature) {
203
+ normalizedToolCall = { ...toolCall };
204
+ delete (normalizedToolCall as { thoughtSignature?: string }).thoughtSignature;
205
+ }
206
+
207
+ if (!isSameModel && normalizeToolCallId) {
208
+ const normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);
209
+ if (normalizedId !== toolCall.id) {
210
+ toolCallIdMap.set(toolCall.id, normalizedId);
211
+ normalizedToolCall = { ...normalizedToolCall, id: normalizedId };
212
+ }
213
+ }
214
+
215
+ return normalizedToolCall;
216
+ }
217
+
218
+ return block;
219
+ });
220
+
221
+ // Only the Anthropic wire shape rejects adjacent private blocks; other targets
222
+ // either degrade reasoning to text above or carry their own encoding rules.
223
+ const replayableContent =
224
+ model.api === "anthropic-messages" ? collapseAdjacentThinking(transformedContent) : transformedContent;
225
+
226
+ return {
227
+ ...assistantMsg,
228
+ content: replayableContent,
229
+ };
230
+ }
231
+ return msg;
232
+ });
233
+ const realToolResultIds = new Set(
234
+ transformed.filter((msg): msg is ToolResultMessage => msg.role === "toolResult").map(msg => msg.toolCallId),
235
+ );
236
+
237
+ // Anthropic rejects `tool_result` blocks whose `tool_use_id` does not appear in a prior
238
+ // `tool_use` block. After handoff/compaction folds an assistant turn into a summary
239
+ // string, the user-side `toolResult` for that turn can survive while the originating
240
+ // `tool_use` disappears — leaving an orphan that triggers HTTP 400. Track the set of
241
+ // `tool_use` ids that survive transformation so the second pass can drop orphans cleanly.
242
+ const validToolUseIds = new Set<string>();
243
+ for (const msg of transformed) {
244
+ if (msg.role !== "assistant") continue;
245
+ for (const block of msg.content) {
246
+ if (block.type === "toolCall") validToolUseIds.add(block.id);
247
+ }
248
+ }
249
+
250
+ // Second pass: insert synthetic empty tool results for orphaned tool calls
251
+ // and preserve aborted/errored tool results when they were already persisted.
252
+ const result: Message[] = [];
253
+ let pendingToolCalls: ToolCall[] = [];
254
+ let pendingAbortedToolCalls = new Map<string, ToolCall>();
255
+ let pendingAbortedTimestamp: number | undefined;
256
+ // Track tool call status: whether resolved (has result) or aborted (synthetic result injected, skip later real results)
257
+ const toolCallStatus = new Map<string, ToolCallStatus>();
258
+
259
+ const flushPendingToolCalls = (timestamp: number): void => {
260
+ if (pendingToolCalls.length === 0) return;
261
+ for (const tc of pendingToolCalls) {
262
+ if (!toolCallStatus.has(tc.id) && !realToolResultIds.has(tc.id)) {
263
+ result.push({
264
+ role: "toolResult",
265
+ toolCallId: tc.id,
266
+ toolName: tc.name,
267
+ content: [{ type: "text", text: "No result provided" }],
268
+ isError: true,
269
+ timestamp,
270
+ } as ToolResultMessage);
271
+ toolCallStatus.set(tc.id, ToolCallStatus.Resolved);
272
+ }
273
+ }
274
+ pendingToolCalls = [];
275
+ };
276
+
277
+ const flushPendingAbortedToolCalls = (): void => {
278
+ if (pendingAbortedTimestamp === undefined) return;
279
+ for (const tc of pendingAbortedToolCalls.values()) {
280
+ if (!toolCallStatus.has(tc.id)) {
281
+ result.push({
282
+ role: "toolResult",
283
+ toolCallId: tc.id,
284
+ toolName: tc.name,
285
+ content: [{ type: "text", text: "aborted" }],
286
+ isError: true,
287
+ timestamp: pendingAbortedTimestamp,
288
+ } as ToolResultMessage);
289
+ toolCallStatus.set(tc.id, ToolCallStatus.Aborted);
290
+ }
291
+ }
292
+ result.push({
293
+ role: "developer",
294
+ content: turnAbortedGuidance,
295
+ timestamp: pendingAbortedTimestamp + 1,
296
+ } as DeveloperMessage);
297
+ pendingAbortedToolCalls = new Map();
298
+ pendingAbortedTimestamp = undefined;
299
+ };
300
+
301
+ for (let i = 0; i < transformed.length; i++) {
302
+ const msg = transformed[i];
303
+ const messageTimestamp = "timestamp" in msg && typeof msg.timestamp === "number" ? msg.timestamp : Date.now();
304
+
305
+ if (msg.role === "assistant") {
306
+ flushPendingToolCalls(messageTimestamp);
307
+ flushPendingAbortedToolCalls();
308
+
309
+ const assistantMsg = msg as AssistantMessage;
310
+ const toolCalls = assistantMsg.content.filter(b => b.type === "toolCall") as ToolCall[];
311
+
312
+ if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") {
313
+ // Keep the assistant message with tool calls intact. If real tool results follow, preserve them;
314
+ // otherwise synthesize aborted results before the next turn boundary.
315
+ result.push(msg);
316
+ pendingAbortedToolCalls = new Map(toolCalls.map(toolCall => [toolCall.id, toolCall] as const));
317
+ pendingAbortedTimestamp = assistantMsg.timestamp;
318
+ continue;
319
+ }
320
+
321
+ if (toolCalls.length > 0) {
322
+ pendingToolCalls = toolCalls;
323
+ }
324
+
325
+ result.push(msg);
326
+ } else if (msg.role === "toolResult") {
327
+ if (pendingAbortedToolCalls.has(msg.toolCallId)) {
328
+ pendingAbortedToolCalls.delete(msg.toolCallId);
329
+ toolCallStatus.set(msg.toolCallId, ToolCallStatus.Resolved);
330
+ result.push(msg);
331
+ continue;
332
+ }
333
+
334
+ if (toolCallStatus.get(msg.toolCallId) === ToolCallStatus.Aborted) continue;
335
+
336
+ if (!validToolUseIds.has(msg.toolCallId)) {
337
+ // Orphan `tool_result`: the originating `tool_use` is not present in the
338
+ // transformed history (typically because handoff/compaction folded the
339
+ // assistant message into a summary string while the user-side result
340
+ // survived). Sending the block as-is would 400 the request, so it must
341
+ // be dropped.
342
+ //
343
+ // If a pending tool-call window is still open (either normal or
344
+ // aborted), the orphan cannot be replaced with a developer note here:
345
+ //
346
+ // * Anthropic requires the next message after an assistant `tool_use`
347
+ // to be the matching `tool_result`. Inserting a developer message
348
+ // would break that contiguity.
349
+ // * `flushPendingAbortedToolCalls` synthesizes "aborted" results
350
+ // without checking whether a real result lands later in history
351
+ // (unlike `flushPendingToolCalls`, which is gated by
352
+ // `realToolResultIds`). Calling it here would convert a legitimate
353
+ // later `tool_result` into a synthetic "aborted" one via the
354
+ // `ToolCallStatus.Aborted` skip-guard.
355
+ //
356
+ // Drop the orphan silently in that case; the upcoming real
357
+ // `tool_result` will land normally on the next iteration.
358
+ if (pendingToolCalls.length > 0 || pendingAbortedToolCalls.size > 0) {
359
+ continue;
360
+ }
361
+ // No pending tool-call window: safe to preserve the text payload so the
362
+ // model still sees what the tool returned.
363
+ //
364
+ // The note is emitted with `role: "user"` rather than `role: "developer"`
365
+ // because the developer role is elevated by some providers:
366
+ //
367
+ // * Ollama maps `developer` -> `system` (highest instruction priority).
368
+ // * OpenAI chat-completions reasoning models forward `developer` as
369
+ // `developer` (above-user instruction priority).
370
+ //
371
+ // Stale, model-untrusted tool output must not gain instruction priority
372
+ // above user/developer messages it lived alongside before compaction.
373
+ // `user` role is mapped to plain user content by every provider, so the
374
+ // content survives without ever being treated as an instruction the
375
+ // model should obey.
376
+ const textParts: string[] = [];
377
+ for (const part of msg.content) {
378
+ if (part.type === "text" && part.text.trim() !== "") textParts.push(part.text);
379
+ }
380
+ if (textParts.length > 0) {
381
+ const errorAttr = msg.isError ? ' is-error="true"' : "";
382
+ result.push({
383
+ role: "user",
384
+ content: `<stale-tool-result tool="${msg.toolName}" id="${msg.toolCallId}"${errorAttr}>\n${textParts.join("\n")}\n</stale-tool-result>`,
385
+ timestamp: messageTimestamp,
386
+ } as UserMessage);
387
+ }
388
+ continue;
389
+ }
390
+
391
+ toolCallStatus.set(msg.toolCallId, ToolCallStatus.Resolved);
392
+ result.push(msg);
393
+ } else if (msg.role === "user" || msg.role === "developer") {
394
+ flushPendingToolCalls(messageTimestamp);
395
+ flushPendingAbortedToolCalls();
396
+ result.push(msg);
397
+ } else {
398
+ flushPendingToolCalls(messageTimestamp);
399
+ flushPendingAbortedToolCalls();
400
+ result.push(msg);
401
+ }
402
+ }
403
+
404
+ flushPendingToolCalls(Date.now());
405
+ flushPendingAbortedToolCalls();
406
+
407
+ return result;
408
+ }
@@ -0,0 +1,8 @@
1
+ import type { ImageContent, TextContent } from "../types";
2
+ export declare const NON_VISION_IMAGE_PLACEHOLDER = "[image omitted: model does not support vision]";
3
+ export declare function partitionVisionContent(content: ReadonlyArray<TextContent | ImageContent>, supportsImages: boolean): {
4
+ textBlocks: TextContent[];
5
+ imageBlocks: ImageContent[];
6
+ omittedImages: boolean;
7
+ };
8
+ export declare function joinTextWithImagePlaceholder(text: string, omittedImages: boolean): string;
@@ -0,0 +1,31 @@
1
+ import type { ImageContent, TextContent } from "../types";
2
+
3
+ export const NON_VISION_IMAGE_PLACEHOLDER = "[image omitted: model does not support vision]";
4
+
5
+ export function partitionVisionContent(
6
+ content: ReadonlyArray<TextContent | ImageContent>,
7
+ supportsImages: boolean,
8
+ ): {
9
+ textBlocks: TextContent[];
10
+ imageBlocks: ImageContent[];
11
+ omittedImages: boolean;
12
+ } {
13
+ const textBlocks = content.filter((block): block is TextContent => block.type === "text");
14
+ const imageBlocks = content.filter((block): block is ImageContent => block.type === "image");
15
+ return {
16
+ textBlocks,
17
+ imageBlocks: supportsImages ? imageBlocks : [],
18
+ omittedImages: !supportsImages && imageBlocks.length > 0,
19
+ };
20
+ }
21
+
22
+ export function joinTextWithImagePlaceholder(text: string, omittedImages: boolean): string {
23
+ const parts: string[] = [];
24
+ if (text.length > 0) {
25
+ parts.push(text);
26
+ }
27
+ if (omittedImages) {
28
+ parts.push(NON_VISION_IMAGE_PLACEHOLDER);
29
+ }
30
+ return parts.join("\n");
31
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Rate limit reason classification and backoff calculation utilities.
3
+ * Ported from opencode-antigravity-auth plugin for consistency.
4
+ */
5
+ export type RateLimitReason = "QUOTA_EXHAUSTED" | "RATE_LIMIT_EXCEEDED" | "MODEL_CAPACITY_EXHAUSTED" | "SERVER_ERROR" | "UNKNOWN";
6
+ /**
7
+ * Classify a rate-limit error message into a reason category.
8
+ * Priority order: MODEL_CAPACITY > RATE_LIMIT > QUOTA > SERVER_ERROR > UNKNOWN.
9
+ *
10
+ * "resource exhausted" maps to MODEL_CAPACITY (transient, short wait)
11
+ * "quota exceeded" maps to QUOTA_EXHAUSTED (long wait, switch account)
12
+ */
13
+ export declare function parseRateLimitReason(errorMessage: string): RateLimitReason;
14
+ /**
15
+ * Calculate backoff delay in ms for a given rate limit reason.
16
+ * MODEL_CAPACITY gets jitter to prevent thundering herd.
17
+ */
18
+ export declare function calculateRateLimitBackoffMs(reason: RateLimitReason): number;
19
+ export declare function isUsageLimitError(errorMessage: string): boolean;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Rate limit reason classification and backoff calculation utilities.
3
+ * Ported from opencode-antigravity-auth plugin for consistency.
4
+ */
5
+
6
+ export type RateLimitReason =
7
+ | "QUOTA_EXHAUSTED"
8
+ | "RATE_LIMIT_EXCEEDED"
9
+ | "MODEL_CAPACITY_EXHAUSTED"
10
+ | "SERVER_ERROR"
11
+ | "UNKNOWN";
12
+
13
+ const QUOTA_EXHAUSTED_BACKOFF_MS = 30 * 60 * 1000; // 30 min
14
+ const RATE_LIMIT_EXCEEDED_BACKOFF_MS = 30 * 1000; // 30s
15
+ const MODEL_CAPACITY_BASE_MS = 45 * 1000; // 45s base
16
+ const MODEL_CAPACITY_JITTER_MS = 30 * 1000; // uniform +0–30s above base → 45–75s total
17
+ const SERVER_ERROR_BACKOFF_MS = 20 * 1000; // 20s
18
+
19
+ /**
20
+ * Classify a rate-limit error message into a reason category.
21
+ * Priority order: MODEL_CAPACITY > RATE_LIMIT > QUOTA > SERVER_ERROR > UNKNOWN.
22
+ *
23
+ * "resource exhausted" maps to MODEL_CAPACITY (transient, short wait)
24
+ * "quota exceeded" maps to QUOTA_EXHAUSTED (long wait, switch account)
25
+ */
26
+ export function parseRateLimitReason(errorMessage: string): RateLimitReason {
27
+ const lower = errorMessage.toLowerCase();
28
+
29
+ if (
30
+ lower.includes("capacity") ||
31
+ lower.includes("overloaded") ||
32
+ lower.includes("529") ||
33
+ lower.includes("503") ||
34
+ lower.includes("resource exhausted")
35
+ ) {
36
+ return "MODEL_CAPACITY_EXHAUSTED";
37
+ }
38
+
39
+ if (
40
+ lower.includes("out_of_credits") ||
41
+ lower.includes("request would exceed your account's rate limit") ||
42
+ lower.includes("request would exceed your accounts rate limit")
43
+ ) {
44
+ return "QUOTA_EXHAUSTED";
45
+ }
46
+
47
+ if (
48
+ lower.includes("per minute") ||
49
+ lower.includes("rate limit") ||
50
+ lower.includes("too many requests") ||
51
+ lower.includes("presque")
52
+ ) {
53
+ return "RATE_LIMIT_EXCEEDED";
54
+ }
55
+
56
+ if (
57
+ lower.includes("exhausted") ||
58
+ lower.includes("quota") ||
59
+ lower.includes("usage limit") ||
60
+ lower.includes("model limit") ||
61
+ lower.includes("model_limit") ||
62
+ lower.includes("message limit") ||
63
+ lower.includes("message_limit") ||
64
+ lower.includes("limit for this model")
65
+ ) {
66
+ return "QUOTA_EXHAUSTED";
67
+ }
68
+
69
+ if (lower.includes("500") || lower.includes("internal error") || lower.includes("internal server error")) {
70
+ return "SERVER_ERROR";
71
+ }
72
+
73
+ return "UNKNOWN";
74
+ }
75
+
76
+ /**
77
+ * Calculate backoff delay in ms for a given rate limit reason.
78
+ * MODEL_CAPACITY gets jitter to prevent thundering herd.
79
+ */
80
+ export function calculateRateLimitBackoffMs(reason: RateLimitReason): number {
81
+ switch (reason) {
82
+ case "QUOTA_EXHAUSTED":
83
+ return QUOTA_EXHAUSTED_BACKOFF_MS;
84
+ case "RATE_LIMIT_EXCEEDED":
85
+ return RATE_LIMIT_EXCEEDED_BACKOFF_MS;
86
+ case "MODEL_CAPACITY_EXHAUSTED":
87
+ return MODEL_CAPACITY_BASE_MS + Math.random() * MODEL_CAPACITY_JITTER_MS;
88
+ case "SERVER_ERROR":
89
+ return SERVER_ERROR_BACKOFF_MS;
90
+ default:
91
+ return QUOTA_EXHAUSTED_BACKOFF_MS; // conservative default
92
+ }
93
+ }
94
+
95
+ /** Detect usage/quota limit errors in error messages (persistent, requires credential switch). */
96
+ // ZAI reports durable token exhaustion as "[1310][Weekly/Monthly Limit Exhausted...]".
97
+ // Keep this explicit so generic "rate limit exhausted, retry..." throttles remain retryable.
98
+ const USAGE_LIMIT_PATTERN =
99
+ /usage.?limit|usage_limit_reached|usage_not_included|limit_reached|model.?limit|model_limit_reached|message.?limit|message_limit_reached|limit for this model|weekly\/monthly\s+limit\s+exhausted|quota.?exceeded|out_of_credits|request would exceed your account.?s rate limit|resource has been exhausted[^\n]*(?:quota|limit)/i;
100
+ export function isUsageLimitError(errorMessage: string): boolean {
101
+ return USAGE_LIMIT_PATTERN.test(errorMessage);
102
+ }
@@ -0,0 +1,45 @@
1
+ import type { Effort } from "./model-thinking";
2
+ import type { AnthropicOptions } from "./providers/anthropic";
3
+ import type { Api, AssistantMessage, Context, Model, OptionsForApi, SimpleStreamOptions, ToolChoice } from "./types";
4
+ import { AssistantMessageEventStream } from "./utils/event-stream";
5
+ /**
6
+ * Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
7
+ *
8
+ * Provider authentication intentionally excludes cwd/.env values. Project dotenv files are
9
+ * loaded into $env for app/tool execution, but must not silently fund Vibrato model requests.
10
+ */
11
+ export declare function getEnvApiKey(provider: string): string | undefined;
12
+ /**
13
+ * Enumerate every provider that has an env-var fallback for `getEnvApiKey`.
14
+ * Used by `vib auth-broker migrate --include-env` to discover env-sourced keys
15
+ * that should be uploaded to the broker.
16
+ */
17
+ export declare function listProvidersWithEnvKey(): string[];
18
+ /**
19
+ * Provider-specific credential guidance appended to "no credential" errors.
20
+ *
21
+ * Headless Vibrato has no interactive `/login` TUI, so a bare "No API key" /
22
+ * "No credentials" error left users — OpenCode Go subscribers especially
23
+ * (#755) — unsure what signal Vibrato actually reads. OpenCode subscriptions are
24
+ * themselves API keys, so this names the env var Vibrato reads for the provider,
25
+ * warns that a project `.env` is intentionally ignored for provider
26
+ * credentials, and points OpenCode users at one-time interactive CLI credential capture.
27
+ *
28
+ * Returns an empty string when the provider has no env-var key and no special
29
+ * handling, so callers can append it unconditionally.
30
+ */
31
+ export declare function formatProviderCredentialHint(provider: string): string;
32
+ export declare function streamFromLazyImport(createInner: () => Promise<AssistantMessageEventStream>, signal?: AbortSignal, onStreamCreated?: () => void): AssistantMessageEventStream;
33
+ /**
34
+ * Build an actionable "missing API key" error for a provider, used by the
35
+ * low-level `stream`/`complete` entry points (#755).
36
+ */
37
+ export declare function formatMissingApiKeyError(provider: string): string;
38
+ export declare function stream<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi>, onStreamCreated?: () => void): AssistantMessageEventStream;
39
+ export declare function complete<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi>): Promise<AssistantMessage>;
40
+ export declare function streamSimple<TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream;
41
+ export declare function completeSimple<TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions): Promise<AssistantMessage>;
42
+ export declare const OUTPUT_FALLBACK_BUFFER = 4000;
43
+ export declare const ANTHROPIC_THINKING: Record<Effort, number>;
44
+ export declare function mapAnthropicToolChoice(choice?: ToolChoice): AnthropicOptions["toolChoice"];
45
+ export declare function resolveDefaultRequestMaxTokens<TApi extends Api>(model: Model<TApi>, requested?: number): number;