omniroute 2.7.2 → 2.7.3

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 (109) 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/settings/page_client-reference-manifest.js +1 -1
  27. package/app/.next/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  28. package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  29. package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  30. package/app/.next/server/app/400/page_client-reference-manifest.js +1 -1
  31. package/app/.next/server/app/401/page_client-reference-manifest.js +1 -1
  32. package/app/.next/server/app/403/page_client-reference-manifest.js +1 -1
  33. package/app/.next/server/app/408/page_client-reference-manifest.js +1 -1
  34. package/app/.next/server/app/429/page_client-reference-manifest.js +1 -1
  35. package/app/.next/server/app/500/page_client-reference-manifest.js +1 -1
  36. package/app/.next/server/app/502/page_client-reference-manifest.js +1 -1
  37. package/app/.next/server/app/503/page_client-reference-manifest.js +1 -1
  38. package/app/.next/server/app/_global-error.html +2 -2
  39. package/app/.next/server/app/_global-error.rsc +1 -1
  40. package/app/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  41. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  42. package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  43. package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  44. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  45. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  46. package/app/.next/server/app/api/v1/api/chat/route.js +3 -3
  47. package/app/.next/server/app/api/v1/audio/speech/route.js +3 -3
  48. package/app/.next/server/app/api/v1/audio/transcriptions/route.js +6 -6
  49. package/app/.next/server/app/api/v1/chat/completions/route.js +7 -7
  50. package/app/.next/server/app/api/v1/completions/route.js +7 -7
  51. package/app/.next/server/app/api/v1/embeddings/route.js +5 -5
  52. package/app/.next/server/app/api/v1/images/generations/route.js +7 -7
  53. package/app/.next/server/app/api/v1/messages/route.js +3 -3
  54. package/app/.next/server/app/api/v1/moderations/route.js +3 -3
  55. package/app/.next/server/app/api/v1/music/generations/route.js +4 -4
  56. package/app/.next/server/app/api/v1/providers/[provider]/chat/completions/route.js +8 -8
  57. package/app/.next/server/app/api/v1/providers/[provider]/embeddings/route.js +5 -5
  58. package/app/.next/server/app/api/v1/providers/[provider]/images/generations/route.js +8 -8
  59. package/app/.next/server/app/api/v1/rerank/route.js +6 -6
  60. package/app/.next/server/app/api/v1/responses/route.js +3 -3
  61. package/app/.next/server/app/api/v1/search/route.js +6 -6
  62. package/app/.next/server/app/api/v1/videos/generations/route.js +6 -6
  63. package/app/.next/server/app/api/v1beta/models/[...path]/route.js +8 -8
  64. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  65. package/app/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  66. package/app/.next/server/app/forbidden/page_client-reference-manifest.js +1 -1
  67. package/app/.next/server/app/forgot-password/page_client-reference-manifest.js +1 -1
  68. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  69. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  70. package/app/.next/server/app/maintenance/page_client-reference-manifest.js +1 -1
  71. package/app/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  72. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  73. package/app/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  74. package/app/.next/server/app/status/page_client-reference-manifest.js +1 -1
  75. package/app/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  76. package/app/.next/server/chunks/[root-of-the-server]__09c944b3._.js +1 -1
  77. package/app/.next/server/chunks/[root-of-the-server]__167585da._.js +1 -1
  78. package/app/.next/server/chunks/[root-of-the-server]__7d9b23e7._.js +1 -1
  79. package/app/.next/server/chunks/[root-of-the-server]__80e3bfc3._.js +1 -1
  80. package/app/.next/server/chunks/[root-of-the-server]__84e445b2._.js +2 -2
  81. package/app/.next/server/chunks/[root-of-the-server]__92cb0def._.js +1 -1
  82. package/app/.next/server/chunks/[root-of-the-server]__db2f9fe0._.js +1 -1
  83. package/app/.next/server/chunks/[root-of-the-server]__dc47ee64._.js +1 -1
  84. package/app/.next/server/chunks/_05c48915._.js +1 -1
  85. package/app/.next/server/chunks/_2115d8de._.js +1 -1
  86. package/app/.next/server/chunks/_3ac953eb._.js +1 -1
  87. package/app/.next/server/chunks/_4b8fd853._.js +1 -1
  88. package/app/.next/server/chunks/_68683848._.js +1 -1
  89. package/app/.next/server/chunks/_6f1b3c3f._.js +1 -1
  90. package/app/.next/server/chunks/_ee9b677b._.js +1 -1
  91. package/app/.next/server/chunks/_ffda39da._.js +10 -10
  92. package/app/.next/server/chunks/src_4787afd3._.js +1 -1
  93. package/app/.next/server/chunks/ssr/[root-of-the-server]__9affb65e._.js +1 -1
  94. package/app/.next/server/chunks/ssr/[root-of-the-server]__a6942102._.js +1 -1
  95. package/app/.next/server/pages/500.html +2 -2
  96. package/app/.next/server/server-reference-manifest.js +1 -1
  97. package/app/.next/server/server-reference-manifest.json +1 -1
  98. package/app/.next/static/chunks/{f83525924aff5f68.js → 1d4f94c2f5112482.js} +1 -1
  99. package/app/CHANGELOG.md +13 -0
  100. package/app/docs/openapi.yaml +1 -1
  101. package/app/package-lock.json +2 -2
  102. package/app/package.json +1 -1
  103. package/app/src/domain/quotaCache.ts +40 -1
  104. package/app/src/sse/services/auth.ts +30 -5
  105. package/app/tests/unit/quota-policy-generalization.test.mjs +40 -0
  106. package/package.json +1 -1
  107. /package/app/.next/static/{_WuQZHRMiXNmIFgVwbr-Q → TaE7xCUJ3vzE5oXXL5DhE}/_buildManifest.js +0 -0
  108. /package/app/.next/static/{_WuQZHRMiXNmIFgVwbr-Q → TaE7xCUJ3vzE5oXXL5DhE}/_clientMiddlewareManifest.json +0 -0
  109. /package/app/.next/static/{_WuQZHRMiXNmIFgVwbr-Q → TaE7xCUJ3vzE5oXXL5DhE}/_ssgManifest.js +0 -0
