@srouterhq/server 0.0.0-stage → 0.9.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 (1027) hide show
  1. package/LICENSE +21 -0
  2. package/client/dist/assets/am-TQ7Jmdqe.js +1 -0
  3. package/client/dist/assets/ar-Bf5a7yfC.js +1 -0
  4. package/client/dist/assets/az-CrosE1xH.js +1 -0
  5. package/client/dist/assets/bg-BvWnmcUz.js +1 -0
  6. package/client/dist/assets/bn-ams5TsJp.js +1 -0
  7. package/client/dist/assets/cs-Dh67CaJ_.js +1 -0
  8. package/client/dist/assets/da-9WlT8Iq7.js +1 -0
  9. package/client/dist/assets/de-lWhJJzz7.js +1 -0
  10. package/client/dist/assets/el-Cu7_GhNq.js +1 -0
  11. package/client/dist/assets/es-BZuzsBcP.js +1 -0
  12. package/client/dist/assets/fa-Dwdn-jKS.js +1 -0
  13. package/client/dist/assets/fi-BFrFyOTy.js +1 -0
  14. package/client/dist/assets/fr-XhbtmPpj.js +1 -0
  15. package/client/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  16. package/client/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  17. package/client/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  18. package/client/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  19. package/client/dist/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  20. package/client/dist/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  21. package/client/dist/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  22. package/client/dist/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  23. package/client/dist/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  24. package/client/dist/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  25. package/client/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  26. package/client/dist/assets/gu-D0uhLUB8.js +1 -0
  27. package/client/dist/assets/ha-CVlm9pqp.js +1 -0
  28. package/client/dist/assets/he-CMIFeoWr.js +1 -0
  29. package/client/dist/assets/hi-ENTwhBpn.js +1 -0
  30. package/client/dist/assets/hr-fc03vMy_.js +1 -0
  31. package/client/dist/assets/hu-YBo2BIYt.js +1 -0
  32. package/client/dist/assets/id-BEWXYX69.js +1 -0
  33. package/client/dist/assets/ig-BKLZFKka.js +1 -0
  34. package/client/dist/assets/index-D9I4KtvR.js +145 -0
  35. package/client/dist/assets/index-txhEmCdb.css +2 -0
  36. package/client/dist/assets/it-Bzmei1Y2.js +1 -0
  37. package/client/dist/assets/ja-BfcpuqEl.js +1 -0
  38. package/client/dist/assets/ka-CnWjRgLo.js +1 -0
  39. package/client/dist/assets/km-BAjPR3Qj.js +1 -0
  40. package/client/dist/assets/kn-B15WKU5m.js +1 -0
  41. package/client/dist/assets/ko-C61fAB-w.js +1 -0
  42. package/client/dist/assets/lt-CYTr4_YW.js +1 -0
  43. package/client/dist/assets/ml-CtqxgyH3.js +1 -0
  44. package/client/dist/assets/mr-X5TMY7aR.js +1 -0
  45. package/client/dist/assets/ms-DSg8RqPS.js +1 -0
  46. package/client/dist/assets/my-D7RqR8uE.js +1 -0
  47. package/client/dist/assets/ne-DaflxkDj.js +1 -0
  48. package/client/dist/assets/nl-BOqqtsC8.js +1 -0
  49. package/client/dist/assets/no-BSHp_StB.js +1 -0
  50. package/client/dist/assets/or-BkLR9Vub.js +1 -0
  51. package/client/dist/assets/pa-CarJ2XgI.js +1 -0
  52. package/client/dist/assets/pl-C2n0V-0k.js +1 -0
  53. package/client/dist/assets/pt-BR-CqJdNhg2.js +1 -0
  54. package/client/dist/assets/pt-PT-C_HpMyKz.js +1 -0
  55. package/client/dist/assets/ro-DVRZqSAS.js +1 -0
  56. package/client/dist/assets/ru-DwAJG7VC.js +1 -0
  57. package/client/dist/assets/si-BxUezXm0.js +1 -0
  58. package/client/dist/assets/sk-eI1VcIfY.js +1 -0
  59. package/client/dist/assets/sr-CJF3auCr.js +1 -0
  60. package/client/dist/assets/srouter-logo-C6ZfjGIi.svg +14 -0
  61. package/client/dist/assets/sv-nqvwHAq_.js +1 -0
  62. package/client/dist/assets/sw-DWynE2pW.js +1 -0
  63. package/client/dist/assets/ta-BVM12knC.js +1 -0
  64. package/client/dist/assets/te-oyzEkF7_.js +1 -0
  65. package/client/dist/assets/th-COVeE0ZQ.js +1 -0
  66. package/client/dist/assets/tl-DsJANnQz.js +1 -0
  67. package/client/dist/assets/tr-B-Fl-urO.js +1 -0
  68. package/client/dist/assets/uk-C5qketAO.js +1 -0
  69. package/client/dist/assets/ur-QU9KugfV.js +1 -0
  70. package/client/dist/assets/uz-DL9cG_mY.js +1 -0
  71. package/client/dist/assets/vi-CQiVy3Pu.js +1 -0
  72. package/client/dist/assets/yo-DqazMdrZ.js +1 -0
  73. package/client/dist/assets/zh-CN-DnYL_Kio.js +1 -0
  74. package/client/dist/assets/zh-TW-5bdbosKj.js +1 -0
  75. package/client/dist/favicon.svg +14 -0
  76. package/client/dist/icons.svg +24 -0
  77. package/client/dist/index.html +37 -0
  78. package/dist/app.d.ts +4 -0
  79. package/dist/app.d.ts.map +1 -0
  80. package/dist/app.js +372 -0
  81. package/dist/app.js.map +1 -0
  82. package/dist/db/index.d.ts +49 -0
  83. package/dist/db/index.d.ts.map +1 -0
  84. package/dist/db/index.js +203 -0
  85. package/dist/db/index.js.map +1 -0
  86. package/dist/db/migrate/TEMPLATE.d.ts +4 -0
  87. package/dist/db/migrate/TEMPLATE.d.ts.map +1 -0
  88. package/dist/db/migrate/TEMPLATE.js +18 -0
  89. package/dist/db/migrate/TEMPLATE.js.map +1 -0
  90. package/dist/db/migrate/cli.d.ts +2 -0
  91. package/dist/db/migrate/cli.d.ts.map +1 -0
  92. package/dist/db/migrate/cli.js +177 -0
  93. package/dist/db/migrate/cli.js.map +1 -0
  94. package/dist/db/migrate/defaults.d.ts +52 -0
  95. package/dist/db/migrate/defaults.d.ts.map +1 -0
  96. package/dist/db/migrate/defaults.js +126 -0
  97. package/dist/db/migrate/defaults.js.map +1 -0
  98. package/dist/db/migrate/runner.d.ts +16 -0
  99. package/dist/db/migrate/runner.d.ts.map +1 -0
  100. package/dist/db/migrate/runner.js +178 -0
  101. package/dist/db/migrate/runner.js.map +1 -0
  102. package/dist/db/migrations/20260101_000000_legacy_baseline.d.ts +4 -0
  103. package/dist/db/migrations/20260101_000000_legacy_baseline.d.ts.map +1 -0
  104. package/dist/db/migrations/20260101_000000_legacy_baseline.js +2240 -0
  105. package/dist/db/migrations/20260101_000000_legacy_baseline.js.map +1 -0
  106. package/dist/db/migrations/20260627_000001_custom_provider_modalities.d.ts +4 -0
  107. package/dist/db/migrations/20260627_000001_custom_provider_modalities.d.ts.map +1 -0
  108. package/dist/db/migrations/20260627_000001_custom_provider_modalities.js +27 -0
  109. package/dist/db/migrations/20260627_000001_custom_provider_modalities.js.map +1 -0
  110. package/dist/db/migrations/20260627_000002_catalog_model_state.d.ts +4 -0
  111. package/dist/db/migrations/20260627_000002_catalog_model_state.d.ts.map +1 -0
  112. package/dist/db/migrations/20260627_000002_catalog_model_state.js +30 -0
  113. package/dist/db/migrations/20260627_000002_catalog_model_state.js.map +1 -0
  114. package/dist/db/migrations/20260628_120000_request_aggregates.d.ts +6 -0
  115. package/dist/db/migrations/20260628_120000_request_aggregates.d.ts.map +1 -0
  116. package/dist/db/migrations/20260628_120000_request_aggregates.js +104 -0
  117. package/dist/db/migrations/20260628_120000_request_aggregates.js.map +1 -0
  118. package/dist/db/migrations/20260630_000001_github_gpt41_context.d.ts +9 -0
  119. package/dist/db/migrations/20260630_000001_github_gpt41_context.d.ts.map +1 -0
  120. package/dist/db/migrations/20260630_000001_github_gpt41_context.js +22 -0
  121. package/dist/db/migrations/20260630_000001_github_gpt41_context.js.map +1 -0
  122. package/dist/db/migrations/20260706_000001_request_client_info.d.ts +4 -0
  123. package/dist/db/migrations/20260706_000001_request_client_info.d.ts.map +1 -0
  124. package/dist/db/migrations/20260706_000001_request_client_info.js +30 -0
  125. package/dist/db/migrations/20260706_000001_request_client_info.js.map +1 -0
  126. package/dist/db/migrations/20260706_000002_custom_model_tool_support.d.ts +17 -0
  127. package/dist/db/migrations/20260706_000002_custom_model_tool_support.d.ts.map +1 -0
  128. package/dist/db/migrations/20260706_000002_custom_model_tool_support.js +20 -0
  129. package/dist/db/migrations/20260706_000002_custom_model_tool_support.js.map +1 -0
  130. package/dist/db/migrations/20260714_000001_profile_chain_backfill.d.ts +12 -0
  131. package/dist/db/migrations/20260714_000001_profile_chain_backfill.d.ts.map +1 -0
  132. package/dist/db/migrations/20260714_000001_profile_chain_backfill.js +45 -0
  133. package/dist/db/migrations/20260714_000001_profile_chain_backfill.js.map +1 -0
  134. package/dist/db/migrations/20260720_000001_key_health_error.d.ts +5 -0
  135. package/dist/db/migrations/20260720_000001_key_health_error.d.ts.map +1 -0
  136. package/dist/db/migrations/20260720_000001_key_health_error.js +16 -0
  137. package/dist/db/migrations/20260720_000001_key_health_error.js.map +1 -0
  138. package/dist/db/migrations/20260726_000001_cooldown_probe_provenance.d.ts +4 -0
  139. package/dist/db/migrations/20260726_000001_cooldown_probe_provenance.d.ts.map +1 -0
  140. package/dist/db/migrations/20260726_000001_cooldown_probe_provenance.js +38 -0
  141. package/dist/db/migrations/20260726_000001_cooldown_probe_provenance.js.map +1 -0
  142. package/dist/db/migrations/20260726_000002_request_attempts.d.ts +4 -0
  143. package/dist/db/migrations/20260726_000002_request_attempts.d.ts.map +1 -0
  144. package/dist/db/migrations/20260726_000002_request_attempts.js +43 -0
  145. package/dist/db/migrations/20260726_000002_request_attempts.js.map +1 -0
  146. package/dist/db/migrations/20260726_000003_model_source_provenance.d.ts +4 -0
  147. package/dist/db/migrations/20260726_000003_model_source_provenance.d.ts.map +1 -0
  148. package/dist/db/migrations/20260726_000003_model_source_provenance.js +80 -0
  149. package/dist/db/migrations/20260726_000003_model_source_provenance.js.map +1 -0
  150. package/dist/db/migrations/20260726_000004_media_model_meta.d.ts +4 -0
  151. package/dist/db/migrations/20260726_000004_media_model_meta.d.ts.map +1 -0
  152. package/dist/db/migrations/20260726_000004_media_model_meta.js +34 -0
  153. package/dist/db/migrations/20260726_000004_media_model_meta.js.map +1 -0
  154. package/dist/db/migrations/20260726_000005_request_served_model.d.ts +4 -0
  155. package/dist/db/migrations/20260726_000005_request_served_model.d.ts.map +1 -0
  156. package/dist/db/migrations/20260726_000005_request_served_model.js +31 -0
  157. package/dist/db/migrations/20260726_000005_request_served_model.js.map +1 -0
  158. package/dist/db/migrations/20260726_000006_attempt_error_summary.d.ts +4 -0
  159. package/dist/db/migrations/20260726_000006_attempt_error_summary.d.ts.map +1 -0
  160. package/dist/db/migrations/20260726_000006_attempt_error_summary.js +29 -0
  161. package/dist/db/migrations/20260726_000006_attempt_error_summary.js.map +1 -0
  162. package/dist/db/migrations/20260727_000001_agent_compatibility.d.ts +4 -0
  163. package/dist/db/migrations/20260727_000001_agent_compatibility.d.ts.map +1 -0
  164. package/dist/db/migrations/20260727_000001_agent_compatibility.js +41 -0
  165. package/dist/db/migrations/20260727_000001_agent_compatibility.js.map +1 -0
  166. package/dist/db/migrations/20260728_000001_tombstone_provenance.d.ts +12 -0
  167. package/dist/db/migrations/20260728_000001_tombstone_provenance.d.ts.map +1 -0
  168. package/dist/db/migrations/20260728_000001_tombstone_provenance.js +37 -0
  169. package/dist/db/migrations/20260728_000001_tombstone_provenance.js.map +1 -0
  170. package/dist/db/migrations/20260729_000001_custom_model_endpoint_identity.d.ts +4 -0
  171. package/dist/db/migrations/20260729_000001_custom_model_endpoint_identity.d.ts.map +1 -0
  172. package/dist/db/migrations/20260729_000001_custom_model_endpoint_identity.js +145 -0
  173. package/dist/db/migrations/20260729_000001_custom_model_endpoint_identity.js.map +1 -0
  174. package/dist/db/migrations/20260802_000001_custom_endpoint_host_labels.d.ts +6 -0
  175. package/dist/db/migrations/20260802_000001_custom_endpoint_host_labels.d.ts.map +1 -0
  176. package/dist/db/migrations/20260802_000001_custom_endpoint_host_labels.js +52 -0
  177. package/dist/db/migrations/20260802_000001_custom_endpoint_host_labels.js.map +1 -0
  178. package/dist/db/migrations/20260805_000001_key_model_scope.d.ts +6 -0
  179. package/dist/db/migrations/20260805_000001_key_model_scope.d.ts.map +1 -0
  180. package/dist/db/migrations/20260805_000001_key_model_scope.js +17 -0
  181. package/dist/db/migrations/20260805_000001_key_model_scope.js.map +1 -0
  182. package/dist/db/migrations/20260805_000002_client_profiles.d.ts +4 -0
  183. package/dist/db/migrations/20260805_000002_client_profiles.d.ts.map +1 -0
  184. package/dist/db/migrations/20260805_000002_client_profiles.js +33 -0
  185. package/dist/db/migrations/20260805_000002_client_profiles.js.map +1 -0
  186. package/dist/db/migrations/20260810_000001_api_key_proxy.d.ts +4 -0
  187. package/dist/db/migrations/20260810_000001_api_key_proxy.d.ts.map +1 -0
  188. package/dist/db/migrations/20260810_000001_api_key_proxy.js +33 -0
  189. package/dist/db/migrations/20260810_000001_api_key_proxy.js.map +1 -0
  190. package/dist/db/migrations/20260819_000001_custom_model_tombstones.d.ts +4 -0
  191. package/dist/db/migrations/20260819_000001_custom_model_tombstones.d.ts.map +1 -0
  192. package/dist/db/migrations/20260819_000001_custom_model_tombstones.js +19 -0
  193. package/dist/db/migrations/20260819_000001_custom_model_tombstones.js.map +1 -0
  194. package/dist/db/migrations/20260820_000001_playground_conversations.d.ts +4 -0
  195. package/dist/db/migrations/20260820_000001_playground_conversations.d.ts.map +1 -0
  196. package/dist/db/migrations/20260820_000001_playground_conversations.js +47 -0
  197. package/dist/db/migrations/20260820_000001_playground_conversations.js.map +1 -0
  198. package/dist/db/migrations/20260823_000001_server_logs.d.ts +4 -0
  199. package/dist/db/migrations/20260823_000001_server_logs.d.ts.map +1 -0
  200. package/dist/db/migrations/20260823_000001_server_logs.js +53 -0
  201. package/dist/db/migrations/20260823_000001_server_logs.js.map +1 -0
  202. package/dist/db/migrations/20260823_000002_backups_table.d.ts +8 -0
  203. package/dist/db/migrations/20260823_000002_backups_table.d.ts.map +1 -0
  204. package/dist/db/migrations/20260823_000002_backups_table.js +22 -0
  205. package/dist/db/migrations/20260823_000002_backups_table.js.map +1 -0
  206. package/dist/db/migrations/20260823_000003_attempt_key_label.d.ts +19 -0
  207. package/dist/db/migrations/20260823_000003_attempt_key_label.d.ts.map +1 -0
  208. package/dist/db/migrations/20260823_000003_attempt_key_label.js +28 -0
  209. package/dist/db/migrations/20260823_000003_attempt_key_label.js.map +1 -0
  210. package/dist/db/migrations/20260823_000004_profile_auto_include.d.ts +14 -0
  211. package/dist/db/migrations/20260823_000004_profile_auto_include.d.ts.map +1 -0
  212. package/dist/db/migrations/20260823_000004_profile_auto_include.js +25 -0
  213. package/dist/db/migrations/20260823_000004_profile_auto_include.js.map +1 -0
  214. package/dist/db/migrations/20260901_000001_idempotency_claims.d.ts +4 -0
  215. package/dist/db/migrations/20260901_000001_idempotency_claims.d.ts.map +1 -0
  216. package/dist/db/migrations/20260901_000001_idempotency_claims.js +46 -0
  217. package/dist/db/migrations/20260901_000001_idempotency_claims.js.map +1 -0
  218. package/dist/db/migrations/20260901_000002_quota_observation_lookup.d.ts +4 -0
  219. package/dist/db/migrations/20260901_000002_quota_observation_lookup.d.ts.map +1 -0
  220. package/dist/db/migrations/20260901_000002_quota_observation_lookup.js +37 -0
  221. package/dist/db/migrations/20260901_000002_quota_observation_lookup.js.map +1 -0
  222. package/dist/db/migrations/20260901_000003_request_caller.d.ts +4 -0
  223. package/dist/db/migrations/20260901_000003_request_caller.d.ts.map +1 -0
  224. package/dist/db/migrations/20260901_000003_request_caller.js +27 -0
  225. package/dist/db/migrations/20260901_000003_request_caller.js.map +1 -0
  226. package/dist/db/migrations/20260902_000001_analytics_latency_percentile_index.d.ts +4 -0
  227. package/dist/db/migrations/20260902_000001_analytics_latency_percentile_index.d.ts.map +1 -0
  228. package/dist/db/migrations/20260902_000001_analytics_latency_percentile_index.js +35 -0
  229. package/dist/db/migrations/20260902_000001_analytics_latency_percentile_index.js.map +1 -0
  230. package/dist/db/migrations/20260903_000001_mcp_enabled_default.d.ts +4 -0
  231. package/dist/db/migrations/20260903_000001_mcp_enabled_default.d.ts.map +1 -0
  232. package/dist/db/migrations/20260903_000001_mcp_enabled_default.js +37 -0
  233. package/dist/db/migrations/20260903_000001_mcp_enabled_default.js.map +1 -0
  234. package/dist/db/migrations/20260903_000002_response_cache.d.ts +4 -0
  235. package/dist/db/migrations/20260903_000002_response_cache.d.ts.map +1 -0
  236. package/dist/db/migrations/20260903_000002_response_cache.js +53 -0
  237. package/dist/db/migrations/20260903_000002_response_cache.js.map +1 -0
  238. package/dist/db/migrations/20260904_000001_key_monthly_budget.d.ts +13 -0
  239. package/dist/db/migrations/20260904_000001_key_monthly_budget.d.ts.map +1 -0
  240. package/dist/db/migrations/20260904_000001_key_monthly_budget.js +35 -0
  241. package/dist/db/migrations/20260904_000001_key_monthly_budget.js.map +1 -0
  242. package/dist/db/migrations/20260913_000001_request_model_attribution.d.ts +4 -0
  243. package/dist/db/migrations/20260913_000001_request_model_attribution.d.ts.map +1 -0
  244. package/dist/db/migrations/20260913_000001_request_model_attribution.js +68 -0
  245. package/dist/db/migrations/20260913_000001_request_model_attribution.js.map +1 -0
  246. package/dist/db/migrations/20260914_000001_key_monthly_usage.d.ts +5 -0
  247. package/dist/db/migrations/20260914_000001_key_monthly_usage.d.ts.map +1 -0
  248. package/dist/db/migrations/20260914_000001_key_monthly_usage.js +37 -0
  249. package/dist/db/migrations/20260914_000001_key_monthly_usage.js.map +1 -0
  250. package/dist/db/migrations/20260915_000001_quota_snapshot_freshness.d.ts +4 -0
  251. package/dist/db/migrations/20260915_000001_quota_snapshot_freshness.d.ts.map +1 -0
  252. package/dist/db/migrations/20260915_000001_quota_snapshot_freshness.js +28 -0
  253. package/dist/db/migrations/20260915_000001_quota_snapshot_freshness.js.map +1 -0
  254. package/dist/db/migrations/20261004_000001_unified_key_sr_prefix.d.ts +4 -0
  255. package/dist/db/migrations/20261004_000001_unified_key_sr_prefix.d.ts.map +1 -0
  256. package/dist/db/migrations/20261004_000001_unified_key_sr_prefix.js +25 -0
  257. package/dist/db/migrations/20261004_000001_unified_key_sr_prefix.js.map +1 -0
  258. package/dist/db/migrations/20261005_000001_key_budget_period.d.ts +10 -0
  259. package/dist/db/migrations/20261005_000001_key_budget_period.d.ts.map +1 -0
  260. package/dist/db/migrations/20261005_000001_key_budget_period.js +78 -0
  261. package/dist/db/migrations/20261005_000001_key_budget_period.js.map +1 -0
  262. package/dist/db/migrations/20261005_000002_key_budget_period_auto.d.ts +21 -0
  263. package/dist/db/migrations/20261005_000002_key_budget_period_auto.d.ts.map +1 -0
  264. package/dist/db/migrations/20261005_000002_key_budget_period_auto.js +41 -0
  265. package/dist/db/migrations/20261005_000002_key_budget_period_auto.js.map +1 -0
  266. package/dist/db/model-pricing.d.ts +39 -0
  267. package/dist/db/model-pricing.d.ts.map +1 -0
  268. package/dist/db/model-pricing.js +274 -0
  269. package/dist/db/model-pricing.js.map +1 -0
  270. package/dist/db/node-sqlite.d.ts +9 -0
  271. package/dist/db/node-sqlite.d.ts.map +1 -0
  272. package/dist/db/node-sqlite.js +87 -0
  273. package/dist/db/node-sqlite.js.map +1 -0
  274. package/dist/db/types.d.ts +22 -0
  275. package/dist/db/types.d.ts.map +1 -0
  276. package/dist/db/types.js +2 -0
  277. package/dist/db/types.js.map +1 -0
  278. package/dist/docs/docs-page.d.ts +2 -0
  279. package/dist/docs/docs-page.d.ts.map +1 -0
  280. package/dist/docs/docs-page.js +319 -0
  281. package/dist/docs/docs-page.js.map +1 -0
  282. package/dist/docs/openapi.d.ts +1896 -0
  283. package/dist/docs/openapi.d.ts.map +1 -0
  284. package/dist/docs/openapi.js +1096 -0
  285. package/dist/docs/openapi.js.map +1 -0
  286. package/dist/env.d.ts +2 -0
  287. package/dist/env.d.ts.map +1 -0
  288. package/dist/env.js +9 -0
  289. package/dist/env.js.map +1 -0
  290. package/dist/index.d.ts +2 -0
  291. package/dist/index.d.ts.map +1 -0
  292. package/dist/index.js +144 -0
  293. package/dist/index.js.map +1 -0
  294. package/dist/lib/anthropic-documents.d.ts +41 -0
  295. package/dist/lib/anthropic-documents.d.ts.map +1 -0
  296. package/dist/lib/anthropic-documents.js +132 -0
  297. package/dist/lib/anthropic-documents.js.map +1 -0
  298. package/dist/lib/app-version.d.ts +5 -0
  299. package/dist/lib/app-version.d.ts.map +1 -0
  300. package/dist/lib/app-version.js +61 -0
  301. package/dist/lib/app-version.js.map +1 -0
  302. package/dist/lib/attempt-trace.d.ts +23 -0
  303. package/dist/lib/attempt-trace.d.ts.map +1 -0
  304. package/dist/lib/attempt-trace.js +32 -0
  305. package/dist/lib/attempt-trace.js.map +1 -0
  306. package/dist/lib/budget.d.ts +6 -0
  307. package/dist/lib/budget.d.ts.map +1 -0
  308. package/dist/lib/budget.js +40 -0
  309. package/dist/lib/budget.js.map +1 -0
  310. package/dist/lib/client-classifier.d.ts +10 -0
  311. package/dist/lib/client-classifier.d.ts.map +1 -0
  312. package/dist/lib/client-classifier.js +126 -0
  313. package/dist/lib/client-classifier.js.map +1 -0
  314. package/dist/lib/client-context.d.ts +10 -0
  315. package/dist/lib/client-context.d.ts.map +1 -0
  316. package/dist/lib/client-context.js +39 -0
  317. package/dist/lib/client-context.js.map +1 -0
  318. package/dist/lib/config.d.ts +33 -0
  319. package/dist/lib/config.d.ts.map +1 -0
  320. package/dist/lib/config.js +94 -0
  321. package/dist/lib/config.js.map +1 -0
  322. package/dist/lib/content.d.ts +33 -0
  323. package/dist/lib/content.d.ts.map +1 -0
  324. package/dist/lib/content.js +201 -0
  325. package/dist/lib/content.js.map +1 -0
  326. package/dist/lib/credential.d.ts +11 -0
  327. package/dist/lib/credential.d.ts.map +1 -0
  328. package/dist/lib/credential.js +18 -0
  329. package/dist/lib/credential.js.map +1 -0
  330. package/dist/lib/crypto.d.ts +31 -0
  331. package/dist/lib/crypto.d.ts.map +1 -0
  332. package/dist/lib/crypto.js +206 -0
  333. package/dist/lib/crypto.js.map +1 -0
  334. package/dist/lib/custom-provider-cleanup.d.ts +13 -0
  335. package/dist/lib/custom-provider-cleanup.d.ts.map +1 -0
  336. package/dist/lib/custom-provider-cleanup.js +43 -0
  337. package/dist/lib/custom-provider-cleanup.js.map +1 -0
  338. package/dist/lib/db-backup.d.ts +31 -0
  339. package/dist/lib/db-backup.d.ts.map +1 -0
  340. package/dist/lib/db-backup.js +255 -0
  341. package/dist/lib/db-backup.js.map +1 -0
  342. package/dist/lib/endpoint-scope.d.ts +42 -0
  343. package/dist/lib/endpoint-scope.d.ts.map +1 -0
  344. package/dist/lib/endpoint-scope.js +95 -0
  345. package/dist/lib/endpoint-scope.js.map +1 -0
  346. package/dist/lib/env-drift.d.ts +17 -0
  347. package/dist/lib/env-drift.d.ts.map +1 -0
  348. package/dist/lib/env-drift.js +108 -0
  349. package/dist/lib/env-drift.js.map +1 -0
  350. package/dist/lib/error-classify.d.ts +40 -0
  351. package/dist/lib/error-classify.d.ts.map +1 -0
  352. package/dist/lib/error-classify.js +687 -0
  353. package/dist/lib/error-classify.js.map +1 -0
  354. package/dist/lib/error-redaction.d.ts +8 -0
  355. package/dist/lib/error-redaction.d.ts.map +1 -0
  356. package/dist/lib/error-redaction.js +45 -0
  357. package/dist/lib/error-redaction.js.map +1 -0
  358. package/dist/lib/fallback-loop.d.ts +306 -0
  359. package/dist/lib/fallback-loop.d.ts.map +1 -0
  360. package/dist/lib/fallback-loop.js +1336 -0
  361. package/dist/lib/fallback-loop.js.map +1 -0
  362. package/dist/lib/file-permissions.d.ts +98 -0
  363. package/dist/lib/file-permissions.d.ts.map +1 -0
  364. package/dist/lib/file-permissions.js +159 -0
  365. package/dist/lib/file-permissions.js.map +1 -0
  366. package/dist/lib/gemini-wire.d.ts +76 -0
  367. package/dist/lib/gemini-wire.d.ts.map +1 -0
  368. package/dist/lib/gemini-wire.js +392 -0
  369. package/dist/lib/gemini-wire.js.map +1 -0
  370. package/dist/lib/guardrails.d.ts +37 -0
  371. package/dist/lib/guardrails.d.ts.map +1 -0
  372. package/dist/lib/guardrails.js +106 -0
  373. package/dist/lib/guardrails.js.map +1 -0
  374. package/dist/lib/header-value.d.ts +8 -0
  375. package/dist/lib/header-value.d.ts.map +1 -0
  376. package/dist/lib/header-value.js +55 -0
  377. package/dist/lib/header-value.js.map +1 -0
  378. package/dist/lib/image-normalize.d.ts +21 -0
  379. package/dist/lib/image-normalize.d.ts.map +1 -0
  380. package/dist/lib/image-normalize.js +218 -0
  381. package/dist/lib/image-normalize.js.map +1 -0
  382. package/dist/lib/inbound-chat.d.ts +48 -0
  383. package/dist/lib/inbound-chat.d.ts.map +1 -0
  384. package/dist/lib/inbound-chat.js +406 -0
  385. package/dist/lib/inbound-chat.js.map +1 -0
  386. package/dist/lib/key-parser.d.ts +79 -0
  387. package/dist/lib/key-parser.d.ts.map +1 -0
  388. package/dist/lib/key-parser.js +701 -0
  389. package/dist/lib/key-parser.js.map +1 -0
  390. package/dist/lib/key-proxy.d.ts +49 -0
  391. package/dist/lib/key-proxy.d.ts.map +1 -0
  392. package/dist/lib/key-proxy.js +92 -0
  393. package/dist/lib/key-proxy.js.map +1 -0
  394. package/dist/lib/log-redaction.d.ts +28 -0
  395. package/dist/lib/log-redaction.d.ts.map +1 -0
  396. package/dist/lib/log-redaction.js +166 -0
  397. package/dist/lib/log-redaction.js.map +1 -0
  398. package/dist/lib/model-scope.d.ts +9 -0
  399. package/dist/lib/model-scope.d.ts.map +1 -0
  400. package/dist/lib/model-scope.js +29 -0
  401. package/dist/lib/model-scope.js.map +1 -0
  402. package/dist/lib/one-time-code.d.ts +15 -0
  403. package/dist/lib/one-time-code.d.ts.map +1 -0
  404. package/dist/lib/one-time-code.js +41 -0
  405. package/dist/lib/one-time-code.js.map +1 -0
  406. package/dist/lib/output-cap.d.ts +24 -0
  407. package/dist/lib/output-cap.d.ts.map +1 -0
  408. package/dist/lib/output-cap.js +80 -0
  409. package/dist/lib/output-cap.js.map +1 -0
  410. package/dist/lib/password.d.ts +3 -0
  411. package/dist/lib/password.d.ts.map +1 -0
  412. package/dist/lib/password.js +27 -0
  413. package/dist/lib/password.js.map +1 -0
  414. package/dist/lib/process-safety-net.d.ts +32 -0
  415. package/dist/lib/process-safety-net.d.ts.map +1 -0
  416. package/dist/lib/process-safety-net.js +123 -0
  417. package/dist/lib/process-safety-net.js.map +1 -0
  418. package/dist/lib/provider-identity.d.ts +37 -0
  419. package/dist/lib/provider-identity.d.ts.map +1 -0
  420. package/dist/lib/provider-identity.js +110 -0
  421. package/dist/lib/provider-identity.js.map +1 -0
  422. package/dist/lib/provider-size-parser.d.ts +6 -0
  423. package/dist/lib/provider-size-parser.d.ts.map +1 -0
  424. package/dist/lib/provider-size-parser.js +72 -0
  425. package/dist/lib/provider-size-parser.js.map +1 -0
  426. package/dist/lib/provider-timeout.d.ts +17 -0
  427. package/dist/lib/provider-timeout.d.ts.map +1 -0
  428. package/dist/lib/provider-timeout.js +70 -0
  429. package/dist/lib/provider-timeout.js.map +1 -0
  430. package/dist/lib/proxy.d.ts +180 -0
  431. package/dist/lib/proxy.d.ts.map +1 -0
  432. package/dist/lib/proxy.js +1002 -0
  433. package/dist/lib/proxy.js.map +1 -0
  434. package/dist/lib/request-log.d.ts +4 -0
  435. package/dist/lib/request-log.d.ts.map +1 -0
  436. package/dist/lib/request-log.js +161 -0
  437. package/dist/lib/request-log.js.map +1 -0
  438. package/dist/lib/reset-code.d.ts +5 -0
  439. package/dist/lib/reset-code.d.ts.map +1 -0
  440. package/dist/lib/reset-code.js +39 -0
  441. package/dist/lib/reset-code.js.map +1 -0
  442. package/dist/lib/retry-hint.d.ts +14 -0
  443. package/dist/lib/retry-hint.d.ts.map +1 -0
  444. package/dist/lib/retry-hint.js +36 -0
  445. package/dist/lib/retry-hint.js.map +1 -0
  446. package/dist/lib/route-live.d.ts +29 -0
  447. package/dist/lib/route-live.d.ts.map +1 -0
  448. package/dist/lib/route-live.js +97 -0
  449. package/dist/lib/route-live.js.map +1 -0
  450. package/dist/lib/sampling-params.d.ts +183 -0
  451. package/dist/lib/sampling-params.d.ts.map +1 -0
  452. package/dist/lib/sampling-params.js +386 -0
  453. package/dist/lib/sampling-params.js.map +1 -0
  454. package/dist/lib/scheduler.d.ts +13 -0
  455. package/dist/lib/scheduler.d.ts.map +1 -0
  456. package/dist/lib/scheduler.js +11 -0
  457. package/dist/lib/scheduler.js.map +1 -0
  458. package/dist/lib/served-model.d.ts +16 -0
  459. package/dist/lib/served-model.d.ts.map +1 -0
  460. package/dist/lib/served-model.js +0 -0
  461. package/dist/lib/served-model.js.map +1 -0
  462. package/dist/lib/server-logs.d.ts +132 -0
  463. package/dist/lib/server-logs.d.ts.map +1 -0
  464. package/dist/lib/server-logs.js +473 -0
  465. package/dist/lib/server-logs.js.map +1 -0
  466. package/dist/lib/setup-code.d.ts +5 -0
  467. package/dist/lib/setup-code.d.ts.map +1 -0
  468. package/dist/lib/setup-code.js +35 -0
  469. package/dist/lib/setup-code.js.map +1 -0
  470. package/dist/lib/structured-output.d.ts +9 -0
  471. package/dist/lib/structured-output.d.ts.map +1 -0
  472. package/dist/lib/structured-output.js +72 -0
  473. package/dist/lib/structured-output.js.map +1 -0
  474. package/dist/lib/system-prompt.d.ts +30 -0
  475. package/dist/lib/system-prompt.d.ts.map +1 -0
  476. package/dist/lib/system-prompt.js +66 -0
  477. package/dist/lib/system-prompt.js.map +1 -0
  478. package/dist/lib/task-type.d.ts +18 -0
  479. package/dist/lib/task-type.d.ts.map +1 -0
  480. package/dist/lib/task-type.js +92 -0
  481. package/dist/lib/task-type.js.map +1 -0
  482. package/dist/lib/think-tags.d.ts +37 -0
  483. package/dist/lib/think-tags.d.ts.map +1 -0
  484. package/dist/lib/think-tags.js +203 -0
  485. package/dist/lib/think-tags.js.map +1 -0
  486. package/dist/lib/tool-args.d.ts +36 -0
  487. package/dist/lib/tool-args.d.ts.map +1 -0
  488. package/dist/lib/tool-args.js +190 -0
  489. package/dist/lib/tool-args.js.map +1 -0
  490. package/dist/lib/tool-call-rescue.d.ts +62 -0
  491. package/dist/lib/tool-call-rescue.d.ts.map +1 -0
  492. package/dist/lib/tool-call-rescue.js +258 -0
  493. package/dist/lib/tool-call-rescue.js.map +1 -0
  494. package/dist/lib/tool-capability.d.ts +13 -0
  495. package/dist/lib/tool-capability.d.ts.map +1 -0
  496. package/dist/lib/tool-capability.js +70 -0
  497. package/dist/lib/tool-capability.js.map +1 -0
  498. package/dist/lib/tool-validate.d.ts +44 -0
  499. package/dist/lib/tool-validate.d.ts.map +1 -0
  500. package/dist/lib/tool-validate.js +165 -0
  501. package/dist/lib/tool-validate.js.map +1 -0
  502. package/dist/lib/ttfb-budget.d.ts +13 -0
  503. package/dist/lib/ttfb-budget.d.ts.map +1 -0
  504. package/dist/lib/ttfb-budget.js +153 -0
  505. package/dist/lib/ttfb-budget.js.map +1 -0
  506. package/dist/lib/url-guard.d.ts +47 -0
  507. package/dist/lib/url-guard.d.ts.map +1 -0
  508. package/dist/lib/url-guard.js +229 -0
  509. package/dist/lib/url-guard.js.map +1 -0
  510. package/dist/lib/wake-detect.d.ts +12 -0
  511. package/dist/lib/wake-detect.d.ts.map +1 -0
  512. package/dist/lib/wake-detect.js +99 -0
  513. package/dist/lib/wake-detect.js.map +1 -0
  514. package/dist/middleware/errorHandler.d.ts +3 -0
  515. package/dist/middleware/errorHandler.d.ts.map +1 -0
  516. package/dist/middleware/errorHandler.js +45 -0
  517. package/dist/middleware/errorHandler.js.map +1 -0
  518. package/dist/middleware/rateLimit.d.ts +4 -0
  519. package/dist/middleware/rateLimit.d.ts.map +1 -0
  520. package/dist/middleware/rateLimit.js +125 -0
  521. package/dist/middleware/rateLimit.js.map +1 -0
  522. package/dist/middleware/requireAuth.d.ts +3 -0
  523. package/dist/middleware/requireAuth.d.ts.map +1 -0
  524. package/dist/middleware/requireAuth.js +17 -0
  525. package/dist/middleware/requireAuth.js.map +1 -0
  526. package/dist/providers/aclide.d.ts +18 -0
  527. package/dist/providers/aclide.d.ts.map +1 -0
  528. package/dist/providers/aclide.js +174 -0
  529. package/dist/providers/aclide.js.map +1 -0
  530. package/dist/providers/aihorde.d.ts +42 -0
  531. package/dist/providers/aihorde.d.ts.map +1 -0
  532. package/dist/providers/aihorde.js +192 -0
  533. package/dist/providers/aihorde.js.map +1 -0
  534. package/dist/providers/airforce.d.ts +11 -0
  535. package/dist/providers/airforce.d.ts.map +1 -0
  536. package/dist/providers/airforce.js +32 -0
  537. package/dist/providers/airforce.js.map +1 -0
  538. package/dist/providers/base.d.ts +177 -0
  539. package/dist/providers/base.d.ts.map +1 -0
  540. package/dist/providers/base.js +354 -0
  541. package/dist/providers/base.js.map +1 -0
  542. package/dist/providers/blaze.d.ts +11 -0
  543. package/dist/providers/blaze.d.ts.map +1 -0
  544. package/dist/providers/blaze.js +33 -0
  545. package/dist/providers/blaze.js.map +1 -0
  546. package/dist/providers/blockrun.d.ts +14 -0
  547. package/dist/providers/blockrun.d.ts.map +1 -0
  548. package/dist/providers/blockrun.js +36 -0
  549. package/dist/providers/blockrun.js.map +1 -0
  550. package/dist/providers/clod.d.ts +11 -0
  551. package/dist/providers/clod.d.ts.map +1 -0
  552. package/dist/providers/clod.js +39 -0
  553. package/dist/providers/clod.js.map +1 -0
  554. package/dist/providers/cloudflare.d.ts +15 -0
  555. package/dist/providers/cloudflare.d.ts.map +1 -0
  556. package/dist/providers/cloudflare.js +175 -0
  557. package/dist/providers/cloudflare.js.map +1 -0
  558. package/dist/providers/cohere.d.ts +11 -0
  559. package/dist/providers/cohere.d.ts.map +1 -0
  560. package/dist/providers/cohere.js +117 -0
  561. package/dist/providers/cohere.js.map +1 -0
  562. package/dist/providers/dreamprompting.d.ts +11 -0
  563. package/dist/providers/dreamprompting.d.ts.map +1 -0
  564. package/dist/providers/dreamprompting.js +41 -0
  565. package/dist/providers/dreamprompting.js.map +1 -0
  566. package/dist/providers/electronhub.d.ts +10 -0
  567. package/dist/providers/electronhub.d.ts.map +1 -0
  568. package/dist/providers/electronhub.js +56 -0
  569. package/dist/providers/electronhub.js.map +1 -0
  570. package/dist/providers/experiential.d.ts +10 -0
  571. package/dist/providers/experiential.d.ts.map +1 -0
  572. package/dist/providers/experiential.js +33 -0
  573. package/dist/providers/experiential.js.map +1 -0
  574. package/dist/providers/gizmo.d.ts +15 -0
  575. package/dist/providers/gizmo.d.ts.map +1 -0
  576. package/dist/providers/gizmo.js +54 -0
  577. package/dist/providers/gizmo.js.map +1 -0
  578. package/dist/providers/google.d.ts +30 -0
  579. package/dist/providers/google.d.ts.map +1 -0
  580. package/dist/providers/google.js +766 -0
  581. package/dist/providers/google.js.map +1 -0
  582. package/dist/providers/index.d.ts +13 -0
  583. package/dist/providers/index.d.ts.map +1 -0
  584. package/dist/providers/index.js +561 -0
  585. package/dist/providers/index.js.map +1 -0
  586. package/dist/providers/llmtr.d.ts +15 -0
  587. package/dist/providers/llmtr.d.ts.map +1 -0
  588. package/dist/providers/llmtr.js +51 -0
  589. package/dist/providers/llmtr.js.map +1 -0
  590. package/dist/providers/logfare.d.ts +11 -0
  591. package/dist/providers/logfare.d.ts.map +1 -0
  592. package/dist/providers/logfare.js +33 -0
  593. package/dist/providers/logfare.js.map +1 -0
  594. package/dist/providers/lucidity.d.ts +11 -0
  595. package/dist/providers/lucidity.d.ts.map +1 -0
  596. package/dist/providers/lucidity.js +37 -0
  597. package/dist/providers/lucidity.js.map +1 -0
  598. package/dist/providers/modelscope.d.ts +50 -0
  599. package/dist/providers/modelscope.d.ts.map +1 -0
  600. package/dist/providers/modelscope.js +143 -0
  601. package/dist/providers/modelscope.js.map +1 -0
  602. package/dist/providers/moondream.d.ts +17 -0
  603. package/dist/providers/moondream.d.ts.map +1 -0
  604. package/dist/providers/moondream.js +140 -0
  605. package/dist/providers/moondream.js.map +1 -0
  606. package/dist/providers/openai-compat.d.ts +140 -0
  607. package/dist/providers/openai-compat.d.ts.map +1 -0
  608. package/dist/providers/openai-compat.js +537 -0
  609. package/dist/providers/openai-compat.js.map +1 -0
  610. package/dist/providers/opencode-free.d.ts +24 -0
  611. package/dist/providers/opencode-free.d.ts.map +1 -0
  612. package/dist/providers/opencode-free.js +262 -0
  613. package/dist/providers/opencode-free.js.map +1 -0
  614. package/dist/providers/pollinations.d.ts +32 -0
  615. package/dist/providers/pollinations.d.ts.map +1 -0
  616. package/dist/providers/pollinations.js +65 -0
  617. package/dist/providers/pollinations.js.map +1 -0
  618. package/dist/providers/router9.d.ts +16 -0
  619. package/dist/providers/router9.d.ts.map +1 -0
  620. package/dist/providers/router9.js +42 -0
  621. package/dist/providers/router9.js.map +1 -0
  622. package/dist/providers/sail.d.ts +44 -0
  623. package/dist/providers/sail.d.ts.map +1 -0
  624. package/dist/providers/sail.js +302 -0
  625. package/dist/providers/sail.js.map +1 -0
  626. package/dist/providers/septor.d.ts +10 -0
  627. package/dist/providers/septor.d.ts.map +1 -0
  628. package/dist/providers/septor.js +36 -0
  629. package/dist/providers/septor.js.map +1 -0
  630. package/dist/providers/speechify.d.ts +14 -0
  631. package/dist/providers/speechify.d.ts.map +1 -0
  632. package/dist/providers/speechify.js +28 -0
  633. package/dist/providers/speechify.js.map +1 -0
  634. package/dist/providers/speka.d.ts +12 -0
  635. package/dist/providers/speka.d.ts.map +1 -0
  636. package/dist/providers/speka.js +37 -0
  637. package/dist/providers/speka.js.map +1 -0
  638. package/dist/providers/waterfall.d.ts +11 -0
  639. package/dist/providers/waterfall.d.ts.map +1 -0
  640. package/dist/providers/waterfall.js +33 -0
  641. package/dist/providers/waterfall.js.map +1 -0
  642. package/dist/providers/xkiro.d.ts +71 -0
  643. package/dist/providers/xkiro.d.ts.map +1 -0
  644. package/dist/providers/xkiro.js +119 -0
  645. package/dist/providers/xkiro.js.map +1 -0
  646. package/dist/providers/zhipu.d.ts +43 -0
  647. package/dist/providers/zhipu.d.ts.map +1 -0
  648. package/dist/providers/zhipu.js +95 -0
  649. package/dist/providers/zhipu.js.map +1 -0
  650. package/dist/routes/analytics.d.ts +2 -0
  651. package/dist/routes/analytics.d.ts.map +1 -0
  652. package/dist/routes/analytics.js +738 -0
  653. package/dist/routes/analytics.js.map +1 -0
  654. package/dist/routes/anthropic.d.ts +7 -0
  655. package/dist/routes/anthropic.d.ts.map +1 -0
  656. package/dist/routes/anthropic.js +1076 -0
  657. package/dist/routes/anthropic.js.map +1 -0
  658. package/dist/routes/auth.d.ts +2 -0
  659. package/dist/routes/auth.d.ts.map +1 -0
  660. package/dist/routes/auth.js +310 -0
  661. package/dist/routes/auth.js.map +1 -0
  662. package/dist/routes/backups.d.ts +2 -0
  663. package/dist/routes/backups.d.ts.map +1 -0
  664. package/dist/routes/backups.js +127 -0
  665. package/dist/routes/backups.js.map +1 -0
  666. package/dist/routes/cache.d.ts +2 -0
  667. package/dist/routes/cache.d.ts.map +1 -0
  668. package/dist/routes/cache.js +40 -0
  669. package/dist/routes/cache.js.map +1 -0
  670. package/dist/routes/client-profiles.d.ts +2 -0
  671. package/dist/routes/client-profiles.d.ts.map +1 -0
  672. package/dist/routes/client-profiles.js +128 -0
  673. package/dist/routes/client-profiles.js.map +1 -0
  674. package/dist/routes/compression.d.ts +2 -0
  675. package/dist/routes/compression.d.ts.map +1 -0
  676. package/dist/routes/compression.js +82 -0
  677. package/dist/routes/compression.js.map +1 -0
  678. package/dist/routes/conversations.d.ts +3 -0
  679. package/dist/routes/conversations.d.ts.map +1 -0
  680. package/dist/routes/conversations.js +215 -0
  681. package/dist/routes/conversations.js.map +1 -0
  682. package/dist/routes/docs.d.ts +2 -0
  683. package/dist/routes/docs.d.ts.map +1 -0
  684. package/dist/routes/docs.js +21 -0
  685. package/dist/routes/docs.js.map +1 -0
  686. package/dist/routes/embeddings.d.ts +2 -0
  687. package/dist/routes/embeddings.d.ts.map +1 -0
  688. package/dist/routes/embeddings.js +255 -0
  689. package/dist/routes/embeddings.js.map +1 -0
  690. package/dist/routes/fallback.d.ts +2 -0
  691. package/dist/routes/fallback.d.ts.map +1 -0
  692. package/dist/routes/fallback.js +631 -0
  693. package/dist/routes/fallback.js.map +1 -0
  694. package/dist/routes/free-tier.d.ts +22 -0
  695. package/dist/routes/free-tier.d.ts.map +1 -0
  696. package/dist/routes/free-tier.js +175 -0
  697. package/dist/routes/free-tier.js.map +1 -0
  698. package/dist/routes/gemini.d.ts +2 -0
  699. package/dist/routes/gemini.d.ts.map +1 -0
  700. package/dist/routes/gemini.js +218 -0
  701. package/dist/routes/gemini.js.map +1 -0
  702. package/dist/routes/health.d.ts +2 -0
  703. package/dist/routes/health.d.ts.map +1 -0
  704. package/dist/routes/health.js +72 -0
  705. package/dist/routes/health.js.map +1 -0
  706. package/dist/routes/keys.d.ts +17 -0
  707. package/dist/routes/keys.d.ts.map +1 -0
  708. package/dist/routes/keys.js +1787 -0
  709. package/dist/routes/keys.js.map +1 -0
  710. package/dist/routes/logs.d.ts +2 -0
  711. package/dist/routes/logs.d.ts.map +1 -0
  712. package/dist/routes/logs.js +88 -0
  713. package/dist/routes/logs.js.map +1 -0
  714. package/dist/routes/mcp.d.ts +4 -0
  715. package/dist/routes/mcp.d.ts.map +1 -0
  716. package/dist/routes/mcp.js +563 -0
  717. package/dist/routes/mcp.js.map +1 -0
  718. package/dist/routes/media.d.ts +2 -0
  719. package/dist/routes/media.d.ts.map +1 -0
  720. package/dist/routes/media.js +180 -0
  721. package/dist/routes/media.js.map +1 -0
  722. package/dist/routes/models.d.ts +2 -0
  723. package/dist/routes/models.d.ts.map +1 -0
  724. package/dist/routes/models.js +439 -0
  725. package/dist/routes/models.js.map +1 -0
  726. package/dist/routes/ollama.d.ts +7 -0
  727. package/dist/routes/ollama.d.ts.map +1 -0
  728. package/dist/routes/ollama.js +595 -0
  729. package/dist/routes/ollama.js.map +1 -0
  730. package/dist/routes/profiles.d.ts +3 -0
  731. package/dist/routes/profiles.d.ts.map +1 -0
  732. package/dist/routes/profiles.js +431 -0
  733. package/dist/routes/profiles.js.map +1 -0
  734. package/dist/routes/proxy.d.ts +32 -0
  735. package/dist/routes/proxy.d.ts.map +1 -0
  736. package/dist/routes/proxy.js +2793 -0
  737. package/dist/routes/proxy.js.map +1 -0
  738. package/dist/routes/responses.d.ts +1161 -0
  739. package/dist/routes/responses.d.ts.map +1 -0
  740. package/dist/routes/responses.js +1521 -0
  741. package/dist/routes/responses.js.map +1 -0
  742. package/dist/routes/settings.d.ts +2 -0
  743. package/dist/routes/settings.d.ts.map +1 -0
  744. package/dist/routes/settings.js +549 -0
  745. package/dist/routes/settings.js.map +1 -0
  746. package/dist/routes/status.d.ts +3 -0
  747. package/dist/routes/status.d.ts.map +1 -0
  748. package/dist/routes/status.js +214 -0
  749. package/dist/routes/status.js.map +1 -0
  750. package/dist/routes/update.d.ts +31 -0
  751. package/dist/routes/update.d.ts.map +1 -0
  752. package/dist/routes/update.js +536 -0
  753. package/dist/routes/update.js.map +1 -0
  754. package/dist/routes/url-tokens.d.ts +2 -0
  755. package/dist/routes/url-tokens.d.ts.map +1 -0
  756. package/dist/routes/url-tokens.js +31 -0
  757. package/dist/routes/url-tokens.js.map +1 -0
  758. package/dist/scripts/export-catalog.d.ts +2 -0
  759. package/dist/scripts/export-catalog.d.ts.map +1 -0
  760. package/dist/scripts/export-catalog.js +114 -0
  761. package/dist/scripts/export-catalog.js.map +1 -0
  762. package/dist/scripts/rotate-encryption-key.d.ts +81 -0
  763. package/dist/scripts/rotate-encryption-key.d.ts.map +1 -0
  764. package/dist/scripts/rotate-encryption-key.js +232 -0
  765. package/dist/scripts/rotate-encryption-key.js.map +1 -0
  766. package/dist/scripts/routing-sim.d.ts +2 -0
  767. package/dist/scripts/routing-sim.d.ts.map +1 -0
  768. package/dist/scripts/routing-sim.js +130 -0
  769. package/dist/scripts/routing-sim.js.map +1 -0
  770. package/dist/scripts/test-all-models.d.ts +2 -0
  771. package/dist/scripts/test-all-models.d.ts.map +1 -0
  772. package/dist/scripts/test-all-models.js +56 -0
  773. package/dist/scripts/test-all-models.js.map +1 -0
  774. package/dist/services/anthropic-map.d.ts +39 -0
  775. package/dist/services/anthropic-map.d.ts.map +1 -0
  776. package/dist/services/anthropic-map.js +138 -0
  777. package/dist/services/anthropic-map.js.map +1 -0
  778. package/dist/services/auth.d.ts +30 -0
  779. package/dist/services/auth.d.ts.map +1 -0
  780. package/dist/services/auth.js +124 -0
  781. package/dist/services/auth.js.map +1 -0
  782. package/dist/services/auto-discover.d.ts +77 -0
  783. package/dist/services/auto-discover.d.ts.map +1 -0
  784. package/dist/services/auto-discover.js +1047 -0
  785. package/dist/services/auto-discover.js.map +1 -0
  786. package/dist/services/backups.d.ts +67 -0
  787. package/dist/services/backups.d.ts.map +1 -0
  788. package/dist/services/backups.js +444 -0
  789. package/dist/services/backups.js.map +1 -0
  790. package/dist/services/builtin-model-discovery.d.ts +107 -0
  791. package/dist/services/builtin-model-discovery.d.ts.map +1 -0
  792. package/dist/services/builtin-model-discovery.js +296 -0
  793. package/dist/services/builtin-model-discovery.js.map +1 -0
  794. package/dist/services/cache.d.ts +190 -0
  795. package/dist/services/cache.d.ts.map +1 -0
  796. package/dist/services/cache.js +617 -0
  797. package/dist/services/cache.js.map +1 -0
  798. package/dist/services/catalog-sync.d.ts +257 -0
  799. package/dist/services/catalog-sync.d.ts.map +1 -0
  800. package/dist/services/catalog-sync.js +1041 -0
  801. package/dist/services/catalog-sync.js.map +1 -0
  802. package/dist/services/compression/config.d.ts +33 -0
  803. package/dist/services/compression/config.d.ts.map +1 -0
  804. package/dist/services/compression/config.js +158 -0
  805. package/dist/services/compression/config.js.map +1 -0
  806. package/dist/services/compression/engines/aging.d.ts +2 -0
  807. package/dist/services/compression/engines/aging.d.ts.map +1 -0
  808. package/dist/services/compression/engines/aging.js +53 -0
  809. package/dist/services/compression/engines/aging.js.map +1 -0
  810. package/dist/services/compression/engines/custom-filters.d.ts +4 -0
  811. package/dist/services/compression/engines/custom-filters.d.ts.map +1 -0
  812. package/dist/services/compression/engines/custom-filters.js +49 -0
  813. package/dist/services/compression/engines/custom-filters.js.map +1 -0
  814. package/dist/services/compression/engines/dedup.d.ts +2 -0
  815. package/dist/services/compression/engines/dedup.d.ts.map +1 -0
  816. package/dist/services/compression/engines/dedup.js +61 -0
  817. package/dist/services/compression/engines/dedup.js.map +1 -0
  818. package/dist/services/compression/engines/filter-definitions.d.ts +75 -0
  819. package/dist/services/compression/engines/filter-definitions.d.ts.map +1 -0
  820. package/dist/services/compression/engines/filter-definitions.js +45 -0
  821. package/dist/services/compression/engines/filter-definitions.js.map +1 -0
  822. package/dist/services/compression/engines/hard-budget.d.ts +2 -0
  823. package/dist/services/compression/engines/hard-budget.d.ts.map +1 -0
  824. package/dist/services/compression/engines/hard-budget.js +52 -0
  825. package/dist/services/compression/engines/hard-budget.js.map +1 -0
  826. package/dist/services/compression/engines/index.d.ts +9 -0
  827. package/dist/services/compression/engines/index.d.ts.map +1 -0
  828. package/dist/services/compression/engines/index.js +9 -0
  829. package/dist/services/compression/engines/index.js.map +1 -0
  830. package/dist/services/compression/engines/jsoncompact.d.ts +3 -0
  831. package/dist/services/compression/engines/jsoncompact.d.ts.map +1 -0
  832. package/dist/services/compression/engines/jsoncompact.js +145 -0
  833. package/dist/services/compression/engines/jsoncompact.js.map +1 -0
  834. package/dist/services/compression/engines/lite.d.ts +2 -0
  835. package/dist/services/compression/engines/lite.d.ts.map +1 -0
  836. package/dist/services/compression/engines/lite.js +34 -0
  837. package/dist/services/compression/engines/lite.js.map +1 -0
  838. package/dist/services/compression/engines/read-lifecycle.d.ts +2 -0
  839. package/dist/services/compression/engines/read-lifecycle.d.ts.map +1 -0
  840. package/dist/services/compression/engines/read-lifecycle.js +70 -0
  841. package/dist/services/compression/engines/read-lifecycle.js.map +1 -0
  842. package/dist/services/compression/engines/relevance.d.ts +2 -0
  843. package/dist/services/compression/engines/relevance.d.ts.map +1 -0
  844. package/dist/services/compression/engines/relevance.js +74 -0
  845. package/dist/services/compression/engines/relevance.js.map +1 -0
  846. package/dist/services/compression/engines/toolfilter.d.ts +2 -0
  847. package/dist/services/compression/engines/toolfilter.d.ts.map +1 -0
  848. package/dist/services/compression/engines/toolfilter.js +195 -0
  849. package/dist/services/compression/engines/toolfilter.js.map +1 -0
  850. package/dist/services/compression/fidelity-gate.d.ts +12 -0
  851. package/dist/services/compression/fidelity-gate.d.ts.map +1 -0
  852. package/dist/services/compression/fidelity-gate.js +90 -0
  853. package/dist/services/compression/fidelity-gate.js.map +1 -0
  854. package/dist/services/compression/helpers.d.ts +9 -0
  855. package/dist/services/compression/helpers.d.ts.map +1 -0
  856. package/dist/services/compression/helpers.js +52 -0
  857. package/dist/services/compression/helpers.js.map +1 -0
  858. package/dist/services/compression/pipeline.d.ts +7 -0
  859. package/dist/services/compression/pipeline.d.ts.map +1 -0
  860. package/dist/services/compression/pipeline.js +245 -0
  861. package/dist/services/compression/pipeline.js.map +1 -0
  862. package/dist/services/compression/preservation.d.ts +27 -0
  863. package/dist/services/compression/preservation.d.ts.map +1 -0
  864. package/dist/services/compression/preservation.js +109 -0
  865. package/dist/services/compression/preservation.js.map +1 -0
  866. package/dist/services/compression/registry.d.ts +6 -0
  867. package/dist/services/compression/registry.d.ts.map +1 -0
  868. package/dist/services/compression/registry.js +16 -0
  869. package/dist/services/compression/registry.js.map +1 -0
  870. package/dist/services/compression/stats.d.ts +29 -0
  871. package/dist/services/compression/stats.d.ts.map +1 -0
  872. package/dist/services/compression/stats.js +55 -0
  873. package/dist/services/compression/stats.js.map +1 -0
  874. package/dist/services/compression/types.d.ts +90 -0
  875. package/dist/services/compression/types.d.ts.map +1 -0
  876. package/dist/services/compression/types.js +2 -0
  877. package/dist/services/compression/types.js.map +1 -0
  878. package/dist/services/context-handoff.d.ts +22 -0
  879. package/dist/services/context-handoff.d.ts.map +1 -0
  880. package/dist/services/context-handoff.js +164 -0
  881. package/dist/services/context-handoff.js.map +1 -0
  882. package/dist/services/cooldown-probe.d.ts +24 -0
  883. package/dist/services/cooldown-probe.d.ts.map +1 -0
  884. package/dist/services/cooldown-probe.js +181 -0
  885. package/dist/services/cooldown-probe.js.map +1 -0
  886. package/dist/services/custom-endpoint.d.ts +58 -0
  887. package/dist/services/custom-endpoint.d.ts.map +1 -0
  888. package/dist/services/custom-endpoint.js +167 -0
  889. package/dist/services/custom-endpoint.js.map +1 -0
  890. package/dist/services/custom-media-register.d.ts +22 -0
  891. package/dist/services/custom-media-register.d.ts.map +1 -0
  892. package/dist/services/custom-media-register.js +45 -0
  893. package/dist/services/custom-media-register.js.map +1 -0
  894. package/dist/services/custom-model-register.d.ts +50 -0
  895. package/dist/services/custom-model-register.d.ts.map +1 -0
  896. package/dist/services/custom-model-register.js +103 -0
  897. package/dist/services/custom-model-register.js.map +1 -0
  898. package/dist/services/custom-model-seed.d.ts +18 -0
  899. package/dist/services/custom-model-seed.d.ts.map +1 -0
  900. package/dist/services/custom-model-seed.js +42 -0
  901. package/dist/services/custom-model-seed.js.map +1 -0
  902. package/dist/services/custom-model-sync.d.ts +37 -0
  903. package/dist/services/custom-model-sync.d.ts.map +1 -0
  904. package/dist/services/custom-model-sync.js +118 -0
  905. package/dist/services/custom-model-sync.js.map +1 -0
  906. package/dist/services/custom-model-tombstone.d.ts +5 -0
  907. package/dist/services/custom-model-tombstone.d.ts.map +1 -0
  908. package/dist/services/custom-model-tombstone.js +30 -0
  909. package/dist/services/custom-model-tombstone.js.map +1 -0
  910. package/dist/services/declarative-config.d.ts +356 -0
  911. package/dist/services/declarative-config.d.ts.map +1 -0
  912. package/dist/services/declarative-config.js +427 -0
  913. package/dist/services/declarative-config.js.map +1 -0
  914. package/dist/services/degradation.d.ts +40 -0
  915. package/dist/services/degradation.d.ts.map +1 -0
  916. package/dist/services/degradation.js +119 -0
  917. package/dist/services/degradation.js.map +1 -0
  918. package/dist/services/embeddings.d.ts +76 -0
  919. package/dist/services/embeddings.d.ts.map +1 -0
  920. package/dist/services/embeddings.js +319 -0
  921. package/dist/services/embeddings.js.map +1 -0
  922. package/dist/services/fusion.d.ts +162 -0
  923. package/dist/services/fusion.d.ts.map +1 -0
  924. package/dist/services/fusion.js +789 -0
  925. package/dist/services/fusion.js.map +1 -0
  926. package/dist/services/gemini-map.d.ts +14 -0
  927. package/dist/services/gemini-map.d.ts.map +1 -0
  928. package/dist/services/gemini-map.js +78 -0
  929. package/dist/services/gemini-map.js.map +1 -0
  930. package/dist/services/health.d.ts +52 -0
  931. package/dist/services/health.d.ts.map +1 -0
  932. package/dist/services/health.js +352 -0
  933. package/dist/services/health.js.map +1 -0
  934. package/dist/services/idempotency.d.ts +49 -0
  935. package/dist/services/idempotency.d.ts.map +1 -0
  936. package/dist/services/idempotency.js +140 -0
  937. package/dist/services/idempotency.js.map +1 -0
  938. package/dist/services/key-budget.d.ts +74 -0
  939. package/dist/services/key-budget.d.ts.map +1 -0
  940. package/dist/services/key-budget.js +200 -0
  941. package/dist/services/key-budget.js.map +1 -0
  942. package/dist/services/media.d.ts +123 -0
  943. package/dist/services/media.d.ts.map +1 -0
  944. package/dist/services/media.js +954 -0
  945. package/dist/services/media.js.map +1 -0
  946. package/dist/services/model-discovery.d.ts +126 -0
  947. package/dist/services/model-discovery.d.ts.map +1 -0
  948. package/dist/services/model-discovery.js +662 -0
  949. package/dist/services/model-discovery.js.map +1 -0
  950. package/dist/services/model-groups.d.ts +149 -0
  951. package/dist/services/model-groups.d.ts.map +1 -0
  952. package/dist/services/model-groups.js +314 -0
  953. package/dist/services/model-groups.js.map +1 -0
  954. package/dist/services/model-listing.d.ts +18 -0
  955. package/dist/services/model-listing.d.ts.map +1 -0
  956. package/dist/services/model-listing.js +94 -0
  957. package/dist/services/model-listing.js.map +1 -0
  958. package/dist/services/model-retirement.d.ts +29 -0
  959. package/dist/services/model-retirement.d.ts.map +1 -0
  960. package/dist/services/model-retirement.js +86 -0
  961. package/dist/services/model-retirement.js.map +1 -0
  962. package/dist/services/model-state.d.ts +90 -0
  963. package/dist/services/model-state.d.ts.map +1 -0
  964. package/dist/services/model-state.js +342 -0
  965. package/dist/services/model-state.js.map +1 -0
  966. package/dist/services/model-weight-overrides.d.ts +48 -0
  967. package/dist/services/model-weight-overrides.d.ts.map +1 -0
  968. package/dist/services/model-weight-overrides.js +127 -0
  969. package/dist/services/model-weight-overrides.js.map +1 -0
  970. package/dist/services/notification-emitter.d.ts +50 -0
  971. package/dist/services/notification-emitter.d.ts.map +1 -0
  972. package/dist/services/notification-emitter.js +177 -0
  973. package/dist/services/notification-emitter.js.map +1 -0
  974. package/dist/services/opencode-free-sync.d.ts +29 -0
  975. package/dist/services/opencode-free-sync.d.ts.map +1 -0
  976. package/dist/services/opencode-free-sync.js +206 -0
  977. package/dist/services/opencode-free-sync.js.map +1 -0
  978. package/dist/services/penalty-inspector.d.ts +56 -0
  979. package/dist/services/penalty-inspector.d.ts.map +1 -0
  980. package/dist/services/penalty-inspector.js +167 -0
  981. package/dist/services/penalty-inspector.js.map +1 -0
  982. package/dist/services/profile-models.d.ts +5 -0
  983. package/dist/services/profile-models.d.ts.map +1 -0
  984. package/dist/services/profile-models.js +62 -0
  985. package/dist/services/profile-models.js.map +1 -0
  986. package/dist/services/provider-credential.d.ts +19 -0
  987. package/dist/services/provider-credential.d.ts.map +1 -0
  988. package/dist/services/provider-credential.js +51 -0
  989. package/dist/services/provider-credential.js.map +1 -0
  990. package/dist/services/provider-quota.d.ts +64 -0
  991. package/dist/services/provider-quota.d.ts.map +1 -0
  992. package/dist/services/provider-quota.js +563 -0
  993. package/dist/services/provider-quota.js.map +1 -0
  994. package/dist/services/quirks.d.ts +0 -0
  995. package/dist/services/quirks.d.ts.map +1 -0
  996. package/dist/services/quirks.js +0 -0
  997. package/dist/services/quirks.js.map +1 -0
  998. package/dist/services/quota-forecast.d.ts +50 -0
  999. package/dist/services/quota-forecast.d.ts.map +1 -0
  1000. package/dist/services/quota-forecast.js +150 -0
  1001. package/dist/services/quota-forecast.js.map +1 -0
  1002. package/dist/services/quota-outlook.d.ts +4 -0
  1003. package/dist/services/quota-outlook.d.ts.map +1 -0
  1004. package/dist/services/quota-outlook.js +92 -0
  1005. package/dist/services/quota-outlook.js.map +1 -0
  1006. package/dist/services/ratelimit.d.ts +249 -0
  1007. package/dist/services/ratelimit.d.ts.map +1 -0
  1008. package/dist/services/ratelimit.js +1182 -0
  1009. package/dist/services/ratelimit.js.map +1 -0
  1010. package/dist/services/request-retention.d.ts +60 -0
  1011. package/dist/services/request-retention.d.ts.map +1 -0
  1012. package/dist/services/request-retention.js +229 -0
  1013. package/dist/services/request-retention.js.map +1 -0
  1014. package/dist/services/router.d.ts +384 -0
  1015. package/dist/services/router.d.ts.map +1 -0
  1016. package/dist/services/router.js +1986 -0
  1017. package/dist/services/router.js.map +1 -0
  1018. package/dist/services/scoring.d.ts +156 -0
  1019. package/dist/services/scoring.d.ts.map +1 -0
  1020. package/dist/services/scoring.js +435 -0
  1021. package/dist/services/scoring.js.map +1 -0
  1022. package/dist/services/url-tokens.d.ts +15 -0
  1023. package/dist/services/url-tokens.d.ts.map +1 -0
  1024. package/dist/services/url-tokens.js +55 -0
  1025. package/dist/services/url-tokens.js.map +1 -0
  1026. package/package.json +77 -4
  1027. package/README.md +0 -3
