omniroute 2.8.5 → 2.8.7

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 (255) 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/embeddings/route.js +7 -6
  162. package/app/.next/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  163. package/app/.next/server/app/api/v1/management/proxies/assignments/route.js +1 -1
  164. package/app/.next/server/app/api/v1/management/proxies/assignments/route.js.nft.json +1 -1
  165. package/app/.next/server/app/api/v1/management/proxies/bulk-assign/route.js +1 -1
  166. package/app/.next/server/app/api/v1/management/proxies/bulk-assign/route.js.nft.json +1 -1
  167. package/app/.next/server/app/api/v1/management/proxies/health/route.js +1 -1
  168. package/app/.next/server/app/api/v1/management/proxies/health/route.js.nft.json +1 -1
  169. package/app/.next/server/app/api/v1/management/proxies/route.js +1 -1
  170. package/app/.next/server/app/api/v1/management/proxies/route.js.nft.json +1 -1
  171. package/app/.next/server/app/api/v1/models/route.js +1 -1
  172. package/app/.next/server/app/api/v1/models/route.js.nft.json +1 -1
  173. package/app/.next/server/app/api/v1/route.js +1 -1
  174. package/app/.next/server/app/api/v1/route.js.nft.json +1 -1
  175. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  176. package/app/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  177. package/app/.next/server/app/forbidden/page_client-reference-manifest.js +1 -1
  178. package/app/.next/server/app/forgot-password/page_client-reference-manifest.js +1 -1
  179. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  180. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  181. package/app/.next/server/app/maintenance/page_client-reference-manifest.js +1 -1
  182. package/app/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  183. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  184. package/app/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  185. package/app/.next/server/app/status/page_client-reference-manifest.js +1 -1
  186. package/app/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  187. package/app/.next/server/chunks/[root-of-the-server]__007da72e._.js +3 -0
  188. package/app/.next/server/chunks/[root-of-the-server]__09c944b3._.js +1 -1
  189. package/app/.next/server/chunks/[root-of-the-server]__784fb7c5._.js +1 -1
  190. package/app/.next/server/chunks/[root-of-the-server]__7d9b23e7._.js +1 -1
  191. package/app/.next/server/chunks/[root-of-the-server]__80e3bfc3._.js +1 -1
  192. package/app/.next/server/chunks/[root-of-the-server]__84e445b2._.js +2 -2
  193. package/app/.next/server/chunks/[root-of-the-server]__92cb0def._.js +1 -1
  194. package/app/.next/server/chunks/[root-of-the-server]__a630d6ef._.js +5 -5
  195. package/app/.next/server/chunks/[root-of-the-server]__c8e3c8a9._.js +50 -0
  196. package/app/.next/server/chunks/[root-of-the-server]__d4563e10._.js +1 -1
  197. package/app/.next/server/chunks/[root-of-the-server]__db2f9fe0._.js +1 -1
  198. package/app/.next/server/chunks/[root-of-the-server]__e27a89bd._.js +1 -1
  199. package/app/.next/server/chunks/_05c48915._.js +1 -1
  200. package/app/.next/server/chunks/_1244636c._.js +2 -2
  201. package/app/.next/server/chunks/_14963fed._.js +1 -1
  202. package/app/.next/server/chunks/_1717e651._.js +1 -1
  203. package/app/.next/server/chunks/_2115d8de._.js +1 -1
  204. package/app/.next/server/chunks/_3ac953eb._.js +1 -1
  205. package/app/.next/server/chunks/_4b8fd853._.js +1 -1
  206. package/app/.next/server/chunks/_5677b5e2._.js +1 -1
  207. package/app/.next/server/chunks/_5bbb2e7a._.js +1 -1
  208. package/app/.next/server/chunks/_68683848._.js +1 -1
  209. package/app/.next/server/chunks/_b39b1914._.js +3 -0
  210. package/app/.next/server/chunks/_c05b9de3._.js +1 -1
  211. package/app/.next/server/chunks/_c795fc74._.js +1 -1
  212. package/app/.next/server/chunks/_ee7b7859._.js +1 -1
  213. package/app/.next/server/chunks/_ee9b677b._.js +1 -1
  214. package/app/.next/server/chunks/open-sse_translator_index_ts_f5fd0821._.js +2 -2
  215. package/app/.next/server/chunks/src_lib_localDb_ts_83220848._.js +1 -1
  216. package/app/.next/server/chunks/src_shared_validation_schemas_ts_4e63863a._.js +1 -1
  217. package/app/.next/server/chunks/ssr/[root-of-the-server]__9affb65e._.js +1 -1
  218. package/app/.next/server/chunks/ssr/[root-of-the-server]__a6942102._.js +1 -1
  219. package/app/.next/server/chunks/ssr/src_9197fb9b._.js +1 -1
  220. package/app/.next/server/chunks/ssr/src_d3225e36._.js +1 -1
  221. package/app/.next/server/chunks/ssr/src_i18n_messages_en_json_c3d5c412._.js +1 -1
  222. package/app/.next/server/chunks/ssr/src_i18n_messages_zh-CN_json_f4112d90._.js +1 -1
  223. package/app/.next/server/pages/500.html +2 -2
  224. package/app/.next/server/server-reference-manifest.js +1 -1
  225. package/app/.next/server/server-reference-manifest.json +1 -1
  226. package/app/.next/static/chunks/1042694db0c08f1f.css +1 -0
  227. package/app/.next/static/chunks/{ec1938d17386c6db.js → 34569b4e9d93c0ad.js} +2 -2
  228. package/app/.next/static/chunks/{d9a70775eb233dc3.js → 53e0c73d409ce003.js} +1 -1
  229. package/app/.next/static/chunks/91761ba00c702cff.js +1 -0
  230. package/app/CHANGELOG.md +50 -0
  231. package/app/docs/openapi.yaml +1 -1
  232. package/app/open-sse/handlers/chatCore.ts +6 -2
  233. package/app/open-sse/services/rateLimitManager.ts +10 -5
  234. package/app/open-sse/services/roleNormalizer.ts +14 -19
  235. package/app/open-sse/translator/index.ts +27 -3
  236. package/app/package-lock.json +2 -2
  237. package/app/package.json +1 -1
  238. package/app/src/app/(dashboard)/dashboard/cli-tools/CLIToolsPageClient.tsx +12 -0
  239. package/app/src/app/(dashboard)/dashboard/cli-tools/components/AntigravityToolCard.tsx +5 -5
  240. package/app/src/app/(dashboard)/dashboard/providers/[id]/page.tsx +381 -62
  241. package/app/src/app/api/provider-models/route.ts +47 -6
  242. package/app/src/app/api/v1/embeddings/route.ts +33 -3
  243. package/app/src/i18n/messages/en.json +10 -0
  244. package/app/src/i18n/messages/zh-CN.json +10 -0
  245. package/app/src/lib/db/models.ts +130 -13
  246. package/app/src/lib/localDb.ts +5 -0
  247. package/app/src/shared/validation/schemas.ts +1 -0
  248. package/package.json +1 -1
  249. package/app/.next/server/chunks/[root-of-the-server]__3972de72._.js +0 -50
  250. package/app/.next/server/chunks/[root-of-the-server]__6b56b04f._.js +0 -3
  251. package/app/.next/static/chunks/af071ff826ecff1b.css +0 -1
  252. package/app/.next/static/chunks/d19ab4efcaddd1db.js +0 -1
  253. /package/app/.next/static/{coLESPH6_RrEzzULWq8F5 → zi0Yj1AW2_CKS-WmB5ZUc}/_buildManifest.js +0 -0
  254. /package/app/.next/static/{coLESPH6_RrEzzULWq8F5 → zi0Yj1AW2_CKS-WmB5ZUc}/_clientMiddlewareManifest.json +0 -0
  255. /package/app/.next/static/{coLESPH6_RrEzzULWq8F5 → zi0Yj1AW2_CKS-WmB5ZUc}/_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 }