@@ -1,3 +1,3 @@
1
- module.exports=[287726,e=>{"use strict";e.i(245272);var t=e.i(385498),r=e.i(125852),i=e.i(548941),n=e.i(25687),l=e.i(441637),o=e.i(828059),a=e.i(16023),s=e.i(706901),c=e.i(73114);function d(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function u(e){return"string"==typeof e&&e.trim().length>0?e:null}function f(e,t=0){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&e.trim().length>0){let r=Number(e);return Number.isFinite(r)?r:t}return t}function A(e){let t=d(e);return{id:u(t.id)||"",isActive:!0===t.isActive,rateLimitedUntil:u(t.rateLimitedUntil),testStatus:u(t.testStatus),apiKey:u(t.apiKey),accessToken:u(t.accessToken),refreshToken:u(t.refreshToken),tokenExpiresAt:u(t.tokenExpiresAt),expiresAt:u(t.expiresAt),projectId:u(t.projectId),providerSpecificData:d(t.providerSpecificData),lastUsedAt:u(t.lastUsedAt),consecutiveUseCount:f(t.consecutiveUseCount,0),priority:f(t.priority,999),lastError:u(t.lastError),lastErrorType:u(t.lastErrorType),lastErrorSource:u(t.lastErrorSource),errorCode:"string"==typeof t.errorCode||"number"==typeof t.errorCode?t.errorCode:null,backoffLevel:f(t.backoffLevel,0)}}function p(e,t){return"boolean"==typeof e?e:t}function m(e,t=90){return Math.min(100,Math.max(1,f(e,t)))}function h(e){if("string"!=typeof e)return null;let t=e.trim().toLowerCase();return t.length>0?t:null}function y(e){if(!e)return null;let t=new Date(e).getTime();return!Number.isFinite(t)||t<=Date.now()?null:t}function g(e){return e.map(e=>({raw:e,ms:y(e)})).filter(e=>null!==e.ms).sort((e,t)=>e.ms-t.ms)[0]?.raw||null}let U=Promise.resolve(),w=new Map;async function T(e,r=null,o=null){let a,u=U;U=new Promise(e=>{a=e});try{let a;await u;let U=await (0,t.getProviderConnections)({provider:e,isActive:!0}),w=(Array.isArray(U)?U:[]).map(A).filter(e=>e.id.length>0);if(o&&o.length>0&&(w=w.filter(e=>o.includes(e.id))),s.debug("AUTH",`${e} | total connections: ${w.length}, excludeId: ${r||"none"}`),0===w.length){let r=await (0,t.getProviderConnections)({provider:e}),i=(Array.isArray(r)?r:[]).map(A).filter(e=>e.id.length>0);if(s.debug("AUTH",`${e} | all connections (incl inactive): ${i.length}`),i.length>0){let t=(0,l.getEarliestRateLimitedUntil)(i);if(t)return s.warn("AUTH",`${e} | all ${i.length} accounts rate limited (${(0,l.formatRetryAfter)(t)})`),{allRateLimited:!0,retryAfter:t,retryAfterHuman:(0,l.formatRetryAfter)(t)};s.warn("AUTH",`${e} | ${i.length} accounts found but none active`),i.forEach(e=>{s.debug("AUTH",` → ${e.id?.slice(0,8)} | isActive=${e.isActive} | rateLimitedUntil=${e.rateLimitedUntil||"none"} | testStatus=${e.testStatus}`)})}return s.warn("AUTH",`No credentials for ${e}`),null}let T=w.filter(e=>!(r&&e.id===r||(0,l.isAccountUnavailable)(e.rateLimitedUntil)));if(s.debug("AUTH",`${e} | available: ${T.length}/${w.length}`),w.forEach(e=>{let t=r&&e.id===r,i=(0,l.isAccountUnavailable)(e.rateLimitedUntil);(t||i)&&s.debug("AUTH",` → ${e.id?.slice(0,8)} | ${t?"excluded":""} ${i?`rateLimited until ${e.rateLimitedUntil}`:""}`)}),0===T.length){let t=(0,l.getEarliestRateLimitedUntil)(w);if(t){let r=w.filter(e=>e.rateLimitedUntil&&new Date(e.rateLimitedUntil).getTime()>Date.now()).sort((e,t)=>new Date(e.rateLimitedUntil||0).getTime()-new Date(t.rateLimitedUntil||0).getTime())[0];return s.warn("AUTH",`${e} | all ${w.length} active accounts rate limited (${(0,l.formatRetryAfter)(t)}) | lastErrorCode=${r?.errorCode}, lastError=${r?.lastError?.slice(0,50)}`),{allRateLimited:!0,retryAfter:t,retryAfterHuman:(0,l.formatRetryAfter)(t),lastError:r?.lastError||null,lastErrorCode:r?.errorCode||null}}return s.warn("AUTH",`${e} | all ${w.length} accounts unavailable`),null}let v=T,b=[];if(v=T.filter(t=>{let r=function(e,t){let r=function(e,t){let r=d(t.limitPolicy),i=(Array.isArray(r.windows)?r.windows:[]).map(h).filter(Boolean);if("codex"===e){var n;let e,l,o,a=(n=t,l=(e=d(n.codexLimitPolicy),{use5h:p(e.use5h,!0),useWeekly:p(e.useWeekly,!0)}),o=[],l.use5h&&o.push("session"),l.useWeekly&&o.push("weekly"),o),s=i.length>0?i:a;return{enabled:p(r.enabled,s.length>0),thresholdPercent:m(r.thresholdPercent),windows:s}}return{enabled:p(r.enabled,!1),thresholdPercent:m(r.thresholdPercent),windows:i}}(e,t.providerSpecificData);if(!r.enabled||0===r.windows.length)return{blocked:!1,reasons:[],resetAt:null};let i=[],l=[];for(let e of r.windows){let o=(0,n.getQuotaWindowStatus)(t.id,e,r.thresholdPercent);o?.reachedThreshold&&(i.push(`${e} usage ${Math.round(o.usedPercentage)}%`),l.push(o.resetAt))}return{blocked:i.length>0,reasons:i,resetAt:g(l)}}(e,t);return!r.blocked||(b.push({id:t.id,reasons:r.reasons,resetAt:r.resetAt}),!1)}),b.length>0&&s.info("AUTH",`${e} | quota policy filtered ${b.length} account(s): ${b.map(e=>`${e.id.slice(0,8)}(${e.reasons.join(", ")})`).join("; ")}`),0===v.length&&T.length>0){let t=g(b.map(e=>e.resetAt)),r=y(t),i=r?new Date(r).toISOString():new Date(Date.now()+3e5).toISOString();return{allRateLimited:!0,retryAfter:i,retryAfterHuman:(0,l.formatRetryAfter)(i),lastError:`All ${e} accounts reached configured quota threshold`,lastErrorCode:429}}let S=v.filter(e=>!(0,n.isAccountQuotaExhausted)(e.id)),$=v.filter(e=>(0,n.isAccountQuotaExhausted)(e.id)),k=S.length>0?[...S,...$]:v;$.length>0&&s.debug("AUTH",`${e} | quota-aware: ${S.length} with quota, ${$.length} exhausted`);let E=await (0,i.getSettings)(),L=E.fallbackStrategy||"fill-first";if("round-robin"===L){let i=f(E.stickyRoundRobinLimit,3);if(null!==r)a=[...k].sort((e,t)=>{let r=e.backoffLevel||0,i=t.backoffLevel||0;return r!==i?r-i:e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(e.lastUsedAt).getTime()-new Date(t.lastUsedAt).getTime():1:-1:(e.priority||999)-(t.priority||999)})[0],s.info("AUTH",`${e} round-robin: FALLBACK MODE - excluded ${r?.slice(0,8)}..., picked LRU ${a.id?.slice(0,8)}...`),await (0,t.updateProviderConnection)(a.id,{lastUsedAt:new Date().toISOString(),consecutiveUseCount:1});else{let r=[...k].sort((e,t)=>e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(t.lastUsedAt).getTime()-new Date(e.lastUsedAt).getTime():-1:1:(e.priority||999)-(t.priority||999))[0],n=r?.consecutiveUseCount||0;r&&r.lastUsedAt&&n<i?(a=r,s.debug("AUTH",`${e} round-robin: staying with ${r.id?.slice(0,8)}... (count=${n}/${i})`),await (0,t.updateProviderConnection)(a.id,{lastUsedAt:new Date().toISOString(),consecutiveUseCount:(a.consecutiveUseCount||0)+1})):(a=[...k].sort((e,t)=>{let r=e.backoffLevel||0,i=t.backoffLevel||0;return r!==i?r-i:e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(e.lastUsedAt).getTime()-new Date(t.lastUsedAt).getTime():1:-1:(e.priority||999)-(t.priority||999)})[0],s.debug("AUTH",`${e} round-robin: switching to LRU ${a.id?.slice(0,8)}... (current count=${n} >= limit=${i} or no lastUsedAt)`),await (0,t.updateProviderConnection)(a.id,{lastUsedAt:new Date().toISOString(),consecutiveUseCount:1}))}}else if("p2c"===L)if(k.length<=2)a=k[0];else{let e=Math.floor(Math.random()*k.length),t=Math.floor(Math.random()*(k.length-1));t>=e&&t++;let r=k[e],i=k[t],n=(r.consecutiveUseCount||0)+10*!!r.lastError,l=(i.consecutiveUseCount||0)+10*!!i.lastError;a=n<=l?r:i}else if("random"===L){let e=Math.floor(Math.random()*k.length);a=k[e]}else if("least-used"===L)a=[...k].sort((e,t)=>e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(e.lastUsedAt).getTime()-new Date(t.lastUsedAt).getTime():1:-1:(e.priority||999)-(t.priority||999))[0];else if("cost-optimized"===L)a=[...k].sort((e,t)=>(e.priority||999)-(t.priority||999))[0];else if("strict-random"===L){let t=k.map(e=>e.id),r=(0,c.getNextFromDeckSync)(`conn:${e}`,t);a=k.find(e=>e.id===r)||k[0]}else a=k[0];return{apiKey:a.apiKey,accessToken:a.accessToken,refreshToken:a.refreshToken,expiresAt:a.tokenExpiresAt||a.expiresAt||null,projectId:a.projectId,copilotToken:"string"==typeof a.providerSpecificData.copilotToken?a.providerSpecificData.copilotToken:null,providerSpecificData:a.providerSpecificData,connectionId:a.id,testStatus:a.testStatus,lastError:a.lastError,lastErrorType:a.lastErrorType,lastErrorSource:a.lastErrorSource,errorCode:a.errorCode,rateLimitedUntil:a.rateLimitedUntil}}finally{a&&a()}}async function v(e,r,i,n=null,c=null){let d,u=w.get(e)||Promise.resolve();w.set(e,new Promise(e=>{d=e}));try{await u;let d=await (0,t.getProviderConnections)({provider:n}),f=(Array.isArray(d)?d:[]).map(A).filter(e=>e.id.length>0).find(t=>t.id===e),p=f?.backoffLevel||0;if(f?.rateLimitedUntil&&new Date(f.rateLimitedUntil).getTime()>Date.now())return s.info("AUTH",`${e.slice(0,8)} already marked unavailable (until ${f.rateLimitedUntil}), skipping duplicate mark`),{shouldFallback:!0,cooldownMs:new Date(f.rateLimitedUntil).getTime()-Date.now()};let{shouldFallback:m,cooldownMs:h,newBackoffLevel:y,reason:g}=(0,l.checkFallbackError)(r,i,p,c,n);if(!m)return{shouldFallback:!1,cooldownMs:0};let U=f?.providerSpecificData?.baseUrl;if((0,o.isLocalProvider)(U)&&404===r&&n&&c){let t=a.COOLDOWN_MS.notFoundLocal;return(0,l.lockModel)(n,e,c,"local_not_found",t),s.info("AUTH",`Local 404 for ${c} — model-only lockout ${t/1e3}s (connection stays active)`),{shouldFallback:!0,cooldownMs:t}}let w=(0,l.getUnavailableUntil)(h),T="string"==typeof i?i.slice(0,100):"Provider error";return await (0,t.updateProviderConnection)(e,{rateLimitedUntil:w,testStatus:"unavailable",lastError:T,errorCode:r,lastErrorAt:new Date().toISOString(),backoffLevel:y??p}),n&&c&&h>0&&(0,l.lockModel)(n,e,c,g||"unknown",h),n&&r&&T&&console.error(`❌ ${n} [${r}]: ${T}`),{shouldFallback:!0,cooldownMs:h}}finally{d&&d(),w.delete(e)}}async function b(e,r){(r.testStatus&&"active"!==r.testStatus||r.lastError||r.rateLimitedUntil||r.errorCode||r.lastErrorType||r.lastErrorSource)&&(await (0,t.updateProviderConnection)(e,{testStatus:"active",lastError:null,lastErrorAt:null,lastErrorType:null,lastErrorSource:null,errorCode:null,rateLimitedUntil:null,backoffLevel:0}),s.info("AUTH",`Account ${e.slice(0,8)} error cleared`))}async function S(e){e?.connectionId&&await b(e.connectionId,e)}function $(e){let t=e.headers.get("Authorization");return t?.startsWith("Bearer ")?t.slice(7):null}async function k(e){return!!e&&await (0,r.validateApiKey)(e)}e.s(["clearAccountError",()=>b,"clearRecoveredProviderState",()=>S,"extractApiKey",()=>$,"getProviderCredentials",()=>T,"isValidApiKey",()=>k,"markAccountUnavailable",()=>v])},478847,e=>{"use strict";var t=e.i(287726);e.i(245272);var r=e.i(125852),i=e.i(362225),n=e.i(719201),l=e.i(16023),o=e.i(706901);async function a(e,a){let s=(0,t.extractApiKey)(e);if(!s)return{apiKey:null,apiKeyInfo:null,rejection:null};let c=null;try{c=await (0,r.getApiKeyMetadata)(s)}catch(e){return o.error("API_POLICY","Failed to fetch API key metadata. Request blocked.",{error:e}),{apiKey:s,apiKeyInfo:null,rejection:(0,n.errorResponse)(l.HTTP_STATUS.SERVICE_UNAVAILABLE,"API key policy unavailable")}}if(!c)return{apiKey:s,apiKeyInfo:null,rejection:null};if(!1===c.isActive)return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.FORBIDDEN,"This API key is disabled")};if(c.accessSchedule&&c.accessSchedule.enabled&&!function(e){let t,r;if(!e.enabled)return!0;let i=new Date;try{t=new Intl.DateTimeFormat("en-US",{timeZone:e.tz,hour:"2-digit",minute:"2-digit",hour12:!1}).format(i)}catch{return!0}let[n,l]=t.replace(/^24:/,"00:").split(":").map(Number),o=60*n+l;try{r=new Intl.DateTimeFormat("en-US",{timeZone:e.tz,weekday:"short"}).format(i)}catch{return!0}let a={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6}[r]??i.getDay();if(!e.days.includes(a))return!1;let[s,c]=e.from.split(":").map(Number),[d,u]=e.until.split(":").map(Number),f=60*s+c,A=60*d+u;return A<f?o>=f||o<A:o>=f&&o<A}(c.accessSchedule)){let{from:e,until:t,tz:r}=c.accessSchedule;return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.FORBIDDEN,`Access denied outside allowed hours (${e}–${t} ${r})`)}}if(a&&c.allowedModels&&c.allowedModels.length>0&&!await (0,r.isModelAllowedForKey)(s,a))return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.FORBIDDEN,`Model "${a}" is not allowed for this API key`)};if(c.id)try{let e=(0,i.checkBudget)(c.id);if(!e.allowed)return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.RATE_LIMITED,e.reason||"Budget limit exceeded")}}catch(e){return o.error("API_POLICY","Budget check failed. Request blocked.",{error:e}),{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.SERVICE_UNAVAILABLE,"Budget policy unavailable")}}return{apiKey:s,apiKeyInfo:c,rejection:null}}e.s(["enforceApiKeyPolicy",()=>a])}];
1
+ module.exports=[287726,e=>{"use strict";e.i(245272);var t=e.i(385498),r=e.i(125852),i=e.i(548941),n=e.i(25687),l=e.i(441637),o=e.i(828059),a=e.i(16023),s=e.i(706901),c=e.i(73114);function d(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function u(e){return"string"==typeof e&&e.trim().length>0?e:null}function f(e,t=0){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&e.trim().length>0){let r=Number(e);return Number.isFinite(r)?r:t}return t}function A(e){let t=d(e);return{id:u(t.id)||"",isActive:!0===t.isActive,rateLimitedUntil:u(t.rateLimitedUntil),testStatus:u(t.testStatus),apiKey:u(t.apiKey),accessToken:u(t.accessToken),refreshToken:u(t.refreshToken),tokenExpiresAt:u(t.tokenExpiresAt),expiresAt:u(t.expiresAt),projectId:u(t.projectId),providerSpecificData:d(t.providerSpecificData),lastUsedAt:u(t.lastUsedAt),consecutiveUseCount:f(t.consecutiveUseCount,0),priority:f(t.priority,999),lastError:u(t.lastError),lastErrorType:u(t.lastErrorType),lastErrorSource:u(t.lastErrorSource),errorCode:"string"==typeof t.errorCode||"number"==typeof t.errorCode?t.errorCode:null,backoffLevel:f(t.backoffLevel,0)}}function p(e,t){return"boolean"==typeof e?e:t}function m(e,t=90){return Math.min(100,Math.max(1,f(e,t)))}function h(e){if("string"!=typeof e)return null;let t=e.trim().toLowerCase();return t.length>0?t:null}function y(e){if("string"!=typeof e)return null;let t=e.trim().toLowerCase();return"session (5h)"===t||"5h"===t||"five_hour"===t?"session":"weekly (7d)"===t||"7d"===t||"seven_day"===t?"weekly":t}function g(e){if(!e)return null;let t=new Date(e).getTime();return!Number.isFinite(t)||t<=Date.now()?null:t}function U(e){return e.map(e=>({raw:e,ms:g(e)})).filter(e=>null!==e.ms).sort((e,t)=>e.ms-t.ms)[0]?.raw||null}let w=Promise.resolve(),T=new Map;async function v(e,r=null,o=null){let a,u=w;w=new Promise(e=>{a=e});try{let a;await u;let w=await (0,t.getProviderConnections)({provider:e,isActive:!0}),T=(Array.isArray(w)?w:[]).map(A).filter(e=>e.id.length>0);if(o&&o.length>0&&(T=T.filter(e=>o.includes(e.id))),s.debug("AUTH",`${e} | total connections: ${T.length}, excludeId: ${r||"none"}`),0===T.length){let r=await (0,t.getProviderConnections)({provider:e}),i=(Array.isArray(r)?r:[]).map(A).filter(e=>e.id.length>0);if(s.debug("AUTH",`${e} | all connections (incl inactive): ${i.length}`),i.length>0){let t=(0,l.getEarliestRateLimitedUntil)(i);if(t)return s.warn("AUTH",`${e} | all ${i.length} accounts rate limited (${(0,l.formatRetryAfter)(t)})`),{allRateLimited:!0,retryAfter:t,retryAfterHuman:(0,l.formatRetryAfter)(t)};s.warn("AUTH",`${e} | ${i.length} accounts found but none active`),i.forEach(e=>{s.debug("AUTH",` → ${e.id?.slice(0,8)} | isActive=${e.isActive} | rateLimitedUntil=${e.rateLimitedUntil||"none"} | testStatus=${e.testStatus}`)})}return s.warn("AUTH",`No credentials for ${e}`),null}let v=T.filter(e=>!(r&&e.id===r||(0,l.isAccountUnavailable)(e.rateLimitedUntil)));if(s.debug("AUTH",`${e} | available: ${v.length}/${T.length}`),T.forEach(e=>{let t=r&&e.id===r,i=(0,l.isAccountUnavailable)(e.rateLimitedUntil);(t||i)&&s.debug("AUTH",` → ${e.id?.slice(0,8)} | ${t?"excluded":""} ${i?`rateLimited until ${e.rateLimitedUntil}`:""}`)}),0===v.length){let t=(0,l.getEarliestRateLimitedUntil)(T);if(t){let r=T.filter(e=>e.rateLimitedUntil&&new Date(e.rateLimitedUntil).getTime()>Date.now()).sort((e,t)=>new Date(e.rateLimitedUntil||0).getTime()-new Date(t.rateLimitedUntil||0).getTime())[0];return s.warn("AUTH",`${e} | all ${T.length} active accounts rate limited (${(0,l.formatRetryAfter)(t)}) | lastErrorCode=${r?.errorCode}, lastError=${r?.lastError?.slice(0,50)}`),{allRateLimited:!0,retryAfter:t,retryAfterHuman:(0,l.formatRetryAfter)(t),lastError:r?.lastError||null,lastErrorCode:r?.errorCode||null}}return s.warn("AUTH",`${e} | all ${T.length} accounts unavailable`),null}let S=v,b=[];if(S=v.filter(t=>{let r=function(e,t){let r=function(e,t){let r=d(t.limitPolicy),i=(Array.isArray(r.windows)?r.windows:[]).map(h).filter(Boolean);if("codex"===e){var n,l;let e,o,a,s=(n=i,l=t,o=(e=d(l.codexLimitPolicy),{use5h:p(e.use5h,!0),useWeekly:p(e.useWeekly,!0)}),a=(a=[...n.map(y).filter(Boolean)]).filter(e=>"session"===e?o.use5h:"weekly"!==e||o.useWeekly),o.use5h&&a.push("session"),o.useWeekly&&a.push("weekly"),[...new Set(a)]);return{enabled:p(r.enabled,s.length>0),thresholdPercent:m(r.thresholdPercent),windows:s}}return{enabled:p(r.enabled,!1),thresholdPercent:m(r.thresholdPercent),windows:i}}(e,t.providerSpecificData);if(!r.enabled||0===r.windows.length)return{blocked:!1,reasons:[],resetAt:null};let i=[],l=[];for(let e of r.windows){let o=(0,n.getQuotaWindowStatus)(t.id,e,r.thresholdPercent);o?.reachedThreshold&&(i.push(`${e} usage ${Math.round(o.usedPercentage)}%`),l.push(o.resetAt))}return{blocked:i.length>0,reasons:i,resetAt:U(l)}}(e,t);return!r.blocked||(b.push({id:t.id,reasons:r.reasons,resetAt:r.resetAt}),!1)}),b.length>0&&s.info("AUTH",`${e} | quota policy filtered ${b.length} account(s): ${b.map(e=>`${e.id.slice(0,8)}(${e.reasons.join(", ")})`).join("; ")}`),0===S.length&&v.length>0){let t=U(b.map(e=>e.resetAt)),r=g(t),i=r?new Date(r).toISOString():new Date(Date.now()+3e5).toISOString();return{allRateLimited:!0,retryAfter:i,retryAfterHuman:(0,l.formatRetryAfter)(i),lastError:`All ${e} accounts reached configured quota threshold`,lastErrorCode:429}}let $=S.filter(e=>!(0,n.isAccountQuotaExhausted)(e.id)),k=S.filter(e=>(0,n.isAccountQuotaExhausted)(e.id)),E=$.length>0?[...$,...k]:S;k.length>0&&s.debug("AUTH",`${e} | quota-aware: ${$.length} with quota, ${k.length} exhausted`);let L=await (0,i.getSettings)(),D=L.fallbackStrategy||"fill-first";if("round-robin"===D){let i=f(L.stickyRoundRobinLimit,3);if(null!==r)a=[...E].sort((e,t)=>{let r=e.backoffLevel||0,i=t.backoffLevel||0;return r!==i?r-i:e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(e.lastUsedAt).getTime()-new Date(t.lastUsedAt).getTime():1:-1:(e.priority||999)-(t.priority||999)})[0],s.info("AUTH",`${e} round-robin: FALLBACK MODE - excluded ${r?.slice(0,8)}..., picked LRU ${a.id?.slice(0,8)}...`),await (0,t.updateProviderConnection)(a.id,{lastUsedAt:new Date().toISOString(),consecutiveUseCount:1});else{let r=[...E].sort((e,t)=>e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(t.lastUsedAt).getTime()-new Date(e.lastUsedAt).getTime():-1:1:(e.priority||999)-(t.priority||999))[0],n=r?.consecutiveUseCount||0;r&&r.lastUsedAt&&n<i?(a=r,s.debug("AUTH",`${e} round-robin: staying with ${r.id?.slice(0,8)}... (count=${n}/${i})`),await (0,t.updateProviderConnection)(a.id,{lastUsedAt:new Date().toISOString(),consecutiveUseCount:(a.consecutiveUseCount||0)+1})):(a=[...E].sort((e,t)=>{let r=e.backoffLevel||0,i=t.backoffLevel||0;return r!==i?r-i:e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(e.lastUsedAt).getTime()-new Date(t.lastUsedAt).getTime():1:-1:(e.priority||999)-(t.priority||999)})[0],s.debug("AUTH",`${e} round-robin: switching to LRU ${a.id?.slice(0,8)}... (current count=${n} >= limit=${i} or no lastUsedAt)`),await (0,t.updateProviderConnection)(a.id,{lastUsedAt:new Date().toISOString(),consecutiveUseCount:1}))}}else if("p2c"===D)if(E.length<=2)a=E[0];else{let e=Math.floor(Math.random()*E.length),t=Math.floor(Math.random()*(E.length-1));t>=e&&t++;let r=E[e],i=E[t],n=(r.consecutiveUseCount||0)+10*!!r.lastError,l=(i.consecutiveUseCount||0)+10*!!i.lastError;a=n<=l?r:i}else if("random"===D){let e=Math.floor(Math.random()*E.length);a=E[e]}else if("least-used"===D)a=[...E].sort((e,t)=>e.lastUsedAt||t.lastUsedAt?e.lastUsedAt?t.lastUsedAt?new Date(e.lastUsedAt).getTime()-new Date(t.lastUsedAt).getTime():1:-1:(e.priority||999)-(t.priority||999))[0];else if("cost-optimized"===D)a=[...E].sort((e,t)=>(e.priority||999)-(t.priority||999))[0];else if("strict-random"===D){let t=E.map(e=>e.id),r=(0,c.getNextFromDeckSync)(`conn:${e}`,t);a=E.find(e=>e.id===r)||E[0]}else a=E[0];return{apiKey:a.apiKey,accessToken:a.accessToken,refreshToken:a.refreshToken,expiresAt:a.tokenExpiresAt||a.expiresAt||null,projectId:a.projectId,copilotToken:"string"==typeof a.providerSpecificData.copilotToken?a.providerSpecificData.copilotToken:null,providerSpecificData:a.providerSpecificData,connectionId:a.id,testStatus:a.testStatus,lastError:a.lastError,lastErrorType:a.lastErrorType,lastErrorSource:a.lastErrorSource,errorCode:a.errorCode,rateLimitedUntil:a.rateLimitedUntil}}finally{a&&a()}}async function S(e,r,i,n=null,c=null){let d,u=T.get(e)||Promise.resolve();T.set(e,new Promise(e=>{d=e}));try{await u;let d=await (0,t.getProviderConnections)({provider:n}),f=(Array.isArray(d)?d:[]).map(A).filter(e=>e.id.length>0).find(t=>t.id===e),p=f?.backoffLevel||0;if(f?.rateLimitedUntil&&new Date(f.rateLimitedUntil).getTime()>Date.now())return s.info("AUTH",`${e.slice(0,8)} already marked unavailable (until ${f.rateLimitedUntil}), skipping duplicate mark`),{shouldFallback:!0,cooldownMs:new Date(f.rateLimitedUntil).getTime()-Date.now()};let{shouldFallback:m,cooldownMs:h,newBackoffLevel:y,reason:g}=(0,l.checkFallbackError)(r,i,p,c,n);if(!m)return{shouldFallback:!1,cooldownMs:0};let U=f?.providerSpecificData?.baseUrl;if((0,o.isLocalProvider)(U)&&404===r&&n&&c){let t=a.COOLDOWN_MS.notFoundLocal;return(0,l.lockModel)(n,e,c,"local_not_found",t),s.info("AUTH",`Local 404 for ${c} — model-only lockout ${t/1e3}s (connection stays active)`),{shouldFallback:!0,cooldownMs:t}}let w=(0,l.getUnavailableUntil)(h),T="string"==typeof i?i.slice(0,100):"Provider error";return await (0,t.updateProviderConnection)(e,{rateLimitedUntil:w,testStatus:"unavailable",lastError:T,errorCode:r,lastErrorAt:new Date().toISOString(),backoffLevel:y??p}),n&&c&&h>0&&(0,l.lockModel)(n,e,c,g||"unknown",h),n&&r&&T&&console.error(`❌ ${n} [${r}]: ${T}`),{shouldFallback:!0,cooldownMs:h}}finally{d&&d(),T.delete(e)}}async function b(e,r){(r.testStatus&&"active"!==r.testStatus||r.lastError||r.rateLimitedUntil||r.errorCode||r.lastErrorType||r.lastErrorSource)&&(await (0,t.updateProviderConnection)(e,{testStatus:"active",lastError:null,lastErrorAt:null,lastErrorType:null,lastErrorSource:null,errorCode:null,rateLimitedUntil:null,backoffLevel:0}),s.info("AUTH",`Account ${e.slice(0,8)} error cleared`))}async function $(e){e?.connectionId&&await b(e.connectionId,e)}function k(e){let t=e.headers.get("Authorization");return t?.startsWith("Bearer ")?t.slice(7):null}async function E(e){return!!e&&await (0,r.validateApiKey)(e)}e.s(["clearAccountError",()=>b,"clearRecoveredProviderState",()=>$,"extractApiKey",()=>k,"getProviderCredentials",()=>v,"isValidApiKey",()=>E,"markAccountUnavailable",()=>S])},478847,e=>{"use strict";var t=e.i(287726);e.i(245272);var r=e.i(125852),i=e.i(362225),n=e.i(719201),l=e.i(16023),o=e.i(706901);async function a(e,a){let s=(0,t.extractApiKey)(e);if(!s)return{apiKey:null,apiKeyInfo:null,rejection:null};let c=null;try{c=await (0,r.getApiKeyMetadata)(s)}catch(e){return o.error("API_POLICY","Failed to fetch API key metadata. Request blocked.",{error:e}),{apiKey:s,apiKeyInfo:null,rejection:(0,n.errorResponse)(l.HTTP_STATUS.SERVICE_UNAVAILABLE,"API key policy unavailable")}}if(!c)return{apiKey:s,apiKeyInfo:null,rejection:null};if(!1===c.isActive)return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.FORBIDDEN,"This API key is disabled")};if(c.accessSchedule&&c.accessSchedule.enabled&&!function(e){let t,r;if(!e.enabled)return!0;let i=new Date;try{t=new Intl.DateTimeFormat("en-US",{timeZone:e.tz,hour:"2-digit",minute:"2-digit",hour12:!1}).format(i)}catch{return!0}let[n,l]=t.replace(/^24:/,"00:").split(":").map(Number),o=60*n+l;try{r=new Intl.DateTimeFormat("en-US",{timeZone:e.tz,weekday:"short"}).format(i)}catch{return!0}let a={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6}[r]??i.getDay();if(!e.days.includes(a))return!1;let[s,c]=e.from.split(":").map(Number),[d,u]=e.until.split(":").map(Number),f=60*s+c,A=60*d+u;return A<f?o>=f||o<A:o>=f&&o<A}(c.accessSchedule)){let{from:e,until:t,tz:r}=c.accessSchedule;return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.FORBIDDEN,`Access denied outside allowed hours (${e}–${t} ${r})`)}}if(a&&c.allowedModels&&c.allowedModels.length>0&&!await (0,r.isModelAllowedForKey)(s,a))return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.FORBIDDEN,`Model "${a}" is not allowed for this API key`)};if(c.id)try{let e=(0,i.checkBudget)(c.id);if(!e.allowed)return{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.RATE_LIMITED,e.reason||"Budget limit exceeded")}}catch(e){return o.error("API_POLICY","Budget check failed. Request blocked.",{error:e}),{apiKey:s,apiKeyInfo:c,rejection:(0,n.errorResponse)(l.HTTP_STATUS.SERVICE_UNAVAILABLE,"Budget policy unavailable")}}return{apiKey:s,apiKeyInfo:c,rejection:null}}e.s(["enforceApiKeyPolicy",()=>a])}];
2
2
 