@@ -0,0 +1,687 @@
1
+ // Upstream-error classification shared by the proxy chat path, the responses
2
+ // path, and the fusion panel. Pure functions over an error's message/status —
3
+ // no I/O — so they live in a neutral lib module that any of those can import
4
+ // without forming an import cycle (fusion ↔ proxy in particular).
5
+ export function isRetryableError(err) {
6
+ const msg = (err.message ?? '').toLowerCase();
7
+ // Trust the upstream HTTP status the provider attached to the error first
8
+ // (providerHttpError in providers/base.ts sets err.status on every adapter).
9
+ // This structured check is the robust primary signal; the message-substring
10
+ // rules below are the fallback for errors that carry a code in their text but
11
+ // no numeric status. It's the fix for #337/#339: an Ollama "410 Gone", or any
12
+ // upstream 5xx the substring allowlist never enumerated (502/504/507…), used to
13
+ // fall through to a 502 and STRAND the healthy paid routes still queued later in
14
+ // the chain — because the old code matched specific substrings and ignored
15
+ // err.status for every code except 403. 408 (request timeout), 409 (conflict),
16
+ // 410 (model pulled upstream), 429 (rate limit) and all 5xx are transient or
17
+ // fail-over-able; 400/401 stay fatal (status 0 here, handled by the absence of a
18
+ // matching rule) and 403 is handled by isModelAccessForbiddenError below.
19
+ // 422 (notably Mistral's strict validation) is a provider-side request-shape
20
+ // rejection: fail over to another provider, but if the whole chain rejects it
21
+ // exhaustedRetryError renders a client-facing 400 via isProviderBadRequestError.
22
+ const status = typeof err?.status === 'number' ? err.status : 0;
23
+ if (status === 408 || status === 409 || status === 410 || status === 422 || status === 429 || status >= 500)
24
+ return true;
25
+ return msg.includes('429') || msg.includes('rate limit') || msg.includes('too many requests')
26
+ || msg.includes('quota') || msg.includes('resource_exhausted')
27
+ || msg.includes('aborted') || msg.includes('timeout') || msg.includes('etimedout')
28
+ || msg.includes('econnrefused') || msg.includes('econnreset')
29
+ || msg.includes('fetch failed') // undici transport error (proxy down, DNS, TLS, etc.)
30
+ || msg.includes('503') || msg.includes('unavailable')
31
+ // Provider marks the hosted deployment itself as sick (NVIDIA NIM's
32
+ // "DEGRADED function cannot be invoked" arrives as a 400, #522). The
33
+ // 'api error 400' rule below already catches the NIM shape; this keeps
34
+ // degraded conditions retryable even when a provider words it differently.
35
+ || msg.includes('degraded')
36
+ || msg.includes('500') || msg.includes('internal server error')
37
+ // 413: this model's payload limit is too small for the request, but another
38
+ // provider in the fallback chain may have a larger limit. Same reasoning as 503.
39
+ || msg.includes('413') || msg.includes('payload too large') || msg.includes('request body too large')
40
+ || msg.includes('request entity too large') || msg.includes('content too large')
41
+ // Context/prompt-too-large in all its provider wordings (Anthropic "prompt
42
+ // is too long", Google "input token count ... exceeds", OpenAI "maximum
43
+ // context length", …): another candidate may have a larger window, so fail
44
+ // over; if EVERY candidate rejects it the exhaustion ladder renders an
45
+ // honest 413 instead of a generic failure.
46
+ || isContextTooLargeError(err)
47
+ // 404: model deprecated/removed upstream (e.g. OpenRouter's "no endpoints found"
48
+ // for a model that's been pulled). Rotate to the next model in the chain —
49
+ // setCooldown + the health checker will avoid this model on subsequent requests.
50
+ || msg.includes('404') || msg.includes('not found') || msg.includes('no endpoints found')
51
+ // 410: the model/endpoint was permanently removed upstream (e.g. Ollama Cloud
52
+ // "API error 410: Gone", #339). Like a 404 it won't return on this provider, so
53
+ // rotate to the next route; isModelNotFoundError benches the whole model. The
54
+ // structured status check above already catches the 410 when the provider
55
+ // attaches err.status — this is the text fallback for errors that don't.
56
+ || msg.includes('410') || msg.includes('gone')
57
+ // 403: the key is valid (it passed validateKey, and the health checker
58
+ // disables truly-forbidden keys) but this specific model is off-limits to
59
+ // the key's tier — e.g. gpt-4o on GitHub Models' free tier, subscription-only
60
+ // models on Cloudflare. Another model in the chain is reachable, so fail over
61
+ // instead of 502-ing the whole request. Paired with isModelAccessForbiddenError
62
+ // to rule the model out for this request and a day-long bench. See issue #256.
63
+ || isModelAccessForbiddenError(err)
64
+ // 400: one provider may reject parameters another accepts (e.g. max_tokens
65
+ // limits, unsupported params). The matching pattern is "api error 400"
66
+ // which comes from the OpenAI-compat provider's error formatting, not
67
+ // a bare "400" which is deliberately non-retryable for validation errors.
68
+ || msg.includes('api error 400')
69
+ // 422: Mistral and other strict OpenAI-compatible endpoints use
70
+ // Unprocessable Entity for request-shape validation. Rotate to a provider
71
+ // that accepts the same OpenAI payload; if every provider rejects it, render
72
+ // a clean invalid_request_error instead of a rate-limit exhaustion.
73
+ || msg.includes('api error 422') || msg.includes('unprocessable entity')
74
+ // 402: this provider/key is out of credits (e.g. HuggingFace Router
75
+ // "API error 402: Payment required"). The SAME model often lives on another
76
+ // provider (Kimi K2.6 is on HF + Cloudflare + NVIDIA), so fail over instead
77
+ // of killing the workflow. Paired with a long cooldown (isPaymentRequiredError)
78
+ // so we don't re-hammer the broke key every retry.
79
+ || isPaymentRequiredError(err)
80
+ // Dead-turn classes from the stream turn-integrity layer (#231 audit):
81
+ // all thrown before any byte reached the client, so another model can
82
+ // serve the request invisibly.
83
+ || msg.includes('empty completion')
84
+ // The model answered in prose despite a response_format request (and the
85
+ // JSON couldn't be healed out of the text) — thrown before any byte
86
+ // reached the client, so the next candidate can serve it invisibly.
87
+ || msg.includes('ignored response_format')
88
+ // The model DID emit JSON but ran out of max_tokens mid-value
89
+ // (finish_reason 'length'). A terser model may fit the same schema in the
90
+ // same budget, so fail over — but the thrower marks the model skipped for
91
+ // this request: retrying the same model would truncate identically.
92
+ || msg.includes('truncated json')
93
+ || msg.includes('in-band provider error')
94
+ || msg.includes('stream ended unexpectedly')
95
+ || msg.includes('stream stalled')
96
+ // First-byte timeout (#584): the grace budget expired before ANY byte
97
+ // reached the client, so the next candidate can serve it invisibly.
98
+ || msg.includes('no first byte')
99
+ || msg.includes('unparseable inline tool-call dialect')
100
+ // The model emitted a tool call whose arguments violate the schema the
101
+ // caller declared (opt-in check, lib/tool-validate.ts). Thrown before any
102
+ // byte reached the client, and a different model usually gets the same
103
+ // call right — the thrower marks the model skipped for this request, since
104
+ // a sibling key would misbehave identically.
105
+ || msg.includes('invalid tool arguments')
106
+ // A transport failure undici buried in `err.cause` rather than the
107
+ // top-level message (see isTransportError). Purely additive: every rule
108
+ // above is unchanged, and this is a second, structured signal for the
109
+ // errors whose real cause never reaches the text we match on.
110
+ || isTransportError(err);
111
+ }
112
+ // ── Transport failures hidden in the cause chain (undici) ────────────────────
113
+ // Every rule in isRetryableError above reads the TOP-LEVEL message, and undici
114
+ // does not always put the real failure there. The INITIAL-CONNECT case is
115
+ // covered by luck: undici words a connection that never opened "fetch failed",
116
+ // and the allowlist matches that string. A socket that dies MID-request does
117
+ // not get the same treatment — it surfaces as a generic wrapper (a bare
118
+ // `TypeError: terminated`, or an adapter's own re-throw) whose `.cause` carries
119
+ // the actual ECONNRESET / EPIPE / "socket hang up" / "premature close" /
120
+ // "other side closed" error, sometimes nested a link or two deeper still.
121
+ // Those fell through every rule and classified FATAL: the client got a 502
122
+ // while the healthy paid routes queued behind the dead one were never tried.
123
+ //
124
+ // Everything matched here is a transient network fault that says nothing about
125
+ // the request or the model, so the next candidate in the chain can serve it.
126
+ // The walk is bounded and cycle-safe: `cause` is attacker-adjacent data (it can
127
+ // come from a provider's own error object) and a self-referential chain on this
128
+ // hot path would hang the request, not just slow it.
129
+ const TRANSPORT_CAUSE_MAX_DEPTH = 5;
130
+ const TRANSPORT_ERROR_CODES = new Set([
131
+ // Node socket-level codes. A dead/refused/unreachable host is transient from
132
+ // the chain's point of view either way: the next candidate is a DIFFERENT
133
+ // host, so even a permanently bad one here is worth failing over rather than
134
+ // 502-ing the caller.
135
+ 'ECONNRESET', 'ECONNREFUSED', 'ECONNABORTED', 'EPIPE', 'ETIMEDOUT',
136
+ 'EAI_AGAIN', 'ENOTFOUND', 'EHOSTUNREACH', 'ENETUNREACH', 'EADDRNOTAVAIL',
137
+ ]);
138
+ // undici stamps its own transport failures with a `UND_ERR_*` code
139
+ // (UND_ERR_SOCKET, UND_ERR_CONNECT_TIMEOUT, UND_ERR_HEADERS_TIMEOUT,
140
+ // UND_ERR_BODY_TIMEOUT, …). Matched by PREFIX rather than enumerated: the list
141
+ // grows with undici releases, and every member of it is a transport condition.
142
+ const UNDICI_ERROR_CODE_PREFIX = 'UND_ERR_';
143
+ const TRANSPORT_MESSAGE_HINTS = [
144
+ 'socket hang up',
145
+ 'premature close',
146
+ 'other side closed',
147
+ // A socket dropped before the TLS handshake finished — undici's full wording
148
+ // is "Client network socket disconnected before secure TLS connection was
149
+ // established". The peer closed the TCP connection mid-handshake; transient.
150
+ 'client network socket disconnected',
151
+ // The same codes as above, for the links that carry them in text only (an
152
+ // error stringified across a boundary keeps the code in its message but
153
+ // loses the `code` property).
154
+ 'econnreset', 'econnrefused', 'epipe', 'etimedout', 'eai_again',
155
+ ];
156
+ /** Walk an error's `cause` chain, yielding each link's `code` and `message`.
157
+ * Includes the error itself as the first link. Bounded to
158
+ * TRANSPORT_CAUSE_MAX_DEPTH hops and cycle-safe. */
159
+ function errorChainLinks(err) {
160
+ const links = [];
161
+ const seen = new Set();
162
+ let cur = err;
163
+ for (let depth = 0; cur != null && depth <= TRANSPORT_CAUSE_MAX_DEPTH; depth++) {
164
+ if (typeof cur !== 'object' && typeof cur !== 'function')
165
+ break;
166
+ if (seen.has(cur))
167
+ break;
168
+ seen.add(cur);
169
+ links.push({
170
+ code: typeof cur.code === 'string' ? cur.code : '',
171
+ message: typeof cur.message === 'string' ? cur.message : '',
172
+ });
173
+ cur = cur.cause;
174
+ }
175
+ return links;
176
+ }
177
+ /** True when the error — or anything in its bounded cause chain — is a
178
+ * transient network transport failure: a reset, dropped, refused or timed-out
179
+ * socket, a failed TLS handshake, or an undici transport code. */
180
+ export function isTransportError(err) {
181
+ if (err == null)
182
+ return false;
183
+ // A client hang-up and the fallback time-budget hedge BOTH reach undici as an
184
+ // aborted socket, and undici labels that abort UND_ERR_ABORTED — the very
185
+ // same code a genuine mid-flight socket death carries. Neither is provider
186
+ // health, so classifying either retryable would resurrect exactly what the
187
+ // two marked abort errors exist to prevent (no cooldown, no health penalty,
188
+ // no failure stats for a request the GATEWAY canceled). The structured
189
+ // markers are authoritative and win over any transport evidence below.
190
+ if (isClientAbortError(err) || isHedgeAbortError(err))
191
+ return false;
192
+ for (const { code, message } of errorChainLinks(err)) {
193
+ if (code && (TRANSPORT_ERROR_CODES.has(code) || code.startsWith(UNDICI_ERROR_CODE_PREFIX)))
194
+ return true;
195
+ const msg = message.toLowerCase();
196
+ if (!msg)
197
+ continue;
198
+ if (TRANSPORT_MESSAGE_HINTS.some(hint => msg.includes(hint)))
199
+ return true;
200
+ // undici's wording for a response body whose socket died mid-read is the
201
+ // bare word "terminated". Matched as the WHOLE message and never as a
202
+ // substring: "your account has been terminated" is a fatal billing/auth
203
+ // condition, and retrying that around the entire chain would burn every
204
+ // candidate on a request that can never succeed.
205
+ if (msg.trim() === 'terminated')
206
+ return true;
207
+ }
208
+ return false;
209
+ }
210
+ // A genuine provider QUOTA signal: a structured 429 or rate-limit/quota wording.
211
+ // Distinct from the much broader isRetryableError: timeouts, 5xx, transport
212
+ // failures and dead-turn classes are retryable but say nothing about quotas.
213
+ // The null-limits exhaustion heuristic in getCooldownDecisionForLimit (services/
214
+ // ratelimit.ts) keys off this: only an actual quota signal may feed its
215
+ // "effectively daily-exhausted" escalation ladder. Before this split, a slow
216
+ // local Ollama route timing out twice classified retryable → recorded as a
217
+ // null-limit "429" → escalated 2m→10m→1h→24h and 429'd every request while the
218
+ // server was merely busy generating (#592).
219
+ // Mirrors the other classifiers: trust the structured status when the adapter
220
+ // attached one (providerHttpError sets err.status everywhere); fall back to
221
+ // message markers only when there is no status.
222
+ export function isRateLimitSignal(err) {
223
+ const status = typeof err?.status === 'number' ? err.status : 0;
224
+ if (status !== 0)
225
+ return status === 429;
226
+ const msg = (err?.message ?? '').toLowerCase();
227
+ return msg.includes('429') || msg.includes('rate limit') || msg.includes('too many requests')
228
+ || msg.includes('quota') || msg.includes('resource_exhausted');
229
+ }
230
+ // ── Timeout wording ─────────────────────────────────────────────────────────
231
+ // The message markers that mean "this attempt ran out of time", in every
232
+ // wording the stack produces: the per-attempt HTTP deadline ("The operation was
233
+ // aborted (groq, chat, 120s)" — enrichAbort in lib/proxy.ts), the mid-stream
234
+ // inactivity watchdog ("… stream stalled: no data for 90000ms (timeout)"), the
235
+ // first-byte grace budget, and a raw socket ETIMEDOUT.
236
+ //
237
+ // A client hang-up is deliberately NOT in here: newClientAbortError's message
238
+ // ("client disconnected — upstream request canceled") carries none of these
239
+ // markers precisely so a vanished client is never read as provider slowness.
240
+ //
241
+ // Single source of truth for two consumers: the attempt-trail classifier
242
+ // (classifyAttemptError) and the analytics query that folds timeouts into the
243
+ // speed score (refreshStatsCache, #619) — so the trail and the score always
244
+ // agree about what a timeout is.
245
+ export const TIMEOUT_ERROR_MARKERS = ['timeout', 'stalled', 'etimedout', 'aborted'];
246
+ /** True when an error message reads as a timeout. Expects raw text; caller need
247
+ * not lowercase it. */
248
+ export function isTimeoutErrorText(message) {
249
+ const msg = (typeof message === 'string' ? message : String(message ?? '')).toLowerCase();
250
+ return TIMEOUT_ERROR_MARKERS.some(marker => msg.includes(marker));
251
+ }
252
+ // ── Client-caused aborts ─────────────────────────────────────────────────────
253
+ // When the gateway's OWN client hangs up, the proxy surfaces abort the composed
254
+ // fetch signal with this marked error, and undici rejects the in-flight fetch /
255
+ // body read / stream read with the same object (fetch propagates the signal's
256
+ // abort reason). It is deliberately NOT an AbortError and its message contains
257
+ // neither "aborted" nor "timeout": enrichAbort (lib/proxy.ts) must pass it
258
+ // through untouched, and it must never classify as a retryable provider
259
+ // timeout — a vanished client says nothing about provider health, so the
260
+ // fallback loop stops without a cooldown, health penalty, or failure stats.
261
+ export function newClientAbortError() {
262
+ const err = new Error('client disconnected — upstream request canceled');
263
+ err.clientAbort = true;
264
+ return err;
265
+ }
266
+ /** True when an error is (or wraps) the client-disconnect abort above. The
267
+ * structured marker is the primary signal; `cause` is checked because some
268
+ * transports re-wrap the abort reason, and the message substring is the last
269
+ * resort for errors that were stringified across a boundary. */
270
+ export function isClientAbortError(err) {
271
+ if (err?.clientAbort === true)
272
+ return true;
273
+ if (err?.cause && err.cause.clientAbort === true)
274
+ return true;
275
+ const msg = (err?.message ?? '').toLowerCase();
276
+ return msg.includes('client disconnected');
277
+ }
278
+ // ── Fallback time-budget hedging (fallback-v2) ──────────────────────────────
279
+ // When the wall-clock retry budget expires MID-FLIGHT (the current attempt is
280
+ // still waiting on a stalled upstream), the fallback loop aborts the composed
281
+ // fetch signal with this marked error. Same rationale as the client abort: it
282
+ // is NOT a provider-health signal, so it must never bench/cooldown/penalize
283
+ // the model+key, and enrichAbort must pass it through untouched. The loop
284
+ // catches it, renders timedOut exhaustion (the budget is spent — nothing left
285
+ // to try), and stops without failure bookkeeping.
286
+ export function newHedgeAbortError() {
287
+ const err = new Error('fallback time budget expired — upstream request canceled');
288
+ err.hedgeAbort = true;
289
+ return err;
290
+ }
291
+ /** True when an error is (or wraps) the time-budget hedge abort above. */
292
+ export function isHedgeAbortError(err) {
293
+ if (err?.hedgeAbort === true)
294
+ return true;
295
+ if (err?.cause && err.cause.hedgeAbort === true)
296
+ return true;
297
+ const msg = (err?.message ?? '').toLowerCase();
298
+ return msg.includes('fallback time budget expired');
299
+ }
300
+ /** True for any fetch-abort rejection surfacing out of a body read — the
301
+ * per-attempt timeout ('request'-bounds deadline in fetchWithTimeout), an
302
+ * AbortSignal.timeout, or the client disconnect above. Adapters that wrap
303
+ * res.json() in a diagnostic catch (openai-compat's non-JSON-body split) must
304
+ * rethrow these instead of classifying them as a malformed provider body. */
305
+ export function isAbortLikeError(err) {
306
+ if (isClientAbortError(err))
307
+ return true;
308
+ const name = err?.name;
309
+ return name === 'AbortError' || name === 'TimeoutError' || /\baborted\b/i.test(err?.message ?? '');
310
+ }
311
+ // A 401 / invalid-API-key error from a provider. KEY-fatal, not request-fatal:
312
+ // the same request is fine on the provider's sibling key or on another provider,
313
+ // so the fallback loop rotates past the bad key (and triggers an immediate
314
+ // health revalidation) instead of 502-ing the whole request. Deliberately NOT
315
+ // added to isRetryableError: a bad key must be skipped and revalidated, not
316
+ // blindly re-benched like a rate limit — the loop handles it as its own class.
317
+ //
318
+ // Status handling: every provider adapter attaches err.status (providerHttpError
319
+ // in providers/base.ts), so the structured status is the primary signal.
320
+ // - 401 → always key-auth.
321
+ // - 400 → key-auth ONLY for Google-style key-specific phrasings: Google
322
+ // reports a bad/expired key as HTTP 400 INVALID_ARGUMENT with "API key not
323
+ // valid" / "API key expired" / API_KEY_INVALID (#268, providers/google.ts).
324
+ // Without this a dead Google key classified as a provider bad-request and
325
+ // could exhaust into a client-blaming 400 "rejected the request as invalid".
326
+ // Generic auth wording (unauthorized etc.) stays excluded on a 400 so
327
+ // ordinary payload rejections never classify as key-auth.
328
+ // - any other status → not key-auth (e.g. a 403 stays model-forbidden).
329
+ // - no status at all → key-specific OR generic auth substrings.
330
+ export function isKeyAuthError(err) {
331
+ const status = typeof err?.status === 'number' ? err.status : 0;
332
+ if (status === 401)
333
+ return true;
334
+ const msg = (err?.message ?? '').toLowerCase();
335
+ const keySpecific = msg.includes('api key not valid')
336
+ || msg.includes('api key expired')
337
+ || msg.includes('api_key_invalid');
338
+ if (status === 400)
339
+ return keySpecific;
340
+ if (status !== 0)
341
+ return false;
342
+ return keySpecific
343
+ || msg.includes('401')
344
+ || msg.includes('unauthorized')
345
+ || msg.includes('invalid api key')
346
+ || msg.includes('invalid_api_key')
347
+ || msg.includes('incorrect api key')
348
+ || msg.includes('authentication failed');
349
+ }
350
+ // A 429 whose body says the provider's DAILY free allocation is spent (observed
351
+ // live: Cloudflare "you have used up your daily free allocation of 10,000
352
+ // neurons"; OpenRouter "free-models-per-day"). A transient 90s cooldown just
353
+ // makes the router re-pick a dead-for-the-day provider all day, so the caller
354
+ // benches until the next UTC midnight instead. Requires BOTH a daily marker and
355
+ // a quota/allocation marker so an ordinary per-minute 429 never matches.
356
+ //
357
+ // Groq ends every limit error, per-minute and request-too-large alike, with
358
+ // "Need more tokens? Upgrade to Dev Tier today at …". That "today" is sales
359
+ // copy, not a window, so it is cut before looking for a daily marker; and a
360
+ // request too big for the model is never a spent allowance.
361
+ const UPGRADE_UPSELL = /\bupgrade to [^.?!]*?\btoday\b/g;
362
+ export function isDailyQuotaExhaustedError(err) {
363
+ if (err?.dailyQuotaExhausted === true)
364
+ return true;
365
+ if (isContextTooLargeError(err))
366
+ return false;
367
+ const msg = (err?.message ?? '').toLowerCase().replace(UPGRADE_UPSELL, '');
368
+ if (!/daily|per[ -_]?day|\btoday\b/.test(msg))
369
+ return false;
370
+ return /allocation|quota|limit|exhaust|used up/.test(msg);
371
+ }
372
+ // A provider-side "this hosted model is temporarily degraded" condition dressed
373
+ // up as a 400. Observed live on NVIDIA NIM (issue #522): a degraded function
374
+ // returns `400 {"detail":"Function id '...': DEGRADED function cannot be
375
+ // invoked"}` — the request is fine; the deployment is sick. Must NOT classify
376
+ // as a provider bad-request: exhausting on it would render a client-blaming
377
+ // 400 invalid_request_error for what is capacity/health, not request shape.
378
+ export function isProviderDegradedError(err) {
379
+ const msg = (err?.message ?? '').toLowerCase();
380
+ return msg.includes('degraded');
381
+ }
382
+ // #788: provider-level failures — 5xx, timeouts, transport/network errors, a
383
+ // degraded deployment — are symptoms of the PROVIDER being sick, not of this
384
+ // particular key. Retrying the same provider with a sibling key would fail
385
+ // identically, so the fallback loop must skip the WHOLE platform for the
386
+ // request instead of burning one failover hop per key. Key-scoped failures
387
+ // (auth, quota, 403 tier) stay out of here so a dead key can still rotate to
388
+ // a healthy sibling on the same platform.
389
+ //
390
+ // Classified on the STRUCTURED status — every adapter attaches one to an HTTP
391
+ // failure (providerHttpError in providers/base.ts) — plus the two families that
392
+ // carry no status at all: a timeout and a transport-level failure. Deliberately
393
+ // NO bare '500' / '503' / 'unavailable' / 'internal server error' substrings: a
394
+ // token count, a duration ("… took 5003ms") or a key-scoped message naming an
395
+ // unavailable model would each condemn a healthy platform for the whole request.
396
+ // A message check therefore only runs when there is no status to trust.
397
+ export function isProviderLevelError(err) {
398
+ // A failure the thrower explicitly scoped to the MODEL (`skipModelForRequest`
399
+ // — an ignored response_format, invalid tool arguments) is never provider
400
+ // health, and its message quotes caller- and model-supplied text: a tool
401
+ // named `set_timeout`, or an Ajv complaint about an instance path `/timeout`,
402
+ // would otherwise trip the substring checks below and condemn a healthy
403
+ // platform for the whole request. The structured marker is authoritative;
404
+ // the text is not.
405
+ if (err?.skipModelForRequest === true)
406
+ return false;
407
+ const status = typeof err?.status === 'number' ? err.status : 0;
408
+ if (status >= 500)
409
+ return true;
410
+ // A DEGRADED hosted deployment (NVIDIA NIM, #522) is provider health wearing
411
+ // a 400 — same source of truth as everywhere else, not a second substring.
412
+ if (isProviderDegradedError(err))
413
+ return true;
414
+ if (status !== 0)
415
+ return false;
416
+ const msg = (err?.message ?? '').toLowerCase();
417
+ return isTimeoutErrorText(msg)
418
+ || msg.includes('econnrefused') || msg.includes('econnreset')
419
+ || msg.includes('fetch failed'); // undici transport error (DNS/TLS/proxy down)
420
+ }
421
+ // #809: kilo's free relay occasionally answers with a bare classification
422
+ // word ("safe" / "unsafe") instead of a real reply — an upstream content
423
+ // filter, not the requested model. Such a turn is a dead turn: treat it like
424
+ // an empty completion so the fallback loop fails over to the next provider
425
+ // instead of surfacing "safe"/"unsafe" as the answer.
426
+ //
427
+ // Scoped to the relay that actually does this. "safe"/"unsafe" is a LEGITIMATE
428
+ // one-word answer for moderation and guard-model workloads, so applying the
429
+ // rule everywhere would throw away correct responses and burn the whole
430
+ // fallback chain for anyone doing classification. Only platforms observed
431
+ // injecting a filter verdict in place of the model's reply belong here.
432
+ const CLASSIFICATION_RELAY_PLATFORMS = new Set(['kilo']);
433
+ export function isUpstreamClassificationOutput(text, platform) {
434
+ if (!platform || !CLASSIFICATION_RELAY_PLATFORMS.has(platform.toLowerCase()))
435
+ return false;
436
+ const t = (typeof text === 'string' ? text : '').trim().toLowerCase();
437
+ return t === 'safe' || t === 'unsafe';
438
+ }
439
+ // Provider-side 400s are retryable because another provider may accept the same
440
+ // request shape. If every routed provider rejects it, however, the client should
441
+ // see an invalid-request error rather than a misleading rate-limit exhaustion.
442
+ export function isProviderBadRequestError(err) {
443
+ if (isProviderDegradedError(err))
444
+ return false;
445
+ const status = typeof err?.status === 'number' ? err.status : 0;
446
+ const msg = (err?.message ?? '').toLowerCase();
447
+ if (status === 400)
448
+ return msg.includes('api error 400');
449
+ if (status === 422)
450
+ return msg.includes('api error 422') || msg.includes('unprocessable entity');
451
+ if (status !== 0)
452
+ return false;
453
+ return msg.includes('api error 400') || msg.includes('api error 422') || msg.includes('unprocessable entity');
454
+ }
455
+ // A "this request/prompt is too large" rejection. Providers word it very
456
+ // differently and even disagree on the HTTP status:
457
+ // - OpenAI-compat: 400 with code `context_length_exceeded` — "This model's
458
+ // maximum context length is 8192 tokens. However, your messages resulted
459
+ // in 10001 tokens. Please reduce the length of the messages."
460
+ // - Anthropic: 400 invalid_request_error — "prompt is too long: 210000
461
+ // tokens > 200000 maximum" (Bedrock words it "Input is too long for
462
+ // requested model.")
463
+ // - Google/Gemini: 400 INVALID_ARGUMENT — "The input token count (1200000)
464
+ // exceeds the maximum number of tokens allowed (1048576)."
465
+ // - Groq: a literal HTTP 413 — "Request too large for model `x` ... on
466
+ // tokens per minute (TPM): Limit 30000, Requested 33476". Requested >
467
+ // Limit can never fit that candidate's window, so it belongs here (too
468
+ // large for the candidate), not with transient per-minute 429s.
469
+ // - Reverse proxies / gateways: 413 "Payload Too Large" / "request entity
470
+ // too large" / "content too large".
471
+ // Structured status first (providerHttpError attaches err.status on every
472
+ // adapter), then the code field, then message markers — mirroring how the
473
+ // other classifiers in this file work. Retryable (a sibling candidate may have
474
+ // a larger window), but when EVERY attempt dies this way the exhaustion ladder
475
+ // renders an honest 413 instead of a generic failure.
476
+ export function isContextTooLargeError(err) {
477
+ if (err?.status === 413)
478
+ return true;
479
+ if (typeof err?.code === 'string' && err.code.toLowerCase() === 'context_length_exceeded')
480
+ return true;
481
+ const msg = (err?.message ?? '').toLowerCase();
482
+ return msg.includes('context_length_exceeded')
483
+ || msg.includes('maximum context length')
484
+ || msg.includes('context length exceeded')
485
+ || /exceeds[^.]*context (length|window|size)/.test(msg)
486
+ || msg.includes('prompt is too long')
487
+ || msg.includes('input is too long')
488
+ || /input token count[^.]*exceeds/.test(msg)
489
+ || msg.includes('exceeds the maximum number of tokens')
490
+ || msg.includes('request too large')
491
+ || msg.includes('payload too large')
492
+ || msg.includes('request entity too large')
493
+ || msg.includes('request body too large')
494
+ || msg.includes('content too large')
495
+ // Zhipu AI (bigmodel.cn) 400, error code 1261: "Prompt exceeds max length"
496
+ // (#873). Its wording matches none of the markers above, so without this it
497
+ // was mis-bucketed as provider_bad_request instead of context_too_large.
498
+ || msg.includes('exceeds max length')
499
+ || msg.includes('api error 413');
500
+ }
501
+ // A 402 Payment Required / out-of-credits error. Distinct from a transient 429:
502
+ // it won't recover on the next window, so the caller benches the model+key with
503
+ // PAYMENT_REQUIRED_COOLDOWN_MS (a full day) rather than the 90s transient cooldown.
504
+ //
505
+ // The digits 402 only count as the STATUS. A bare `includes('402')` also
506
+ // matched token counts and request ids ("Limit 30000, Requested 34026",
507
+ // "14023 tokens used"), and since the 402 bench covers the key on every model
508
+ // of the platform for a day (#1239), one unlucky number took a whole provider
509
+ // out. So: an error that states another status is never a 402 by its digits,
510
+ // and otherwise 402 has to stand alone rather than sit inside a longer number.
511
+ const STATED_STATUS = /\bapi error (\d{3})\b|\(http (\d{3})\)/;
512
+ const STANDALONE_402 = /(?<![\w.])402(?![\w.])/;
513
+ export function isPaymentRequiredError(err) {
514
+ const msg = String(err?.message ?? '').toLowerCase();
515
+ if (msg.includes('payment required')
516
+ || msg.includes('insufficient_quota') || msg.includes('insufficient credit')
517
+ || msg.includes('insufficient balance'))
518
+ return true;
519
+ const stated = msg.match(STATED_STATUS);
520
+ const status = typeof err?.status === 'number' ? err.status : Number(stated?.[1] ?? stated?.[2]);
521
+ if (Number.isFinite(status))
522
+ return status === 402;
523
+ return STANDALONE_402.test(msg);
524
+ }
525
+ // "model 'x' does not exist" / "model \"x\" does not exist" / "model x does not
526
+ // exist" — one non-space token (optionally quoted) between the word "model" and
527
+ // the verdict. Bounded so an unrelated sentence containing both words never
528
+ // matches; the model id itself is never inspected.
529
+ const MODEL_ID_DOES_NOT_EXIST = /\bmodel\b\s+['"`]?[^\s'"`]{1,200}['"`]?\s+(?:does\s+not|doesn't)\s+exist\b/;
530
+ // A 404 "model removed/deprecated upstream" error. It's a MODEL-level failure,
531
+ // not a key-level one: every key for the platform will 404 the same way, so the
532
+ // retry loop skips the entire model for the rest of the request instead of
533
+ // burning one fallback attempt per key on the same dead route.
534
+ // (PR #111, credits @barbotkonv.)
535
+ export function isModelNotFoundError(err) {
536
+ // 404 (removed/deprecated) and 410 (permanently Gone) are both MODEL-level: every
537
+ // key for the platform fails the same way, so skip the whole model for the rest
538
+ // of the request instead of burning one fallback attempt per sibling key. 410
539
+ // added for #339 (Ollama Cloud "Gone"); prefer the structured status when present.
540
+ if (err?.status === 404 || err?.status === 410)
541
+ return true;
542
+ const msg = (err?.message ?? '').toLowerCase();
543
+ return msg.includes('404') || msg.includes('not found') || msg.includes('no endpoints found')
544
+ || msg.includes('410') || msg.includes('gone')
545
+ // Some aggregators report a removed/stale model with a 400 (not a 404) whose
546
+ // body reads "No model found: <id>", "model not found", "unknown model" or
547
+ // "model does not exist" (#: Routeway 400 "No model found: llama-3.3-70b-instruct:free").
548
+ // Note "No model found" does NOT contain the substring "not found" (words are
549
+ // no/model/found), so it slipped past the checks above and fell through to
550
+ // isProviderBadRequestError — surfacing as a request-blaming 400 instead of a
551
+ // stale-catalog 404. These phrasings are MODEL-level (every sibling key fails
552
+ // identically), so they belong here for the whole-model skip.
553
+ || msg.includes('no model found') || msg.includes('model not found')
554
+ || msg.includes('unknown model') || msg.includes('model does not exist')
555
+ || msg.includes('no such model')
556
+ // The same verdict with the model id quoted in the middle (#1239: NavyAI
557
+ // 400 "The model 'o3-mini' does not exist or is not supported for chat
558
+ // completions."). The bare "model does not exist" substring above never
559
+ // matches that wording, so every one of a platform's stale rows was booked
560
+ // as provider_bad_request — no whole-model skip, a hop burned per dead
561
+ // model, and the exhaustion body blamed the caller's request.
562
+ || MODEL_ID_DOES_NOT_EXIST.test(msg)
563
+ // "not supported for chat completions" is MODEL-level too: the id is real
564
+ // but this platform cannot serve it on the endpoint we use, and a sibling
565
+ // key would be told the same. Route it out for the request like a 404.
566
+ || msg.includes('not supported for chat completions');
567
+ }
568
+ // A 403 that suspends the ACCOUNT, not one model: NavyAI answers every model
569
+ // behind a benched free key with "The Free plan is temporarily disabled due to
570
+ // abuse. You can purchase a plan ...". Every model of the platform fails the
571
+ // same way, so classifying it as model-forbidden benched ONE model per attempt:
572
+ // with 93 catalog rows on that platform, each request burned its whole failover
573
+ // budget re-discovering the same dead account. Not key-auth either: the
574
+ // credential itself is valid, the plan behind it is not, and validateKey's
575
+ // /models probe still passes, so the health checker never demotes the key.
576
+ // Status-gated to 403 (or a status-less message that names one) so provider
577
+ // wording alone can never condemn a healthy key.
578
+ export function isAccountSuspendedError(err) {
579
+ const status = typeof err?.status === 'number' ? err.status : 0;
580
+ const msg = (err?.message ?? '').toLowerCase();
581
+ if (status !== 403 && !(status === 0 && msg.includes('403')))
582
+ return false;
583
+ return /\b(plan|account|subscription) (is|has been|was) (temporarily )?(disabled|suspended|banned|deactivated)\b/.test(msg)
584
+ || msg.includes('due to abuse');
585
+ }
586
+ // A 403 Forbidden returned for a specific model behind an otherwise-valid key.
587
+ // Drives the same whole-model skip as a 404: every key on this platform's tier
588
+ // would be forbidden the same model, so rule it out for the rest of the request
589
+ // rather than trying it again with a sibling key. Distinct from a dead key —
590
+ // validateKey returns false on 401/403, so the health checker disables genuinely
591
+ // forbidden keys; a 403 reaching here is model-not-on-this-tier. See issue #256.
592
+ export function isModelAccessForbiddenError(err) {
593
+ if (err?.status === 403)
594
+ return true;
595
+ const msg = (err?.message ?? '').toLowerCase();
596
+ if (msg.includes('403') || msg.includes('forbidden'))
597
+ return true;
598
+ // Not every provider spells "this key may not use this model" as a 403 (issue
599
+ // #618): observed live as a 400 whose body reads "user is not allowed to
600
+ // access model kat-coder-pro-v2.5", and as plan-gate wordings like "action
601
+ // plan limited". Classified transient, those took the 90s bench — and the
602
+ // auto-router re-picked the same permanently-unreachable model the moment it
603
+ // expired, failing and re-benching forever with an ever-growing penalty.
604
+ // Deliberately narrow: only 400/401 (or a status-less error), and only for
605
+ // phrasings that name access/permission to the MODEL. A bare "Bad Request",
606
+ // a generic "Unauthorized" (which isKeyAuthError owns), or a parameter
607
+ // rejection must keep their current classification.
608
+ const status = typeof err?.status === 'number' ? err.status : 0;
609
+ if (status !== 0 && status !== 400 && status !== 401)
610
+ return false;
611
+ return MODEL_ACCESS_DENIED_PHRASES.some(phrase => msg.includes(phrase));
612
+ }
613
+ const MODEL_ACCESS_DENIED_PHRASES = [
614
+ 'not allowed to access',
615
+ 'not allowed to use',
616
+ 'not authorized to access',
617
+ 'not authorized to use',
618
+ 'unauthorized to access',
619
+ 'not permitted to access',
620
+ 'not permitted to use',
621
+ 'do not have access to',
622
+ 'does not have access to',
623
+ 'no access to model',
624
+ 'no access to this model',
625
+ 'model access denied',
626
+ 'access to this model is restricted',
627
+ // Plan/subscription gates the provider words as a limit rather than a denial.
628
+ 'action plan limited',
629
+ ];
630
+ const END_OF_LIFE_PHRASES = [
631
+ 'end of life',
632
+ 'end-of-life',
633
+ 'has been retired',
634
+ 'has been decommissioned',
635
+ 'has been sunset',
636
+ ];
637
+ const MODEL_GONE_PHRASES = [
638
+ 'no longer available',
639
+ 'no longer offered',
640
+ 'no longer supported',
641
+ 'has been removed',
642
+ 'was removed',
643
+ 'has been discontinued',
644
+ 'has been deprecated',
645
+ 'is deprecated',
646
+ ];
647
+ export function modelRetirementSignal(err) {
648
+ const msg = (err?.message ?? '').toLowerCase();
649
+ const status = typeof err?.status === 'number' ? err.status : 0;
650
+ const gone = status === 410 || /\berror 410\b/.test(msg) || /\b410 gone\b/.test(msg);
651
+ // An end-of-life phrase is only definitive when the status agrees the model
652
+ // is not there. On its own it is just text, and 'definitive' skips the
653
+ // corroboration gate in noteModelRetirementSignal — so a 429 or 500 whose
654
+ // body happens to mention a retirement (an advisory notice, a status-page
655
+ // quote, a message about a DIFFERENT model) disabled a live model on one
656
+ // response. Unmatched here means it falls through and teaches nothing.
657
+ if (gone || (isModelNotFoundError(err) && END_OF_LIFE_PHRASES.some(phrase => msg.includes(phrase))))
658
+ return 'definitive';
659
+ if (!isModelNotFoundError(err))
660
+ return null;
661
+ return MODEL_GONE_PHRASES.some(phrase => msg.includes(phrase)) ? 'probable' : null;
662
+ }
663
+ // A stream that ended without its terminal marker (`[DONE]` and/or a
664
+ // finish_reason): the upstream connection was reset or the response truncated
665
+ // mid-generation. Observed live on Kilo Gateway (5 attempts in one session,
666
+ // #1218): the gateway answers 200, streams content, then dies without
667
+ // `data: [DONE]` — `readSseStream` throws
668
+ // "…stream ended unexpectedly (no [DONE], no finish_reason)".
669
+ //
670
+ // The truncation is UPSTREAM transport, not request shape, so the plain
671
+ // retryable path (a fresh attempt on a sibling key, or even the same key
672
+ // later) is the right response — but a stream that dies with zero content
673
+ // deltas is usually the ROUTE (platform+model+key edge) that is sick, not
674
+ // bad luck: three empty-ended truncations in a row on the same route
675
+ // reliably precede another one. Callers use this signal to bench the route
676
+ // after a short streak instead of re-paying the round trip every request.
677
+ export function isStreamTruncatedError(err) {
678
+ const msg = (err?.message ?? '').toLowerCase();
679
+ return msg.includes('stream ended unexpectedly')
680
+ || msg.includes('no [done], no finish_reason')
681
+ // undici surfaces an abrupt RST as "terminated" on the body read; with
682
+ // our SSE reader the top-level message is "terminated" and the real
683
+ // cause is buried in err.cause (see isTransportError). Count it too:
684
+ // a terminated mid-stream body is the same dead route either way.
685
+ || msg === 'terminated';
686
+ }
687
+ //# sourceMappingURL=error-classify.js.map