@yina-npm/openrouterx 0.4.23 → 0.4.24

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 (269) hide show
  1. package/app/.next/BUILD_ID +1 -1
  2. package/app/.next/app-path-routes-manifest.json +2 -2
  3. package/app/.next/build-manifest.json +2 -2
  4. package/app/.next/server/app/(dashboard)/dashboard/admin/keys/page_client-reference-manifest.js +1 -1
  5. package/app/.next/server/app/(dashboard)/dashboard/admin/users/page.js +1 -1
  6. package/app/.next/server/app/(dashboard)/dashboard/admin/users/page_client-reference-manifest.js +1 -1
  7. package/app/.next/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  8. package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  9. package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  10. package/app/.next/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  11. package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  12. package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +11 -11
  13. package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  14. package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  15. package/app/.next/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  16. package/app/.next/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  17. package/app/.next/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  18. package/app/.next/server/app/(dashboard)/dashboard/page.js +1 -1
  19. package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  20. package/app/.next/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  21. package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  22. package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  23. package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  24. package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  25. package/app/.next/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  26. package/app/.next/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  27. package/app/.next/server/app/(dashboard)/dashboard/skills/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/(dashboard)/dashboard/user/page_client-reference-manifest.js +1 -1
  31. package/app/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  32. package/app/.next/server/app/_global-error.html +1 -1
  33. package/app/.next/server/app/_global-error.rsc +1 -1
  34. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  35. package/app/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  36. package/app/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  37. package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  38. package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  39. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  40. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  41. package/app/.next/server/app/_not-found.html +1 -1
  42. package/app/.next/server/app/_not-found.rsc +4 -4
  43. package/app/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  44. package/app/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  45. package/app/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  46. package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  47. package/app/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  48. package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  49. package/app/.next/server/app/api/auth/login/route.js +1 -1
  50. package/app/.next/server/app/api/auth/me/route.js +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/test/route.js +1 -1
  53. package/app/.next/server/app/api/cli-tools/claude-settings/route.js +1 -1
  54. package/app/.next/server/app/api/cli-tools/codex-settings/route.js +2 -2
  55. package/app/.next/server/app/api/cli-tools/cowork-mcp-registry/route.js +1 -1
  56. package/app/.next/server/app/api/cli-tools/cowork-settings/route.js +1 -1
  57. package/app/.next/server/app/api/cli-tools/droid-settings/route.js +1 -1
  58. package/app/.next/server/app/api/cli-tools/hermes-settings/route.js +1 -1
  59. package/app/.next/server/app/api/cli-tools/openclaw-settings/route.js +1 -1
  60. package/app/.next/server/app/api/cli-tools/opencode-settings/route.js +1 -1
  61. package/app/.next/server/app/api/cloud/auth/route.js +1 -1
  62. package/app/.next/server/app/api/cloud/credentials/update/route.js +1 -1
  63. package/app/.next/server/app/api/cloud/model/resolve/route.js +1 -1
  64. package/app/.next/server/app/api/cloud/models/alias/route.js +1 -1
  65. package/app/.next/server/app/api/combos/[id]/route.js +1 -1
  66. package/app/.next/server/app/api/combos/route.js +1 -1
  67. package/app/.next/server/app/api/keys/[id]/route.js +1 -1
  68. package/app/.next/server/app/api/keys/route.js +1 -1
  69. package/app/.next/server/app/api/media-providers/tts/deepgram/voices/route.js +1 -1
  70. package/app/.next/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
  71. package/app/.next/server/app/api/media-providers/tts/inworld/voices/route.js +1 -1
  72. package/app/.next/server/app/api/models/alias/route.js +1 -1
  73. package/app/.next/server/app/api/models/availability/route.js +1 -1
  74. package/app/.next/server/app/api/models/custom/route.js +1 -1
  75. package/app/.next/server/app/api/models/disabled/route.js +1 -1
  76. package/app/.next/server/app/api/models/route.js +1 -1
  77. package/app/.next/server/app/api/models/test/route.js +1 -1
  78. package/app/.next/server/app/api/models/test/route.js.nft.json +1 -1
  79. package/app/.next/server/app/api/oauth/[provider]/[action]/route.js +2 -2
  80. package/app/.next/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  81. package/app/.next/server/app/api/oauth/cursor/import/route.js +1 -1
  82. package/app/.next/server/app/api/oauth/gitlab/pat/route.js +1 -1
  83. package/app/.next/server/app/api/oauth/iflow/cookie/route.js +1 -1
  84. package/app/.next/server/app/api/oauth/kiro/import/route.js +1 -1
  85. package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
  86. package/app/.next/server/app/api/pricing/route.js +1 -1
  87. package/app/.next/server/app/api/provider-nodes/[id]/route.js +1 -1
  88. package/app/.next/server/app/api/provider-nodes/route.js +1 -1
  89. package/app/.next/server/app/api/provider-nodes/route.js.nft.json +1 -1
  90. package/app/.next/server/app/api/providers/[id]/models/route.js +1 -1
  91. package/app/.next/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  92. package/app/.next/server/app/api/providers/[id]/route.js +1 -1
  93. package/app/.next/server/app/api/providers/[id]/route.js.nft.json +1 -1
  94. package/app/.next/server/app/api/providers/[id]/test/route.js +1 -1
  95. package/app/.next/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  96. package/app/.next/server/app/api/providers/[id]/test-models/route.js +1 -1
  97. package/app/.next/server/app/api/providers/client/route.js +1 -1
  98. package/app/.next/server/app/api/providers/client/route.js.nft.json +1 -1
  99. package/app/.next/server/app/api/providers/route.js +1 -1
  100. package/app/.next/server/app/api/providers/route.js.nft.json +1 -1
  101. package/app/.next/server/app/api/providers/test-batch/route.js +1 -1
  102. package/app/.next/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  103. package/app/.next/server/app/api/providers/validate/route.js +1 -1
  104. package/app/.next/server/app/api/providers/validate/route.js.nft.json +1 -1
  105. package/app/.next/server/app/api/proxy-pools/[id]/route.js +1 -1
  106. package/app/.next/server/app/api/proxy-pools/[id]/test/route.js +1 -1
  107. package/app/.next/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
  108. package/app/.next/server/app/api/proxy-pools/route.js +1 -1
  109. package/app/.next/server/app/api/proxy-pools/vercel-deploy/route.js +1 -1
  110. package/app/.next/server/app/api/settings/database/route.js +1 -1
  111. package/app/.next/server/app/api/settings/proxy-test/route.js +1 -1
  112. package/app/.next/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
  113. package/app/.next/server/app/api/settings/require-login/route.js +1 -1
  114. package/app/.next/server/app/api/settings/route.js +1 -1
  115. package/app/.next/server/app/api/translator/console-logs/route.js +1 -1
  116. package/app/.next/server/app/api/translator/console-logs/stream/route.js +1 -1
  117. package/app/.next/server/app/api/translator/send/route.js +1 -1
  118. package/app/.next/server/app/api/translator/send/route.js.nft.json +1 -1
  119. package/app/.next/server/app/api/translator/translate/route.js +1 -1
  120. package/app/.next/server/app/api/translator/translate/route.js.nft.json +1 -1
  121. package/app/.next/server/app/api/usage/[connectionId]/route.js +1 -1
  122. package/app/.next/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  123. package/app/.next/server/app/api/usage/api-keys/route.js +1 -1
  124. package/app/.next/server/app/api/usage/chart/route.js +1 -1
  125. package/app/.next/server/app/api/usage/history/route.js +1 -1
  126. package/app/.next/server/app/api/usage/logs/route.js +1 -1
  127. package/app/.next/server/app/api/usage/providers/route.js +1 -1
  128. package/app/.next/server/app/api/usage/request-details/route.js +1 -1
  129. package/app/.next/server/app/api/usage/request-logs/route.js +1 -1
  130. package/app/.next/server/app/api/usage/stats/route.js +1 -1
  131. package/app/.next/server/app/api/usage/stream/route.js +2 -2
  132. package/app/.next/server/app/api/users/[id]/route.js +1 -1
  133. package/app/.next/server/app/api/users/route.js +1 -1
  134. package/app/.next/server/app/api/v1/api/chat/route.js +1 -1
  135. package/app/.next/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  136. package/app/.next/server/app/api/v1/audio/speech/route.js +1 -1
  137. package/app/.next/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  138. package/app/.next/server/app/api/v1/audio/transcriptions/route.js +1 -1
  139. package/app/.next/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  140. package/app/.next/server/app/api/v1/chat/completions/route.js +1 -1
  141. package/app/.next/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  142. package/app/.next/server/app/api/v1/embeddings/route.js +1 -1
  143. package/app/.next/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  144. package/app/.next/server/app/api/v1/images/generations/route.js +2 -2
  145. package/app/.next/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  146. package/app/.next/server/app/api/v1/messages/route.js +1 -1
  147. package/app/.next/server/app/api/v1/messages/route.js.nft.json +1 -1
  148. package/app/.next/server/app/api/v1/models/[kind]/route.js +1 -1
  149. package/app/.next/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  150. package/app/.next/server/app/api/v1/models/route.js +1 -1
  151. package/app/.next/server/app/api/v1/models/route.js.nft.json +1 -1
  152. package/app/.next/server/app/api/v1/responses/compact/route.js +1 -1
  153. package/app/.next/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  154. package/app/.next/server/app/api/v1/responses/route.js +1 -1
  155. package/app/.next/server/app/api/v1/responses/route.js.nft.json +1 -1
  156. package/app/.next/server/app/api/v1/route.js +1 -1
  157. package/app/.next/server/app/api/v1/route.js.nft.json +1 -1
  158. package/app/.next/server/app/api/v1/search/route.js +1 -1
  159. package/app/.next/server/app/api/v1/search/route.js.nft.json +1 -1
  160. package/app/.next/server/app/api/v1/web/fetch/route.js +1 -1
  161. package/app/.next/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  162. package/app/.next/server/app/api/v1beta/models/[...path]/route.js +1 -1
  163. package/app/.next/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  164. package/app/.next/server/app/api/version/route.js +1 -1
  165. package/app/.next/server/app/api/version/update/route.js +1 -1
  166. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  167. package/app/.next/server/app/callback.html +1 -1
  168. package/app/.next/server/app/callback.rsc +4 -4
  169. package/app/.next/server/app/callback.segments/_full.segment.rsc +4 -4
  170. package/app/.next/server/app/callback.segments/_head.segment.rsc +1 -1
  171. package/app/.next/server/app/callback.segments/_index.segment.rsc +4 -4
  172. package/app/.next/server/app/callback.segments/_tree.segment.rsc +2 -2
  173. package/app/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  174. package/app/.next/server/app/callback.segments/callback.segment.rsc +1 -1
  175. package/app/.next/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  176. package/app/.next/server/app/dashboard/settings/pricing.html +1 -1
  177. package/app/.next/server/app/dashboard/settings/pricing.rsc +4 -4
  178. package/app/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  179. package/app/.next/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  180. package/app/.next/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +4 -4
  181. package/app/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  182. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  183. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  184. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  185. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  186. package/app/.next/server/app/index.html +1 -1
  187. package/app/.next/server/app/index.rsc +4 -4
  188. package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  189. package/app/.next/server/app/index.segments/_full.segment.rsc +4 -4
  190. package/app/.next/server/app/index.segments/_head.segment.rsc +1 -1
  191. package/app/.next/server/app/index.segments/_index.segment.rsc +4 -4
  192. package/app/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  193. package/app/.next/server/app/landing/page.js +1 -1
  194. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  195. package/app/.next/server/app/landing.html +1 -1
  196. package/app/.next/server/app/landing.rsc +5 -5
  197. package/app/.next/server/app/landing.segments/_full.segment.rsc +5 -5
  198. package/app/.next/server/app/landing.segments/_head.segment.rsc +1 -1
  199. package/app/.next/server/app/landing.segments/_index.segment.rsc +4 -4
  200. package/app/.next/server/app/landing.segments/_tree.segment.rsc +2 -2
  201. package/app/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
  202. package/app/.next/server/app/landing.segments/landing.segment.rsc +1 -1
  203. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  204. package/app/.next/server/app/login.html +1 -1
  205. package/app/.next/server/app/login.rsc +5 -5
  206. package/app/.next/server/app/login.segments/_full.segment.rsc +5 -5
  207. package/app/.next/server/app/login.segments/_head.segment.rsc +1 -1
  208. package/app/.next/server/app/login.segments/_index.segment.rsc +4 -4
  209. package/app/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  210. package/app/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  211. package/app/.next/server/app/login.segments/login.segment.rsc +1 -1
  212. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  213. package/app/.next/server/app-paths-manifest.json +2 -2
  214. package/app/.next/server/chunks/1679.js +1 -0
  215. package/app/.next/server/chunks/2506.js +2 -2
  216. package/app/.next/server/chunks/2574.js +1 -0
  217. package/app/.next/server/chunks/3110.js +14 -0
  218. package/app/.next/server/chunks/3605.js +1 -0
  219. package/app/.next/server/chunks/3855.js +1 -1
  220. package/app/.next/server/chunks/4122.js +1 -1
  221. package/app/.next/server/chunks/4664.js +1 -1
  222. package/app/.next/server/chunks/4989.js +2 -2
  223. package/app/.next/server/chunks/5627.js +2 -2
  224. package/app/.next/server/chunks/5681.js +1 -1
  225. package/app/.next/server/chunks/6108.js +1 -1
  226. package/app/.next/server/chunks/6182.js +4 -3
  227. package/app/.next/server/chunks/6774.js +1 -1
  228. package/app/.next/server/chunks/7341.js +1 -1
  229. package/app/.next/server/chunks/7595.js +1 -1
  230. package/app/.next/server/chunks/7937.js +7 -16
  231. package/app/.next/server/chunks/8590.js +1 -1
  232. package/app/.next/server/chunks/8760.js +1 -1
  233. package/app/.next/server/chunks/8895.js +1 -1
  234. package/app/.next/server/chunks/9489.js +1 -1
  235. package/app/.next/server/chunks/9547.js +4 -14
  236. package/app/.next/server/chunks/9609.js +1 -1
  237. package/app/.next/server/chunks/9718.js +1 -1
  238. package/app/.next/server/middleware-build-manifest.js +1 -1
  239. package/app/.next/server/middleware.js +1 -1
  240. package/app/.next/server/pages/404.html +1 -1
  241. package/app/.next/server/pages/500.html +1 -1
  242. package/app/.next/static/chunks/1321-e48fd14f5bef6d7a.js +1 -0
  243. package/app/.next/static/chunks/2336-36a1f30358e691c6.js +28 -0
  244. package/app/.next/static/chunks/app/(dashboard)/dashboard/admin/users/page-adc5d5e8da3a0761.js +1 -0
  245. package/app/.next/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/{page-eb5193b550d3e8de.js → page-c77fedcd9ba7bcac.js} +14 -14
  246. package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-ceb9bffbc34711bc.js +1 -0
  247. package/app/.next/static/chunks/app/landing/{page-c7ae6a40e2a2228d.js → page-4644660041715534.js} +1 -1
  248. package/app/.next/static/css/d726e4e5a2cfbfd1.css +1 -0
  249. package/app/package.json +1 -1
  250. package/app/public/providers/commandcode.png +0 -0
  251. package/app/src/mitm/cert/install.js +13 -8
  252. package/app/src/mitm/cert/rootCA.js +20 -5
  253. package/app/src/mitm/config.js +12 -1
  254. package/app/src/mitm/dns/dnsConfig.js +2 -2
  255. package/app/src/mitm/handlers/openrouter.js +82 -3
  256. package/app/src/mitm/manager.js +2 -2
  257. package/package.json +1 -1
  258. package/src/cli/api/client.js +2 -2
  259. package/src/cli/terminalUI.js +2 -2
  260. package/src/cli/tray/autostart.js +25 -24
  261. package/src/cli/tray/tray.js +3 -3
  262. package/app/.next/server/chunks/2343.js +0 -1
  263. package/app/.next/static/chunks/1321-c90a1f54884edb62.js +0 -1
  264. package/app/.next/static/chunks/2336-4ac589bb36571207.js +0 -38
  265. package/app/.next/static/chunks/app/(dashboard)/dashboard/admin/users/page-15091159f6d63fb7.js +0 -1
  266. package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-6289612ce5f7c181.js +0 -1
  267. package/app/.next/static/css/81b7abc9204a4458.css +0 -1
  268. /package/app/.next/static/{s_c_Y_7O0OBMovBwrwXBp → SQn85l_D0P4BshNJQkGiZ}/_buildManifest.js +0 -0
  269. /package/app/.next/static/{s_c_Y_7O0OBMovBwrwXBp → SQn85l_D0P4BshNJQkGiZ}/_ssgManifest.js +0 -0