3
3
  //# sourceMappingURL=src_4787afd3._.js.map
@@ -1,3 +1,3 @@
1
- module.exports=[918622,(a,b,c)=>{b.exports=a.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},677850,a=>a.a(async(b,c)=>{try{let b=await a.y("zod");a.n(b),c()}catch(a){c(a)}},!0),342602,(a,b,c)=>{"use strict";b.exports=a.r(918622)},187924,(a,b,c)=>{"use strict";b.exports=a.r(342602).vendored["react-ssr"].ReactJsxRuntime},572131,(a,b,c)=>{"use strict";b.exports=a.r(342602).vendored["react-ssr"].React},804730,a=>{a.v({name:"omniroute",version:"2.7.2",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.",type:"module",bin:{omniroute:"bin/omniroute.mjs","omniroute-reset-password":"bin/reset-password.mjs"},files:["bin/","app/","open-sse/mcp-server/","src/shared/contracts/","scripts/postinstall.mjs","scripts/native-binary-compat.mjs","README.md","LICENSE"],workspaces:["open-sse"],engines:{node:">=18.0.0 <24.0.0"},keywords:["ai","router","proxy","openai","claude","anthropic","gemini","fallback","cursor","cline","codex","llm","auto-fallback"],license:"MIT",author:"diegosouzapw",repository:{type:"git",url:"https://github.com/diegosouzapw/OmniRoute"},homepage:"https://omniroute.online",scripts:{dev:"node scripts/run-next.mjs dev",build:"next build","build:cli":"node scripts/prepublish.mjs",start:"node scripts/run-next.mjs start",lint:"eslint .","electron:dev":'concurrently "npm run dev" "wait-on http://localhost:20128 && cd electron && npm run dev"',"electron:build":"npm run build && cd electron && npm run build","electron:build:win":"npm run build && cd electron && npm run build:win","electron:build:mac":"npm run build && cd electron && npm run build:mac","electron:build:linux":"npm run build && cd electron && npm run build:linux",test:"node --import tsx/esm --test tests/unit/*.test.mjs","test:unit":"node --import tsx/esm --test tests/unit/*.test.mjs","test:plan3":"node --import tsx/esm --test tests/unit/plan3-p0.test.mjs","test:fixes":"node --import tsx/esm --test tests/unit/fixes-p1.test.mjs","test:security":"node --import tsx/esm --test tests/unit/security-fase01.test.mjs","check:cycles":"node scripts/check-cycles.mjs","check:route-validation:t06":"node scripts/check-route-validation.mjs","check:any-budget:t11":"node scripts/check-t11-any-budget.mjs","check:docs-sync":"node scripts/check-docs-sync.mjs","typecheck:core":"tsc --pretty false -p tsconfig.typecheck-core.json","typecheck:noimplicit:core":"tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json","test:integration":"node --import tsx/esm --test tests/integration/*.test.mjs","test:e2e":"node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts","test:protocols:e2e":"node scripts/run-protocol-clients-tests.mjs","test:vitest":"vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts","test:ecosystem":"node scripts/run-ecosystem-tests.mjs","test:coverage":"npx c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs","test:all":"npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",check:"npm run lint && npm run test",prepublishOnly:"npm run build:cli",postinstall:"node scripts/postinstall.mjs",prepare:"husky","system-info":"node scripts/system-info.mjs"},dependencies:{"@modelcontextprotocol/sdk":"^1.27.1","@monaco-editor/react":"^4.7.0",bcryptjs:"^3.0.3","better-sqlite3":"^12.6.2",bottleneck:"^2.19.5",dompurify:"^3.3.2",express:"^5.2.1","fetch-socks":"^1.3.2","http-proxy-middleware":"^3.0.5","https-proxy-agent":"^8.0.0",jose:"^6.1.3",lowdb:"^7.0.1","monaco-editor":"^0.55.1",next:"^16.1.6","next-intl":"^4.8.3","node-machine-id":"^1.1.12",open:"^11.0.0",ora:"^9.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.4","react-dom":"19.2.4",recharts:"^3.7.0",selfsigned:"^5.5.0",tsx:"^4.21.0",undici:"^7.19.2",uuid:"^13.0.0","wreq-js":"^2.0.1",zod:"^4.3.6",zustand:"^5.0.10","@swc/helpers":"0.5.19"},devDependencies:{"@playwright/test":"^1.58.2","@tailwindcss/postcss":"^4.1.18","@types/bcryptjs":"^3.0.0","@types/better-sqlite3":"^7.6.13","@types/node":"^25.2.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3",concurrently:"^9.2.1","cross-env":"^10.1.0",eslint:"^9.39.2","eslint-config-next":"16.1.6",husky:"^9.1.7","lint-staged":"^16.2.7",prettier:"^3.8.1",tailwindcss:"^4",typescript:"^5.9.3","typescript-eslint":"^8.56.0",vitest:"^4.0.18","wait-on":"^9.0.4"},"lint-staged":{"*.{js,jsx,ts,tsx,mjs}":["prettier --write","eslint --fix --no-error-on-unmatched-pattern"],"*.{json,md,yml,yaml,css}":["prettier --write"]},pnpm:{onlyBuiltDependencies:["@parcel/watcher","@swc/core","better-sqlite3","esbuild","omniroute","sharp"]}})},588788,a=>{"use strict";var b=a.i(32886),c=a.i(187924);function d({locale:a,...d}){if(!a)throw Error(void 0);return(0,c.jsx)(b.IntlProvider,{locale:a,...d})}a.s(["default",()=>d])}];
1
+ module.exports=[918622,(a,b,c)=>{b.exports=a.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},677850,a=>a.a(async(b,c)=>{try{let b=await a.y("zod");a.n(b),c()}catch(a){c(a)}},!0),342602,(a,b,c)=>{"use strict";b.exports=a.r(918622)},187924,(a,b,c)=>{"use strict";b.exports=a.r(342602).vendored["react-ssr"].ReactJsxRuntime},572131,(a,b,c)=>{"use strict";b.exports=a.r(342602).vendored["react-ssr"].React},804730,a=>{a.v({name:"omniroute",version:"2.7.3",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.",type:"module",bin:{omniroute:"bin/omniroute.mjs","omniroute-reset-password":"bin/reset-password.mjs"},files:["bin/","app/","open-sse/mcp-server/","src/shared/contracts/","scripts/postinstall.mjs","scripts/native-binary-compat.mjs","README.md","LICENSE"],workspaces:["open-sse"],engines:{node:">=18.0.0 <24.0.0"},keywords:["ai","router","proxy","openai","claude","anthropic","gemini","fallback","cursor","cline","codex","llm","auto-fallback"],license:"MIT",author:"diegosouzapw",repository:{type:"git",url:"https://github.com/diegosouzapw/OmniRoute"},homepage:"https://omniroute.online",scripts:{dev:"node scripts/run-next.mjs dev",build:"next build","build:cli":"node scripts/prepublish.mjs",start:"node scripts/run-next.mjs start",lint:"eslint .","electron:dev":'concurrently "npm run dev" "wait-on http://localhost:20128 && cd electron && npm run dev"',"electron:build":"npm run build && cd electron && npm run build","electron:build:win":"npm run build && cd electron && npm run build:win","electron:build:mac":"npm run build && cd electron && npm run build:mac","electron:build:linux":"npm run build && cd electron && npm run build:linux",test:"node --import tsx/esm --test tests/unit/*.test.mjs","test:unit":"node --import tsx/esm --test tests/unit/*.test.mjs","test:plan3":"node --import tsx/esm --test tests/unit/plan3-p0.test.mjs","test:fixes":"node --import tsx/esm --test tests/unit/fixes-p1.test.mjs","test:security":"node --import tsx/esm --test tests/unit/security-fase01.test.mjs","check:cycles":"node scripts/check-cycles.mjs","check:route-validation:t06":"node scripts/check-route-validation.mjs","check:any-budget:t11":"node scripts/check-t11-any-budget.mjs","check:docs-sync":"node scripts/check-docs-sync.mjs","typecheck:core":"tsc --pretty false -p tsconfig.typecheck-core.json","typecheck:noimplicit:core":"tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json","test:integration":"node --import tsx/esm --test tests/integration/*.test.mjs","test:e2e":"node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts","test:protocols:e2e":"node scripts/run-protocol-clients-tests.mjs","test:vitest":"vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts","test:ecosystem":"node scripts/run-ecosystem-tests.mjs","test:coverage":"npx c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs","test:all":"npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",check:"npm run lint && npm run test",prepublishOnly:"npm run build:cli",postinstall:"node scripts/postinstall.mjs",prepare:"husky","system-info":"node scripts/system-info.mjs"},dependencies:{"@modelcontextprotocol/sdk":"^1.27.1","@monaco-editor/react":"^4.7.0",bcryptjs:"^3.0.3","better-sqlite3":"^12.6.2",bottleneck:"^2.19.5",dompurify:"^3.3.2",express:"^5.2.1","fetch-socks":"^1.3.2","http-proxy-middleware":"^3.0.5","https-proxy-agent":"^8.0.0",jose:"^6.1.3",lowdb:"^7.0.1","monaco-editor":"^0.55.1",next:"^16.1.6","next-intl":"^4.8.3","node-machine-id":"^1.1.12",open:"^11.0.0",ora:"^9.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.4","react-dom":"19.2.4",recharts:"^3.7.0",selfsigned:"^5.5.0",tsx:"^4.21.0",undici:"^7.19.2",uuid:"^13.0.0","wreq-js":"^2.0.1",zod:"^4.3.6",zustand:"^5.0.10","@swc/helpers":"0.5.19"},devDependencies:{"@playwright/test":"^1.58.2","@tailwindcss/postcss":"^4.1.18","@types/bcryptjs":"^3.0.0","@types/better-sqlite3":"^7.6.13","@types/node":"^25.2.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3",concurrently:"^9.2.1","cross-env":"^10.1.0",eslint:"^9.39.2","eslint-config-next":"16.1.6",husky:"^9.1.7","lint-staged":"^16.2.7",prettier:"^3.8.1",tailwindcss:"^4",typescript:"^5.9.3","typescript-eslint":"^8.56.0",vitest:"^4.0.18","wait-on":"^9.0.4"},"lint-staged":{"*.{js,jsx,ts,tsx,mjs}":["prettier --write","eslint --fix --no-error-on-unmatched-pattern"],"*.{json,md,yml,yaml,css}":["prettier --write"]},pnpm:{onlyBuiltDependencies:["@parcel/watcher","@swc/core","better-sqlite3","esbuild","omniroute","sharp"]}})},588788,a=>{"use strict";var b=a.i(32886),c=a.i(187924);function d({locale:a,...d}){if(!a)throw Error(void 0);return(0,c.jsx)(b.IntlProvider,{locale:a,...d})}a.s(["default",()=>d])}];
2
2
 
3
3
  //# sourceMappingURL=%5Broot-of-the-server%5D__9affb65e._.js.map
@@ -1,3 +1,3 @@
1
- module.exports=[193695,(a,b,c)=>{b.exports=a.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},677850,a=>a.a(async(b,c)=>{try{let b=await a.y("zod");a.n(b),c()}catch(a){c(a)}},!0),804730,a=>{a.v({name:"omniroute",version:"2.7.2",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.",type:"module",bin:{omniroute:"bin/omniroute.mjs","omniroute-reset-password":"bin/reset-password.mjs"},files:["bin/","app/","open-sse/mcp-server/","src/shared/contracts/","scripts/postinstall.mjs","scripts/native-binary-compat.mjs","README.md","LICENSE"],workspaces:["open-sse"],engines:{node:">=18.0.0 <24.0.0"},keywords:["ai","router","proxy","openai","claude","anthropic","gemini","fallback","cursor","cline","codex","llm","auto-fallback"],license:"MIT",author:"diegosouzapw",repository:{type:"git",url:"https://github.com/diegosouzapw/OmniRoute"},homepage:"https://omniroute.online",scripts:{dev:"node scripts/run-next.mjs dev",build:"next build","build:cli":"node scripts/prepublish.mjs",start:"node scripts/run-next.mjs start",lint:"eslint .","electron:dev":'concurrently "npm run dev" "wait-on http://localhost:20128 && cd electron && npm run dev"',"electron:build":"npm run build && cd electron && npm run build","electron:build:win":"npm run build && cd electron && npm run build:win","electron:build:mac":"npm run build && cd electron && npm run build:mac","electron:build:linux":"npm run build && cd electron && npm run build:linux",test:"node --import tsx/esm --test tests/unit/*.test.mjs","test:unit":"node --import tsx/esm --test tests/unit/*.test.mjs","test:plan3":"node --import tsx/esm --test tests/unit/plan3-p0.test.mjs","test:fixes":"node --import tsx/esm --test tests/unit/fixes-p1.test.mjs","test:security":"node --import tsx/esm --test tests/unit/security-fase01.test.mjs","check:cycles":"node scripts/check-cycles.mjs","check:route-validation:t06":"node scripts/check-route-validation.mjs","check:any-budget:t11":"node scripts/check-t11-any-budget.mjs","check:docs-sync":"node scripts/check-docs-sync.mjs","typecheck:core":"tsc --pretty false -p tsconfig.typecheck-core.json","typecheck:noimplicit:core":"tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json","test:integration":"node --import tsx/esm --test tests/integration/*.test.mjs","test:e2e":"node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts","test:protocols:e2e":"node scripts/run-protocol-clients-tests.mjs","test:vitest":"vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts","test:ecosystem":"node scripts/run-ecosystem-tests.mjs","test:coverage":"npx c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs","test:all":"npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",check:"npm run lint && npm run test",prepublishOnly:"npm run build:cli",postinstall:"node scripts/postinstall.mjs",prepare:"husky","system-info":"node scripts/system-info.mjs"},dependencies:{"@modelcontextprotocol/sdk":"^1.27.1","@monaco-editor/react":"^4.7.0",bcryptjs:"^3.0.3","better-sqlite3":"^12.6.2",bottleneck:"^2.19.5",dompurify:"^3.3.2",express:"^5.2.1","fetch-socks":"^1.3.2","http-proxy-middleware":"^3.0.5","https-proxy-agent":"^8.0.0",jose:"^6.1.3",lowdb:"^7.0.1","monaco-editor":"^0.55.1",next:"^16.1.6","next-intl":"^4.8.3","node-machine-id":"^1.1.12",open:"^11.0.0",ora:"^9.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.4","react-dom":"19.2.4",recharts:"^3.7.0",selfsigned:"^5.5.0",tsx:"^4.21.0",undici:"^7.19.2",uuid:"^13.0.0","wreq-js":"^2.0.1",zod:"^4.3.6",zustand:"^5.0.10","@swc/helpers":"0.5.19"},devDependencies:{"@playwright/test":"^1.58.2","@tailwindcss/postcss":"^4.1.18","@types/bcryptjs":"^3.0.0","@types/better-sqlite3":"^7.6.13","@types/node":"^25.2.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3",concurrently:"^9.2.1","cross-env":"^10.1.0",eslint:"^9.39.2","eslint-config-next":"16.1.6",husky:"^9.1.7","lint-staged":"^16.2.7",prettier:"^3.8.1",tailwindcss:"^4",typescript:"^5.9.3","typescript-eslint":"^8.56.0",vitest:"^4.0.18","wait-on":"^9.0.4"},"lint-staged":{"*.{js,jsx,ts,tsx,mjs}":["prettier --write","eslint --fix --no-error-on-unmatched-pattern"],"*.{json,md,yml,yaml,css}":["prettier --write"]},pnpm:{onlyBuiltDependencies:["@parcel/watcher","@swc/core","better-sqlite3","esbuild","omniroute","sharp"]}})},569264,a=>{a.n(a.i(354832))},650645,a=>{a.n(a.i(827572))},923576,a=>{a.n(a.i(104858))},825210,a=>{a.n(a.i(402747))},517537,a=>{a.n(a.i(903363))},13718,a=>{a.n(a.i(685523))},118198,a=>{a.n(a.i(545518))},296736,(a,b,c)=>{"use strict";function d(a){if("function"!=typeof WeakMap)return null;var b=new WeakMap,c=new WeakMap;return(d=function(a){return a?c:b})(a)}c._=function(a,b){if(!b&&a&&a.__esModule)return a;if(null===a||"object"!=typeof a&&"function"!=typeof a)return{default:a};var c=d(b);if(c&&c.has(a))return c.get(a);var e={__proto__:null},f=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var g in a)if("default"!==g&&Object.prototype.hasOwnProperty.call(a,g)){var h=f?Object.getOwnPropertyDescriptor(a,g):null;h&&(h.get||h.set)?Object.defineProperty(e,g,h):e[g]=a[g]}return e.default=a,c&&c.set(a,e),e}},500790,(a,b,c)=>{let{createClientModuleProxy:d}=a.r(211857);a.n(d("[project]/node_modules/next/dist/client/app-dir/link.js <module evaluation>"))},784707,(a,b,c)=>{let{createClientModuleProxy:d}=a.r(211857);a.n(d("[project]/node_modules/next/dist/client/app-dir/link.js"))},297647,a=>{"use strict";a.i(500790);var b=a.i(784707);a.n(b)},395936,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={default:function(){return i},useLinkStatus:function(){return h.useLinkStatus}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});let f=a.r(296736),g=a.r(907997),h=f._(a.r(297647));function i(a){let b=a.legacyBehavior,c="string"==typeof a.children||"number"==typeof a.children||"string"==typeof a.children?.type,d=a.children?.type?.$$typeof===Symbol.for("react.client.reference");return!b||c||d||(a.children?.type?.$$typeof===Symbol.for("react.lazy")?console.error("Using a Lazy Component as a direct child of `<Link legacyBehavior>` from a Server Component is not supported. If you need legacyBehavior, wrap your Lazy Component in a Client Component that renders the Link's `<a>` tag."):console.error("Using a Server Component as a direct child of `<Link legacyBehavior>` is not supported. If you need legacyBehavior, wrap your Server Component in a Client Component that renders the Link's `<a>` tag.")),(0,g.jsx)(h.default,{...a})}("function"==typeof c.default||"object"==typeof c.default&&null!==c.default)&&void 0===c.default.__esModule&&(Object.defineProperty(c.default,"__esModule",{value:!0}),Object.assign(c.default,c),b.exports=c.default)},330878,a=>{"use strict";var b=a.i(800717),c=a.i(118845),d=a.i(40953),e=(0,b.cache)(function(a,b){return function({_cache:a=(0,c.b)(),_formatters:b=(0,c.c)(a),getMessageFallback:e=d.d,messages:f,namespace:g,onError:h=d.b,...i}){return function({messages:a,namespace:b,...c},e){return a=a["!"],b=(0,d.r)(b,"!"),(0,d.a)({...c,messages:a,namespace:b})}({...i,onError:h,cache:a,formatters:b,getMessageFallback:e,messages:{"!":f},namespace:g?`!.${g}`:"!"},0)}({...a,namespace:b})});a.s(["default",()=>e],330878)},442979,a=>{"use strict";var b=a.i(330878),c=a.i(767228),d=a.i(800717)["use".trim()];function e(...[a]){let f=function(a){var b=(0,c.default)();try{return d(b)}catch(b){throw b instanceof TypeError&&b.message.includes("Cannot read properties of null (reading 'use')")?Error(`\`${a}\` is not callable within an async component. Please refer to https://next-intl.dev/docs/environments/server-client-components#async-components`,{cause:b}):b}}("useTranslations");return(0,b.default)(f,a)}a.s(["useTranslations",()=>e],442979)}];
1
+ module.exports=[193695,(a,b,c)=>{b.exports=a.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},677850,a=>a.a(async(b,c)=>{try{let b=await a.y("zod");a.n(b),c()}catch(a){c(a)}},!0),804730,a=>{a.v({name:"omniroute",version:"2.7.3",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.",type:"module",bin:{omniroute:"bin/omniroute.mjs","omniroute-reset-password":"bin/reset-password.mjs"},files:["bin/","app/","open-sse/mcp-server/","src/shared/contracts/","scripts/postinstall.mjs","scripts/native-binary-compat.mjs","README.md","LICENSE"],workspaces:["open-sse"],engines:{node:">=18.0.0 <24.0.0"},keywords:["ai","router","proxy","openai","claude","anthropic","gemini","fallback","cursor","cline","codex","llm","auto-fallback"],license:"MIT",author:"diegosouzapw",repository:{type:"git",url:"https://github.com/diegosouzapw/OmniRoute"},homepage:"https://omniroute.online",scripts:{dev:"node scripts/run-next.mjs dev",build:"next build","build:cli":"node scripts/prepublish.mjs",start:"node scripts/run-next.mjs start",lint:"eslint .","electron:dev":'concurrently "npm run dev" "wait-on http://localhost:20128 && cd electron && npm run dev"',"electron:build":"npm run build && cd electron && npm run build","electron:build:win":"npm run build && cd electron && npm run build:win","electron:build:mac":"npm run build && cd electron && npm run build:mac","electron:build:linux":"npm run build && cd electron && npm run build:linux",test:"node --import tsx/esm --test tests/unit/*.test.mjs","test:unit":"node --import tsx/esm --test tests/unit/*.test.mjs","test:plan3":"node --import tsx/esm --test tests/unit/plan3-p0.test.mjs","test:fixes":"node --import tsx/esm --test tests/unit/fixes-p1.test.mjs","test:security":"node --import tsx/esm --test tests/unit/security-fase01.test.mjs","check:cycles":"node scripts/check-cycles.mjs","check:route-validation:t06":"node scripts/check-route-validation.mjs","check:any-budget:t11":"node scripts/check-t11-any-budget.mjs","check:docs-sync":"node scripts/check-docs-sync.mjs","typecheck:core":"tsc --pretty false -p tsconfig.typecheck-core.json","typecheck:noimplicit:core":"tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json","test:integration":"node --import tsx/esm --test tests/integration/*.test.mjs","test:e2e":"node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts","test:protocols:e2e":"node scripts/run-protocol-clients-tests.mjs","test:vitest":"vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts","test:ecosystem":"node scripts/run-ecosystem-tests.mjs","test:coverage":"npx c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs","test:all":"npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",check:"npm run lint && npm run test",prepublishOnly:"npm run build:cli",postinstall:"node scripts/postinstall.mjs",prepare:"husky","system-info":"node scripts/system-info.mjs"},dependencies:{"@modelcontextprotocol/sdk":"^1.27.1","@monaco-editor/react":"^4.7.0",bcryptjs:"^3.0.3","better-sqlite3":"^12.6.2",bottleneck:"^2.19.5",dompurify:"^3.3.2",express:"^5.2.1","fetch-socks":"^1.3.2","http-proxy-middleware":"^3.0.5","https-proxy-agent":"^8.0.0",jose:"^6.1.3",lowdb:"^7.0.1","monaco-editor":"^0.55.1",next:"^16.1.6","next-intl":"^4.8.3","node-machine-id":"^1.1.12",open:"^11.0.0",ora:"^9.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.4","react-dom":"19.2.4",recharts:"^3.7.0",selfsigned:"^5.5.0",tsx:"^4.21.0",undici:"^7.19.2",uuid:"^13.0.0","wreq-js":"^2.0.1",zod:"^4.3.6",zustand:"^5.0.10","@swc/helpers":"0.5.19"},devDependencies:{"@playwright/test":"^1.58.2","@tailwindcss/postcss":"^4.1.18","@types/bcryptjs":"^3.0.0","@types/better-sqlite3":"^7.6.13","@types/node":"^25.2.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3",concurrently:"^9.2.1","cross-env":"^10.1.0",eslint:"^9.39.2","eslint-config-next":"16.1.6",husky:"^9.1.7","lint-staged":"^16.2.7",prettier:"^3.8.1",tailwindcss:"^4",typescript:"^5.9.3","typescript-eslint":"^8.56.0",vitest:"^4.0.18","wait-on":"^9.0.4"},"lint-staged":{"*.{js,jsx,ts,tsx,mjs}":["prettier --write","eslint --fix --no-error-on-unmatched-pattern"],"*.{json,md,yml,yaml,css}":["prettier --write"]},pnpm:{onlyBuiltDependencies:["@parcel/watcher","@swc/core","better-sqlite3","esbuild","omniroute","sharp"]}})},569264,a=>{a.n(a.i(354832))},650645,a=>{a.n(a.i(827572))},923576,a=>{a.n(a.i(104858))},825210,a=>{a.n(a.i(402747))},517537,a=>{a.n(a.i(903363))},13718,a=>{a.n(a.i(685523))},118198,a=>{a.n(a.i(545518))},296736,(a,b,c)=>{"use strict";function d(a){if("function"!=typeof WeakMap)return null;var b=new WeakMap,c=new WeakMap;return(d=function(a){return a?c:b})(a)}c._=function(a,b){if(!b&&a&&a.__esModule)return a;if(null===a||"object"!=typeof a&&"function"!=typeof a)return{default:a};var c=d(b);if(c&&c.has(a))return c.get(a);var e={__proto__:null},f=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var g in a)if("default"!==g&&Object.prototype.hasOwnProperty.call(a,g)){var h=f?Object.getOwnPropertyDescriptor(a,g):null;h&&(h.get||h.set)?Object.defineProperty(e,g,h):e[g]=a[g]}return e.default=a,c&&c.set(a,e),e}},500790,(a,b,c)=>{let{createClientModuleProxy:d}=a.r(211857);a.n(d("[project]/node_modules/next/dist/client/app-dir/link.js <module evaluation>"))},784707,(a,b,c)=>{let{createClientModuleProxy:d}=a.r(211857);a.n(d("[project]/node_modules/next/dist/client/app-dir/link.js"))},297647,a=>{"use strict";a.i(500790);var b=a.i(784707);a.n(b)},395936,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={default:function(){return i},useLinkStatus:function(){return h.useLinkStatus}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});let f=a.r(296736),g=a.r(907997),h=f._(a.r(297647));function i(a){let b=a.legacyBehavior,c="string"==typeof a.children||"number"==typeof a.children||"string"==typeof a.children?.type,d=a.children?.type?.$$typeof===Symbol.for("react.client.reference");return!b||c||d||(a.children?.type?.$$typeof===Symbol.for("react.lazy")?console.error("Using a Lazy Component as a direct child of `<Link legacyBehavior>` from a Server Component is not supported. If you need legacyBehavior, wrap your Lazy Component in a Client Component that renders the Link's `<a>` tag."):console.error("Using a Server Component as a direct child of `<Link legacyBehavior>` is not supported. If you need legacyBehavior, wrap your Server Component in a Client Component that renders the Link's `<a>` tag.")),(0,g.jsx)(h.default,{...a})}("function"==typeof c.default||"object"==typeof c.default&&null!==c.default)&&void 0===c.default.__esModule&&(Object.defineProperty(c.default,"__esModule",{value:!0}),Object.assign(c.default,c),b.exports=c.default)},330878,a=>{"use strict";var b=a.i(800717),c=a.i(118845),d=a.i(40953),e=(0,b.cache)(function(a,b){return function({_cache:a=(0,c.b)(),_formatters:b=(0,c.c)(a),getMessageFallback:e=d.d,messages:f,namespace:g,onError:h=d.b,...i}){return function({messages:a,namespace:b,...c},e){return a=a["!"],b=(0,d.r)(b,"!"),(0,d.a)({...c,messages:a,namespace:b})}({...i,onError:h,cache:a,formatters:b,getMessageFallback:e,messages:{"!":f},namespace:g?`!.${g}`:"!"},0)}({...a,namespace:b})});a.s(["default",()=>e],330878)},442979,a=>{"use strict";var b=a.i(330878),c=a.i(767228),d=a.i(800717)["use".trim()];function e(...[a]){let f=function(a){var b=(0,c.default)();try{return d(b)}catch(b){throw b instanceof TypeError&&b.message.includes("Cannot read properties of null (reading 'use')")?Error(`\`${a}\` is not callable within an async component. Please refer to https://next-intl.dev/docs/environments/server-client-components#async-components`,{cause:b}):b}}("useTranslations");return(0,b.default)(f,a)}a.s(["useTranslations",()=>e],442979)}];
2
2
 
3
3
  //# sourceMappingURL=%5Broot-of-the-server%5D__a6942102._.js.map
@@ -1,2 +1,2 @@
1
- <!DOCTYPE html><!--_WuQZHRMiXNmIFgVwbr_Q--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e22b90cf374c3818.js"/><script src="/_next/static/chunks/2ba176114bbe6b2f.js" async=""></script><script src="/_next/static/chunks/b133d1854532ff8c.js" async=""></script><script src="/_next/static/chunks/726579f2940c2a2f.js" async=""></script><script src="/_next/static/chunks/956d411224e8600a.js" async=""></script><script src="/_next/static/chunks/turbopack-cce160b74a108c3f.js" async=""></script><script src="/_next/static/chunks/d96012bcfc98706a.js" async=""></script><script src="/_next/static/chunks/16ea27c3b926bc31.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
- @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/e22b90cf374c3818.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[339756,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"default\"]\n3:I[837457,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"default\"]\n4:I[897367,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[897367,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"ViewportBoundary\"]\n9:I[897367,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"MetadataBoundary\"]\nb:I[168027,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"_WuQZHRMiXNmIFgVwbr-Q\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/d96012bcfc98706a.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/16ea27c3b926bc31.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--TaE7xCUJ3vzE5oXXL5DhE--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e22b90cf374c3818.js"/><script src="/_next/static/chunks/2ba176114bbe6b2f.js" async=""></script><script src="/_next/static/chunks/b133d1854532ff8c.js" async=""></script><script src="/_next/static/chunks/726579f2940c2a2f.js" async=""></script><script src="/_next/static/chunks/956d411224e8600a.js" async=""></script><script src="/_next/static/chunks/turbopack-cce160b74a108c3f.js" async=""></script><script src="/_next/static/chunks/d96012bcfc98706a.js" async=""></script><script src="/_next/static/chunks/16ea27c3b926bc31.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
+ @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/e22b90cf374c3818.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[339756,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"default\"]\n3:I[837457,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"default\"]\n4:I[897367,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[897367,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"ViewportBoundary\"]\n9:I[897367,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"MetadataBoundary\"]\nb:I[168027,[\"/_next/static/chunks/d96012bcfc98706a.js\",\"/_next/static/chunks/16ea27c3b926bc31.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"TaE7xCUJ3vzE5oXXL5DhE\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/d96012bcfc98706a.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/16ea27c3b926bc31.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
@@ -1 +1 @@
1
- self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"GX6YbzExMmscZSwAYLBzAPEJgPrAnF2CLDAcWo0bvjk=\"\n}"
1
+ self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"ibM0I8aNYJ2QdSke9mv7/Lb8RwNJNtXTsIFfUKVxVws=\"\n}"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "node": {},
3
3
  "edge": {},
4
- "encryptionKey": "GX6YbzExMmscZSwAYLBzAPEJgPrAnF2CLDAcWo0bvjk="
4
+ "encryptionKey": "ibM0I8aNYJ2QdSke9mv7/Lb8RwNJNtXTsIFfUKVxVws="
5
5
  }
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,804730,t=>{t.v({name:"omniroute",version:"2.7.2",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.",type:"module",bin:{omniroute:"bin/omniroute.mjs","omniroute-reset-password":"bin/reset-password.mjs"},files:["bin/","app/","open-sse/mcp-server/","src/shared/contracts/","scripts/postinstall.mjs","scripts/native-binary-compat.mjs","README.md","LICENSE"],workspaces:["open-sse"],engines:{node:">=18.0.0 <24.0.0"},keywords:["ai","router","proxy","openai","claude","anthropic","gemini","fallback","cursor","cline","codex","llm","auto-fallback"],license:"MIT",author:"diegosouzapw",repository:{type:"git",url:"https://github.com/diegosouzapw/OmniRoute"},homepage:"https://omniroute.online",scripts:{dev:"node scripts/run-next.mjs dev",build:"next build","build:cli":"node scripts/prepublish.mjs",start:"node scripts/run-next.mjs start",lint:"eslint .","electron:dev":'concurrently "npm run dev" "wait-on http://localhost:20128 && cd electron && npm run dev"',"electron:build":"npm run build && cd electron && npm run build","electron:build:win":"npm run build && cd electron && npm run build:win","electron:build:mac":"npm run build && cd electron && npm run build:mac","electron:build:linux":"npm run build && cd electron && npm run build:linux",test:"node --import tsx/esm --test tests/unit/*.test.mjs","test:unit":"node --import tsx/esm --test tests/unit/*.test.mjs","test:plan3":"node --import tsx/esm --test tests/unit/plan3-p0.test.mjs","test:fixes":"node --import tsx/esm --test tests/unit/fixes-p1.test.mjs","test:security":"node --import tsx/esm --test tests/unit/security-fase01.test.mjs","check:cycles":"node scripts/check-cycles.mjs","check:route-validation:t06":"node scripts/check-route-validation.mjs","check:any-budget:t11":"node scripts/check-t11-any-budget.mjs","check:docs-sync":"node scripts/check-docs-sync.mjs","typecheck:core":"tsc --pretty false -p tsconfig.typecheck-core.json","typecheck:noimplicit:core":"tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json","test:integration":"node --import tsx/esm --test tests/integration/*.test.mjs","test:e2e":"node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts","test:protocols:e2e":"node scripts/run-protocol-clients-tests.mjs","test:vitest":"vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts","test:ecosystem":"node scripts/run-ecosystem-tests.mjs","test:coverage":"npx c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs","test:all":"npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",check:"npm run lint && npm run test",prepublishOnly:"npm run build:cli",postinstall:"node scripts/postinstall.mjs",prepare:"husky","system-info":"node scripts/system-info.mjs"},dependencies:{"@modelcontextprotocol/sdk":"^1.27.1","@monaco-editor/react":"^4.7.0",bcryptjs:"^3.0.3","better-sqlite3":"^12.6.2",bottleneck:"^2.19.5",dompurify:"^3.3.2",express:"^5.2.1","fetch-socks":"^1.3.2","http-proxy-middleware":"^3.0.5","https-proxy-agent":"^8.0.0",jose:"^6.1.3",lowdb:"^7.0.1","monaco-editor":"^0.55.1",next:"^16.1.6","next-intl":"^4.8.3","node-machine-id":"^1.1.12",open:"^11.0.0",ora:"^9.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.4","react-dom":"19.2.4",recharts:"^3.7.0",selfsigned:"^5.5.0",tsx:"^4.21.0",undici:"^7.19.2",uuid:"^13.0.0","wreq-js":"^2.0.1",zod:"^4.3.6",zustand:"^5.0.10","@swc/helpers":"0.5.19"},devDependencies:{"@playwright/test":"^1.58.2","@tailwindcss/postcss":"^4.1.18","@types/bcryptjs":"^3.0.0","@types/better-sqlite3":"^7.6.13","@types/node":"^25.2.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3",concurrently:"^9.2.1","cross-env":"^10.1.0",eslint:"^9.39.2","eslint-config-next":"16.1.6",husky:"^9.1.7","lint-staged":"^16.2.7",prettier:"^3.8.1",tailwindcss:"^4",typescript:"^5.9.3","typescript-eslint":"^8.56.0",vitest:"^4.0.18","wait-on":"^9.0.4"},"lint-staged":{"*.{js,jsx,ts,tsx,mjs}":["prettier --write","eslint --fix --no-error-on-unmatched-pattern"],"*.{json,md,yml,yaml,css}":["prettier --write"]},pnpm:{onlyBuiltDependencies:["@parcel/watcher","@swc/core","better-sqlite3","esbuild","omniroute","sharp"]}})},175696,t=>{"use strict";var e=t.i(861745),s=t.i(843476);function n({locale:t,...n}){if(!t)throw Error(void 0);return(0,s.jsx)(e.IntlProvider,{locale:t,...n})}t.s(["default",()=>n])}]);
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,804730,t=>{t.v({name:"omniroute",version:"2.7.3",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.",type:"module",bin:{omniroute:"bin/omniroute.mjs","omniroute-reset-password":"bin/reset-password.mjs"},files:["bin/","app/","open-sse/mcp-server/","src/shared/contracts/","scripts/postinstall.mjs","scripts/native-binary-compat.mjs","README.md","LICENSE"],workspaces:["open-sse"],engines:{node:">=18.0.0 <24.0.0"},keywords:["ai","router","proxy","openai","claude","anthropic","gemini","fallback","cursor","cline","codex","llm","auto-fallback"],license:"MIT",author:"diegosouzapw",repository:{type:"git",url:"https://github.com/diegosouzapw/OmniRoute"},homepage:"https://omniroute.online",scripts:{dev:"node scripts/run-next.mjs dev",build:"next build","build:cli":"node scripts/prepublish.mjs",start:"node scripts/run-next.mjs start",lint:"eslint .","electron:dev":'concurrently "npm run dev" "wait-on http://localhost:20128 && cd electron && npm run dev"',"electron:build":"npm run build && cd electron && npm run build","electron:build:win":"npm run build && cd electron && npm run build:win","electron:build:mac":"npm run build && cd electron && npm run build:mac","electron:build:linux":"npm run build && cd electron && npm run build:linux",test:"node --import tsx/esm --test tests/unit/*.test.mjs","test:unit":"node --import tsx/esm --test tests/unit/*.test.mjs","test:plan3":"node --import tsx/esm --test tests/unit/plan3-p0.test.mjs","test:fixes":"node --import tsx/esm --test tests/unit/fixes-p1.test.mjs","test:security":"node --import tsx/esm --test tests/unit/security-fase01.test.mjs","check:cycles":"node scripts/check-cycles.mjs","check:route-validation:t06":"node scripts/check-route-validation.mjs","check:any-budget:t11":"node scripts/check-t11-any-budget.mjs","check:docs-sync":"node scripts/check-docs-sync.mjs","typecheck:core":"tsc --pretty false -p tsconfig.typecheck-core.json","typecheck:noimplicit:core":"tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json","test:integration":"node --import tsx/esm --test tests/integration/*.test.mjs","test:e2e":"node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts","test:protocols:e2e":"node scripts/run-protocol-clients-tests.mjs","test:vitest":"vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts","test:ecosystem":"node scripts/run-ecosystem-tests.mjs","test:coverage":"npx c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs","test:all":"npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",check:"npm run lint && npm run test",prepublishOnly:"npm run build:cli",postinstall:"node scripts/postinstall.mjs",prepare:"husky","system-info":"node scripts/system-info.mjs"},dependencies:{"@modelcontextprotocol/sdk":"^1.27.1","@monaco-editor/react":"^4.7.0",bcryptjs:"^3.0.3","better-sqlite3":"^12.6.2",bottleneck:"^2.19.5",dompurify:"^3.3.2",express:"^5.2.1","fetch-socks":"^1.3.2","http-proxy-middleware":"^3.0.5","https-proxy-agent":"^8.0.0",jose:"^6.1.3",lowdb:"^7.0.1","monaco-editor":"^0.55.1",next:"^16.1.6","next-intl":"^4.8.3","node-machine-id":"^1.1.12",open:"^11.0.0",ora:"^9.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.4","react-dom":"19.2.4",recharts:"^3.7.0",selfsigned:"^5.5.0",tsx:"^4.21.0",undici:"^7.19.2",uuid:"^13.0.0","wreq-js":"^2.0.1",zod:"^4.3.6",zustand:"^5.0.10","@swc/helpers":"0.5.19"},devDependencies:{"@playwright/test":"^1.58.2","@tailwindcss/postcss":"^4.1.18","@types/bcryptjs":"^3.0.0","@types/better-sqlite3":"^7.6.13","@types/node":"^25.2.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3",concurrently:"^9.2.1","cross-env":"^10.1.0",eslint:"^9.39.2","eslint-config-next":"16.1.6",husky:"^9.1.7","lint-staged":"^16.2.7",prettier:"^3.8.1",tailwindcss:"^4",typescript:"^5.9.3","typescript-eslint":"^8.56.0",vitest:"^4.0.18","wait-on":"^9.0.4"},"lint-staged":{"*.{js,jsx,ts,tsx,mjs}":["prettier --write","eslint --fix --no-error-on-unmatched-pattern"],"*.{json,md,yml,yaml,css}":["prettier --write"]},pnpm:{onlyBuiltDependencies:["@parcel/watcher","@swc/core","better-sqlite3","esbuild","omniroute","sharp"]}})},175696,t=>{"use strict";var e=t.i(861745),s=t.i(843476);function n({locale:t,...n}){if(!t)throw Error(void 0);return(0,s.jsx)(e.IntlProvider,{locale:t,...n})}t.s(["default",()=>n])}]);
package/app/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## [2.7.3] — 2026-03-18
8
+
9
+ > Sprint: Codex direct API quota fallback fix.
10
+
11
+ ### 🐛 Bug Fixes
12
+
13
+ - **fix(codex)**: Block weekly-exhausted accounts in direct API fallback (#440)
14
+ - `resolveQuotaWindow()` prefix matching: `"weekly"` now matches `"weekly (7d)"` cache keys
15
+ - `applyCodexWindowPolicy()` enforces `useWeekly`/`use5h` toggles correctly
16
+ - 4 new regression tests (766 total)
17
+
18
+ ---
19
+
7
20
  ## [2.7.2] — 2026-03-18
8
21
 
9
22
  > Sprint: Light mode UI contrast fixes.
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OmniRoute API
4
- version: 2.7.2
4
+ version: 2.7.3
5
5
  description: |
6
6
  OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
7
7
  endpoint that routes requests to multiple AI providers with load balancing,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.7.2",
3
+ "version": "2.7.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omniroute",
9
- "version": "2.7.2",
9
+ "version": "2.7.3",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "workspaces": [
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.7.2",
3
+ "version": "2.7.3",
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": {
@@ -101,6 +101,45 @@ function clampPercent(value: number): number {
101
101
  return Math.max(0, Math.min(100, value));
102
102
  }
103
103
 
104
+ function normalizeWindowKey(value: unknown): string {
105
+ if (typeof value !== "string") return "";
106
+ return value
107
+ .toLowerCase()
108
+ .replace(/[^a-z0-9]+/g, " ")
109
+ .trim();
110
+ }
111
+
112
+ function resolveQuotaWindow(
113
+ quotas: Record<string, QuotaInfo>,
114
+ windowName: string
115
+ ): QuotaInfo | null {
116
+ const direct = quotas[windowName];
117
+ if (direct) return direct;
118
+
119
+ const normalizedTarget = normalizeWindowKey(windowName);
120
+ if (!normalizedTarget) return null;
121
+
122
+ const prefixMatches: Array<{ key: string; quota: QuotaInfo }> = [];
123
+ for (const [key, quota] of Object.entries(quotas)) {
124
+ const normalizedKey = normalizeWindowKey(key);
125
+ if (!normalizedKey) continue;
126
+ if (normalizedKey === normalizedTarget) return quota;
127
+ // Support canonical selection of generic windows from labeled windows,
128
+ // e.g. "weekly" from "weekly (7d)" or "session" from "session (5h)".
129
+ if (normalizedKey.startsWith(`${normalizedTarget} `)) {
130
+ prefixMatches.push({ key, quota });
131
+ }
132
+ }
133
+
134
+ // Deterministic fallback: choose the lexicographically first matching key.
135
+ if (prefixMatches.length > 0) {
136
+ prefixMatches.sort((a, b) => a.key.localeCompare(b.key));
137
+ return prefixMatches[0].quota;
138
+ }
139
+
140
+ return null;
141
+ }
142
+
104
143
  function earliestResetAt(quotas: Record<string, QuotaInfo>): string | null {
105
144
  let earliest: string | null = null;
106
145
  let earliestMs = Infinity;
@@ -201,7 +240,7 @@ export function getQuotaWindowStatus(
201
240
 
202
241
  const now = Date.now();
203
242
 
204
- const window = entry.quotas[windowName];
243
+ const window = resolveQuotaWindow(entry.quotas, windowName);
205
244
  if (!window) return null;
206
245
 
207
246
  const remainingPercentage = clampPercent(window.remainingPercentage);
@@ -132,12 +132,38 @@ function normalizeWindowName(windowName: unknown): string | null {
132
132
  return normalized.length > 0 ? normalized : null;
133
133
  }
134
134
 
135
- function getLegacyCodexWindows(providerSpecificData: JsonRecord): string[] {
135
+ function uniqueWindows(windows: string[]): string[] {
136
+ return [...new Set(windows)];
137
+ }
138
+
139
+ function normalizeCodexWindowName(windowName: unknown): string | null {
140
+ if (typeof windowName !== "string") return null;
141
+ const normalized = windowName.trim().toLowerCase();
142
+ if (normalized === "session (5h)" || normalized === "5h" || normalized === "five_hour") {
143
+ return "session";
144
+ }
145
+ if (normalized === "weekly (7d)" || normalized === "7d" || normalized === "seven_day") {
146
+ return "weekly";
147
+ }
148
+ return normalized;
149
+ }
150
+
151
+ function applyCodexWindowPolicy(rawWindows: string[], providerSpecificData: JsonRecord): string[] {
136
152
  const codexPolicy = getCodexLimitPolicy(providerSpecificData);
137
- const windows: string[] = [];
153
+ const normalizedRaw = rawWindows.map(normalizeCodexWindowName).filter(Boolean) as string[];
154
+
155
+ // Preserve explicitly configured custom windows, but enforce canonical Codex windows
156
+ // from toggles so weekly exhaustion is never skipped when useWeekly=true.
157
+ let windows = [...normalizedRaw];
158
+ windows = windows.filter((windowName) => {
159
+ if (windowName === "session") return codexPolicy.use5h;
160
+ if (windowName === "weekly") return codexPolicy.useWeekly;
161
+ return true;
162
+ });
138
163
  if (codexPolicy.use5h) windows.push("session");
139
164
  if (codexPolicy.useWeekly) windows.push("weekly");
140
- return windows;
165
+
166
+ return uniqueWindows(windows);
141
167
  }
142
168
 
143
169
  export function resolveQuotaLimitPolicy(
@@ -149,8 +175,7 @@ export function resolveQuotaLimitPolicy(
149
175
  const windows = rawWindows.map(normalizeWindowName).filter(Boolean) as string[];
150
176
 
151
177
  if (provider === "codex") {
152
- const fallbackWindows = getLegacyCodexWindows(providerSpecificData);
153
- const defaultWindows = windows.length > 0 ? windows : fallbackWindows;
178
+ const defaultWindows = applyCodexWindowPolicy(windows, providerSpecificData);
154
179
  const enabled = toBooleanOrDefault(rawPolicy.enabled, defaultWindows.length > 0);
155
180
 
156
181
  return {
@@ -21,6 +21,26 @@ test("resolveQuotaLimitPolicy keeps codex legacy defaults when generic policy is
21
21
  assert.equal(policy.thresholdPercent, 90);
22
22
  });
23
23
 
24
+ test("resolveQuotaLimitPolicy enforces codex weekly window when weekly toggle is enabled", () => {
25
+ const policy = auth.resolveQuotaLimitPolicy("codex", {
26
+ codexLimitPolicy: { use5h: true, useWeekly: true },
27
+ limitPolicy: { enabled: true, windows: ["session"] },
28
+ });
29
+
30
+ assert.equal(policy.enabled, true);
31
+ assert.deepEqual(policy.windows.sort(), ["session", "weekly"]);
32
+ });
33
+
34
+ test("resolveQuotaLimitPolicy removes codex weekly window when weekly toggle is disabled", () => {
35
+ const policy = auth.resolveQuotaLimitPolicy("codex", {
36
+ codexLimitPolicy: { use5h: true, useWeekly: false },
37
+ limitPolicy: { enabled: true, windows: ["session", "weekly"] },
38
+ });
39
+
40
+ assert.equal(policy.enabled, true);
41
+ assert.deepEqual(policy.windows, ["session"]);
42
+ });
43
+
24
44
  test("resolveQuotaLimitPolicy disables non-codex policy by default", () => {
25
45
  const policy = auth.resolveQuotaLimitPolicy("openai", {});
26
46
  assert.equal(policy.enabled, false);
@@ -60,6 +80,26 @@ test("evaluateQuotaLimitPolicy blocks when configured window reaches threshold",
60
80
  assert.equal(result.resetAt, resetAt);
61
81
  });
62
82
 
83
+ test("evaluateQuotaLimitPolicy matches canonical weekly window against labeled cache keys", () => {
84
+ const resetAt = new Date(Date.now() + 60_000).toISOString();
85
+ quotaCache.setQuotaCache("conn-policy-weekly-label", "codex", {
86
+ "weekly (7d)": { remainingPercentage: 0, resetAt },
87
+ });
88
+
89
+ const result = auth.evaluateQuotaLimitPolicy(
90
+ "codex",
91
+ buildConnection("conn-policy-weekly-label", {
92
+ codexLimitPolicy: { use5h: true, useWeekly: true },
93
+ limitPolicy: { enabled: true, windows: ["weekly"] },
94
+ })
95
+ );
96
+
97
+ assert.equal(result.blocked, true);
98
+ assert.equal(result.reasons.length, 1);
99
+ assert.match(result.reasons[0], /weekly usage/i);
100
+ assert.equal(result.resetAt, resetAt);
101
+ });
102
+
63
103
  test("evaluateQuotaLimitPolicy does not block when no quota data exists", () => {
64
104
  const result = auth.evaluateQuotaLimitPolicy(
65
105
  "openai",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.7.2",
3
+ "version": "2.7.3",
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": {