omniroute 2.8.4 → 2.8.6

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 (267) hide show
  1. package/app/.next/BUILD_ID +1 -1
  2. package/app/.next/build-manifest.json +2 -2
  3. package/app/.next/prerender-manifest.json +3 -3
  4. package/app/.next/server/app/(dashboard)/dashboard/a2a/page_client-reference-manifest.js +1 -1
  5. package/app/.next/server/app/(dashboard)/dashboard/agents/page_client-reference-manifest.js +1 -1
  6. package/app/.next/server/app/(dashboard)/dashboard/analytics/page_client-reference-manifest.js +1 -1
  7. package/app/.next/server/app/(dashboard)/dashboard/api-manager/page_client-reference-manifest.js +1 -1
  8. package/app/.next/server/app/(dashboard)/dashboard/audit-log/page_client-reference-manifest.js +1 -1
  9. package/app/.next/server/app/(dashboard)/dashboard/auto-combo/page_client-reference-manifest.js +1 -1
  10. package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  11. package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  12. package/app/.next/server/app/(dashboard)/dashboard/costs/page_client-reference-manifest.js +1 -1
  13. package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  14. package/app/.next/server/app/(dashboard)/dashboard/health/page_client-reference-manifest.js +1 -1
  15. package/app/.next/server/app/(dashboard)/dashboard/limits/page_client-reference-manifest.js +1 -1
  16. package/app/.next/server/app/(dashboard)/dashboard/logs/page_client-reference-manifest.js +1 -1
  17. package/app/.next/server/app/(dashboard)/dashboard/mcp/page_client-reference-manifest.js +1 -1
  18. package/app/.next/server/app/(dashboard)/dashboard/media/page_client-reference-manifest.js +1 -1
  19. package/app/.next/server/app/(dashboard)/dashboard/onboarding/page_client-reference-manifest.js +1 -1
  20. package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  21. package/app/.next/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  22. package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  23. package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  24. package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  25. package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  26. package/app/.next/server/app/(dashboard)/dashboard/search-tools/page_client-reference-manifest.js +1 -1
  27. package/app/.next/server/app/(dashboard)/dashboard/settings/page_client-reference-manifest.js +1 -1
  28. package/app/.next/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  29. package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  30. package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  31. package/app/.next/server/app/400/page_client-reference-manifest.js +1 -1
  32. package/app/.next/server/app/401/page_client-reference-manifest.js +1 -1
  33. package/app/.next/server/app/403/page_client-reference-manifest.js +1 -1
  34. package/app/.next/server/app/408/page_client-reference-manifest.js +1 -1
  35. package/app/.next/server/app/429/page_client-reference-manifest.js +1 -1
  36. package/app/.next/server/app/500/page_client-reference-manifest.js +1 -1
  37. package/app/.next/server/app/502/page_client-reference-manifest.js +1 -1
  38. package/app/.next/server/app/503/page_client-reference-manifest.js +1 -1
  39. package/app/.next/server/app/_global-error.html +2 -2
  40. package/app/.next/server/app/_global-error.rsc +1 -1
  41. package/app/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  42. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  43. package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  44. package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  45. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  46. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  47. package/app/.next/server/app/api/acp/agents/route.js +1 -1
  48. package/app/.next/server/app/api/acp/agents/route.js.nft.json +1 -1
  49. package/app/.next/server/app/api/auth/login/route.js +1 -1
  50. package/app/.next/server/app/api/auth/login/route.js.nft.json +1 -1
  51. package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route.js +1 -1
  52. package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  53. package/app/.next/server/app/api/cloud/auth/route.js +1 -1
  54. package/app/.next/server/app/api/cloud/auth/route.js.nft.json +1 -1
  55. package/app/.next/server/app/api/cloud/credentials/update/route.js +1 -1
  56. package/app/.next/server/app/api/cloud/credentials/update/route.js.nft.json +1 -1
  57. package/app/.next/server/app/api/cloud/model/resolve/route.js +1 -1
  58. package/app/.next/server/app/api/cloud/model/resolve/route.js.nft.json +1 -1
  59. package/app/.next/server/app/api/cloud/models/alias/route.js +1 -1
  60. package/app/.next/server/app/api/cloud/models/alias/route.js.nft.json +1 -1
  61. package/app/.next/server/app/api/combos/[id]/route.js +1 -1
  62. package/app/.next/server/app/api/combos/[id]/route.js.nft.json +1 -1
  63. package/app/.next/server/app/api/combos/route.js +1 -1
  64. package/app/.next/server/app/api/combos/route.js.nft.json +1 -1
  65. package/app/.next/server/app/api/combos/test/route.js +1 -1
  66. package/app/.next/server/app/api/combos/test/route.js.nft.json +1 -1
  67. package/app/.next/server/app/api/db-backups/export/route.js +1 -1
  68. package/app/.next/server/app/api/db-backups/export/route.js.nft.json +1 -1
  69. package/app/.next/server/app/api/db-backups/import/route.js +1 -1
  70. package/app/.next/server/app/api/db-backups/import/route.js.nft.json +1 -1
  71. package/app/.next/server/app/api/db-backups/route.js +1 -1
  72. package/app/.next/server/app/api/db-backups/route.js.nft.json +1 -1
  73. package/app/.next/server/app/api/keys/[id]/route.js +1 -1
  74. package/app/.next/server/app/api/keys/[id]/route.js.nft.json +1 -1
  75. package/app/.next/server/app/api/keys/route.js +1 -1
  76. package/app/.next/server/app/api/keys/route.js.nft.json +1 -1
  77. package/app/.next/server/app/api/logs/detail/route.js +1 -1
  78. package/app/.next/server/app/api/logs/detail/route.js.nft.json +1 -1
  79. package/app/.next/server/app/api/models/alias/route.js +1 -1
  80. package/app/.next/server/app/api/models/alias/route.js.nft.json +1 -1
  81. package/app/.next/server/app/api/models/openrouter-catalog/route.js +1 -1
  82. package/app/.next/server/app/api/models/openrouter-catalog/route.js.nft.json +1 -1
  83. package/app/.next/server/app/api/models/route.js +1 -1
  84. package/app/.next/server/app/api/models/route.js.nft.json +1 -1
  85. package/app/.next/server/app/api/monitoring/health/route.js +1 -1
  86. package/app/.next/server/app/api/monitoring/health/route.js.nft.json +1 -1
  87. package/app/.next/server/app/api/oauth/[provider]/[action]/route.js +1 -1
  88. package/app/.next/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  89. package/app/.next/server/app/api/oauth/cursor/auto-import/route.js +1 -1
  90. package/app/.next/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  91. package/app/.next/server/app/api/oauth/cursor/import/route.js +1 -1
  92. package/app/.next/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  93. package/app/.next/server/app/api/oauth/kiro/auto-import/route.js +1 -1
  94. package/app/.next/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
  95. package/app/.next/server/app/api/oauth/kiro/import/route.js +1 -1
  96. package/app/.next/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  97. package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
  98. package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  99. package/app/.next/server/app/api/pricing/models/route.js +1 -1
  100. package/app/.next/server/app/api/pricing/models/route.js.nft.json +1 -1
  101. package/app/.next/server/app/api/pricing/route.js +1 -1
  102. package/app/.next/server/app/api/pricing/route.js.nft.json +1 -1
  103. package/app/.next/server/app/api/provider-models/route.js +2 -2
  104. package/app/.next/server/app/api/provider-models/route.js.nft.json +1 -1
  105. package/app/.next/server/app/api/provider-nodes/[id]/route.js +1 -1
  106. package/app/.next/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  107. package/app/.next/server/app/api/provider-nodes/route.js +1 -1
  108. package/app/.next/server/app/api/provider-nodes/route.js.nft.json +1 -1
  109. package/app/.next/server/app/api/providers/[id]/models/route.js +1 -1
  110. package/app/.next/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  111. package/app/.next/server/app/api/providers/[id]/refresh/route.js +1 -1
  112. package/app/.next/server/app/api/providers/[id]/refresh/route.js.nft.json +1 -1
  113. package/app/.next/server/app/api/providers/[id]/route.js +1 -1
  114. package/app/.next/server/app/api/providers/[id]/route.js.nft.json +1 -1
  115. package/app/.next/server/app/api/providers/[id]/test/route.js +1 -1
  116. package/app/.next/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  117. package/app/.next/server/app/api/providers/client/route.js +1 -1
  118. package/app/.next/server/app/api/providers/client/route.js.nft.json +1 -1
  119. package/app/.next/server/app/api/providers/route.js +1 -1
  120. package/app/.next/server/app/api/providers/route.js.nft.json +1 -1
  121. package/app/.next/server/app/api/providers/test-batch/route.js +2 -2
  122. package/app/.next/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  123. package/app/.next/server/app/api/providers/validate/route.js +1 -1
  124. package/app/.next/server/app/api/providers/validate/route.js.nft.json +1 -1
  125. package/app/.next/server/app/api/rate-limits/route.js +1 -1
  126. package/app/.next/server/app/api/rate-limits/route.js.nft.json +1 -1
  127. package/app/.next/server/app/api/resilience/route.js +1 -1
  128. package/app/.next/server/app/api/resilience/route.js.nft.json +1 -1
  129. package/app/.next/server/app/api/search/providers/route.js +1 -1
  130. package/app/.next/server/app/api/search/providers/route.js.nft.json +1 -1
  131. package/app/.next/server/app/api/search/stats/route.js +1 -1
  132. package/app/.next/server/app/api/search/stats/route.js.nft.json +1 -1
  133. package/app/.next/server/app/api/settings/codex-service-tier/route.js +1 -1
  134. package/app/.next/server/app/api/settings/codex-service-tier/route.js.nft.json +1 -1
  135. package/app/.next/server/app/api/settings/combo-defaults/route.js +1 -1
  136. package/app/.next/server/app/api/settings/combo-defaults/route.js.nft.json +1 -1
  137. package/app/.next/server/app/api/settings/proxies/assignments/route.js +2 -2
  138. package/app/.next/server/app/api/settings/proxies/bulk-assign/route.js +2 -2
  139. package/app/.next/server/app/api/settings/proxies/route.js +1 -1
  140. package/app/.next/server/app/api/settings/proxy/route.js +2 -2
  141. package/app/.next/server/app/api/settings/require-login/route.js +1 -1
  142. package/app/.next/server/app/api/settings/require-login/route.js.nft.json +1 -1
  143. package/app/.next/server/app/api/settings/route.js +1 -1
  144. package/app/.next/server/app/api/settings/route.js.nft.json +1 -1
  145. package/app/.next/server/app/api/settings/system-prompt/route.js +1 -1
  146. package/app/.next/server/app/api/settings/system-prompt/route.js.nft.json +1 -1
  147. package/app/.next/server/app/api/settings/thinking-budget/route.js +1 -1
  148. package/app/.next/server/app/api/settings/thinking-budget/route.js.nft.json +1 -1
  149. package/app/.next/server/app/api/sync/cloud/route.js +1 -1
  150. package/app/.next/server/app/api/sync/cloud/route.js.nft.json +1 -1
  151. package/app/.next/server/app/api/sync/initialize/route.js +1 -1
  152. package/app/.next/server/app/api/sync/initialize/route.js.nft.json +1 -1
  153. package/app/.next/server/app/api/system/version/route.js +1 -1
  154. package/app/.next/server/app/api/system/version/route.js.nft.json +1 -1
  155. package/app/.next/server/app/api/translator/send/route.js +1 -1
  156. package/app/.next/server/app/api/translator/send/route.js.nft.json +1 -1
  157. package/app/.next/server/app/api/translator/translate/route.js +1 -1
  158. package/app/.next/server/app/api/translator/translate/route.js.nft.json +1 -1
  159. package/app/.next/server/app/api/usage/quota/route.js +1 -1
  160. package/app/.next/server/app/api/usage/quota/route.js.nft.json +1 -1
  161. package/app/.next/server/app/api/v1/management/proxies/assignments/route.js +1 -1
  162. package/app/.next/server/app/api/v1/management/proxies/assignments/route.js.nft.json +1 -1
  163. package/app/.next/server/app/api/v1/management/proxies/bulk-assign/route.js +1 -1
  164. package/app/.next/server/app/api/v1/management/proxies/bulk-assign/route.js.nft.json +1 -1
  165. package/app/.next/server/app/api/v1/management/proxies/health/route.js +1 -1
  166. package/app/.next/server/app/api/v1/management/proxies/health/route.js.nft.json +1 -1
  167. package/app/.next/server/app/api/v1/management/proxies/route.js +1 -1
  168. package/app/.next/server/app/api/v1/management/proxies/route.js.nft.json +1 -1
  169. package/app/.next/server/app/api/v1/models/route.js +1 -1
  170. package/app/.next/server/app/api/v1/models/route.js.nft.json +1 -1
  171. package/app/.next/server/app/api/v1/route.js +1 -1
  172. package/app/.next/server/app/api/v1/route.js.nft.json +1 -1
  173. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  174. package/app/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  175. package/app/.next/server/app/forbidden/page_client-reference-manifest.js +1 -1
  176. package/app/.next/server/app/forgot-password/page_client-reference-manifest.js +1 -1
  177. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  178. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  179. package/app/.next/server/app/maintenance/page_client-reference-manifest.js +1 -1
  180. package/app/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  181. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  182. package/app/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  183. package/app/.next/server/app/status/page_client-reference-manifest.js +1 -1
  184. package/app/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  185. package/app/.next/server/chunks/[root-of-the-server]__09c944b3._.js +1 -1
  186. package/app/.next/server/chunks/[root-of-the-server]__134baf4c._.js +1 -1
  187. package/app/.next/server/chunks/[root-of-the-server]__179c5303._.js +1 -1
  188. package/app/.next/server/chunks/[root-of-the-server]__237e5042._.js +1 -1
  189. package/app/.next/server/chunks/[root-of-the-server]__46fad57a._.js +1 -1
  190. package/app/.next/server/chunks/[root-of-the-server]__784fb7c5._.js +1 -1
  191. package/app/.next/server/chunks/[root-of-the-server]__7d9b23e7._.js +1 -1
  192. package/app/.next/server/chunks/[root-of-the-server]__80e3bfc3._.js +2 -2
  193. package/app/.next/server/chunks/[root-of-the-server]__84e445b2._.js +1 -1
  194. package/app/.next/server/chunks/[root-of-the-server]__92cb0def._.js +1 -1
  195. package/app/.next/server/chunks/[root-of-the-server]__9bbd49c8._.js +1 -1
  196. package/app/.next/server/chunks/[root-of-the-server]__a630d6ef._.js +5 -5
  197. package/app/.next/server/chunks/[root-of-the-server]__add0a68c._.js +1 -1
  198. package/app/.next/server/chunks/[root-of-the-server]__c393c81f._.js +1 -1
  199. package/app/.next/server/chunks/[root-of-the-server]__c8e3c8a9._.js +50 -0
  200. package/app/.next/server/chunks/[root-of-the-server]__cd42b732._.js +1 -1
  201. package/app/.next/server/chunks/[root-of-the-server]__d4563e10._.js +1 -1
  202. package/app/.next/server/chunks/[root-of-the-server]__db2f9fe0._.js +1 -1
  203. package/app/.next/server/chunks/[root-of-the-server]__e27a89bd._.js +1 -1
  204. package/app/.next/server/chunks/[root-of-the-server]__e56edf04._.js +1 -1
  205. package/app/.next/server/chunks/[root-of-the-server]__e6e94646._.js +1 -1
  206. package/app/.next/server/chunks/[root-of-the-server]__eb98039a._.js +1 -1
  207. package/app/.next/server/chunks/[root-of-the-server]__f31b4656._.js +1 -1
  208. package/app/.next/server/chunks/_05c48915._.js +1 -1
  209. package/app/.next/server/chunks/_1244636c._.js +2 -2
  210. package/app/.next/server/chunks/_14963fed._.js +1 -1
  211. package/app/.next/server/chunks/_1717e651._.js +1 -1
  212. package/app/.next/server/chunks/_2115d8de._.js +1 -1
  213. package/app/.next/server/chunks/_3ac953eb._.js +1 -1
  214. package/app/.next/server/chunks/_4b8fd853._.js +1 -1
  215. package/app/.next/server/chunks/_5bbb2e7a._.js +1 -1
  216. package/app/.next/server/chunks/_68683848._.js +1 -1
  217. package/app/.next/server/chunks/_c05b9de3._.js +1 -1
  218. package/app/.next/server/chunks/_c795fc74._.js +1 -1
  219. package/app/.next/server/chunks/_ee7b7859._.js +1 -1
  220. package/app/.next/server/chunks/_ee9b677b._.js +1 -1
  221. package/app/.next/server/chunks/open-sse_cf4d5692._.js +1 -1
  222. package/app/.next/server/chunks/open-sse_config_constants_ts_9583de19._.js +1 -1
  223. package/app/.next/server/chunks/open-sse_services_826884e1._.js +2 -1
  224. package/app/.next/server/chunks/open-sse_translator_index_ts_f5fd0821._.js +2 -2
  225. package/app/.next/server/chunks/src_lib_localDb_ts_83220848._.js +1 -1
  226. package/app/.next/server/chunks/src_shared_validation_schemas_ts_4e63863a._.js +1 -1
  227. package/app/.next/server/chunks/ssr/[root-of-the-server]__9affb65e._.js +1 -1
  228. package/app/.next/server/chunks/ssr/[root-of-the-server]__a6942102._.js +1 -1
  229. package/app/.next/server/chunks/ssr/src_9197fb9b._.js +2 -2
  230. package/app/.next/server/chunks/ssr/src_d3225e36._.js +1 -1
  231. package/app/.next/server/chunks/ssr/src_i18n_messages_en_json_c3d5c412._.js +1 -1
  232. package/app/.next/server/chunks/ssr/src_i18n_messages_zh-CN_json_f4112d90._.js +1 -1
  233. package/app/.next/server/chunks/ssr/src_lib_initCloudSync_ts_982b9d4d._.js +1 -1
  234. package/app/.next/server/pages/500.html +2 -2
  235. package/app/.next/server/server-reference-manifest.js +1 -1
  236. package/app/.next/server/server-reference-manifest.json +1 -1
  237. package/app/.next/static/chunks/1042694db0c08f1f.css +1 -0
  238. package/app/.next/static/chunks/{0f71d7fbf89bb737.js → 34569b4e9d93c0ad.js} +2 -2
  239. package/app/.next/static/chunks/{1e206030e7793015.js → 353ef826fbae436d.js} +1 -1
  240. package/app/.next/static/chunks/91761ba00c702cff.js +1 -0
  241. package/app/CHANGELOG.md +56 -0
  242. package/app/docs/openapi.yaml +1 -1
  243. package/app/open-sse/config/constants.ts +3 -3
  244. package/app/open-sse/handlers/chatCore.ts +6 -2
  245. package/app/open-sse/services/comboAgentMiddleware.ts +9 -1
  246. package/app/open-sse/services/roleNormalizer.ts +14 -19
  247. package/app/open-sse/translator/index.ts +27 -3
  248. package/app/package-lock.json +2 -2
  249. package/app/package.json +1 -1
  250. package/app/src/app/(dashboard)/dashboard/cli-tools/CLIToolsPageClient.tsx +12 -0
  251. package/app/src/app/(dashboard)/dashboard/cli-tools/components/AntigravityToolCard.tsx +5 -5
  252. package/app/src/app/(dashboard)/dashboard/providers/[id]/page.tsx +381 -62
  253. package/app/src/app/api/provider-models/route.ts +47 -6
  254. package/app/src/i18n/messages/en.json +10 -0
  255. package/app/src/i18n/messages/zh-CN.json +10 -0
  256. package/app/src/lib/db/models.ts +130 -13
  257. package/app/src/lib/localDb.ts +5 -0
  258. package/app/src/shared/constants/cliTools.ts +2 -2
  259. package/app/src/shared/validation/schemas.ts +1 -0
  260. package/app/tests/e2e/providers-bailian-coding-plan.spec.ts +14 -0
  261. package/package.json +1 -1
  262. package/app/.next/server/chunks/[root-of-the-server]__3972de72._.js +0 -50
  263. package/app/.next/static/chunks/af071ff826ecff1b.css +0 -1
  264. package/app/.next/static/chunks/d19ab4efcaddd1db.js +0 -1
  265. /package/app/.next/static/{Ys6bRJXPNt8j-MKOjvZwp → m9BrfW8GQTdaCjvX6OgP2}/_buildManifest.js +0 -0
  266. /package/app/.next/static/{Ys6bRJXPNt8j-MKOjvZwp → m9BrfW8GQTdaCjvX6OgP2}/_clientMiddlewareManifest.json +0 -0
  267. /package/app/.next/static/{Ys6bRJXPNt8j-MKOjvZwp → m9BrfW8GQTdaCjvX6OgP2}/_ssgManifest.js +0 -0