@@ -16,7 +16,18 @@ const URL_PATTERNS = {
16
16
  copilot: ["/chat/completions", "/v1/messages", "/responses"],
17
17
  kiro: ["/generateAssistantResponse"],
18
18
  cursor: ["/BidiAppend", "/RunSSE", "/RunPoll", "/Run"],
19
- openrouter: ["/models", "/api/v1/models", "/chat/completions", "/v1/chat/completions", "/v1/messages", "/responses"],
19
+ openrouter: [
20
+ "/models",
21
+ "/api/v1/models",
22
+ "/api/v1/key",
23
+ "/api/v1/auth/key",
24
+ "/chat/completions",
25
+ "/v1/chat/completions",
26
+ "/api/v1/chat/completions",
27
+ "/v1/messages",
28
+ "/responses",
29
+ "/api/v1/responses",
30
+ ],
20
31
  };
21
32
 
22
33
  // Synonym map: rawModel from request → canonical alias key in mitmAlias DB
@@ -12,8 +12,8 @@ const { runElevatedPowerShell, isAdmin } = require("../winElevated.js");
12
12
  * If anything fails mid-way, restore from `.bak`. Same-volume renames are atomic on NTFS.
13
13
  */
14
14
  function atomicWriteHostsWin(target, originalContent, newContent) {
15
- const tmpNew = `${target}.9router.new`;
16
- const tmpBak = `${target}.9router.bak`;
15
+ const tmpNew = `${target}.openrouterx.new`;
16
+ const tmpBak = `${target}.openrouterx.bak`;
17
17
  try {
18
18
  fs.writeFileSync(tmpNew, newContent, "utf8");
19
19
  try { fs.unlinkSync(tmpBak); } catch { /* none */ }
@@ -4,21 +4,35 @@ const { err } = require("../logger");
4
4
  const { fetchRouter, pipeSSE } = require("./base");
5
5
 
6
6
  const URL_MAP = {
7
+ "/api/v1/chat/completions": "/v1/chat/completions",
7
8
  "/v1/chat/completions": "/v1/chat/completions",
8
9
  "/chat/completions": "/v1/chat/completions",
9
10
  "/v1/messages": "/v1/messages",
11
+ "/api/v1/responses": "/v1/responses",
12
+ "/v1/responses": "/v1/responses",
10
13
  "/responses": "/v1/responses",
14
+ "/api/v1/models": "/v1/models",
15
+ "/v1/models": "/v1/models",
11
16
  };
12
17
 
13
18
  function resolveRouterPath(reqUrl) {
19
+ const [pathname, query = ""] = String(reqUrl || "").split("?");
14
20
  for (const [pattern, routerPath] of Object.entries(URL_MAP)) {
15
- if (reqUrl.includes(pattern)) return routerPath;
21
+ if (pathname === pattern || pathname.endsWith(pattern)) {
22
+ return query ? `${routerPath}?${query}` : routerPath;
23
+ }
16
24
  }
17
25
  return "/v1/chat/completions";
18
26
  }
19
27
 
20
28
  function isModelsRequest(reqUrl) {
21
- return reqUrl.includes("/models") || reqUrl.includes("/api/v1/models");
29
+ const pathname = String(reqUrl || "").split("?")[0];
30
+ return pathname === "/models" || pathname === "/v1/models" || pathname === "/api/v1/models" || pathname.endsWith("/models");
31
+ }
32
+
33
+ function isKeyInfoRequest(reqUrl) {
34
+ const pathname = String(reqUrl || "").split("?")[0];
35
+ return pathname === "/api/v1/key" || pathname === "/api/v1/auth/key";
22
36
  }
23
37
 
24
38
  function getLocalModelsPayload() {
@@ -36,6 +50,52 @@ function sendJsonPayload(res, payload) {
36
50
  res.end(payload);
37
51
  }
38
52
 
53
+ function sendOptions(res) {
54
+ if (res.writableEnded) return;
55
+ res.writeHead(204, {
56
+ "Access-Control-Allow-Origin": "*",
57
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
58
+ "Access-Control-Allow-Headers": "*",
59
+ });
60
+ res.end();
61
+ }
62
+
63
+ function buildKeyInfoPayload() {
64
+ return {
65
+ data: {
66
+ label: "openrouterX MITM API Key",
67
+ limit: null,
68
+ usage: 0,
69
+ usage_daily: 0,
70
+ usage_weekly: 0,
71
+ usage_monthly: 0,
72
+ byok_usage: 0,
73
+ byok_usage_daily: 0,
74
+ byok_usage_weekly: 0,
75
+ byok_usage_monthly: 0,
76
+ is_free_tier: false,
77
+ limit_remaining: null,
78
+ limit_reset: null,
79
+ include_byok_in_limit: false,
80
+ is_provisioning_key: false,
81
+ is_management_key: false,
82
+ rate_limit: { interval: "1h", requests: 100000 },
83
+ },
84
+ };
85
+ }
86
+
87
+ function sendKeyInfo(res) {
88
+ if (res.writableEnded) return;
89
+ const payload = JSON.stringify(buildKeyInfoPayload());
90
+ res.writeHead(200, {
91
+ "Content-Type": "application/json; charset=utf-8",
92
+ "Access-Control-Allow-Origin": "*",
93
+ "Cache-Control": "no-store",
94
+ "Content-Length": Buffer.byteLength(payload),
95
+ });
96
+ res.end(payload);
97
+ }
98
+
39
99
  function buildInjectedModel(publicModelId) {
40
100
  const [provider = "openrouter"] = String(publicModelId || "").split("/");
41
101
  return {
@@ -102,6 +162,16 @@ async function handleModelsRequest(req, res, bodyBuffer, passthrough, aliasMappi
102
162
  */
103
163
  async function intercept(req, res, bodyBuffer, mappedModel, passthrough, aliasMappings = {}) {
104
164
  try {
165
+ if (req.method === "OPTIONS") {
166
+ sendOptions(res);
167
+ return;
168
+ }
169
+
170
+ if (req.method === "GET" && isKeyInfoRequest(req.url)) {
171
+ sendKeyInfo(res);
172
+ return;
173
+ }
174
+
105
175
  if (isModelsRequest(req.url)) {
106
176
  return handleModelsRequest(req, res, bodyBuffer, passthrough, aliasMappings);
107
177
  }
@@ -119,4 +189,13 @@ async function intercept(req, res, bodyBuffer, mappedModel, passthrough, aliasMa
119
189
  }
120
190
  }
121
191
 
122
- module.exports = { intercept, resolveRouterPath, isModelsRequest, injectPublicModels, buildInjectedModel };
192
+ module.exports = {
193
+ intercept,
194
+ resolveRouterPath,
195
+ isModelsRequest,
196
+ isKeyInfoRequest,
197
+ sendKeyInfo,
198
+ buildKeyInfoPayload,
199
+ injectPublicModels,
200
+ buildInjectedModel,
201
+ };
@@ -62,7 +62,7 @@ function resolveBundledServerPath() {
62
62
 
63
63
  const SERVER_PATH = resolveBundledServerPath();
64
64
  const ENCRYPT_ALGO = "aes-256-gcm";
65
- const ENCRYPT_SALT = "9router-mitm-pwd";
65
+ const ENCRYPT_SALT = "openrouterx-mitm-pwd";
66
66
 
67
67
  function getProcessUsingPort443() {
68
68
  try {
@@ -524,7 +524,7 @@ async function startServer(apiKey, sudoPassword, forceKillPort443 = false) {
524
524
  log(`[MITM] server.js missing at ${effectiveServerPath} → recopying`);
525
525
  effectiveServerPath = ensureRuntimeServer(resolveBundledServerPath());
526
526
  if (!effectiveServerPath || !fs.existsSync(effectiveServerPath)) {
527
- throw new Error(`MITM server.js not found at ${effectiveServerPath}. Reinstall 9router.`);
527
+ throw new Error(`MITM server.js not found at ${effectiveServerPath}. Reinstall openrouterX.`);
528
528
  }
529
529
  }
530
530
  const mitmRouterBase = await resolveMitmRouterBaseUrl();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yina-npm/openrouterx",
3
- "version": "0.4.23",
3
+ "version": "0.4.24",
4
4
  "description": "openrouterX CLI - Start and manage 9Router server",
5
5
  "bin": {
6
6
  "openrouterX": "./cli.js"
@@ -10,8 +10,8 @@ const DEFAULT_CONFIG = {
10
10
  protocol: "http:",
11
11
  };
12
12
 
13
- const CLI_TOKEN_HEADER = "x-9r-cli-token";
14
- const CLI_TOKEN_SALT = "9r-cli-auth";
13
+ const CLI_TOKEN_HEADER = "x-openrouterx-cli-token";
14
+ const CLI_TOKEN_SALT = "openrouterx-cli-auth";
15
15
 
16
16
  let config = { ...DEFAULT_CONFIG };
17
17
  let cachedCliToken = null;
@@ -57,11 +57,11 @@ async function startTerminalUI(port) {
57
57
  // Configure API client
58
58
  api.configure({ port });
59
59
 
60
- const basePath = ["9Router"];
60
+ const basePath = ["openrouterX"];
61
61
 
62
62
  // Main menu
63
63
  await showMenuWithBack({
64
- title: "📡 9Router Terminal UI",
64
+ title: "📡 openrouterX Terminal UI",
65
65
  breadcrumb: basePath,
66
66
  headerContent: async () => await buildHeaderContent(port),
67
67
  refresh: async () => ({}), // Refresh header on each loop
@@ -3,17 +3,18 @@ const path = require("path");
3
3
  const os = require("os");
4
4
  const { execSync } = require("child_process");
5
5
 
6
- const APP_NAME = "9router";
7
- const APP_LABEL = "com.9router.autostart";
6
+ const APP_NAME = "openrouterX";
7
+ const APP_FILE_BASENAME = "openrouterx";
8
+ const APP_LABEL = "com.openrouterx.autostart";
8
9
 
9
10
  /**
10
- * Get the command to run 9router in tray mode
11
+ * Get the command to run openrouterX in tray mode
11
12
  */
12
13
  function getStartCommand() {
13
- // Find the global npm bin path for 9router
14
+ // Find the global npm bin path for openrouterX
14
15
  try {
15
16
  const npmBin = execSync("npm bin -g", { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
16
- const routerPath = path.join(npmBin, "9router");
17
+ const routerPath = path.join(npmBin, APP_NAME);
17
18
  if (fs.existsSync(routerPath)) {
18
19
  return `"${routerPath}" --tray --skip-update`;
19
20
  }
@@ -22,7 +23,7 @@ function getStartCommand() {
22
23
  }
23
24
 
24
25
  // Fallback: use npx
25
- return "npx 9router --tray --skip-update";
26
+ return "npx @yina-npm/openrouterx --tray --skip-update";
26
27
  }
27
28
 
28
29
  /**
@@ -92,10 +93,10 @@ function isAutoStartEnabled() {
92
93
  const plistPath = path.join(os.homedir(), "Library", "LaunchAgents", `${APP_LABEL}.plist`);
93
94
  return fs.existsSync(plistPath);
94
95
  } else if (platform === "win32") {
95
- const startupPath = path.join(process.env.APPDATA, "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${APP_NAME}.vbs`);
96
+ const startupPath = path.join(process.env.APPDATA, "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${APP_FILE_BASENAME}.vbs`);
96
97
  return fs.existsSync(startupPath);
97
98
  } else if (platform === "linux") {
98
- const desktopPath = path.join(os.homedir(), ".config", "autostart", `${APP_NAME}.desktop`);
99
+ const desktopPath = path.join(os.homedir(), ".config", "autostart", `${APP_FILE_BASENAME}.desktop`);
99
100
  return fs.existsSync(desktopPath);
100
101
  }
101
102
  } catch (e) {}
@@ -114,7 +115,7 @@ function enableMacOS(cliPath) {
114
115
  fs.mkdirSync(launchAgentsDir, { recursive: true });
115
116
  }
116
117
 
117
- // Get absolute paths for node and 9router script
118
+ // Get absolute paths for node and openrouterX script
118
119
  const nodePath = process.execPath;
119
120
  let routerScript;
120
121
 
@@ -125,11 +126,11 @@ function enableMacOS(cliPath) {
125
126
  // Fallback: try to resolve from npm bin
126
127
  try {
127
128
  const npmBin = execSync("npm bin -g", { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
128
- const routerLink = path.join(npmBin, "9router");
129
+ const routerLink = path.join(npmBin, APP_NAME);
129
130
  routerScript = fs.realpathSync(routerLink);
130
131
  } catch (e) {
131
132
  // Last resort fallback
132
- routerScript = "/usr/local/lib/node_modules/9router/cli.js";
133
+ routerScript = "/usr/local/lib/node_modules/@yina-npm/openrouterx/cli.js";
133
134
  }
134
135
  }
135
136
 
@@ -154,9 +155,9 @@ function enableMacOS(cliPath) {
154
155
  <key>KeepAlive</key>
155
156
  <false/>
156
157
  <key>StandardOutPath</key>
157
- <string>/tmp/9router.log</string>
158
+ <string>/tmp/openrouterx.log</string>
158
159
  <key>StandardErrorPath</key>
159
- <string>/tmp/9router.error.log</string>
160
+ <string>/tmp/openrouterx.error.log</string>
160
161
  </dict>
161
162
  </plist>`;
162
163
 
@@ -188,7 +189,7 @@ function disableMacOS() {
188
189
 
189
190
  function enableWindows(cliPath) {
190
191
  const startupDir = path.join(process.env.APPDATA, "Microsoft", "Windows", "Start Menu", "Programs", "Startup");
191
- const vbsPath = path.join(startupDir, `${APP_NAME}.vbs`);
192
+ const vbsPath = path.join(startupDir, `${APP_FILE_BASENAME}.vbs`);
192
193
 
193
194
  // Ensure startup directory exists
194
195
  if (!fs.existsSync(startupDir)) {
@@ -206,12 +207,12 @@ function enableWindows(cliPath) {
206
207
  // Fallback: try to resolve from npm bin
207
208
  try {
208
209
  const npmBin = execSync("npm bin -g", { encoding: "utf8", shell: true, stdio: ["ignore", "pipe", "ignore"] }).trim();
209
- const routerLink = path.join(npmBin, "9router.cmd");
210
+ const routerLink = path.join(npmBin, `${APP_NAME}.cmd`);
210
211
  if (fs.existsSync(routerLink)) {
211
212
  routerScript = routerLink;
212
213
  } else {
213
214
  // Try to resolve actual script
214
- const routerJs = path.join(npmBin, "../lib/node_modules/9router/cli.js");
215
+ const routerJs = path.join(npmBin, "../lib/node_modules/@yina-npm/openrouterx/cli.js");
215
216
  if (fs.existsSync(routerJs)) {
216
217
  routerScript = routerJs;
217
218
  }
@@ -236,7 +237,7 @@ WshShell.Run """${routerScript}"" --tray --skip-update", 0, False
236
237
  } else {
237
238
  // Fallback to npx
238
239
  vbsContent = `Set WshShell = CreateObject("WScript.Shell")
239
- WshShell.Run "npx 9router --tray --skip-update", 0, False
240
+ WshShell.Run "npx @yina-npm/openrouterx --tray --skip-update", 0, False
240
241
  `;
241
242
  }
242
243
 
@@ -245,7 +246,7 @@ WshShell.Run "npx 9router --tray --skip-update", 0, False
245
246
  }
246
247
 
247
248
  function disableWindows() {
248
- const vbsPath = path.join(process.env.APPDATA, "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${APP_NAME}.vbs`);
249
+ const vbsPath = path.join(process.env.APPDATA, "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${APP_FILE_BASENAME}.vbs`);
249
250
 
250
251
  if (fs.existsSync(vbsPath)) {
251
252
  fs.unlinkSync(vbsPath);
@@ -258,7 +259,7 @@ function disableWindows() {
258
259
 
259
260
  function enableLinux(cliPath) {
260
261
  const autostartDir = path.join(os.homedir(), ".config", "autostart");
261
- const desktopPath = path.join(autostartDir, `${APP_NAME}.desktop`);
262
+ const desktopPath = path.join(autostartDir, `${APP_FILE_BASENAME}.desktop`);
262
263
 
263
264
  // Ensure directory exists
264
265
  if (!fs.existsSync(autostartDir)) {
@@ -280,20 +281,20 @@ function enableLinux(cliPath) {
280
281
  // Fallback: try to resolve from npm bin
281
282
  try {
282
283
  const npmBin = execSync("npm bin -g", { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
283
- const routerLink = path.join(npmBin, "9router");
284
+ const routerLink = path.join(npmBin, APP_NAME);
284
285
  if (fs.existsSync(routerLink)) {
285
286
  routerScript = fs.realpathSync(routerLink);
286
287
  }
287
288
  } catch (e) {
288
289
  // Last resort fallback
289
- routerScript = "/usr/local/lib/node_modules/9router/cli.js";
290
+ routerScript = "/usr/local/lib/node_modules/@yina-npm/openrouterx/cli.js";
290
291
  }
291
292
  }
292
293
 
293
294
  const desktopContent = `[Desktop Entry]
294
295
  Type=Application
295
- Name=9Router
296
- Comment=9Router API Proxy
296
+ Name=openrouterX
297
+ Comment=openrouterX API Proxy
297
298
  Exec=${nodePath} ${routerScript} --tray --skip-update
298
299
  Hidden=false
299
300
  NoDisplay=false
@@ -305,7 +306,7 @@ X-GNOME-Autostart-enabled=true
305
306
  }
306
307
 
307
308
  function disableLinux() {
308
- const desktopPath = path.join(os.homedir(), ".config", "autostart", `${APP_NAME}.desktop`);
309
+ const desktopPath = path.join(os.homedir(), ".config", "autostart", `${APP_FILE_BASENAME}.desktop`);
309
310
 
310
311
  if (fs.existsSync(desktopPath)) {
311
312
  fs.unlinkSync(desktopPath);
@@ -64,11 +64,11 @@ function initTray(options) {
64
64
  const menu = {
65
65
  icon: getIconBase64(),
66
66
  // macOS requires empty title; Windows uses title as the tray icon tooltip
67
- title: isWin ? `9Router - Port ${port}` : "",
68
- tooltip: `9Router - Port ${port}`,
67
+ title: isWin ? `openrouterX - Port ${port}` : "",
68
+ tooltip: `openrouterX - Port ${port}`,
69
69
  items: [
70
70
  {
71
- title: `9Router (Port ${port})`,
71
+ title: `openrouterX (Port ${port})`,
72
72
  tooltip: "Server is running",
73
73
  enabled: false
74
74
  },
@@ -1 +0,0 @@
1
- "use strict";exports.id=2343,exports.ids=[2343],exports.modules={2574:(a,b,c)=>{c.r(b),c.d(b,{GET:()=>p,OPTIONS:()=>o,buildModelsList:()=>n});var d=c(81329),e=c(75681),f=c(89718),g=c(9132),h=c(38775);let i=/[-_][0-9a-f]{8,}$/i,j={image:"image",tts:"tts",embedding:"embedding",stt:"stt",imageToText:"imageToText"};function k(a){return a?.type&&j[a.type]||"llm"}async function l(a){if(!a?.apiKey)return[];let b="string"==typeof a?.providerSpecificData?.baseUrl?a.providerSpecificData.baseUrl.trim().replace(/\/$/,""):"";if(!b)return[];let c=`${b}/models`,d={"Content-Type":"application/json"};if((0,e.mq)(a.provider))d.Authorization=`Bearer ${a.apiKey}`;else{if(!(0,e.gb)(a.provider))return[];c.endsWith("/messages/models")?c=c.slice(0,-9):c.endsWith("/messages")&&(c=`${c.slice(0,-9)}/models`),d["x-api-key"]=a.apiKey,d["anthropic-version"]="2023-06-01",d.Authorization=`Bearer ${a.apiKey}`}try{var f;let a=new AbortController,b=setTimeout(()=>a.abort(),5e3),e=await fetch(c,{method:"GET",headers:d,cache:"no-store",signal:a.signal});if(clearTimeout(b),!e.ok)return[];let g=(f=await e.json(),Array.isArray(f)?f:f?.data||f?.models||f?.results||[]);return Array.from(new Set(g.map(a=>a?.id||a?.name||a?.model).filter(a=>"string"==typeof a&&""!==a.trim())))}catch{return[]}}function m(a,b){let c=e.AI_PROVIDERS[a],d=Array.isArray(c?.serviceKinds)&&c.serviceKinds.length>0?c.serviceKinds:["llm"];return b.some(a=>d.includes(a))}async function n(a,b=null){let c=b?await (0,g.RG)(b):null,j=[];try{j=(j=await (0,f.getProviderConnections)()).filter(a=>!1!==a.isActive),c&&(j=j.filter(a=>(0,g.iI)(c,a.provider)))}catch(a){console.log("Could not fetch providers, returning all models")}let o=[];try{o=await (0,f.Uv)()}catch(a){console.log("Could not fetch combos")}let p=[];try{p=await (0,f.uv)()}catch(a){console.log("Could not fetch custom models")}let q={};try{q=await (0,f.OM)()}catch(a){console.log("Could not fetch model aliases")}let r=new Map;for(let a of j)r.has(a.provider)||r.set(a.provider,a);let s=[],t=Math.floor(Date.now()/1e3);for(let b of o){if(!function(a,b){let c=a?.kind||"llm";return b.includes(c)}(b,a))continue;if(c){let a=!0;for(let d of b.models||[]){let b=await (0,h.mA)(d);if(!b?.provider||!(0,g.iI)(c,b.provider)){a=!1;break}}if(!a)continue}let d={id:b.name,object:"model",created:t,owned_by:"combo"};("webSearch"===b.kind||"webFetch"===b.kind)&&(d.kind=b.kind),s.push(d)}if(0===j.length){let b=Object.fromEntries(Object.entries(d.Xg).map(([a,b])=>[b,a]));for(let[e,f]of Object.entries(d.vq)){let d=b[e]||e;if((!c||(0,g.iI)(c,d))&&m(d,a))for(let b of f)a.includes(k(b))&&s.push({id:`${e}/${b.id}`,object:"model",created:t,owned_by:e})}for(let b of p){if(!b?.id||b.type&&"llm"!==b.type||!a.includes("llm"))continue;let d=b.providerAlias;if(!d)continue;let e=String(b.id).trim();if(e){if(c){let a=await (0,h.mA)(`${d}/${e}`);if(!a?.provider||!(0,g.iI)(c,a.provider))continue}s.push({id:`${d}/${e}`,object:"model",created:t,owned_by:d})}}}else for(let[b,f]of r.entries()){if(c&&!(0,g.iI)(c,b)||!m(b,a))continue;let h=d.Xg[b]||b,j=(f?.providerSpecificData?.prefix||(0,e.wG)(b)||h).trim(),n=d.vq[h]||[],o=f?.providerSpecificData?.enabledModels,r=Array.isArray(o)&&o.length>0,u=(0,e.mq)(b)||(0,e.gb)(b),v=new Map(n.map(a=>[a.id,k(a)])),w=r?Array.from(new Set(o.filter(a=>"string"==typeof a&&""!==a.trim()))):n.map(a=>a.id);for(let c of(u&&0===w.length&&!i.test(b)&&(w=await l(f)),Array.from(new Set([...w.map(a=>a.startsWith(`${j}/`)?a.slice(j.length+1):a.startsWith(`${h}/`)?a.slice(h.length+1):a.startsWith(`${b}/`)?a.slice(b.length+1):a).filter(a=>"string"==typeof a&&""!==a.trim()),...p.filter(a=>{if(!a?.id||a.type&&"llm"!==a.type)return!1;let c=a.providerAlias;return c===h||c===j||c===b}).map(a=>String(a.id).trim()).filter(a=>""!==a),...Object.values(q||{}).filter(a=>"string"==typeof a&&!!a.includes("/")&&(a.startsWith(`${j}/`)||a.startsWith(`${h}/`)||a.startsWith(`${b}/`))).map(a=>a.startsWith(`${j}/`)?a.slice(j.length+1):a.startsWith(`${h}/`)?a.slice(h.length+1):a.startsWith(`${b}/`)?a.slice(b.length+1):a).filter(a=>"string"==typeof a&&""!==a.trim())])))){let b=v.get(c)||function(a){let b=String(a).toLowerCase();return/embed/.test(b)?"embedding":/tts|speech|audio|voice/.test(b)?"tts":/image|imagen|dall-?e|flux|sdxl|sd-|stable-diffusion/.test(b)?"image":"llm"}(c);a.includes(b)&&s.push({id:`${j}/${c}`,object:"model",created:t,owned_by:j})}let x=e.AI_PROVIDERS[b],y=[];if(a.includes("tts")&&Array.isArray(x?.ttsConfig?.models))for(let a of x.ttsConfig.models)a?.id&&y.push(a.id);if(a.includes("embedding")&&Array.isArray(x?.embeddingConfig?.models))for(let a of x.embeddingConfig.models)a?.id&&y.push(a.id);for(let a of y)s.push({id:`${j}/${a}`,object:"model",created:t,owned_by:j});a.includes("webSearch")&&x?.searchConfig&&s.push({id:`${j}/search`,object:"model",kind:"webSearch",created:t,owned_by:j}),a.includes("webFetch")&&x?.fetchConfig&&s.push({id:`${j}/fetch`,object:"model",kind:"webFetch",created:t,owned_by:j})}let u=[],v=new Set;for(let a of s)!a?.id||v.has(a.id)||(v.add(a.id),u.push(a));return u}async function o(){return new Response(null,{headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*"}})}async function p(a){try{let b=await (0,g.RG)(a),c=[];try{c=(c=await (0,f.getProviderConnections)()).filter(a=>!1!==a.isActive),b&&(c=c.filter(a=>(0,g.iI)(b,a.provider)))}catch(a){console.log("Could not fetch providers, returning all models")}let j=[];try{j=await (0,f.Uv)()}catch(a){console.log("Could not fetch combos")}let k=new Map;for(let a of c)k.has(a.provider)||k.set(a.provider,a);let m=[],n=Math.floor(Date.now()/1e3);for(let a of j){if(b){let c=!0;for(let d of a.models||[]){let a=await (0,h.mA)(d);if(!a?.provider||!(0,g.iI)(b,a.provider)){c=!1;break}}if(!c)continue}m.push({id:a.name,object:"model",created:n,owned_by:"combo",permission:[],root:a.name,parent:null})}if(0===c.length)for(let[a,c]of Object.entries(d.vq)){let e=Object.entries(d.Xg).find(([b,c])=>c===a)?.[0]||a;if((0,g.iI)(b,e))for(let b of c)m.push({id:`${a}/${b.id}`,object:"model",created:n,owned_by:a,permission:[],root:b.id,parent:null})}else for(let[a,c]of k.entries()){if(!(0,g.iI)(b,a))continue;let f=d.Xg[a]||a,h=(c?.providerSpecificData?.prefix||(0,e.wG)(a)||f).trim(),j=d.vq[f]||[],k=c?.providerSpecificData?.enabledModels,o=Array.isArray(k)&&k.length>0,p=(0,e.mq)(a)||(0,e.gb)(a),q=o?Array.from(new Set(k.filter(a=>"string"==typeof a&&""!==a.trim()))):j.map(a=>a.id);for(let b of(p&&0===q.length&&!i.test(a)&&(q=await l(c)),q.map(b=>b.startsWith(`${h}/`)?b.slice(h.length+1):b.startsWith(`${f}/`)?b.slice(f.length+1):b.startsWith(`${a}/`)?b.slice(a.length+1):b).filter(a=>"string"==typeof a&&""!==a.trim())))m.push({id:`${h}/${b}`,object:"model",created:n,owned_by:h,permission:[],root:b,parent:null})}return Response.json({object:"list",data:m},{headers:{"Access-Control-Allow-Origin":"*"}})}catch(a){return console.log("Error fetching models:",a),Response.json({error:{message:a.message,type:"server_error"}},{status:500})}}},9132:(a,b,c)=>{c.d(b,{Mv:()=>j,RG:()=>h,iI:()=>i});var d=c(68658),e=c(89718),f=c(54200);function g(a,b){return a&&"sub_user"===a.role?{role:"sub_user",userId:a.id,username:a.username||null,permissions:Array.isArray(a.permissions)?a.permissions:[],allowedProviders:(0,f.cc)(a),source:b}:null}async function h(a,b=null){let c=b||function(a){let b=a?.headers?.get("Authorization");if(b?.startsWith("Bearer "))return b.slice(7);let c=a?.headers?.get("x-api-key");return c||null}(a);if(c){let a=await (0,e.y7)(c);if(a?.userId){let b=g(await (0,e.kl)(a.userId),"api_key");if(b)return b}}let f=await (0,d.f1)(a);if(!f||"sub_user"!==f.role||!f.userId)return null;let i=await (0,e.kl)(f.userId);return i?g(i,"cookie"):g({id:f.userId,username:f.username||null,role:f.role,permissions:f.permissions||[],allowedProviders:f.allowedProviders},"cookie")}function i(a,b){return!a||"sub_user"!==a.role||a.allowedProviders.includes(b)}function j(a,b){return b&&"sub_user"===b.role?a.filter(a=>i(b,a.provider)):a}},38775:(a,b,c)=>{c.d(b,{d_:()=>g,mA:()=>f});var d=c(89718),e=c(40669);async function f(a){let b=(0,e.Xh)(a);if(!b.isAlias){let a=(await (0,d.getProviderNodes)({type:"openai-compatible"})).find(a=>a.prefix===b.providerAlias);if(a)return{provider:a.id,model:b.model};let c=(await (0,d.getProviderNodes)({type:"anthropic-compatible"})).find(a=>a.prefix===b.providerAlias);if(c)return{provider:c.id,model:b.model};let e=(await (0,d.getProviderNodes)({type:"custom-embedding"})).find(a=>a.prefix===b.providerAlias);if(e)return{provider:e.id,model:b.model};let f=(await (0,d.getProviderNodes)({type:"custom-image"})).find(a=>a.prefix===b.providerAlias);return f?{provider:f.id,model:b.model}:{provider:b.provider,model:b.model}}return await (0,d.Dj)(b.model)?{provider:null,model:b.model}:(0,e.js)(a,d.OM)}async function g(a){if(a.includes("/"))return null;let b=await (0,d.Dj)(a);return b&&b.models&&b.models.length>0?b.models:null}},40669:(a,b,c)=>{c.d(b,{Xh:()=>e,js:()=>f});let d={cc:"claude",cx:"codex",gc:"gemini-cli",qw:"qwen",if:"iflow",ag:"antigravity",gh:"github",kr:"kiro",cu:"cursor",kc:"kilocode",kmc:"kimi-coding",cl:"cline",oc:"opencode",ocg:"opencode-go",el:"elevenlabs",openai:"openai",anthropic:"anthropic",gemini:"gemini",openrouter:"openrouter",glm:"glm",kimi:"kimi",minimax:"minimax","minimax-cn":"minimax-cn",ds:"deepseek",deepseek:"deepseek",groq:"groq",xai:"xai",mistral:"mistral",pplx:"perplexity",perplexity:"perplexity",together:"together",fireworks:"fireworks",cerebras:"cerebras",cohere:"cohere",nvidia:"nvidia",nebius:"nebius",siliconflow:"siliconflow",hyp:"hyperbolic",hyperbolic:"hyperbolic",dg:"deepgram",deepgram:"deepgram",aai:"assemblyai",assemblyai:"assemblyai",nb:"nanobanana",nanobanana:"nanobanana",ch:"chutes",chutes:"chutes",ark:"volcengine-ark","volcengine-ark":"volcengine-ark",byteplus:"byteplus",bpm:"byteplus",cursor:"cursor",vx:"vertex",vertex:"vertex",vxp:"vertex-partner","vertex-partner":"vertex-partner",gw:"grok-web","grok-web":"grok-web",pw:"perplexity-web","perplexity-web":"perplexity-web",mimo:"xiaomi-mimo","xiaomi-mimo":"xiaomi-mimo",cf:"cloudflare-ai","cloudflare-ai":"cloudflare-ai",fal:"fal-ai","fal-ai":"fal-ai",stability:"stability-ai","stability-ai":"stability-ai",bfl:"black-forest-labs","black-forest-labs":"black-forest-labs",recraft:"recraft",topaz:"topaz",runway:"runwayml",runwayml:"runwayml",jina:"jina-ai","jina-ai":"jina-ai",polly:"aws-polly","aws-polly":"aws-polly"};function e(a){if(!a)return{provider:null,model:null,isAlias:!1,providerAlias:null};if(a.includes("/")){let b=a.indexOf("/"),c=a.slice(0,b),e=a.slice(b+1);return{provider:d[c]||c,model:e,isAlias:!1,providerAlias:c}}return{provider:null,model:a,isAlias:!0,providerAlias:null}}async function f(a,b){let c=e(a);if(!c.isAlias)return{provider:c.provider,model:c.model};let f="function"==typeof b?await b():b,g=function(a,b){var c,e;if(!b)return null;let f=b[a];if(!f)return null;if("string"==typeof f&&f.includes("/")){let a=f.indexOf("/");return{provider:d[c=f.slice(0,a)]||c,model:f.slice(a+1)}}return"object"==typeof f&&f.provider&&f.model?{provider:d[e=f.provider]||e,model:f.model}:null}(c.model,f);return g||{provider:function(a){if(!a)return"openai";let b=a.toLowerCase();return b.startsWith("claude-")?"anthropic":b.startsWith("gemini-")?"gemini":b.startsWith("gpt-")||b.startsWith("o1")||b.startsWith("o3")||b.startsWith("o4")?"openai":b.startsWith("deepseek-")?"openrouter":"openai"}(c.model),model:c.model}}},49120:(a,b,c)=>{c.d(b,{n:()=>i}),c(29021);var d,e=c(33873),f=c.n(e),g=c(21820),h=c.n(g);let i=process.env.DATA_DIR?process.env.DATA_DIR:(d="openrouterx","win32"===process.platform?f().join(process.env.APPDATA||f().join(h().homedir(),"AppData","Roaming"),d):f().join(h().homedir(),`.${d}`))},54200:(a,b,c)=>{c.d(b,{cc:()=>f,vJ:()=>e});let d=["codex","alicode"];function e(a){return Array.isArray(a)?Array.from(new Set(a.map(a=>"string"==typeof a?a.trim():"").filter(Boolean))):[]}function f(a,b=d){return a&&"object"==typeof a&&Object.prototype.hasOwnProperty.call(a,"allowedProviders")?e(a.allowedProviders):e(b)}},54603:(a,b,c)=>{c.d(b,{Xj:()=>e});var d=c(19713);async function e(a=null){let b=a||process.env.MACHINE_ID_SALT||"endpoint-proxy-salt";try{let a=(0,d.machineIdSync)();return(await Promise.resolve().then(c.t.bind(c,55511,23))).createHash("sha256").update(a+b).digest("hex").substring(0,16)}catch(a){return console.log("Error getting machine ID:",a),crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){let b=16*Math.random()|0;return("x"==a?b:3&b|8).toString(16)})}}},68658:(a,b,c)=>{c.d(b,{f1:()=>f}),c(23211);var d=c(69614);c(89718),c(54603);let e=new TextEncoder().encode(process.env.JWT_SECRET||"9router-default-secret-change-me");async function f(a){let b=a.cookies.get("auth_token")?.value;if(!b)return null;try{let{payload:a}=await (0,d.V)(b,e);return a}catch{return null}}},69614:(a,b,c)=>{c.d(b,{V:()=>p});var d=c(88888),e=c(91356),f=c(99129),g=c(73575),h=c(41570),i=c(19035),j=c(24762),k=c(80308),l=c(55956);async function m(a,b,c){if(!(0,i.Gv)(a))throw new f.Ye("Flattened JWS must be an object");if(void 0===a.protected&&void 0===a.header)throw new f.Ye('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==a.protected&&"string"!=typeof a.protected)throw new f.Ye("JWS Protected Header incorrect type");if(void 0===a.payload)throw new f.Ye("JWS Payload missing");if("string"!=typeof a.signature)throw new f.Ye("JWS Signature missing or incorrect type");if(void 0!==a.header&&!(0,i.Gv)(a.header))throw new f.Ye("JWS Unprotected Header incorrect type");let m={};if(a.protected)try{let b=(0,d.D)(a.protected);m=JSON.parse(g.D0.decode(b))}catch{throw new f.Ye("JWS Protected Header is invalid")}if(!(0,i.fz)(m,a.header))throw new f.Ye("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");let n={...m,...a.header},o=(0,k.n)(f.Ye,new Map([["b64",!0]]),c?.crit,m,n),p=!0;if(o.has("b64")&&"boolean"!=typeof(p=m.b64))throw new f.Ye('The "b64" (base64url-encode payload) Header Parameter must be a boolean');let{alg:q}=n;if("string"!=typeof q||!q)throw new f.Ye('JWS "alg" (Algorithm) Header Parameter missing or invalid');let r=c&&function(a,b){if(void 0!==b&&(!Array.isArray(b)||b.some(a=>"string"!=typeof a)))throw TypeError(`"${a}" option must be an array of strings`);if(b)return new Set(b)}("algorithms",c.algorithms);if(r&&!r.has(q))throw new f.Rb('"alg" (Algorithm) Header Parameter value not allowed');if(p){if("string"!=typeof a.payload)throw new f.Ye("JWS Payload must be a string")}else if("string"!=typeof a.payload&&!(a.payload instanceof Uint8Array))throw new f.Ye("JWS Payload must be a string or an Uint8Array instance");let s=!1;"function"==typeof b&&(b=await b(m,a),s=!0),(0,j.y)(q,b,"verify");let t=(0,g.xW)(void 0!==a.protected?(0,g.lF)(a.protected):new Uint8Array,(0,g.lF)("."),"string"==typeof a.payload?p?(0,g.lF)(a.payload):g.Rd.encode(a.payload):a.payload),u=(0,h.h2)(a.signature,"signature",f.Ye),v=await (0,l.l)(b,q);if(!await (0,e.MX)(q,v,u,t))throw new f.h2;let w={payload:p?(0,h.h2)(a.payload,"payload",f.Ye):"string"==typeof a.payload?g.Rd.encode(a.payload):a.payload};return(void 0!==a.protected&&(w.protectedHeader=m),void 0!==a.header&&(w.unprotectedHeader=a.header),s)?{...w,key:v}:w}async function n(a,b,c){if(a instanceof Uint8Array&&(a=g.D0.decode(a)),"string"!=typeof a)throw new f.Ye("Compact JWS must be a string or Uint8Array");let{0:d,1:e,2:h,length:i}=a.split(".");if(3!==i)throw new f.Ye("Invalid Compact JWS");let j=await m({payload:e,protected:d,signature:h},b,c),k={payload:j.payload,protectedHeader:j.protectedHeader};return"function"==typeof b?{...k,key:j.key}:k}var o=c(17347);async function p(a,b,c){let d=await n(a,b,c);if(d.protectedHeader.crit?.includes("b64")&&!1===d.protectedHeader.b64)throw new f.Dp("JWTs MUST NOT use unencoded payload");let e={payload:(0,o.k6)(d.protectedHeader,d.payload,c),protectedHeader:d.protectedHeader};return"function"==typeof b?{...e,key:d.key}:e}},81329:(a,b,c)=>{c.d(b,{Xg:()=>d.Xg,eh:()=>e,vq:()=>d.vq});var d=c(44404);Object.entries(c(75681).AI_PROVIDERS).filter(([,a])=>a.passthroughModels).map(([a])=>a);let e=Object.entries(d.vq).flatMap(([a,b])=>b.map(b=>({provider:a,model:b.id,name:b.name})))}};