@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,40 @@
1
+ // Monthly free-tier budgets are stored as human labels like '~120M', '~50-100M',
2
+ // '~12M', or '~500K'. Parse the upper bound to an absolute token count for
3
+ // quota math (headroom guardrail, token-usage bar). Returns 0 for unknown/empty
4
+ // labels, which callers treat as "no budget info".
5
+ export function parseBudget(s) {
6
+ if (!s)
7
+ return 0;
8
+ // Require a magnitude unit (M/K). A bare number with no unit is a rate limit
9
+ // or placeholder, not a monthly token budget — "free · 40 RPM",
10
+ // "free · 200/hr per IP", "promo (trial)", "~? (anon)" — so treat those as
11
+ // "no budget info" (0), per this function's contract. Without the required
12
+ // unit the old regex parsed "free · 40 RPM" as 40 tokens, which showed a bogus
13
+ // budget and made the headroom guardrail penalize the model after one request.
14
+ const m = s.match(/~?([\d.]+)(?:-([\d.]+))?([MK])/);
15
+ if (!m)
16
+ return 0;
17
+ const high = parseFloat(m[2] ?? m[1]);
18
+ if (Number.isNaN(high))
19
+ return 0;
20
+ const unit = m[3] === 'M' ? 1_000_000 : 1_000;
21
+ return high * unit;
22
+ }
23
+ // Sort score for the "budget" preset on the fallback/profiles dashboards.
24
+ // Shares parseBudget so rate-limit labels can't masquerade as budgets: the
25
+ // per-route copies this replaced multiplied the bare number in
26
+ // "free · 40 RPM" by 1e6 because the 'M' in "RPM" hit the unit check, ranking
27
+ // a 40-requests-per-minute model as a 40-million-token budget.
28
+ // tpd_limit still wins when present (a concrete daily cap beats a "~" label),
29
+ // and "unlimited"/"∞" labels keep sorting above every parsed budget.
30
+ export function monthlyBudgetScore(m) {
31
+ if (m.tpd_limit != null)
32
+ return m.tpd_limit * 30;
33
+ const str = m.monthly_token_budget;
34
+ if (!str)
35
+ return 0;
36
+ if (str.toLowerCase().includes('unlimited') || str.includes('∞'))
37
+ return Infinity;
38
+ return parseBudget(str);
39
+ }
40
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/lib/budget.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,2EAA2E;AAC3E,gFAAgF;AAChF,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,6EAA6E;IAC7E,gEAAgE;IAChE,2EAA2E;IAC3E,2EAA2E;IAC3E,+EAA+E;IAC/E,+EAA+E;IAC/E,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9C,OAAO,IAAI,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,+DAA+D;AAC/D,8EAA8E;AAC9E,+DAA+D;AAC/D,8EAA8E;AAC9E,qEAAqE;AACrE,MAAM,UAAU,kBAAkB,CAAC,CAA6D;IAC9F,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI;QAAE,OAAO,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC;IACjD,MAAM,GAAG,GAAG,CAAC,CAAC,oBAAoB,CAAC;IACnC,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC;IACnB,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClF,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Request } from 'express';
2
+ export declare const CLIENT_AGENTS: readonly ["claude-code", "codex", "cline", "roo", "continue", "aider", "opencode", "goose", "qwen-code", "kilo-code", "crush", "deepseek-harness", "mimo-code", "atomcode", "openclaw", "hermes-agent", "pi", "cursor", "gemini-cli", "zed", "jetbrains", "ollama-client", "openai-sdk", "anthropic-sdk", "unknown"];
3
+ export type ClientAgent = (typeof CLIENT_AGENTS)[number];
4
+ /**
5
+ * Best-effort classifier from stable protocol/header signals first, then UA.
6
+ * It intentionally returns a coarse enum: analytics should remain useful when
7
+ * a client revs its version string or wraps an underlying SDK.
8
+ */
9
+ export declare function classifyClientAgent(req: Request): ClientAgent;
10
+ //# sourceMappingURL=client-classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-classifier.d.ts","sourceRoot":"","sources":["../../src/lib/client-classifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,eAAO,MAAM,aAAa,sTA0BhB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAOzD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CA+D7D"}
@@ -0,0 +1,126 @@
1
+ export const CLIENT_AGENTS = [
2
+ 'claude-code',
3
+ 'codex',
4
+ 'cline',
5
+ 'roo',
6
+ 'continue',
7
+ 'aider',
8
+ 'opencode',
9
+ 'goose',
10
+ 'qwen-code',
11
+ 'kilo-code',
12
+ 'crush',
13
+ 'deepseek-harness',
14
+ 'mimo-code',
15
+ 'atomcode',
16
+ 'openclaw',
17
+ 'hermes-agent',
18
+ 'pi',
19
+ 'cursor',
20
+ 'gemini-cli',
21
+ 'zed',
22
+ 'jetbrains',
23
+ 'ollama-client',
24
+ 'openai-sdk',
25
+ 'anthropic-sdk',
26
+ 'unknown',
27
+ ];
28
+ function header(req, name) {
29
+ const raw = req.headers[name];
30
+ return (Array.isArray(raw) ? raw[0] : raw)?.toLowerCase() ?? '';
31
+ }
32
+ /**
33
+ * Best-effort classifier from stable protocol/header signals first, then UA.
34
+ * It intentionally returns a coarse enum: analytics should remain useful when
35
+ * a client revs its version string or wraps an underlying SDK.
36
+ */
37
+ export function classifyClientAgent(req) {
38
+ const path = (req.originalUrl ?? req.url ?? '').split('?')[0].toLowerCase();
39
+ const tokenizedPath = path.replace(/^\/v1\/t\/[^/]+/, '');
40
+ const ua = header(req, 'user-agent');
41
+ // Strongest signal first: the dedicated session header only Claude Code sets.
42
+ if (header(req, 'x-claude-code-session-id'))
43
+ return 'claude-code';
44
+ // UA signals must beat wire-format fallbacks: Qwen Code speaks the Gemini
45
+ // wire on /v1beta, and a plain openai SDK can call /v1/responses — neither
46
+ // should be counted as the surface's flagship client. Claude Code's real UA
47
+ // is `claude-cli/x.y.z (external, cli)`.
48
+ if (/claude[- ]?code|\bclaude-cli\b/.test(ua))
49
+ return 'claude-code';
50
+ if (/\bcodex\b/.test(ua))
51
+ return 'codex';
52
+ if (/qwen[- ]?code|\bqwen-cli\b/.test(ua))
53
+ return 'qwen-code';
54
+ if (/gemini[- /]?cli/.test(ua))
55
+ return 'gemini-cli';
56
+ if (/kilo[- ]?code|\bkilocode\b/.test(ua))
57
+ return 'kilo-code';
58
+ if (/\bcrush(?:\/|\s|$)/.test(ua))
59
+ return 'crush';
60
+ // `deepseek-harness/<version> (+https://github.com/deepseek-ai/deepseek-harness)`
61
+ if (/deepseek[- ]?harness|\bdsh\//.test(ua))
62
+ return 'deepseek-harness';
63
+ // MiMo Code is an OpenCode derivative and can carry either name in its UA,
64
+ // so it has to be tested before the plain `opencode` rule below.
65
+ if (/mimo[- ]?code|\bmimo\//.test(ua))
66
+ return 'mimo-code';
67
+ // `atomcode/<version>`
68
+ if (/\batomcode\b/.test(ua))
69
+ return 'atomcode';
70
+ // OpenClaw names itself only through the static provider header our
71
+ // generator writes (`openclaw`); its own `openclaw/<version>` UA is reserved
72
+ // for endpoints it recognises.
73
+ if (/\bopenclaw\b/.test(ua))
74
+ return 'openclaw';
75
+ // Hermes Agent likewise only names itself to hosts it knows; the generator's
76
+ // `default_headers` sends `hermes-agent`, and its /v1/models probe sends
77
+ // `hermes-cli/<version>` on its own.
78
+ if (/hermes[- ]?agent|\bhermes-cli\b/.test(ua))
79
+ return 'hermes-agent';
80
+ // Pi likewise only names itself to hosts it knows; the generator's provider
81
+ // header sends `pi-coding-agent`, and Pi's own UA is
82
+ // `pi/<version> (<platform>; node/<version>; <arch>)`.
83
+ if (/\bpi-coding-agent\b|^pi\/\d/.test(ua))
84
+ return 'pi';
85
+ if (/opencode/.test(ua))
86
+ return 'opencode';
87
+ if (/\bcline\b/.test(ua))
88
+ return 'cline';
89
+ // The Roo Code extension and CLI send `RooCode/<version>`.
90
+ if (/\broo[- /]/.test(ua) || /roo ?code/.test(ua))
91
+ return 'roo';
92
+ if (/continue(?:\.dev)?/.test(ua))
93
+ return 'continue';
94
+ if (/\baider\b/.test(ua))
95
+ return 'aider';
96
+ if (/\bgoose\b/.test(ua))
97
+ return 'goose';
98
+ if (/\bcursor\b/.test(ua))
99
+ return 'cursor';
100
+ if (/\bzed\b/.test(ua))
101
+ return 'zed';
102
+ if (/jetbrains|intellij|pycharm|webstorm/.test(ua))
103
+ return 'jetbrains';
104
+ if (/\bollama\b/.test(ua))
105
+ return 'ollama-client';
106
+ if (/anthropic|claude-sdk/.test(ua))
107
+ return 'anthropic-sdk';
108
+ if (/openai|langchain|litellm/.test(ua))
109
+ return 'openai-sdk';
110
+ // Wire-format fallbacks for clients with no recognizable UA.
111
+ if (path.startsWith('/v1/responses') || tokenizedPath.startsWith('/responses'))
112
+ return 'codex';
113
+ if (path.startsWith('/v1beta/'))
114
+ return 'gemini-cli';
115
+ if (path.startsWith('/v1/messages')) {
116
+ // anthropic.ts session affinity treats x-session-id as a Claude Code
117
+ // signal on this surface; anything else Anthropic-shaped stays coarse.
118
+ return header(req, 'x-session-id') ? 'claude-code' : 'anthropic-sdk';
119
+ }
120
+ if (tokenizedPath.startsWith('/api/chat')
121
+ || tokenizedPath.startsWith('/api/generate')
122
+ || tokenizedPath.startsWith('/api/tags'))
123
+ return 'ollama-client';
124
+ return 'unknown';
125
+ }
126
+ //# sourceMappingURL=client-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-classifier.js","sourceRoot":"","sources":["../../src/lib/client-classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { NextFunction, Request, Response } from 'express';
2
+ import { type ClientAgent } from './client-classifier.js';
3
+ export interface ClientContext {
4
+ ip: string | null;
5
+ userAgent: string | null;
6
+ agent: ClientAgent | null;
7
+ }
8
+ export declare function clientContextMiddleware(req: Request, _res: Response, next: NextFunction): void;
9
+ export declare function getClientContext(): ClientContext;
10
+ //# sourceMappingURL=client-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-context.d.ts","sourceRoot":"","sources":["../../src/lib/client-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE/E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3B;AA0BD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAW9F;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD"}
@@ -0,0 +1,39 @@
1
+ import { AsyncLocalStorage } from 'async_hooks';
2
+ import { classifyClientAgent } from './client-classifier.js';
3
+ // Request-scoped caller identity, readable from anywhere below the middleware
4
+ // without threading parameters through every logRequest() call site (the chat
5
+ // proxy, responses, anthropic, fusion, embeddings and media paths all log).
6
+ const storage = new AsyncLocalStorage();
7
+ // Resolve the client IP. With Express's `trust proxy` disabled (the default),
8
+ // this is the socket peer address and a spoofed X-Forwarded-For from a LAN
9
+ // client is ignored. When TRUST_PROXY (#1024) opts into trusting a reverse
10
+ // proxy, `req.ip` walks the configured trusted-proxy chain and returns the
11
+ // first untrusted address — instead of trusting the leftmost caller-supplied
12
+ // X-Forwarded-For value, which would let any direct caller spoof it.
13
+ function resolveClientIp(req) {
14
+ const raw = req.ip ?? req.socket.remoteAddress ?? null;
15
+ // Normalize IPv4-mapped IPv6 ("::ffff:192.168.0.5" -> "192.168.0.5").
16
+ return raw?.replace(/^::ffff:/i, '') ?? null;
17
+ }
18
+ // Privacy opt-out: REQUEST_ANALYTICS_LOG_CLIENT=false stores nulls instead of
19
+ // the caller's IP/UA. Read per request (not at module load) so tests and
20
+ // embedders can toggle it without re-importing.
21
+ function clientLoggingEnabled() {
22
+ return process.env.REQUEST_ANALYTICS_LOG_CLIENT !== 'false';
23
+ }
24
+ export function clientContextMiddleware(req, _res, next) {
25
+ if (!clientLoggingEnabled()) {
26
+ storage.run({ ip: null, userAgent: null, agent: null }, next);
27
+ return;
28
+ }
29
+ const ua = req.headers['user-agent'];
30
+ storage.run({
31
+ ip: resolveClientIp(req),
32
+ userAgent: typeof ua === 'string' ? ua.slice(0, 256) : null,
33
+ agent: classifyClientAgent(req),
34
+ }, next);
35
+ }
36
+ export function getClientContext() {
37
+ return storage.getStore() ?? { ip: null, userAgent: null, agent: null };
38
+ }
39
+ //# sourceMappingURL=client-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-context.js","sourceRoot":"","sources":["../../src/lib/client-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAoB,MAAM,wBAAwB,CAAC;AAQ/E,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAiB,CAAC;AAEvD,8EAA8E;AAC9E,2EAA2E;AAC3E,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,qEAAqE;AACrE,SAAS,eAAe,CAAC,GAAY;IACnC,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,IAAI,CAAC;IACvD,sEAAsE;IACtE,OAAO,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;AAC/C,CAAC;AAED,8EAA8E;AAC9E,yEAAyE;AACzE,gDAAgD;AAChD,SAAS,oBAAoB;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,OAAO,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,GAAY,EAAE,IAAc,EAAE,IAAkB;IACtF,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IACD,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC;QACV,EAAE,EAAE,eAAe,CAAC,GAAG,CAAC;QACxB,SAAS,EAAE,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;QAC3D,KAAK,EAAE,mBAAmB,CAAC,GAAG,CAAC;KAChC,EAAE,IAAI,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,33 @@
1
+ export interface Config {
2
+ port: number | string;
3
+ host: string;
4
+ dbPath: string | null;
5
+ dashboardOrigins: string[];
6
+ clientDist: string | null;
7
+ proxyRateLimitRpm: number;
8
+ /** JSON body limit (bytes) for the LLM wire surfaces — see
9
+ * parseRequestBodyLimitBytes. REQUEST_BODY_LIMIT_MB overrides. */
10
+ requestBodyLimitBytes: number;
11
+ nodeEnv: string;
12
+ serveStaticAssets: boolean;
13
+ /**
14
+ * Express `trust proxy` setting, parsed from TRUST_PROXY (#1024).
15
+ * - false: do not trust forwarded headers (default; direct callers
16
+ * cannot spoof X-Forwarded-For).
17
+ * - true: trust all proxies (with a security warning).
18
+ * - number: trust that many hops counted from the socket peer
19
+ * (Express's `trust proxy: 1` idiom for one proxy in front).
20
+ * - string[]: trust only these proxy addresses/CIDRs.
21
+ */
22
+ trustProxy: boolean | number | string[];
23
+ /**
24
+ * Tri-state override for the CSP `upgrade-insecure-requests` directive (#682).
25
+ * - undefined: auto — emit the directive only when the request arrived over
26
+ * TLS (or behind an HTTPS reverse proxy that forwarded X-Forwarded-Proto).
27
+ * - true: always emit (force HTTPS upgrade even on plain HTTP).
28
+ * - false: never emit (let HTTP LAN installs render the dashboard).
29
+ */
30
+ cspUpgradeInsecureRequests: boolean | undefined;
31
+ }
32
+ export declare function loadConfig(): Config;
33
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAqCA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B;uEACmE;IACnE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;;;;OAQG;IACH,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC;;;;;;OAMG;IACH,0BAA0B,EAAE,OAAO,GAAG,SAAS,CAAC;CACjD;AAED,wBAAgB,UAAU,IAAI,MAAM,CAuBnC"}
@@ -0,0 +1,94 @@
1
+ const DEFAULT_RPM = 120;
2
+ // JSON body ceiling for the LLM wire surfaces (/v1, /v1beta, /mcp, Ollama
3
+ // /api/*). Vision requests inline base64 images (~33% inflation over the raw
4
+ // bytes; google.ts alone forwards images up to 8MB, ~10.7MB in base64), so a
5
+ // single-screenshot Codex turn easily clears 10MB, and history replay stacks
6
+ // several of them (an 11.85MB real-world request was observed). express.json
7
+ // buffers the whole body in memory (2-3x transiently during the parse), so
8
+ // this also bounds the per-request spike on small containers. Anything past
9
+ // the ceiling 413s before routing — no fallback, no analytics row — so it
10
+ // must sit above the largest payload we expect to serve. 25MB is the balance
11
+ // point: it clears the observed 11.85MB replayed session with room to spare,
12
+ // while keeping the worst case survivable on the small hosts this runs on (a
13
+ // Pi or a 512MB VPS — the limit is PER REQUEST, so a handful of concurrent
14
+ // maximal bodies is the number that actually has to fit in RAM). Inbound
15
+ // image normalization shrinks payloads ~6-10x right after the parse, so the
16
+ // steady state sits far below this. Raise REQUEST_BODY_LIMIT_MB on a bigger
17
+ // box if a client genuinely sends more. The dashboard/admin surface keeps its
18
+ // own smaller fixed ceiling.
19
+ const DEFAULT_REQUEST_BODY_LIMIT_MB = 25;
20
+ function parseRateLimitRpm() {
21
+ const raw = process.env.PROXY_RATE_LIMIT_RPM;
22
+ if (raw === undefined || raw.trim() === '')
23
+ return DEFAULT_RPM;
24
+ const n = Number(raw);
25
+ if (!Number.isFinite(n) || n < 0)
26
+ return DEFAULT_RPM;
27
+ return Math.floor(n);
28
+ }
29
+ function parseRequestBodyLimitBytes() {
30
+ const raw = process.env.REQUEST_BODY_LIMIT_MB;
31
+ if (raw === undefined || raw.trim() === '')
32
+ return DEFAULT_REQUEST_BODY_LIMIT_MB * 1024 * 1024;
33
+ const n = Number(raw);
34
+ if (!Number.isFinite(n) || n < 1)
35
+ return DEFAULT_REQUEST_BODY_LIMIT_MB * 1024 * 1024;
36
+ return Math.floor(n) * 1024 * 1024;
37
+ }
38
+ export function loadConfig() {
39
+ return {
40
+ port: process.env.PORT ?? 20268,
41
+ // Dual-stack ('::') by default so the dashboard is reachable over both IPv4
42
+ // and IPv6 (e.g. IPv6-enabled Docker networks — #180). Hosts with IPv6
43
+ // disabled fall back to IPv4-only below; HOST overrides the default outright.
44
+ host: process.env.HOST ?? '::',
45
+ dbPath: process.env.SROUTER_DB_PATH?.trim() || null,
46
+ dashboardOrigins: (process.env.DASHBOARD_ORIGINS ?? '')
47
+ .split(',')
48
+ .map(s => s.trim())
49
+ .filter(Boolean),
50
+ clientDist: process.env.CLIENT_DIST ?? null,
51
+ proxyRateLimitRpm: parseRateLimitRpm(),
52
+ requestBodyLimitBytes: parseRequestBodyLimitBytes(),
53
+ nodeEnv: process.env.NODE_ENV ?? 'development',
54
+ serveStaticAssets: true,
55
+ trustProxy: parseTrustProxy(),
56
+ // CSP_UPGRADE_INSECURE_REQUESTS: true|false forces the directive on/off;
57
+ // unset (the default) leaves it on auto — emit only when the request is
58
+ // already TLS or forwarded as https, so HTTP LAN installs still render.
59
+ cspUpgradeInsecureRequests: parseCspUpgradeInsecureRequests(),
60
+ };
61
+ }
62
+ // Parse TRUST_PROXY (#1024). unset/empty/false → false (do not trust forwarded
63
+ // headers); true → trust all proxies; a non-negative integer → that many hops
64
+ // from the socket peer (so `TRUST_PROXY=1` means "one proxy in front", the
65
+ // Express idiom, not "trust everything"); otherwise a comma-separated list of
66
+ // proxy addresses/CIDRs → trust only those hops.
67
+ function parseTrustProxy() {
68
+ const raw = process.env.TRUST_PROXY;
69
+ if (raw === undefined || raw.trim() === '')
70
+ return false;
71
+ const lower = raw.trim().toLowerCase();
72
+ if (lower === 'true' || lower === 'yes')
73
+ return true;
74
+ if (lower === 'false' || lower === 'no')
75
+ return false;
76
+ if (/^\d+$/.test(lower)) {
77
+ const hops = Number(lower);
78
+ return hops > 0 ? hops : false;
79
+ }
80
+ const addrs = raw.split(',').map(s => s.trim()).filter(Boolean);
81
+ return addrs.length > 0 ? addrs : false;
82
+ }
83
+ function parseCspUpgradeInsecureRequests() {
84
+ const raw = process.env.CSP_UPGRADE_INSECURE_REQUESTS;
85
+ if (raw === undefined || raw.trim() === '')
86
+ return undefined;
87
+ const lower = raw.trim().toLowerCase();
88
+ if (lower === 'true' || lower === '1' || lower === 'yes')
89
+ return true;
90
+ if (lower === 'false' || lower === '0' || lower === 'no')
91
+ return false;
92
+ return undefined;
93
+ }
94
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { ChatMessage } from '@srouter/shared/types.js';
2
+ export type ContentTextBlock = {
3
+ type: 'text';
4
+ text: string;
5
+ };
6
+ export type ContentBlock = ContentTextBlock | {
7
+ type: string;
8
+ [key: string]: unknown;
9
+ };
10
+ export declare function contentToString(content: unknown): string;
11
+ export declare function estimateInputTokens(messages: ChatMessage[], tools?: readonly unknown[]): number;
12
+ export declare function flattenMessageContent(messages: ChatMessage[]): ChatMessage[];
13
+ export declare function contentHasImage(content: unknown): boolean;
14
+ export declare function messageHasImage(messages: ChatMessage[]): boolean;
15
+ export declare function stripImagesFromMessages(messages: ChatMessage[]): ChatMessage[];
16
+ export declare const GITHUB_MAX_INPUT_TOKENS = 7500;
17
+ /**
18
+ * Fit a message list inside GitHub Models' input ceiling before dispatch.
19
+ * Keeps the leading system prompt verbatim (its instructions are the whole
20
+ * point of prepending one) and then as many of the NEWEST messages as the
21
+ * remaining budget allows, dropping the oldest turns first — the same trade a
22
+ * client's own context window makes. A single message that blows the budget on
23
+ * its own is truncated rather than dropped, so the turn is never dispatched
24
+ * with nothing to answer.
25
+ *
26
+ * Returns the ORIGINAL array when the request already fits, which is both the
27
+ * common case and the cheap one: callers can hand every github-routed request
28
+ * through here without copying anything.
29
+ */
30
+ export declare function truncateMessagesForGithub(messages: ChatMessage[], budget?: number): ChatMessage[];
31
+ export declare function sanitizeResponse<T>(payload: T): T;
32
+ export declare function normalizeOutboundContent<T>(payload: T): T;
33
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/lib/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAU5D,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9D,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAEvF,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAoBxD;AASD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAQ/F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAK5E;AAKD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAMzD;AAID,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAEhE;AAID,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAU9E;AAOD,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAqB5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,WAAW,EAAE,EACvB,MAAM,GAAE,MAAgC,GACvC,WAAW,EAAE,CAyBf;AAcD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAcjD;AAYD,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAczD"}
@@ -0,0 +1,201 @@
1
+ export function contentToString(content) {
2
+ if (typeof content === 'string')
3
+ return content;
4
+ if (content == null)
5
+ return '';
6
+ if (Array.isArray(content)) {
7
+ return content
8
+ .map((b) => {
9
+ if (typeof b === 'string')
10
+ return b;
11
+ const block = b;
12
+ // OpenAI blocks carry type:'text'; Gemini-lineage agents (Qwen Code,
13
+ // AionUI) send part-style `{ text }` with no type at all — accept any
14
+ // block whose `text` is a string and whose type doesn't say it's
15
+ // something else. (#200)
16
+ if (typeof block?.text === 'string' && (block.type === 'text' || block.type === undefined)) {
17
+ return block.text;
18
+ }
19
+ return '';
20
+ })
21
+ .join('');
22
+ }
23
+ return '';
24
+ }
25
+ // Rough input-token count (~4 chars per token) used for routing and budget
26
+ // checks: message text, assistant tool-call arguments, and the tool schemas
27
+ // the request carries. Tool schemas go upstream on every turn and count
28
+ // against the provider's context window and TPM ceiling. An agent client like
29
+ // Claude Code sends ~16k tokens of them next to ~4k of messages, so leaving
30
+ // them out routed its requests to models they could never fit (a Groq 8k-TPM
31
+ // model answered 413 to an "estimated" 4k request that was really 17.7k).
32
+ export function estimateInputTokens(messages, tools) {
33
+ const messageTokens = messages.reduce((sum, m) => {
34
+ const calls = (m.tool_calls ?? [])
35
+ .reduce((n, call) => n + call.function.name.length + call.function.arguments.length, 0);
36
+ return sum + Math.ceil((contentToString(m.content).length + calls) / 4);
37
+ }, 0);
38
+ const toolTokens = tools && tools.length > 0 ? Math.ceil(JSON.stringify(tools).length / 4) : 0;
39
+ return messageTokens + toolTokens;
40
+ }
41
+ export function flattenMessageContent(messages) {
42
+ return messages.map((m) => ({
43
+ ...m,
44
+ content: contentToString(m.content),
45
+ }));
46
+ }
47
+ // True if the content array carries an image block. OpenAI's multimodal
48
+ // envelope uses `{ type: 'image_url', image_url: { url } }`; some clients send
49
+ // a bare `{ type: 'image', ... }`.
50
+ export function contentHasImage(content) {
51
+ if (!Array.isArray(content))
52
+ return false;
53
+ return content.some((block) => {
54
+ const type = block?.type;
55
+ return type === 'image_url' || type === 'image';
56
+ });
57
+ }
58
+ // True if any message carries an image content block. Used to route image
59
+ // requests only to vision-capable models (#118, #125).
60
+ export function messageHasImage(messages) {
61
+ return messages.some((m) => contentHasImage(m.content));
62
+ }
63
+ // Drop image blocks from every message so a text-only model (e.g. the fusion
64
+ // judge, which synthesizes from panel text answers) never receives pixels.
65
+ export function stripImagesFromMessages(messages) {
66
+ return messages.map((m) => {
67
+ if (!Array.isArray(m.content))
68
+ return m;
69
+ const kept = m.content.filter((block) => {
70
+ const type = block?.type;
71
+ return type !== 'image_url' && type !== 'image';
72
+ });
73
+ if (kept.length === m.content.length)
74
+ return m;
75
+ return { ...m, content: kept.length > 0 ? kept : '' };
76
+ });
77
+ }
78
+ // GitHub Models refuses a long history outright (413) rather than truncating
79
+ // it the way most providers do, so an oversized body turns every github hop in
80
+ // the fallback chain into a wasted attempt. 7500 is the input budget we trim
81
+ // to: comfortably inside the ~8000-token ceiling observed live, with room for
82
+ // the tool schemas and the system prompt the gateway prepends.
83
+ export const GITHUB_MAX_INPUT_TOKENS = 7500;
84
+ // The proxy's own chars/4 input estimate, per message — same arithmetic the
85
+ // routing/budget paths use, so the guard below trims against the number the
86
+ // rest of the gateway reasons about.
87
+ function estimateMessageTokens(message) {
88
+ return Math.ceil(contentToString(message.content).length / 4);
89
+ }
90
+ // Trim one message's text down to a token budget. Non-string content
91
+ // (multimodal envelopes) is returned untouched — dropping or rewriting image
92
+ // blocks here would corrupt the envelope, and text is the only thing this
93
+ // guard is allowed to shorten.
94
+ function truncateMessageText(message, budget) {
95
+ if (typeof message.content !== 'string')
96
+ return message;
97
+ const maxChars = Math.max(0, budget) * 4;
98
+ return message.content.length <= maxChars
99
+ ? message
100
+ : { ...message, content: message.content.slice(0, maxChars) };
101
+ }
102
+ /**
103
+ * Fit a message list inside GitHub Models' input ceiling before dispatch.
104
+ * Keeps the leading system prompt verbatim (its instructions are the whole
105
+ * point of prepending one) and then as many of the NEWEST messages as the
106
+ * remaining budget allows, dropping the oldest turns first — the same trade a
107
+ * client's own context window makes. A single message that blows the budget on
108
+ * its own is truncated rather than dropped, so the turn is never dispatched
109
+ * with nothing to answer.
110
+ *
111
+ * Returns the ORIGINAL array when the request already fits, which is both the
112
+ * common case and the cheap one: callers can hand every github-routed request
113
+ * through here without copying anything.
114
+ */
115
+ export function truncateMessagesForGithub(messages, budget = GITHUB_MAX_INPUT_TOKENS) {
116
+ if (messages.length === 0)
117
+ return messages;
118
+ const total = messages.reduce((sum, m) => sum + estimateMessageTokens(m), 0);
119
+ if (total <= budget)
120
+ return messages;
121
+ const systemIdx = messages.findIndex(m => m.role === 'system');
122
+ const systemMessage = systemIdx >= 0 ? messages[systemIdx] : null;
123
+ const rest = messages.filter((_, i) => i !== systemIdx);
124
+ const systemTokens = systemMessage ? estimateMessageTokens(systemMessage) : 0;
125
+ let used = systemTokens;
126
+ const kept = [];
127
+ // Newest → oldest: the most recent context is the context the answer needs.
128
+ for (let i = rest.length - 1; i >= 0; i--) {
129
+ const tokens = estimateMessageTokens(rest[i]);
130
+ if (used + tokens > budget)
131
+ break;
132
+ kept.unshift(rest[i]);
133
+ used += tokens;
134
+ }
135
+ // Nothing fit alongside the system prompt: keep the newest message in
136
+ // truncated form instead of sending an empty conversation.
137
+ if (kept.length === 0 && rest.length > 0) {
138
+ kept.push(truncateMessageText(rest[rest.length - 1], budget - systemTokens));
139
+ }
140
+ return systemMessage ? [systemMessage, ...kept] : kept;
141
+ }
142
+ // Harden the OUTBOUND envelope so strict OpenAI clients don't choke on the
143
+ // shape variations free-tier providers emit. Complements normalizeOutboundContent
144
+ // (which fixes array content) by fixing the *frame* fields, not the content:
145
+ // - `model` coerced to a string (some providers send null/number).
146
+ // - `choices[].finish_reason` defaulted to null when absent — the field must
147
+ // exist per spec; Rust agents (the #200 class of compat bugs) branch on it.
148
+ // - a literal `tool_calls: null` on a message/delta is DELETED — OpenAI omits
149
+ // the field entirely when there are no calls, and `null` breaks clients that
150
+ // test for its presence (this is the response-side mirror of the #200 fix).
151
+ // Content, real tool_calls arrays, reasoning_content, and every other field are
152
+ // left untouched. Mutates and returns the same object (frames are parsed fresh
153
+ // per SSE line, so in-place mutation is safe), matching normalizeOutboundContent.
154
+ export function sanitizeResponse(payload) {
155
+ const p = payload;
156
+ if (!p || typeof p !== 'object')
157
+ return payload;
158
+ if (p.model != null && typeof p.model !== 'string')
159
+ p.model = String(p.model);
160
+ if (Array.isArray(p.choices)) {
161
+ for (const choice of p.choices) {
162
+ if (!choice || typeof choice !== 'object')
163
+ continue;
164
+ const c = choice;
165
+ if (c.finish_reason === undefined)
166
+ c.finish_reason = null;
167
+ if (c.message && typeof c.message === 'object' && c.message.tool_calls === null)
168
+ delete c.message.tool_calls;
169
+ if (c.delta && typeof c.delta === 'object' && c.delta.tool_calls === null)
170
+ delete c.delta.tool_calls;
171
+ }
172
+ }
173
+ return payload;
174
+ }
175
+ // Normalize the OUTBOUND (provider → client) shape so we honor the OpenAI
176
+ // contract on the response path the same way `contentToString` does on the
177
+ // request path. Per spec, `choices[].delta.content` (streaming) and
178
+ // `choices[].message.content` (non-stream) are strings; some providers
179
+ // (e.g. Mistral magistral) return an array of content blocks. Forwarding the
180
+ // array verbatim breaks string-consuming clients ("expected str, got list")
181
+ // and, mid-stream, drops the turn's tool calls. We coerce array content to a
182
+ // string while leaving `tool_calls` and every other field untouched. Mutates
183
+ // and returns the same object (chunks are parsed fresh from JSON per frame, so
184
+ // in-place mutation is safe). Non-array content passes through unchanged. (#166)
185
+ export function normalizeOutboundContent(payload) {
186
+ const choices = payload?.choices;
187
+ if (!Array.isArray(choices))
188
+ return payload;
189
+ for (const choice of choices) {
190
+ const delta = choice?.delta;
191
+ if (delta && Array.isArray(delta.content)) {
192
+ delta.content = contentToString(delta.content);
193
+ }
194
+ const message = choice?.message;
195
+ if (message && Array.isArray(message.content)) {
196
+ message.content = contentToString(message.content);
197
+ }
198
+ }
199
+ return payload;
200
+ }
201
+ //# sourceMappingURL=content.js.map