@@ -4,6 +4,8 @@ import {
4
4
  addCustomModel,
5
5
  removeCustomModel,
6
6
  updateCustomModel,
7
+ getModelCompatOverrides,
8
+ mergeModelCompatOverride,
7
9
  } from "@/lib/localDb";
8
10
  import { isAuthenticated } from "@/shared/utils/apiAuth";
9
11
  import { providerModelMutationSchema } from "@/shared/validation/schemas";
@@ -27,8 +29,9 @@ export async function GET(request) {
27
29
  const provider = searchParams.get("provider");
28
30
 
29
31
  const models = provider ? await getCustomModels(provider) : await getAllCustomModels();
32
+ const modelCompatOverrides = provider ? getModelCompatOverrides(provider) : [];
30
33
 
31
- return Response.json({ models });
34
+ return Response.json({ models, modelCompatOverrides });
32
35
  } catch (error) {
33
36
  return Response.json(
34
37
  { error: { message: error.message, type: "server_error" } },
@@ -113,17 +116,55 @@ export async function PUT(request) {
113
116
  return Response.json({ error: validation.error }, { status: 400 });
114
117
  }
115
118
 
116
- const { provider, modelId, modelName, apiFormat, supportedEndpoints, normalizeToolCallId } =
117
- validation.data;
118
-
119
- const model = await updateCustomModel(provider, modelId, {
119
+ const {
120
+ provider,
121
+ modelId,
120
122
  modelName,
121
123
  apiFormat,
122
124
  supportedEndpoints,
123
125
  normalizeToolCallId,
124
- });
126
+ preserveOpenAIDeveloperRole,
127
+ } = validation.data;
128
+
129
+ const raw = rawBody as Record<string, unknown>;
130
+ const updates: Record<string, unknown> = {};
131
+ if ("modelName" in raw) updates.modelName = modelName;
132
+ if ("apiFormat" in raw) updates.apiFormat = apiFormat;
133
+ if ("supportedEndpoints" in raw) updates.supportedEndpoints = supportedEndpoints;
134
+ if ("normalizeToolCallId" in raw) updates.normalizeToolCallId = normalizeToolCallId;
135
+ if ("preserveOpenAIDeveloperRole" in raw)
136
+ updates.preserveOpenAIDeveloperRole = preserveOpenAIDeveloperRole;
137
+
138
+ const model = await updateCustomModel(provider, modelId, updates);
125
139
 
126
140
  if (!model) {
141
+ const rawKeys = Object.keys(raw);
142
+ const compatOnly =
143
+ rawKeys.length > 0 &&
144
+ rawKeys.every((k) =>
145
+ ["provider", "modelId", "normalizeToolCallId", "preserveOpenAIDeveloperRole"].includes(k)
146
+ ) &&
147
+ ("normalizeToolCallId" in raw || "preserveOpenAIDeveloperRole" in raw);
148
+ if (compatOnly) {
149
+ const patch: {
150
+ normalizeToolCallId?: boolean;
151
+ preserveOpenAIDeveloperRole?: boolean;
152
+ } = {};
153
+ if ("normalizeToolCallId" in raw && typeof normalizeToolCallId === "boolean") {
154
+ patch.normalizeToolCallId = normalizeToolCallId;
155
+ }
156
+ if (
157
+ "preserveOpenAIDeveloperRole" in raw &&
158
+ typeof preserveOpenAIDeveloperRole === "boolean"
159
+ ) {
160
+ patch.preserveOpenAIDeveloperRole = preserveOpenAIDeveloperRole;
161
+ }
162
+ mergeModelCompatOverride(provider, modelId, patch);
163
+ return Response.json({
164
+ ok: true,
165
+ modelCompatOverrides: getModelCompatOverrides(provider),
166
+ });
167
+ }
127
168
  return Response.json(
128
169
  { error: { message: "Model not found", type: "not_found" } },
129
170
  { status: 404 }
@@ -1382,6 +1382,8 @@
1382
1382
  "addFirstConnectionHint": "Add your first connection to get started",
1383
1383
  "addConnection": "Add Connection",
1384
1384
  "availableModels": "Available Models",
1385
+ "builtInModels": "Built-in models",
1386
+ "builtInModelsHint": "Registry models for this provider. Use the pencil to set compatibility options.",
1385
1387
  "pageAutoRefresh": "Page will refresh automatically...",
1386
1388
  "statusDisabled": "disabled",
1387
1389
  "statusConnected": "connected",
@@ -1422,6 +1424,14 @@
1422
1424
  "openRouterModelPlaceholder": "anthropic/claude-3-opus",
1423
1425
  "customModels": "Custom Models",
1424
1426
  "customModelsHint": "Add model IDs not in the default list. These will be available for routing.",
1427
+ "normalizeToolCallIdLabel": "Normalize tool call IDs to 9 characters (e.g. Mistral)",
1428
+ "preserveDeveloperRoleLabel": "Keep OpenAI Responses developer role (do not map to system)",
1429
+ "compatAdjustmentsTitle": "Compatibility",
1430
+ "compatButtonLabel": "Compatibility",
1431
+ "compatToolIdShort": "Tool ID 9",
1432
+ "compatDeveloperShort": "Developer role",
1433
+ "compatDoNotPreserveDeveloper": "Do not preserve developer role",
1434
+ "compatBadgeNoPreserve": "No preserve",
1425
1435
  "modelId": "Model ID",
1426
1436
  "customModelPlaceholder": "e.g. gpt-4.5-turbo",
1427
1437
  "loading": "Loading...",
@@ -1382,6 +1382,8 @@
1382
1382
  "addFirstConnectionHint": "添加您的第一个连接以开始使用",
1383
1383
  "addConnection": "添加连接",
1384
1384
  "availableModels": "可用模型",
1385
+ "builtInModels": "内置模型",
1386
+ "builtInModelsHint": "该提供商的注册表模型。点击铅笔可设置兼容选项。",
1385
1387
  "pageAutoRefresh": "页面会自动刷新...",
1386
1388
  "statusDisabled": "已禁用",
1387
1389
  "statusConnected": "已连接",
@@ -1422,6 +1424,14 @@
1422
1424
  "openRouterModelPlaceholder": "anthropic/claude-3-opus",
1423
1425
  "customModels": "自定义模型",
1424
1426
  "customModelsHint": "添加默认列表中没有的模型 ID,这些模型也能参与路由。",
1427
+ "normalizeToolCallIdLabel": "将工具调用 ID 规范为 9 位(如 Mistral)",
1428
+ "preserveDeveloperRoleLabel": "保留 Responses 的 developer 角色(不映射为 system)",
1429
+ "compatAdjustmentsTitle": "兼容性",
1430
+ "compatButtonLabel": "兼容性",
1431
+ "compatToolIdShort": "工具 ID 9 位",
1432
+ "compatDeveloperShort": "Developer 角色",
1433
+ "compatDoNotPreserveDeveloper": "不保留 developer 角色",
1434
+ "compatBadgeNoPreserve": "不保留",
1425
1435
  "modelId": "模型 ID",
1426
1436
  "customModelPlaceholder": "例如:gpt-4.5-turbo",
1427
1437
  "loading": "正在加载...",
@@ -7,6 +7,82 @@ import { backupDbFile } from "./backup";
7
7
 
8
8
  type JsonRecord = Record<string, unknown>;
9
9
 
10
+ /** Built-in / alias models: tool-call + developer-role flags without a full custom row */
11
+ const MODEL_COMPAT_NAMESPACE = "modelCompatOverrides";
12
+
13
+ export type ModelCompatOverride = {
14
+ id: string;
15
+ normalizeToolCallId?: boolean;
16
+ preserveOpenAIDeveloperRole?: boolean;
17
+ };
18
+
19
+ function readCompatList(providerId: string): ModelCompatOverride[] {
20
+ const db = getDbInstance();
21
+ const row = db
22
+ .prepare("SELECT value FROM key_value WHERE namespace = ? AND key = ?")
23
+ .get(MODEL_COMPAT_NAMESPACE, providerId);
24
+ const value = getKeyValue(row).value;
25
+ if (!value) return [];
26
+ try {
27
+ const parsed = JSON.parse(value);
28
+ return Array.isArray(parsed) ? parsed : [];
29
+ } catch {
30
+ return [];
31
+ }
32
+ }
33
+
34
+ function writeCompatList(providerId: string, list: ModelCompatOverride[]) {
35
+ const db = getDbInstance();
36
+ if (list.length === 0) {
37
+ db.prepare("DELETE FROM key_value WHERE namespace = ? AND key = ?").run(
38
+ MODEL_COMPAT_NAMESPACE,
39
+ providerId
40
+ );
41
+ } else {
42
+ db.prepare("INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES (?, ?, ?)").run(
43
+ MODEL_COMPAT_NAMESPACE,
44
+ providerId,
45
+ JSON.stringify(list)
46
+ );
47
+ }
48
+ backupDbFile("pre-write");
49
+ }
50
+
51
+ export function getModelCompatOverrides(providerId: string): ModelCompatOverride[] {
52
+ return readCompatList(providerId);
53
+ }
54
+
55
+ export function mergeModelCompatOverride(
56
+ providerId: string,
57
+ modelId: string,
58
+ patch: Partial<Pick<ModelCompatOverride, "normalizeToolCallId" | "preserveOpenAIDeveloperRole">>
59
+ ) {
60
+ const list = readCompatList(providerId);
61
+ const idx = list.findIndex((e) => e.id === modelId);
62
+ const prev = idx >= 0 ? { ...list[idx] } : { id: modelId };
63
+ const next: ModelCompatOverride = { ...prev, id: modelId };
64
+ if ("normalizeToolCallId" in patch) {
65
+ if (patch.normalizeToolCallId) next.normalizeToolCallId = true;
66
+ else delete next.normalizeToolCallId;
67
+ }
68
+ if ("preserveOpenAIDeveloperRole" in patch) {
69
+ next.preserveOpenAIDeveloperRole = Boolean(patch.preserveOpenAIDeveloperRole);
70
+ }
71
+ const filtered = list.filter((e) => e.id !== modelId);
72
+ const hasPreserveFlag = Object.prototype.hasOwnProperty.call(next, "preserveOpenAIDeveloperRole");
73
+ if (next.normalizeToolCallId || hasPreserveFlag) {
74
+ filtered.push(next);
75
+ }
76
+ writeCompatList(providerId, filtered);
77
+ }
78
+
79
+ export function removeModelCompatOverride(providerId: string, modelId: string) {
80
+ const list = readCompatList(providerId);
81
+ const filtered = list.filter((e) => e.id !== modelId);
82
+ if (filtered.length === list.length) return;
83
+ writeCompatList(providerId, filtered);
84
+ }
85
+
10
86
  function asRecord(value: unknown): JsonRecord {
11
87
  return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {};
12
88
  }
@@ -174,11 +250,16 @@ export async function removeCustomModel(providerId, modelId) {
174
250
  );
175
251
  }
176
252
 
253
+ removeModelCompatOverride(providerId, modelId);
177
254
  backupDbFile("pre-write");
178
255
  return true;
179
256
  }
180
257
 
181
- export async function updateCustomModel(providerId, modelId, updates = {}) {
258
+ export async function updateCustomModel(
259
+ providerId: string,
260
+ modelId: string,
261
+ updates: Record<string, unknown> = {}
262
+ ) {
182
263
  const db = getDbInstance();
183
264
  const row = db
184
265
  .prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?")
@@ -203,6 +284,9 @@ export async function updateCustomModel(providerId, modelId, updates = {}) {
203
284
  ...(updates.normalizeToolCallId !== undefined
204
285
  ? { normalizeToolCallId: Boolean(updates.normalizeToolCallId) }
205
286
  : {}),
287
+ ...(updates.preserveOpenAIDeveloperRole !== undefined
288
+ ? { preserveOpenAIDeveloperRole: Boolean(updates.preserveOpenAIDeveloperRole) }
289
+ : {}),
206
290
  };
207
291
 
208
292
  models[index] = next;
@@ -216,24 +300,57 @@ export async function updateCustomModel(providerId, modelId, updates = {}) {
216
300
  return next;
217
301
  }
218
302
 
219
- /**
220
- * Whether the given provider/model has "normalize tool call id" (9-char Mistral-style) enabled.
221
- * Only custom models can have this set; returns false for built-in models.
222
- */
223
- export function getModelNormalizeToolCallId(providerId: string, modelId: string): boolean {
303
+ /** Single custom model row from key_value customModels, or null */
304
+ function getCustomModelRow(providerId: string, modelId: string): JsonRecord | null {
224
305
  const db = getDbInstance();
225
306
  const row = db
226
307
  .prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?")
227
308
  .get(providerId);
228
309
  const value = getKeyValue(row).value;
229
- if (!value) return false;
230
- let models: { id: string; normalizeToolCallId?: boolean }[];
310
+ if (!value) return null;
231
311
  try {
232
- models = JSON.parse(value);
312
+ const models = JSON.parse(value) as unknown;
313
+ if (!Array.isArray(models)) return null;
314
+ const m = models.find((x: unknown) => {
315
+ if (!x || typeof x !== "object" || Array.isArray(x)) return false;
316
+ return (x as { id?: string }).id === modelId;
317
+ }) as JsonRecord | undefined;
318
+ return m ?? null;
233
319
  } catch {
234
- return false;
320
+ return null;
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Whether the given provider/model has "normalize tool call id" (9-char Mistral-style) enabled.
326
+ * Custom model row wins; otherwise {@link getModelCompatOverrides}.
327
+ */
328
+ export function getModelNormalizeToolCallId(providerId: string, modelId: string): boolean {
329
+ const m = getCustomModelRow(providerId, modelId);
330
+ if (m) return Boolean(m.normalizeToolCallId);
331
+ const co = readCompatList(providerId).find((e) => e.id === modelId);
332
+ return Boolean(co?.normalizeToolCallId);
333
+ }
334
+
335
+ /**
336
+ * Explicit preserve-openai-developer preference for this provider/model.
337
+ * `undefined` = unset → routing keeps legacy default (preserve developer for OpenAI format).
338
+ * `false` = map developer → system (e.g. MiniMax). `true` = keep developer.
339
+ */
340
+ export function getModelPreserveOpenAIDeveloperRole(
341
+ providerId: string,
342
+ modelId: string
343
+ ): boolean | undefined {
344
+ const m = getCustomModelRow(providerId, modelId);
345
+ if (m) {
346
+ if (Object.prototype.hasOwnProperty.call(m, "preserveOpenAIDeveloperRole")) {
347
+ return Boolean(m.preserveOpenAIDeveloperRole);
348
+ }
349
+ return undefined;
350
+ }
351
+ const co = readCompatList(providerId).find((e) => e.id === modelId);
352
+ if (co && Object.prototype.hasOwnProperty.call(co, "preserveOpenAIDeveloperRole")) {
353
+ return Boolean(co.preserveOpenAIDeveloperRole);
235
354
  }
236
- if (!Array.isArray(models)) return false;
237
- const m = models.find((x: { id: string }) => x.id === modelId);
238
- return Boolean(m?.normalizeToolCallId);
355
+ return undefined;
239
356
  }
@@ -41,6 +41,11 @@ export {
41
41
  addCustomModel,
42
42
  removeCustomModel,
43
43
  updateCustomModel,
44
+ getModelCompatOverrides,
45
+ mergeModelCompatOverride,
46
+ removeModelCompatOverride,
47
+ getModelNormalizeToolCallId,
48
+ getModelPreserveOpenAIDeveloperRole,
44
49
  } from "./db/models";
45
50
 
46
51
  export {
@@ -193,8 +193,8 @@ export const CLI_TOOLS = {
193
193
  image: "/providers/kiro.png",
194
194
  icon: "psychology_alt",
195
195
  color: "#FF6B35",
196
- description: "Amazon Kiro — AI-powered IDE",
197
- configType: "guide",
196
+ description: "Amazon Kiro — AI-powered IDE with MITM",
197
+ configType: "mitm",
198
198
  guideSteps: [
199
199
  { step: 1, title: "Open Kiro Settings", desc: "Go to Settings → AI Provider" },
200
200
  { step: 2, title: "Base URL", value: "{{baseUrl}}", copyable: true },
@@ -348,6 +348,7 @@ export const providerModelMutationSchema = z.object({
348
348
  apiFormat: z.enum(["chat-completions", "responses"]).default("chat-completions"),
349
349
  supportedEndpoints: z.array(z.enum(["chat", "embeddings", "images", "audio"])).default(["chat"]),
350
350
  normalizeToolCallId: z.boolean().optional(),
351
+ preserveOpenAIDeveloperRole: z.boolean().optional(),
351
352
  });
352
353
 
353
354
  const pricingFieldsSchema = z
@@ -63,6 +63,13 @@ test.describe("Bailian Coding Plan Provider", () => {
63
63
  const redirectedToLogin = page.url().includes("/login");
64
64
  test.skip(redirectedToLogin, "Authentication enabled without a login fixture.");
65
65
 
66
+ // Dismiss any pre-existing dialog/overlay that may appear on page load
67
+ const preExistingDialog = page.getByRole("dialog").first();
68
+ if (await preExistingDialog.isVisible({ timeout: 2000 }).catch(() => false)) {
69
+ await page.keyboard.press("Escape");
70
+ await preExistingDialog.waitFor({ state: "hidden", timeout: 3000 }).catch(() => {});
71
+ }
72
+
66
73
  const addKeyButton = page.getByRole("button", {
67
74
  name: /add.*api.*key|add.*key|add.*connection|connect/i,
68
75
  });
@@ -175,6 +182,13 @@ test.describe("Bailian Coding Plan Provider", () => {
175
182
  const redirectedToLogin = page.url().includes("/login");
176
183
  test.skip(redirectedToLogin, "Authentication enabled without a login fixture.");
177
184
 
185
+ // Dismiss any pre-existing dialog/overlay that may appear on page load
186
+ const preExistingDialog = page.getByRole("dialog").first();
187
+ if (await preExistingDialog.isVisible({ timeout: 2000 }).catch(() => false)) {
188
+ await page.keyboard.press("Escape");
189
+ await preExistingDialog.waitFor({ state: "hidden", timeout: 3000 }).catch(() => {});
190
+ }
191
+
178
192
  const addKeyButton = page.getByRole("button", {
179
193
  name: /add.*api.*key|add.*key|add.*connection|connect/i,
180
194
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.8.4",
3
+ "version": "2.8.6",
4
4
  "description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,50 +0,0 @@
1
- module.exports=[878947,e=>{"use strict";var t=e.i(828059);let r=(0,t.generateModels)(),n=(0,t.generateAliasMap)();function a(e){return r[e]||[]}function i(e){let t=r[e];return t?.[0]?.id||null}function o(e,t,n=new Set){if(n.has(e))return!0;let a=r[e];return!!a&&a.some(e=>e.id===t)}function l(e,t){let n=r[e];if(!n)return t;let a=n.find(e=>e.id===t);return a?.name||t}function s(e,t){let n=r[e];if(!n)return null;let a=n.find(e=>e.id===t);return a?.targetFormat||null}function c(e){return r[n[e]||e]||[]}e.s(["PROVIDER_ID_TO_ALIAS",0,n,"PROVIDER_MODELS",0,r,"findModelName",()=>l,"getDefaultModel",()=>i,"getModelTargetFormat",()=>s,"getModelsByProviderId",()=>c,"getProviderModels",()=>a,"isValidModel",()=>o])},403122,e=>{"use strict";class t{cache=new Map;ttlMs;constructor(e){this.ttlMs=e}get(e){let t=this.cache.get(e);if(t)return Date.now()>t.expiresAt?void this.cache.delete(e):t.value}set(e,t){this.cache.set(e,{value:t,expiresAt:Date.now()+this.ttlMs})}invalidate(e){e?this.cache.delete(e):this.cache.clear()}}let r=new t(5e3),n=new t(3e4),a=new t(5e3);async function i(){let t=r.get("settings");if(t)return t;let{getSettings:n}=await e.A(606102),a=await n();return r.set("settings",a),a}async function o(){let t=n.get("pricing");if(t)return t;let{getPricing:r}=await e.A(606102),a=await r();return n.set("pricing",a),a}async function l(t){if(t&&Object.keys(t).length>0){let{getProviderConnections:r}=await e.A(789543);return r(t)}let r=a.get("all");if(r)return r;let{getProviderConnections:n}=await e.A(789543),i=await n();return a.set("all",i),i}function s(e){e&&"settings"!==e||r.invalidate(),e&&"pricing"!==e||n.invalidate(),e&&"connections"!==e||a.invalidate()}e.s(["getCachedPricing",()=>o,"getCachedProviderConnections",()=>l,"getCachedSettings",()=>i,"invalidateDbCache",()=>s])},792509,(e,t,r)=>{t.exports=e.x("url",()=>require("url"))},785148,(e,t,r)=>{t.exports=e.x("better-sqlite3",()=>require("better-sqlite3"))},814747,(e,t,r)=>{t.exports=e.x("path",()=>require("path"))},522734,(e,t,r)=>{t.exports=e.x("fs",()=>require("fs"))},446786,(e,t,r)=>{t.exports=e.x("os",()=>require("os"))},256770,e=>{"use strict";var t=e.i(814747),r=e.i(446786);let n="omniroute";function a(){try{return r.default.homedir()}catch{return process.cwd()}}function i(e){if("string"!=typeof e)return null;let r=e.trim();return r?t.default.resolve(r):null}function o(){return t.default.join(a(),`.${n}`)}function l({isCloud:e=!1}={}){let r;if(e)return"/tmp";let s=i(process.env.DATA_DIR);return s?s:(a(),(r=i(process.env.XDG_CONFIG_HOME))?t.default.join(r,n):o())}function s(e,r){return!!e&&!!r&&t.default.resolve(e)===t.default.resolve(r)}e.s(["getLegacyDotDataDir",()=>o,"isSamePath",()=>s,"resolveDataDir",()=>l])},666680,(e,t,r)=>{t.exports=e.x("node:crypto",()=>require("node:crypto"))},935050,91429,e=>{"use strict";var t=e.i(785148),r=e.i(814747),n=e.i(522734),a=e.i(157763);let i=new Set;function o(e){i.add(e)}function l(){for(let e of i)try{e()}catch(e){console.warn("[DB] Failed to reset module state:",e)}}e.s(["registerDbStateResetter",()=>o,"resetAllDbModuleState",()=>l],91429);let s=0;function c(e="auto"){try{if(a.isBuildPhase||a.isCloud||!a.SQLITE_FILE||!n.default.existsSync(a.SQLITE_FILE))return null;let t=n.default.statSync(a.SQLITE_FILE);if(t.size<4096)return console.warn(`[DB] Backup SKIPPED — DB too small (${t.size}B)`),null;let i=Date.now();if("manual"!==e&&"pre-restore"!==e&&i-s<36e5)return null;s=i;let o=a.DB_BACKUPS_DIR||r.default.join(a.DATA_DIR,"db_backups");n.default.existsSync(o)||n.default.mkdirSync(o,{recursive:!0});let l=n.default.readdirSync(o).filter(e=>e.startsWith("db_")&&e.endsWith(".sqlite")).sort();if(l.length>0){let e=l[l.length-1],a=n.default.statSync(r.default.join(o,e));if(a.size>4096&&t.size<.5*a.size)return console.warn(`[DB] Backup SKIPPED — DB shrank from ${a.size}B to ${t.size}B`),null}let c=new Date().toISOString().replace(/[:.]/g,"-"),u=r.default.join(o,`db_${c}_${e}.sqlite`);(0,a.getDbInstance)().backup(u).then(()=>{console.log(`[DB] Backup created: ${u} (${t.size} bytes)`)}).catch(e=>{let t=e instanceof Error?e.message:String(e);console.error("[DB] Backup failed:",t)});let p=n.default.readdirSync(o).filter(e=>e.startsWith("db_")&&e.endsWith(".sqlite")).sort();for(;p.length>20;){let e=0,t=1/0;for(let a=0;a<p.length-1;a++)try{let i=n.default.statSync(r.default.join(o,p[a]));i.size<t&&(t=i.size,e=a)}catch{e=a;break}try{n.default.unlinkSync(r.default.join(o,p[e]))}catch{}p.splice(e,1)}return{filename:r.default.basename(u),size:t.size}}catch(e){return console.error("[DB] Backup failed:",e instanceof Error?e.message:String(e)),null}}async function u(){let e=a.DB_BACKUPS_DIR||r.default.join(a.DATA_DIR,"db_backups");try{if(!n.default.existsSync(e))return[];return n.default.readdirSync(e).filter(e=>e.startsWith("db_")&&e.endsWith(".sqlite")).sort().reverse().map(a=>{let i=r.default.join(e,a),o=n.default.statSync(i),l=a.match(/^db_(.+?)_([^.]+)\.sqlite$/),s=l?l[2]:"unknown",c=0;try{let e=new t.default(i,{readonly:!0}),r=e.prepare("SELECT COUNT(*) as cnt FROM provider_connections").get();c=r?.cnt||0,e.close()}catch{}return{id:a,filename:a,createdAt:o.mtime.toISOString(),size:o.size,reason:s,connectionCount:c}})}catch{return[]}}async function p(e){let i=a.DB_BACKUPS_DIR||r.default.join(a.DATA_DIR,"db_backups");if(!e.startsWith("db_")||!e.endsWith(".sqlite")||e.includes(r.default.sep)||e.includes("/"))throw Error("Invalid backup ID");let o=r.default.resolve(i,e);if(!o.startsWith(r.default.resolve(i)+r.default.sep)&&o!==r.default.resolve(i))throw Error("Invalid backup ID: path traversal detected");if(!n.default.existsSync(o))throw Error(`Backup not found: ${e}`);try{let e=new t.default(o,{readonly:!0}),r=e.pragma("integrity_check");if(e.close(),r[0]?.integrity_check!=="ok")throw Error("Backup integrity check failed")}catch(t){if(t instanceof Error&&"Backup integrity check failed"===t.message)throw t;let e=t instanceof Error?t.message:String(t);throw Error(`Backup file is corrupt: ${e}`)}s=0,c("pre-restore"),(0,a.resetDbInstance)(),l();let u=a.SQLITE_FILE;if(!u)throw Error("SQLITE_FILE is unavailable in local backup restore");for(let e of[u,`${u}-wal`,`${u}-shm`,`${u}-journal`])e&&n.default.existsSync(e)&&n.default.unlinkSync(e);n.default.copyFileSync(o,u);let p=(0,a.getDbInstance)(),d=p.prepare("SELECT COUNT(*) as cnt FROM provider_connections").get()?.cnt||0,f=p.prepare("SELECT COUNT(*) as cnt FROM provider_nodes").get()?.cnt||0,y=p.prepare("SELECT COUNT(*) as cnt FROM combos").get()?.cnt||0,E=p.prepare("SELECT COUNT(*) as cnt FROM api_keys").get()?.cnt||0;return console.log(`[DB] Restored backup: ${e} (${d} connections)`),{restored:!0,backupId:e,connectionCount:d,nodeCount:f,comboCount:y,apiKeyCount:E}}e.s(["backupDbFile",()=>c,"listDbBackups",()=>u,"restoreDbBackup",()=>p],935050)},542949,e=>{"use strict";var t=e.i(157763),r=e.i(935050);function n(e){let t=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return{key:"string"==typeof t.key?t.key:null,value:"string"==typeof t.value?t.value:null}}async function a(){let e=(0,t.getDbInstance)().prepare("SELECT key, value FROM key_value WHERE namespace = 'modelAliases'").all(),r={};for(let t of e){let{key:e,value:a}=n(t);e&&null!==a&&(r[e]=JSON.parse(a))}return r}async function i(e,n){(0,t.getDbInstance)().prepare("INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES ('modelAliases', ?, ?)").run(e,JSON.stringify(n)),(0,r.backupDbFile)("pre-write")}async function o(e){(0,t.getDbInstance)().prepare("DELETE FROM key_value WHERE namespace = 'modelAliases' AND key = ?").run(e),(0,r.backupDbFile)("pre-write")}async function l(e){let r=(0,t.getDbInstance)();if(e){let t=n(r.prepare("SELECT value FROM key_value WHERE namespace = 'mitmAlias' AND key = ?").get(e)).value;return t?JSON.parse(t):{}}let a=r.prepare("SELECT key, value FROM key_value WHERE namespace = 'mitmAlias'").all(),i={};for(let e of a){let{key:t,value:r}=n(e);t&&null!==r&&(i[t]=JSON.parse(r))}return i}async function s(e,n){(0,t.getDbInstance)().prepare("INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES ('mitmAlias', ?, ?)").run(e,JSON.stringify(n||{})),(0,r.backupDbFile)("pre-write")}async function c(e){let r=(0,t.getDbInstance)();if(e){let t=n(r.prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?").get(e)).value;return t?JSON.parse(t):[]}let a=r.prepare("SELECT key, value FROM key_value WHERE namespace = 'customModels'").all(),i={};for(let e of a){let{key:t,value:r}=n(e);t&&null!==r&&(i[t]=JSON.parse(r))}return i}async function u(){let e=(0,t.getDbInstance)().prepare("SELECT key, value FROM key_value WHERE namespace = 'customModels'").all(),r={};for(let t of e){let{key:e,value:a}=n(t);e&&null!==a&&(r[e]=JSON.parse(a))}return r}async function p(e,a,i,o="manual",l="chat-completions",s=["chat"]){let c=(0,t.getDbInstance)(),u=n(c.prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?").get(e)).value,d=u?JSON.parse(u):[],f=d.find(e=>e.id===a);if(f)return f;let y={id:a,name:i||a,source:o,apiFormat:l,supportedEndpoints:s};return d.push(y),c.prepare("INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES ('customModels', ?, ?)").run(e,JSON.stringify(d)),(0,r.backupDbFile)("pre-write"),y}async function d(e,a){let i=(0,t.getDbInstance)(),o=i.prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?").get(e);if(!o)return!1;let l=n(o).value;if(!l)return!1;let s=JSON.parse(l),c=s.length,u=s.filter(e=>e.id!==a);return u.length!==c&&(0===u.length?i.prepare("DELETE FROM key_value WHERE namespace = 'customModels' AND key = ?").run(e):i.prepare("UPDATE key_value SET value = ? WHERE namespace = 'customModels' AND key = ?").run(JSON.stringify(u),e),(0,r.backupDbFile)("pre-write"),!0)}async function f(e,a,i={}){let o=(0,t.getDbInstance)(),l=o.prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?").get(e);if(!l)return null;let s=n(l).value;if(!s)return null;let c=JSON.parse(s),u=c.findIndex(e=>e.id===a);if(-1===u)return null;let p=c[u],d={...p,...void 0!==i.modelName?{name:i.modelName||p.name}:{},...void 0!==i.apiFormat?{apiFormat:i.apiFormat}:{},...void 0!==i.supportedEndpoints?{supportedEndpoints:i.supportedEndpoints}:{},...void 0!==i.normalizeToolCallId?{normalizeToolCallId:!!i.normalizeToolCallId}:{}};return c[u]=d,o.prepare("UPDATE key_value SET value = ? WHERE namespace = 'customModels' AND key = ?").run(JSON.stringify(c),e),(0,r.backupDbFile)("pre-write"),d}function y(e,r){let a,i=n((0,t.getDbInstance)().prepare("SELECT value FROM key_value WHERE namespace = 'customModels' AND key = ?").get(e)).value;if(!i)return!1;try{a=JSON.parse(i)}catch{return!1}if(!Array.isArray(a))return!1;let o=a.find(e=>e.id===r);return!!o?.normalizeToolCallId}e.s(["addCustomModel",()=>p,"deleteModelAlias",()=>o,"getAllCustomModels",()=>u,"getCustomModels",()=>c,"getMitmAlias",()=>l,"getModelAliases",()=>a,"getModelNormalizeToolCallId",()=>y,"removeCustomModel",()=>d,"setMitmAliasAll",()=>s,"setModelAlias",()=>i,"updateCustomModel",()=>f])},151205,e=>{"use strict";var t=e.i(689960),r=e.i(157763),n=e.i(935050);function a(e){let t=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return"string"==typeof t.data?t.data:null}async function i(){return(0,r.getDbInstance)().prepare("SELECT data FROM combos ORDER BY name").all().map(e=>a(e)).filter(e=>null!==e).map(e=>JSON.parse(e))}async function o(e){let t=a((0,r.getDbInstance)().prepare("SELECT data FROM combos WHERE id = ?").get(e));return t?JSON.parse(t):null}async function l(e){let t=a((0,r.getDbInstance)().prepare("SELECT data FROM combos WHERE name = ?").get(e));return t?JSON.parse(t):null}async function s(e){let a=(0,r.getDbInstance)(),i=new Date().toISOString(),o={id:(0,t.v4)(),name:e.name,models:e.models||[],strategy:e.strategy||"priority",config:e.config||{},createdAt:i,updatedAt:i};return a.prepare("INSERT INTO combos (id, name, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)").run(o.id,o.name,JSON.stringify(o),i,i),(0,n.backupDbFile)("pre-write"),o}async function c(e,t){let i=(0,r.getDbInstance)(),o=i.prepare("SELECT data FROM combos WHERE id = ?").get(e);if(!o)return null;let l=a(o);if(!l)return null;let s={...JSON.parse(l),...t,updatedAt:new Date().toISOString()};return i.prepare("UPDATE combos SET name = ?, data = ?, updated_at = ? WHERE id = ?").run(s.name,JSON.stringify(s),s.updatedAt,e),(0,n.backupDbFile)("pre-write"),s}async function u(e){return 0!==(0,r.getDbInstance)().prepare("DELETE FROM combos WHERE id = ?").run(e).changes&&((0,n.backupDbFile)("pre-write"),!0)}e.s(["createCombo",()=>s,"deleteCombo",()=>u,"getComboById",()=>o,"getComboByName",()=>l,"getCombos",()=>i,"updateCombo",()=>c])},245272,e=>{"use strict";e.i(385498),e.i(542949),e.i(151205),e.i(125852),e.i(548941),e.i(954031),e.i(751183),e.i(935050),e.i(403122),e.s([])},751183,e=>{"use strict";var t=e.i(157763),r=e.i(403122),n=e.i(935050);let a=["litellm"],i=parseInt(process.env.PRICING_SYNC_INTERVAL||"86400",10),o=Number.isFinite(i)&&i>0?1e3*i:864e5,l=(process.env.PRICING_SYNC_SOURCES||"litellm").split(",").map(e=>e.trim()).filter(e=>a.includes(e)),s={openai:["openai","cx"],anthropic:["anthropic","cc"],vertex_ai:["gemini","gc"],"vertex_ai-anthropic_models":["anthropic"],google:["gemini","gc"],deepseek:["if"],groq:["groq"],together_ai:["openrouter"],bedrock:["kiro"],fireworks_ai:["fireworks"],cerebras:["cerebras"],nvidia_nim:["nvidia"],siliconflow:["siliconflow"]},c=null,u=null,p=0,d=o;async function f(){let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",{signal:AbortSignal.timeout(3e4)});if(!e.ok)throw Error(`LiteLLM fetch failed [${e.status}]: ${e.statusText}`);let t=await e.text();try{return JSON.parse(t)}catch{throw Error(`LiteLLM returned invalid JSON (${t.slice(0,100)}...)`)}}function y(e){let t={};for(let[r,n]of Object.entries(e)){if(n.mode&&!["chat","completion"].includes(n.mode)||!n.input_cost_per_token&&0!==n.input_cost_per_token)continue;let e={input:Math.round(1e3*(1e6*(n.input_cost_per_token||0)))/1e3,output:Math.round(1e3*(1e6*(n.output_cost_per_token||0)))/1e3};null!=n.cache_read_input_token_cost&&(e.cached=Math.round(1e6*n.cache_read_input_token_cost*1e3)/1e3),null!=n.cache_creation_input_token_cost&&(e.cache_creation=Math.round(1e6*n.cache_creation_input_token_cost*1e3)/1e3);let a=r.indexOf("/"),i=a>=0?r.slice(a+1):r,o=n.litellm_provider||"",l=s[o];if(l)for(let r of l)t[r]||(t[r]={}),t[r][i]=e;else o&&(t[o]||(t[o]={}),t[o][i]=e)}return t}function E(){let e=(0,t.getDbInstance)().prepare("SELECT key, value FROM key_value WHERE namespace = 'pricing_synced'").all(),r={};for(let t of e){let e=t&&"object"==typeof t?t:{},n="string"==typeof e.key?e.key:null,a="string"==typeof e.value?e.value:null;if(n&&null!==a)try{r[n]=JSON.parse(a)}catch{console.warn(`[PRICING_SYNC] Corrupted data for provider "${n}", skipping`)}}return r}function v(e){let a=(0,t.getDbInstance)(),i=a.prepare("DELETE FROM key_value WHERE namespace = 'pricing_synced'"),o=a.prepare("INSERT INTO key_value (namespace, key, value) VALUES ('pricing_synced', ?, ?)");a.transaction(()=>{for(let[t,r]of(i.run(),Object.entries(e)))o.run(t,JSON.stringify(r))})(),(0,n.backupDbFile)("pre-write"),(0,r.invalidateDbCache)("pricing")}function _(){(0,t.getDbInstance)().prepare("DELETE FROM key_value WHERE namespace = 'pricing_synced'").run(),(0,n.backupDbFile)("pre-write"),(0,r.invalidateDbCache)("pricing")}async function m(e){let t=e?.sources||l,r=e?.dryRun??!1,n=t.filter(e=>a.includes(e)),i=t.filter(e=>!a.includes(e));if(0===n.length){let e=a.join(", ");return{success:!1,modelCount:0,providerCount:0,source:t.join(","),dryRun:r,error:`No valid sources provided. Supported: ${e}. Invalid: ${i.join(", ")}`}}try{let e={};for(let t of n)if("litellm"===t){let t=await f(),r=y(t);for(let[t,n]of Object.entries(r))e[t]||(e[t]={}),Object.assign(e[t],n)}let t=Object.values(e).reduce((e,t)=>e+Object.keys(t).length,0),a=Object.keys(e).length;return r||(v(e),u=new Date().toISOString(),p=t),{success:!0,modelCount:t,providerCount:a,source:n.join(","),dryRun:r,...i.length>0?{warnings:[`Unknown sources ignored: ${i.join(", ")}`]}:{},...r?{data:e}:{}}}catch(n){let e=n instanceof Error?n.message:String(n);return console.warn("[PRICING_SYNC] Sync failed:",e),{success:!1,modelCount:0,providerCount:0,source:t.join(","),dryRun:r,error:e}}}function g(e){if(c)return;let t=e??o;d=t,console.log(`[PRICING_SYNC] Starting periodic sync every ${t/1e3}s`),m().then(e=>{e.success&&console.log(`[PRICING_SYNC] Initial sync complete: ${e.modelCount} models from ${e.providerCount} providers`)}).catch(e=>{console.warn("[PRICING_SYNC] Initial sync error:",e instanceof Error?e.message:e)}),c=setInterval(()=>{m().then(e=>{e.success&&console.log(`[PRICING_SYNC] Periodic sync complete: ${e.modelCount} models`)}).catch(e=>{console.warn("[PRICING_SYNC] Periodic sync error:",e instanceof Error?e.message:e)})},t)}function h(){c&&(clearInterval(c),c=null,console.log("[PRICING_SYNC] Periodic sync stopped"))}function S(){return{enabled:"true"===process.env.PRICING_SYNC_ENABLED,lastSync:u,lastSyncModelCount:p,nextSync:c&&u?new Date(new Date(u).getTime()+d).toISOString():null,intervalMs:d,sources:l}}async function k(){"true"!==process.env.PRICING_SYNC_ENABLED?console.log("[PRICING_SYNC] Disabled (set PRICING_SYNC_ENABLED=true to enable)"):g()}e.s(["clearSyncedPricing",()=>_,"fetchLiteLLMPricing",()=>f,"getSyncStatus",()=>S,"getSyncedPricing",()=>E,"initPricingSync",()=>k,"saveSyncedPricing",()=>v,"startPeriodicSync",()=>g,"stopPeriodicSync",()=>h,"syncPricingFromSources",()=>m,"transformToOmniRoute",()=>y])},254799,(e,t,r)=>{t.exports=e.x("crypto",()=>require("crypto"))},385498,e=>{"use strict";var t=e.i(689960),r=e.i(157763),n=e.i(935050),a=e.i(254799);let i="aes-256-gcm",o="enc:v1:",l=null;function s(){if(null!==l)return l;let e=process.env.STORAGE_ENCRYPTION_KEY;return e?l=(0,a.scryptSync)(e,"omniroute-field-encryption-v1",32):null}function c(){return!!process.env.STORAGE_ENCRYPTION_KEY}function u(e){if(!e||"string"!=typeof e)return e;let t=s();if(!t||e.startsWith(o))return e;let r=(0,a.randomBytes)(16),n=(0,a.createCipheriv)(i,t,r),l=n.update(e,"utf8","hex");l+=n.final("hex");let c=n.getAuthTag().toString("hex");return`${o}${r.toString("hex")}:${l}:${c}`}function p(e){if(!e||"string"!=typeof e||!e.startsWith(o))return e;let t=s();if(!t)return console.warn("[Encryption] Found encrypted data but STORAGE_ENCRYPTION_KEY is not set. Cannot decrypt."),e;let r=e.slice(o.length).split(":");if(3!==r.length)return console.error("[Encryption] Malformed encrypted value"),e;let[n,l,c]=r;try{let e=Buffer.from(n,"hex"),r=Buffer.from(c,"hex"),o=(0,a.createDecipheriv)(i,t,e);o.setAuthTag(r);let s=o.update(l,"hex","utf8");return s+=o.final("utf8")}catch(t){return console.error("[Encryption] Decryption failed:",t instanceof Error?t.message:String(t)),e}}function d(e){return c()&&e&&(e.apiKey&&(e.apiKey=u(e.apiKey)),e.accessToken&&(e.accessToken=u(e.accessToken)),e.refreshToken&&(e.refreshToken=u(e.refreshToken)),e.idToken&&(e.idToken=u(e.idToken))),e}function f(e){return e&&c()?{...e,apiKey:p(e.apiKey),accessToken:p(e.accessToken),refreshToken:p(e.refreshToken),idToken:p(e.idToken)}:e}var y=e.i(403122);function E(e){return e&&"object"==typeof e?e:{}}function v(e){return"string"==typeof e?e:null}async function _(e={}){let t=(0,r.getDbInstance)(),n="SELECT * FROM provider_connections",a=[],i={};return e.provider&&(a.push("provider = @provider"),i.provider=e.provider),void 0!==e.isActive&&(a.push("is_active = @isActive"),i.isActive=+!!e.isActive),a.length>0&&(n+=" WHERE "+a.join(" AND ")),n+=" ORDER BY priority ASC, updated_at DESC",t.prepare(n).all(i).map(e=>f((0,r.cleanNulls)((0,r.rowToCamel)(e))))}async function m(e){let t=(0,r.getDbInstance)().prepare("SELECT * FROM provider_connections WHERE id = ?").get(e);return t?f((0,r.cleanNulls)((0,r.rowToCamel)(t))):null}async function g(e){var a,i,o;let l=(0,r.getDbInstance)(),s=new Date().toISOString(),c=null;if("oauth"===e.authType&&e.email){let t=v(E(e.providerSpecificData).workspaceId);"codex"===e.provider&&t?(c=l.prepare("SELECT * FROM provider_connections WHERE provider = ? AND auth_type = 'oauth' AND json_extract(provider_specific_data, '$.workspaceId') = ? AND email = ?").get(e.provider,t,e.email)||null)||(c=l.prepare("SELECT * FROM provider_connections WHERE provider = ? AND auth_type = 'oauth' AND json_extract(provider_specific_data, '$.workspaceId') = ? AND (email IS NULL OR email = '')").get(e.provider,t)||null):c=l.prepare("SELECT * FROM provider_connections WHERE provider = ? AND auth_type = 'oauth' AND email = ?").get(e.provider,e.email)||null}else"apikey"===e.authType&&e.name&&(c=l.prepare("SELECT * FROM provider_connections WHERE provider = ? AND auth_type = 'apikey' AND name = ?").get(e.provider,e.name)||null);if(c){let t=v(c.id);if(!t)return null;let a={...E((0,r.rowToCamel)(c)),...e,updatedAt:s};return h(l,t,a),(0,n.backupDbFile)("pre-write"),(0,r.cleanNulls)(a)}let u=e.name||null;!u&&"oauth"===e.authType&&(e.email?u=e.email:e.displayName&&(u=e.displayName));let p=e.priority;if(!p){p=("number"==typeof(a=E(l.prepare("SELECT MAX(priority) as maxP FROM provider_connections WHERE provider = ?").get(e.provider)).maxP)?a:0)+1}let f={id:(0,t.v4)(),provider:e.provider,authType:e.authType||"oauth",name:u,priority:p,isActive:void 0===e.isActive||e.isActive,createdAt:s,updatedAt:s};for(let t of["displayName","email","globalPriority","defaultModel","accessToken","refreshToken","expiresAt","tokenType","scope","idToken","projectId","apiKey","testStatus","lastTested","lastError","lastErrorAt","lastErrorType","lastErrorSource","rateLimitedUntil","expiresIn","errorCode","consecutiveUseCount","rateLimitProtection","group"])void 0!==e[t]&&null!==e[t]&&(f[t]=e[t]);e.providerSpecificData&&Object.keys(e.providerSpecificData).length>0&&(f.providerSpecificData=e.providerSpecificData),i=l,o=d({...f}),i.prepare(`
2
- INSERT INTO provider_connections (
3
- id, provider, auth_type, name, email, priority, is_active,
4
- access_token, refresh_token, expires_at, token_expires_at,
5
- scope, project_id, test_status, error_code, last_error,
6
- last_error_at, last_error_type, last_error_source, backoff_level,
7
- rate_limited_until, health_check_interval, last_health_check_at,
8
- last_tested, api_key, id_token, provider_specific_data,
9
- expires_in, display_name, global_priority, default_model,
10
- token_type, consecutive_use_count, rate_limit_protection, last_used_at, "group", created_at, updated_at
11
- ) VALUES (
12
- @id, @provider, @authType, @name, @email, @priority, @isActive,
13
- @accessToken, @refreshToken, @expiresAt, @tokenExpiresAt,
14
- @scope, @projectId, @testStatus, @errorCode, @lastError,
15
- @lastErrorAt, @lastErrorType, @lastErrorSource, @backoffLevel,
16
- @rateLimitedUntil, @healthCheckInterval, @lastHealthCheckAt,
17
- @lastTested, @apiKey, @idToken, @providerSpecificData,
18
- @expiresIn, @displayName, @globalPriority, @defaultModel,
19
- @tokenType, @consecutiveUseCount, @rateLimitProtection, @lastUsedAt, @group, @createdAt, @updatedAt
20
- )
21
- `).run({id:o.id,provider:o.provider,authType:o.authType||null,name:o.name||null,email:o.email||null,priority:o.priority||0,isActive:+(!1!==o.isActive),accessToken:o.accessToken||null,refreshToken:o.refreshToken||null,expiresAt:o.expiresAt||null,tokenExpiresAt:o.tokenExpiresAt||null,scope:o.scope||null,projectId:o.projectId||null,testStatus:o.testStatus||null,errorCode:o.errorCode||null,lastError:o.lastError||null,lastErrorAt:o.lastErrorAt||null,lastErrorType:o.lastErrorType||null,lastErrorSource:o.lastErrorSource||null,backoffLevel:o.backoffLevel||0,rateLimitedUntil:o.rateLimitedUntil||null,healthCheckInterval:o.healthCheckInterval||null,lastHealthCheckAt:o.lastHealthCheckAt||null,lastTested:o.lastTested||null,apiKey:o.apiKey||null,idToken:o.idToken||null,providerSpecificData:o.providerSpecificData?JSON.stringify(o.providerSpecificData):null,expiresIn:o.expiresIn||null,displayName:o.displayName||null,globalPriority:o.globalPriority||null,defaultModel:o.defaultModel||null,tokenType:o.tokenType||null,consecutiveUseCount:o.consecutiveUseCount||0,rateLimitProtection:+(!0===o.rateLimitProtection||1===o.rateLimitProtection),lastUsedAt:o.lastUsedAt||null,group:o.group||null,createdAt:o.createdAt,updatedAt:o.updatedAt});let _=v(e.provider);return _&&b(l,_),(0,n.backupDbFile)("pre-write"),(0,y.invalidateDbCache)("connections"),(0,r.cleanNulls)(f)}function h(e,t,r){let n=r.updatedAt||new Date().toISOString();e.prepare(`
22
- UPDATE provider_connections SET
23
- provider = @provider, auth_type = @authType, name = @name, email = @email,
24
- priority = @priority, is_active = @isActive, access_token = @accessToken,
25
- refresh_token = @refreshToken, expires_at = @expiresAt, token_expires_at = @tokenExpiresAt,
26
- scope = @scope, project_id = @projectId, test_status = @testStatus, error_code = @errorCode,
27
- last_error = @lastError, last_error_at = @lastErrorAt, last_error_type = @lastErrorType,
28
- last_error_source = @lastErrorSource, backoff_level = @backoffLevel,
29
- rate_limited_until = @rateLimitedUntil, health_check_interval = @healthCheckInterval,
30
- last_health_check_at = @lastHealthCheckAt, last_tested = @lastTested, api_key = @apiKey,
31
- id_token = @idToken, provider_specific_data = @providerSpecificData,
32
- expires_in = @expiresIn, display_name = @displayName, global_priority = @globalPriority,
33
- default_model = @defaultModel, token_type = @tokenType,
34
- consecutive_use_count = @consecutiveUseCount,
35
- rate_limit_protection = @rateLimitProtection,
36
- last_used_at = @lastUsedAt,
37
- "group" = @group,
38
- updated_at = @updatedAt
39
- WHERE id = @id
40
- `).run({id:t,provider:r.provider,authType:r.authType||null,name:r.name||null,email:r.email||null,priority:r.priority||0,isActive:+(!1!==r.isActive),accessToken:r.accessToken||null,refreshToken:r.refreshToken||null,expiresAt:r.expiresAt||null,tokenExpiresAt:r.tokenExpiresAt||null,scope:r.scope||null,projectId:r.projectId||null,testStatus:r.testStatus||null,errorCode:r.errorCode||null,lastError:r.lastError||null,lastErrorAt:r.lastErrorAt||null,lastErrorType:r.lastErrorType||null,lastErrorSource:r.lastErrorSource||null,backoffLevel:r.backoffLevel||0,rateLimitedUntil:r.rateLimitedUntil||null,healthCheckInterval:r.healthCheckInterval||null,lastHealthCheckAt:r.lastHealthCheckAt||null,lastTested:r.lastTested||null,apiKey:r.apiKey||null,idToken:r.idToken||null,providerSpecificData:r.providerSpecificData?JSON.stringify(r.providerSpecificData):null,expiresIn:r.expiresIn||null,displayName:r.displayName||null,globalPriority:r.globalPriority||null,defaultModel:r.defaultModel||null,tokenType:r.tokenType||null,consecutiveUseCount:r.consecutiveUseCount||0,rateLimitProtection:+(!0===r.rateLimitProtection||1===r.rateLimitProtection),lastUsedAt:r.lastUsedAt||null,group:r.group||null,updatedAt:n})}async function S(e,t){let a=(0,r.getDbInstance)(),i=a.prepare("SELECT * FROM provider_connections WHERE id = ?").get(e);if(!i)return null;let o={...(0,r.rowToCamel)(i),...t,updatedAt:new Date().toISOString()};if(h(a,e,d({...o})),(0,n.backupDbFile)("pre-write"),(0,y.invalidateDbCache)("connections"),void 0!==t.priority){let e=E(i);b(a,"string"==typeof e.provider?e.provider:String(e.provider||""))}return(0,r.cleanNulls)(o)}async function k(e){let t=(0,r.getDbInstance)(),a=t.prepare("SELECT provider FROM provider_connections WHERE id = ?").get(e);if(!a)return!1;t.prepare("DELETE FROM provider_connections WHERE id = ?").run(e);let i=E(a);return b(t,"string"==typeof i.provider?i.provider:String(i.provider||"")),(0,n.backupDbFile)("pre-write"),(0,y.invalidateDbCache)("connections"),!0}async function T(e){let t=(0,r.getDbInstance)().prepare("DELETE FROM provider_connections WHERE provider = ?").run(e);return(0,n.backupDbFile)("pre-write"),t.changes}async function D(e){b((0,r.getDbInstance)(),e)}function b(e,t){let r=e.prepare("SELECT id, priority, updated_at FROM provider_connections WHERE provider = ? ORDER BY priority ASC, updated_at DESC").all(t),n=e.prepare("UPDATE provider_connections SET priority = ? WHERE id = ?");r.forEach((e,t)=>{let r=E(e);n.run(t+1,r.id)})}async function C(){return 0}async function I(){return(0,r.getDbInstance)().prepare('SELECT DISTINCT "group" FROM provider_connections WHERE "group" IS NOT NULL ORDER BY "group"').all().map(e=>String(e.group??"")).filter(Boolean)}async function A(e={}){let t=(0,r.getDbInstance)(),n="SELECT * FROM provider_nodes",a={};return e.type&&(n+=" WHERE type = @type",a.type=e.type),t.prepare(n).all(a).map(r.rowToCamel)}async function R(e){let t=(0,r.getDbInstance)().prepare("SELECT * FROM provider_nodes WHERE id = ?").get(e);return t?(0,r.rowToCamel)(t):null}async function N(e){let a=(0,r.getDbInstance)(),i=new Date().toISOString(),o={id:e.id||(0,t.v4)(),type:e.type,name:e.name,prefix:e.prefix||null,apiType:e.apiType||null,baseUrl:e.baseUrl||null,chatPath:e.chatPath||null,modelsPath:e.modelsPath||null,createdAt:i,updatedAt:i};return a.prepare(`
41
- INSERT INTO provider_nodes (id, type, name, prefix, api_type, base_url, chat_path, models_path, created_at, updated_at)
42
- VALUES (@id, @type, @name, @prefix, @apiType, @baseUrl, @chatPath, @modelsPath, @createdAt, @updatedAt)
43
- `).run(o),(0,n.backupDbFile)("pre-write"),o}async function O(e,t){let a=(0,r.getDbInstance)(),i=a.prepare("SELECT * FROM provider_nodes WHERE id = ?").get(e);if(!i)return null;let o={...E((0,r.rowToCamel)(i)),...t,updatedAt:new Date().toISOString()};return a.prepare(`
44
- UPDATE provider_nodes SET type = @type, name = @name, prefix = @prefix,
45
- api_type = @apiType, base_url = @baseUrl, chat_path = @chatPath,
46
- models_path = @modelsPath, updated_at = @updatedAt
47
- WHERE id = @id
48
- `).run({id:e,type:o.type,name:o.name,prefix:o.prefix||null,apiType:o.apiType||null,baseUrl:o.baseUrl||null,chatPath:o.chatPath||null,modelsPath:o.modelsPath||null,updatedAt:o.updatedAt}),(0,n.backupDbFile)("pre-write"),o}async function L(e){let t=(0,r.getDbInstance)(),a=t.prepare("SELECT * FROM provider_nodes WHERE id = ?").get(e);return a?(t.prepare("DELETE FROM provider_nodes WHERE id = ?").run(e),(0,n.backupDbFile)("pre-write"),(0,r.rowToCamel)(a)):null}e.s(["cleanupProviderConnections",()=>C,"createProviderConnection",()=>g,"createProviderNode",()=>N,"deleteProviderConnection",()=>k,"deleteProviderConnectionsByProvider",()=>T,"deleteProviderNode",()=>L,"getDistinctGroups",()=>I,"getProviderConnectionById",()=>m,"getProviderConnections",()=>_,"getProviderNodeById",()=>R,"getProviderNodes",()=>A,"reorderProviderConnections",()=>D,"updateProviderConnection",()=>S,"updateProviderNode",()=>O],385498)}];
49
-
50
- //# sourceMappingURL=%5Broot-of-the-server%5D__3972de72._.js.map