@@ -12,6 +12,7 @@ import {
12
12
  getEmbeddingProvider,
13
13
  buildDynamicEmbeddingProvider,
14
14
  type EmbeddingProviderNodeRow,
15
+ type EmbeddingProvider,
15
16
  } from "@omniroute/open-sse/config/embeddingRegistry.ts";
16
17
  import { errorResponse } from "@omniroute/open-sse/utils/error.ts";
17
18
  import { HTTP_STATUS } from "@omniroute/open-sse/config/constants.ts";
@@ -116,9 +117,9 @@ export async function POST(request) {
116
117
  // Load local provider_nodes for embedding routing (only localhost — prevents auth bypass/SSRF)
117
118
  let dynamicProviders: ReturnType<typeof buildDynamicEmbeddingProvider>[] = [];
118
119
  try {
119
- const nodes = await getProviderNodes();
120
+ const nodes = (await getProviderNodes()) as unknown as EmbeddingProviderNodeRow[];
120
121
  dynamicProviders = (Array.isArray(nodes) ? nodes : [])
121
- .filter((n: EmbeddingProviderNodeRow) => {
122
+ .filter((n) => {
122
123
  // provider_nodes apiType is "chat" or "responses" (not "embeddings") — local OpenAI-compatible
123
124
  // backends expose /embeddings under the same base URL as chat, so we build the URL as baseUrl + /embeddings.
124
125
  if (n.apiType !== "chat" && n.apiType !== "responses") return false;
@@ -157,9 +158,38 @@ export async function POST(request) {
157
158
  }
158
159
 
159
160
  // Resolve provider config — dynamic first (local override), then hardcoded
160
- const providerConfig =
161
+ let providerConfig: EmbeddingProvider | null =
161
162
  dynamicProviders.find((dp) => dp.id === provider) || getEmbeddingProvider(provider) || null;
162
163
 
164
+ // #496: Fallback — resolve from ALL provider_nodes (not just localhost)
165
+ // This enables custom embedding models (e.g. google/gemini-embedding-001) whose
166
+ // providers have remote baseUrls. Safe because getProviderCredentials() authenticates.
167
+ if (!providerConfig) {
168
+ try {
169
+ const allNodes = (await getProviderNodes()) as unknown as EmbeddingProviderNodeRow[];
170
+ const matchingNode = (Array.isArray(allNodes) ? allNodes : []).find(
171
+ (n) =>
172
+ n.prefix === provider && (n.apiType === "chat" || n.apiType === "responses") && n.baseUrl
173
+ );
174
+ if (matchingNode) {
175
+ const baseUrl = String(matchingNode.baseUrl).replace(/\/+$/, "");
176
+ providerConfig = {
177
+ id: matchingNode.prefix,
178
+ baseUrl: `${baseUrl}/embeddings`,
179
+ authType: "apikey",
180
+ authHeader: "bearer",
181
+ models: [],
182
+ };
183
+ log.info(
184
+ "EMBED",
185
+ `Resolved custom embedding provider: ${provider} → ${providerConfig.baseUrl}`
186
+ );
187
+ }
188
+ } catch (err) {
189
+ log.error("EMBED", `Failed to resolve custom embedding provider ${provider}: ${err}`);
190
+ }
191
+ }
192
+
163
193
  if (!providerConfig) {
164
194
  return errorResponse(
165
195
  HTTP_STATUS.BAD_REQUEST,
@@ -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 {
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.8.5",
3
+ "version": "2.8.7",
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
@@ -1,3 +0,0 @@
1
- module.exports=[918622,(e,t,r)=>{t.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},556704,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},832319,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},270406,(e,t,r)=>{t.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},814747,(e,t,r)=>{t.exports=e.x("path",()=>require("path"))},193695,(e,t,r)=>{t.exports=e.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},442315,(e,t,r)=>{"use strict";t.exports=e.r(918622)},347540,(e,t,r)=>{"use strict";t.exports=e.r(442315).vendored["react-rsc"].React},819481,(e,t,r)=>{"use strict";var n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o={},l={RequestCookies:()=>f,ResponseCookies:()=>g,parseCookie:()=>p,parseSetCookie:()=>c,stringifyCookie:()=>u};for(var d in l)n(o,d,{get:l[d],enumerable:!0});function u(e){var t;let r=["path"in e&&e.path&&`Path=${e.path}`,"expires"in e&&(e.expires||0===e.expires)&&`Expires=${("number"==typeof e.expires?new Date(e.expires):e.expires).toUTCString()}`,"maxAge"in e&&"number"==typeof e.maxAge&&`Max-Age=${e.maxAge}`,"domain"in e&&e.domain&&`Domain=${e.domain}`,"secure"in e&&e.secure&&"Secure","httpOnly"in e&&e.httpOnly&&"HttpOnly","sameSite"in e&&e.sameSite&&`SameSite=${e.sameSite}`,"partitioned"in e&&e.partitioned&&"Partitioned","priority"in e&&e.priority&&`Priority=${e.priority}`].filter(Boolean),n=`${e.name}=${encodeURIComponent(null!=(t=e.value)?t:"")}`;return 0===r.length?n:`${n}; ${r.join("; ")}`}function p(e){let t=new Map;for(let r of e.split(/; */)){if(!r)continue;let e=r.indexOf("=");if(-1===e){t.set(r,"true");continue}let[n,i]=[r.slice(0,e),r.slice(e+1)];try{t.set(n,decodeURIComponent(null!=i?i:"true"))}catch{}}return t}function c(e){if(!e)return;let[[t,r],...n]=p(e),{domain:i,expires:s,httponly:a,maxage:o,path:l,samesite:d,secure:u,partitioned:c,priority:f}=Object.fromEntries(n.map(([e,t])=>[e.toLowerCase().replace(/-/g,""),t]));{var g,v,y={name:t,value:decodeURIComponent(r),domain:i,...s&&{expires:new Date(s)},...a&&{httpOnly:!0},..."string"==typeof o&&{maxAge:Number(o)},path:l,...d&&{sameSite:m.includes(g=(g=d).toLowerCase())?g:void 0},...u&&{secure:!0},...f&&{priority:h.includes(v=(v=f).toLowerCase())?v:void 0},...c&&{partitioned:!0}};let e={};for(let t in y)y[t]&&(e[t]=y[t]);return e}}t.exports=((e,t,r,o)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let r of s(t))a.call(e,r)||void 0===r||n(e,r,{get:()=>t[r],enumerable:!(o=i(t,r))||o.enumerable});return e})(n({},"__esModule",{value:!0}),o);var m=["strict","lax","none"],h=["low","medium","high"],f=class{constructor(e){this._parsed=new Map,this._headers=e;const t=e.get("cookie");if(t)for(const[e,r]of p(t))this._parsed.set(e,{name:e,value:r})}[Symbol.iterator](){return this._parsed[Symbol.iterator]()}get size(){return this._parsed.size}get(...e){let t="string"==typeof e[0]?e[0]:e[0].name;return this._parsed.get(t)}getAll(...e){var t;let r=Array.from(this._parsed);if(!e.length)return r.map(([e,t])=>t);let n="string"==typeof e[0]?e[0]:null==(t=e[0])?void 0:t.name;return r.filter(([e])=>e===n).map(([e,t])=>t)}has(e){return this._parsed.has(e)}set(...e){let[t,r]=1===e.length?[e[0].name,e[0].value]:e,n=this._parsed;return n.set(t,{name:t,value:r}),this._headers.set("cookie",Array.from(n).map(([e,t])=>u(t)).join("; ")),this}delete(e){let t=this._parsed,r=Array.isArray(e)?e.map(e=>t.delete(e)):t.delete(e);return this._headers.set("cookie",Array.from(t).map(([e,t])=>u(t)).join("; ")),r}clear(){return this.delete(Array.from(this._parsed.keys())),this}[Symbol.for("edge-runtime.inspect.custom")](){return`RequestCookies ${JSON.stringify(Object.fromEntries(this._parsed))}`}toString(){return[...this._parsed.values()].map(e=>`${e.name}=${encodeURIComponent(e.value)}`).join("; ")}},g=class{constructor(e){var t,r,n;this._parsed=new Map,this._headers=e;const i=null!=(n=null!=(r=null==(t=e.getSetCookie)?void 0:t.call(e))?r:e.get("set-cookie"))?n:[];for(const e of Array.isArray(i)?i:function(e){if(!e)return[];var t,r,n,i,s,a=[],o=0;function l(){for(;o<e.length&&/\s/.test(e.charAt(o));)o+=1;return o<e.length}for(;o<e.length;){for(t=o,s=!1;l();)if(","===(r=e.charAt(o))){for(n=o,o+=1,l(),i=o;o<e.length&&"="!==(r=e.charAt(o))&&";"!==r&&","!==r;)o+=1;o<e.length&&"="===e.charAt(o)?(s=!0,o=i,a.push(e.substring(t,n)),t=o):o=n+1}else o+=1;(!s||o>=e.length)&&a.push(e.substring(t,e.length))}return a}(i)){const t=c(e);t&&this._parsed.set(t.name,t)}}get(...e){let t="string"==typeof e[0]?e[0]:e[0].name;return this._parsed.get(t)}getAll(...e){var t;let r=Array.from(this._parsed.values());if(!e.length)return r;let n="string"==typeof e[0]?e[0]:null==(t=e[0])?void 0:t.name;return r.filter(e=>e.name===n)}has(e){return this._parsed.has(e)}set(...e){let[t,r,n]=1===e.length?[e[0].name,e[0].value,e[0]]:e,i=this._parsed;return i.set(t,function(e={name:"",value:""}){return"number"==typeof e.expires&&(e.expires=new Date(e.expires)),e.maxAge&&(e.expires=new Date(Date.now()+1e3*e.maxAge)),(null===e.path||void 0===e.path)&&(e.path="/"),e}({name:t,value:r,...n})),function(e,t){for(let[,r]of(t.delete("set-cookie"),e)){let e=u(r);t.append("set-cookie",e)}}(i,this._headers),this}delete(...e){let[t,r]="string"==typeof e[0]?[e[0]]:[e[0].name,e[0]];return this.set({...r,name:t,value:"",expires:new Date(0)})}[Symbol.for("edge-runtime.inspect.custom")](){return`ResponseCookies ${JSON.stringify(Object.fromEntries(this._parsed))}`}toString(){return[...this._parsed.values()].map(u).join("; ")}}},792509,(e,t,r)=>{t.exports=e.x("url",()=>require("url"))},785148,(e,t,r)=>{t.exports=e.x("better-sqlite3",()=>require("better-sqlite3"))},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 i(){try{return r.default.homedir()}catch{return process.cwd()}}function s(e){if("string"!=typeof e)return null;let r=e.trim();return r?t.default.resolve(r):null}function a(){return t.default.join(i(),`.${n}`)}function o({isCloud:e=!1}={}){let r;if(e)return"/tmp";let l=s(process.env.DATA_DIR);return l?l:(i(),(r=s(process.env.XDG_CONFIG_HOME))?t.default.join(r,n):a())}function l(e,r){return!!e&&!!r&&t.default.resolve(e)===t.default.resolve(r)}e.s(["getLegacyDotDataDir",()=>a,"isSamePath",()=>l,"resolveDataDir",()=>o])},439951,e=>{"use strict";var t=e.i(157763);function r(){try{return(0,t.getDbInstance)()}catch{return null}}function n(e={}){let t=r();if(!t)return[];let i=[],s=[];e.action&&(i.push("action = ?"),s.push(e.action)),e.actor&&(i.push("actor = ?"),s.push(e.actor));let a=i.length>0?`WHERE ${i.join(" AND ")}`:"",o=e.limit||100,l=e.offset||0;return t.prepare(`SELECT * FROM audit_log ${a} ORDER BY timestamp DESC LIMIT ? OFFSET ?`).all(...s,o,l).map(e=>({...e,details:e.details?JSON.parse(String(e.details)):null}))}parseInt(process.env.LOG_RETENTION_DAYS||"90",10);let i=new Set,s=new Map,a=!1,o=!1;for(let e of(process.env.NO_LOG_API_KEY_IDS||"").split(",").map(e=>e.trim()).filter(Boolean))i.add(e);function l(e,t){t?i.add(e):i.delete(e),s.set(e,{value:t,timestamp:Date.now()})}function d(e){if(!e)return!1;if(i.has(e))return!0;let t=function(e){let t=r();if(!t||!e||!function(e){if(a)return o;try{o=e.prepare("PRAGMA table_info(api_keys)").all().some(e=>"no_log"===e.name)}catch{o=!1}return a=!0,o}(t))return!1;let n=s.get(e);if(n&&Date.now()-n.timestamp<3e4)return n.value;try{let r=t.prepare("SELECT no_log FROM api_keys WHERE id = ?").get(e),n=!!(r&&1===Number(r.no_log));return s.set(e,{value:n,timestamp:Date.now()}),n}catch{return!1}}(e);return t&&i.add(e),t}e.s(["getAuditLog",()=>n,"isNoLog",()=>d,"setNoLog",()=>l])},677850,e=>e.a(async(t,r)=>{try{let t=await e.y("zod");e.n(t),r()}catch(e){r(e)}},!0),200392,e=>e.a(async(t,r)=>{try{var n=e.i(677850),i=t([n]);function s(e,t){let r=e.safeParse(t);if(r.success)return{success:!0,data:r.data};let n=Array.isArray(r.error?.issues)?r.error.issues:[];return{success:!1,error:{message:"Invalid request",details:n.map(e=>({field:e.path.join("."),message:e.message}))}}}function a(e){return!1===e.success}[n]=i.then?(await i)():i,n.z.object({password:n.z.string().min(1,"Password is required").max(200)}),e.s(["isValidationFailure",()=>a,"validateBody",()=>s]),r()}catch(e){r(e)}},!1),662636,e=>{"use strict";function t(e){if(!e)return"Unknown Account";let t="string"==typeof e.name&&e.name.trim()||"string"==typeof e.displayName&&e.displayName.trim()||"string"==typeof e.email&&e.email.trim();return t||("string"==typeof e.id&&e.id?`Account #${e.id.slice(0,6)}`:"Unknown Account")}e.s(["getAccountDisplayName",()=>t])},249157,e=>{"use strict";var t=e.i(706901),r=e.i(161002);e.s(["debug",()=>t.debug,"error",()=>t.error,"info",()=>t.info,"maskKey",()=>r.maskKey,"request",()=>t.request,"response",()=>t.response,"stream",()=>t.stream,"warn",()=>t.warn])},740512,e=>{"use strict";e.s(["toJsonErrorPayload",()=>function e(t,r="Upstream provider error"){let n={error:{message:r,type:"upstream_error",code:"upstream_error"}};if(t&&"object"==typeof t){let e=t.error;return"string"==typeof e?{error:{message:e,type:"upstream_error",code:"upstream_error"}}:e&&"object"==typeof e?t:{error:t}}if("string"==typeof t){let i=t.trim();if(!i)return n;try{let t=JSON.parse(i);return e(t,r)}catch{return{error:{message:i,type:"upstream_error",code:"upstream_error"}}}}return n}])},261189,e=>{"use strict";function t(e){if(!e.prefix||!e.baseUrl)throw Error("Invalid provider_node: missing prefix or baseUrl");if(e.prefix.includes("/")||e.prefix.includes(" "))throw Error(`Invalid provider_node prefix "${e.prefix}": must not contain / or spaces`);let t=e.baseUrl.replace(/\/+$/,"");return{id:e.prefix,baseUrl:`${t}/embeddings`,authType:"none",authHeader:"none",models:[]}}let r={nebius:{id:"nebius",baseUrl:"https://api.tokenfactory.nebius.com/v1/embeddings",authType:"apikey",authHeader:"bearer",models:[{id:"Qwen/Qwen3-Embedding-8B",name:"Qwen3 Embedding 8B",dimensions:4096}]},openai:{id:"openai",baseUrl:"https://api.openai.com/v1/embeddings",authType:"apikey",authHeader:"bearer",models:[{id:"text-embedding-3-small",name:"Text Embedding 3 Small",dimensions:1536},{id:"text-embedding-3-large",name:"Text Embedding 3 Large",dimensions:3072},{id:"text-embedding-ada-002",name:"Text Embedding Ada 002",dimensions:1536}]},mistral:{id:"mistral",baseUrl:"https://api.mistral.ai/v1/embeddings",authType:"apikey",authHeader:"bearer",models:[{id:"mistral-embed",name:"Mistral Embed",dimensions:1024}]},together:{id:"together",baseUrl:"https://api.together.xyz/v1/embeddings",authType:"apikey",authHeader:"bearer",models:[{id:"BAAI/bge-large-en-v1.5",name:"BGE Large EN v1.5",dimensions:1024},{id:"togethercomputer/m2-bert-80M-8k-retrieval",name:"M2 BERT 80M 8K",dimensions:768}]},fireworks:{id:"fireworks",baseUrl:"https://api.fireworks.ai/inference/v1/embeddings",authType:"apikey",authHeader:"bearer",models:[{id:"nomic-ai/nomic-embed-text-v1.5",name:"Nomic Embed Text v1.5",dimensions:768}]},nvidia:{id:"nvidia",baseUrl:"https://integrate.api.nvidia.com/v1/embeddings",authType:"apikey",authHeader:"bearer",models:[{id:"nvidia/nv-embedqa-e5-v5",name:"NV EmbedQA E5 v5",dimensions:1024}]}};function n(e){return r[e]||null}function i(e,t){if(!e)return{provider:null,model:null};let n=e.indexOf("/");if(n>0){for(let[t]of Object.entries(r))if(e.startsWith(t+"/"))return{provider:t,model:e.slice(t.length+1)};if(t){for(let r of t)if(e.startsWith(r.id+"/"))return{provider:r.id,model:e.slice(r.id.length+1)}}return{provider:e.slice(0,n),model:e.slice(n+1)}}for(let[t,n]of Object.entries(r))if(n.models.some(t=>t.id===e))return{provider:t,model:e};return{provider:null,model:e}}function s(){let e=[];for(let[t,n]of Object.entries(r))for(let r of n.models)e.push({id:`${t}/${r.id}`,name:r.name,provider:t,dimensions:r.dimensions});return e}e.s(["buildDynamicEmbeddingProvider",()=>t,"getAllEmbeddingModels",()=>s,"getEmbeddingProvider",()=>n,"parseEmbeddingModel",()=>i])},344448,e=>{"use strict";var t=e.i(261189);e.i(312125);var r=e.i(397506);async function n({body:e,credentials:n,log:i,resolvedProvider:s=null,resolvedModel:a=null}){let o,l,d;if(s)o=s.id,l=a,d=s;else{let r=(0,t.parseEmbeddingModel)(e.model);o=r.provider,l=r.model,d=o?(0,t.getEmbeddingProvider)(o):null}let u=Date.now(),p={model:e.model,input_count:Array.isArray(e.input)?e.input.length:1,dimensions:e.dimensions||void 0};if(!o)return{success:!1,status:400,error:`Invalid embedding model: ${e.model}. Use format: provider/model`};if(!d)return{success:!1,status:400,error:`Unknown embedding provider: ${o}`};let c={model:l,input:e.input};void 0!==e.dimensions&&(c.dimensions=e.dimensions),void 0!==e.encoding_format&&(c.encoding_format=e.encoding_format);let m={"Content-Type":"application/json"},h="none"===d.authType?null:n?.apiKey||n?.accessToken;h&&("bearer"===d.authHeader?m.Authorization=`Bearer ${h}`:"x-api-key"===d.authHeader&&(m["x-api-key"]=h)),i&&i.info("EMBED",`${o}/${l} | input: ${Array.isArray(e.input)?e.input.length+" items":"1 item"}`);try{let e=await fetch(d.baseUrl,{method:"POST",headers:m,body:JSON.stringify(c)});if(!e.ok){let t=await e.text();return i&&i.error("EMBED",`${o} error ${e.status}: ${t.slice(0,200)}`),(0,r.saveCallLog)({method:"POST",path:"/v1/embeddings",status:e.status,model:`${o}/${l}`,provider:o,duration:Date.now()-u,error:t.slice(0,500),requestBody:p}).catch(()=>{}),{success:!1,status:e.status,error:t}}let t=await e.json();return(0,r.saveCallLog)({method:"POST",path:"/v1/embeddings",status:200,model:`${o}/${l}`,provider:o,duration:Date.now()-u,tokens:{prompt_tokens:t.usage?.prompt_tokens||t.usage?.total_tokens||0,completion_tokens:0},requestBody:p,responseBody:{usage:t.usage||null,object:"list",data_count:t.data?.length||0}}).catch(()=>{}),{success:!0,data:{object:"list",data:t.data||t,model:`${o}/${l}`,usage:t.usage||{prompt_tokens:0,total_tokens:0}}}}catch(e){return i&&i.error("EMBED",`${o} fetch error: ${e.message}`),(0,r.saveCallLog)({method:"POST",path:"/v1/embeddings",status:502,model:`${o}/${l}`,provider:o,duration:Date.now()-u,error:e.message,requestBody:p}).catch(()=>{}),{success:!1,status:502,error:`Embedding provider error: ${e.message}`}}}e.s(["handleEmbedding",()=>n])},532400,e=>e.a(async(t,r)=>{try{var n=e.i(224010),i=e.i(344448),s=e.i(287726),a=e.i(261189),o=e.i(719201),l=e.i(16023),d=e.i(706901),u=e.i(249157),p=e.i(740512),c=e.i(478847),m=e.i(676088),h=e.i(200392);e.i(245272);var f=e.i(542949),g=e.i(385498),v=t([m,h]);async function y(){return new Response(null,{headers:{"Access-Control-Allow-Origin":n.CORS_ORIGIN,"Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"*"}})}async function b(){let e=(0,a.getAllEmbeddingModels)(),t=Math.floor(Date.now()/1e3),r=e.map(e=>({id:e.id,object:"model",created:t,owned_by:e.provider,type:"embedding",dimensions:e.dimensions}));try{let e=await (0,f.getAllCustomModels)();for(let[n,i]of Object.entries(e))if(Array.isArray(i))for(let e of i){if(!e?.id||!Array.isArray(e.supportedEndpoints)||!e.supportedEndpoints.includes("embeddings"))continue;let i=`${n}/${e.id}`;r.some(e=>e.id===i)||r.push({id:i,object:"model",created:t,owned_by:n,type:"embedding",dimensions:null})}}catch{}return new Response(JSON.stringify({object:"list",data:r}),{headers:{"Content-Type":"application/json"}})}async function E(e){let t;try{t=await e.json()}catch{return d.warn("EMBED","Invalid JSON body"),(0,o.errorResponse)(l.HTTP_STATUS.BAD_REQUEST,"Invalid JSON body")}let r=(0,h.validateBody)(m.v1EmbeddingsSchema,t);if((0,h.isValidationFailure)(r))return(0,o.errorResponse)(l.HTTP_STATUS.BAD_REQUEST,r.error.message);let n=r.data;if("true"===process.env.REQUIRE_API_KEY){let t=(0,s.extractApiKey)(e);if(!t)return(0,o.errorResponse)(l.HTTP_STATUS.UNAUTHORIZED,"Missing API key");if(!await (0,s.isValidApiKey)(t))return(0,o.errorResponse)(l.HTTP_STATUS.UNAUTHORIZED,"Invalid API key")}let f=await (0,c.enforceApiKeyPolicy)(e,n.model);if(f.rejection)return f.rejection;let v=[];try{let e=await (0,g.getProviderNodes)();v=(Array.isArray(e)?e:[]).filter(e=>{if("chat"!==e.apiType&&"responses"!==e.apiType)return!1;try{let t=new URL(e.baseUrl).hostname;return"localhost"===t||"127.0.0.1"===t||"::1"===t||"[::1]"===t}catch{return!1}}).map(e=>{try{return(0,a.buildDynamicEmbeddingProvider)(e)}catch(t){return d.error("EMBED",`Skipping invalid provider_node ${e.prefix}: ${t}`),null}}).filter(e=>null!==e)}catch(e){d.error("EMBED",`Failed to load provider_nodes for embeddings: ${e}`)}let{provider:y,model:b}=(0,a.parseEmbeddingModel)(n.model,v);if(!y)return(0,o.errorResponse)(l.HTTP_STATUS.BAD_REQUEST,`Invalid embedding model: ${n.model}. Use format: provider/model`);let E=v.find(e=>e.id===y)||(0,a.getEmbeddingProvider)(y)||null;if(!E)return(0,o.errorResponse)(l.HTTP_STATUS.BAD_REQUEST,`Unknown embedding provider: ${y}. No matching hardcoded or local provider found.`);let _=null;if(E&&"none"!==E.authType&&!(_=await (0,s.getProviderCredentials)(y)))return(0,o.errorResponse)(l.HTTP_STATUS.BAD_REQUEST,`No credentials for embedding provider: ${y}`);let x=await (0,i.handleEmbedding)({body:n,credentials:_,log:u,resolvedProvider:E,resolvedModel:b});if(x.success)return _&&await (0,s.clearRecoveredProviderState)(_),new Response(JSON.stringify(x.data),{status:200,headers:{"Content-Type":"application/json"}});let w=(0,p.toJsonErrorPayload)(x.error,"Embedding provider error");return new Response(JSON.stringify(w),{status:x.status,headers:{"Content-Type":"application/json"}})}[m,h]=v.then?(await v)():v,e.s(["GET",()=>b,"OPTIONS",()=>y,"POST",()=>E]),r()}catch(e){r(e)}},!1),559282,e=>e.a(async(t,r)=>{try{var n=e.i(747909),i=e.i(174017),s=e.i(996250),a=e.i(759756),o=e.i(561916),l=e.i(174677),d=e.i(869741),u=e.i(316795),p=e.i(487718),c=e.i(995169),m=e.i(47587),h=e.i(666012),f=e.i(570101),g=e.i(626937),v=e.i(10372),y=e.i(193695);e.i(52474);var b=e.i(600220),E=e.i(532400),_=t([E]);[E]=_.then?(await _)():_;let A=new n.AppRouteRouteModule({definition:{kind:i.RouteKind.APP_ROUTE,page:"/api/v1/embeddings/route",pathname:"/api/v1/embeddings",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/src/app/api/v1/embeddings/route.ts",nextConfigOutput:"standalone",userland:E}),{workAsyncStorage:R,workUnitAsyncStorage:T,serverHooks:S}=A;function x(){return(0,s.patchFetch)({workAsyncStorage:R,workUnitAsyncStorage:T})}async function w(e,t,r){A.isDev&&(0,a.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let n="/api/v1/embeddings/route";n=n.replace(/\/index$/,"")||"/";let s=await A.prepare(e,t,{srcPage:n,multiZoneDraftMode:!1});if(!s)return t.statusCode=400,t.end("Bad Request"),null==r.waitUntil||r.waitUntil.call(r,Promise.resolve()),null;let{buildId:E,params:_,nextConfig:x,parsedUrl:w,isDraftMode:R,prerenderManifest:T,routerServerContext:S,isOnDemandRevalidate:O,revalidateOnlyGenerated:P,resolvedPathname:k,clientReferenceManifest:C,serverActionsManifest:D}=s,$=(0,d.normalizeAppPath)(n),U=!!(T.dynamicRoutes[$]||T.routes[k]),N=async()=>((null==S?void 0:S.render404)?await S.render404(e,t,w,!1):t.end("This page could not be found"),null);if(U&&!R){let e=!!T.routes[k],t=T.dynamicRoutes[$];if(t&&!1===t.fallback&&!e){if(x.experimental.adapterPath)return await N();throw new y.NoFallbackError}}let j=null;!U||A.isDev||R||(j=k,j="/index"===j?"/":j);let I=!0===A.isDev||!U,M=U&&!I;D&&C&&(0,l.setManifestsSingleton)({page:n,clientReferenceManifest:C,serverActionsManifest:D});let H=e.method||"GET",q=(0,o.getTracer)(),B=q.getActiveScopeSpan(),L={params:_,prerenderManifest:T,renderOpts:{experimental:{authInterrupts:!!x.experimental.authInterrupts},cacheComponents:!!x.cacheComponents,supportsDynamicResponse:I,incrementalCache:(0,a.getRequestMeta)(e,"incrementalCache"),cacheLifeProfiles:x.cacheLife,waitUntil:r.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,r,n,i)=>A.onRequestError(e,t,n,i,S)},sharedContext:{buildId:E}},K=new u.NodeNextRequest(e),F=new u.NodeNextResponse(t),G=p.NextRequestAdapter.fromNodeNextRequest(K,(0,p.signalFromNodeResponse)(t));try{let s=async e=>A.handle(G,L).finally(()=>{if(!e)return;e.setAttributes({"http.status_code":t.statusCode,"next.rsc":!1});let r=q.getRootSpanAttributes();if(!r)return;if(r.get("next.span_type")!==c.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${r.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let i=r.get("next.route");if(i){let t=`${H} ${i}`;e.setAttributes({"next.route":i,"http.route":i,"next.span_name":t}),e.updateName(t)}else e.updateName(`${H} ${n}`)}),l=!!(0,a.getRequestMeta)(e,"minimalMode"),d=async a=>{var o,d;let u=async({previousCacheEntry:i})=>{try{if(!l&&O&&P&&!i)return t.statusCode=404,t.setHeader("x-nextjs-cache","REVALIDATED"),t.end("This page could not be found"),null;let n=await s(a);e.fetchMetrics=L.renderOpts.fetchMetrics;let o=L.renderOpts.pendingWaitUntil;o&&r.waitUntil&&(r.waitUntil(o),o=void 0);let d=L.renderOpts.collectedTags;if(!U)return await (0,h.sendResponse)(K,F,n,L.renderOpts.pendingWaitUntil),null;{let e=await n.blob(),t=(0,f.toNodeOutgoingHttpHeaders)(n.headers);d&&(t[v.NEXT_CACHE_TAGS_HEADER]=d),!t["content-type"]&&e.type&&(t["content-type"]=e.type);let r=void 0!==L.renderOpts.collectedRevalidate&&!(L.renderOpts.collectedRevalidate>=v.INFINITE_CACHE)&&L.renderOpts.collectedRevalidate,i=void 0===L.renderOpts.collectedExpire||L.renderOpts.collectedExpire>=v.INFINITE_CACHE?void 0:L.renderOpts.collectedExpire;return{value:{kind:b.CachedRouteKind.APP_ROUTE,status:n.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:r,expire:i}}}}catch(t){throw(null==i?void 0:i.isStale)&&await A.onRequestError(e,t,{routerKind:"App Router",routePath:n,routeType:"route",revalidateReason:(0,m.getRevalidateReason)({isStaticGeneration:M,isOnDemandRevalidate:O})},!1,S),t}},p=await A.handleResponse({req:e,nextConfig:x,cacheKey:j,routeKind:i.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:T,isRoutePPREnabled:!1,isOnDemandRevalidate:O,revalidateOnlyGenerated:P,responseGenerator:u,waitUntil:r.waitUntil,isMinimalMode:l});if(!U)return null;if((null==p||null==(o=p.value)?void 0:o.kind)!==b.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==p||null==(d=p.value)?void 0:d.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});l||t.setHeader("x-nextjs-cache",O?"REVALIDATED":p.isMiss?"MISS":p.isStale?"STALE":"HIT"),R&&t.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let c=(0,f.fromNodeOutgoingHttpHeaders)(p.value.headers);return l&&U||c.delete(v.NEXT_CACHE_TAGS_HEADER),!p.cacheControl||t.getHeader("Cache-Control")||c.get("Cache-Control")||c.set("Cache-Control",(0,g.getCacheControlHeader)(p.cacheControl)),await (0,h.sendResponse)(K,F,new Response(p.value.body,{headers:c,status:p.value.status||200})),null};B?await d(B):await q.withPropagatedContext(e.headers,()=>q.trace(c.BaseServerSpan.handleRequest,{spanName:`${H} ${n}`,kind:o.SpanKind.SERVER,attributes:{"http.method":H,"http.target":e.url}},d))}catch(t){if(t instanceof y.NoFallbackError||await A.onRequestError(e,t,{routerKind:"App Router",routePath:$,routeType:"route",revalidateReason:(0,m.getRevalidateReason)({isStaticGeneration:M,isOnDemandRevalidate:O})},!1,S),U)throw t;return await (0,h.sendResponse)(K,F,new Response(null,{status:500})),null}}e.s(["handler",()=>w,"patchFetch",()=>x,"routeModule",()=>A,"serverHooks",()=>S,"workAsyncStorage",()=>R,"workUnitAsyncStorage",()=>T]),r()}catch(e){r(e)}},!1),605589,e=>{e.v(t=>Promise.all(["server/chunks/src_lib_localDb_ts_83220848._.js"].map(t=>e.l(t))).then(()=>t(969738)))},606102,e=>{e.v(e=>Promise.resolve().then(()=>e(548941)))},789543,e=>{e.v(e=>Promise.resolve().then(()=>e(385498)))},579042,e=>{e.v(t=>Promise.all(["server/chunks/src_shared_utils_apiKey_ts_fa113e09._.js"].map(t=>e.l(t))).then(()=>t(65448)))},49794,e=>{e.v(t=>Promise.all(["server/chunks/src_shared_constants_pricing_ts_65de0558._.js"].map(t=>e.l(t))).then(()=>t(404503)))},386305,e=>{e.v(e=>Promise.resolve().then(()=>e(878947)))}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__6b56b04f._.js.map