@sifxprime/krouter 0.5.152 → 0.5.153

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 (206) hide show
  1. package/app/.next-cli-build/BUILD_ID +1 -1
  2. package/app/.next-cli-build/app-path-routes-manifest.json +8 -8
  3. package/app/.next-cli-build/build-manifest.json +2 -2
  4. package/app/.next-cli-build/prerender-manifest.json +25 -25
  5. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  6. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/environment/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +3 -3
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/presidio/page_client-reference-manifest.js +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  33. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  34. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  35. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  36. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  37. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  38. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  39. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  40. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  41. package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  42. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  43. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
  44. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  45. package/app/.next-cli-build/server/app/api/models/live/route.js +1 -1
  46. package/app/.next-cli-build/server/app/api/models/route.js +1 -1
  47. package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  48. package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js +1 -1
  49. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  50. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  51. package/app/.next-cli-build/server/app/api/v1/search/route.js +1 -1
  52. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  53. package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  54. package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  55. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  56. package/app/.next-cli-build/server/app/callback.html +1 -1
  57. package/app/.next-cli-build/server/app/callback.rsc +4 -4
  58. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  59. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
  60. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
  61. package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  62. package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
  63. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +10 -9
  64. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
  65. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
  66. package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  67. package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +6 -6
  68. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +11 -9
  69. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
  70. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
  71. package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  72. package/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
  73. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +11 -9
  74. package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
  75. package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
  76. package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  77. package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
  78. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +11 -9
  79. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
  80. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
  81. package/app/.next-cli-build/server/app/dashboard/environment.html +1 -1
  82. package/app/.next-cli-build/server/app/dashboard/environment.rsc +6 -6
  83. package/app/.next-cli-build/server/app/dashboard/environment.segments/!KGRhc2hib2FyZCk/dashboard/environment/__PAGE__.segment.rsc +11 -9
  84. package/app/.next-cli-build/server/app/dashboard/environment.segments/_full.segment.rsc +6 -6
  85. package/app/.next-cli-build/server/app/dashboard/environment.segments/_tree.segment.rsc +2 -2
  86. package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  87. package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +19 -17
  88. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +11 -9
  89. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +19 -17
  90. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
  91. package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  92. package/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
  93. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +10 -9
  94. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
  95. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
  96. package/app/.next-cli-build/server/app/dashboard/presidio.html +1 -1
  97. package/app/.next-cli-build/server/app/dashboard/presidio.rsc +5 -5
  98. package/app/.next-cli-build/server/app/dashboard/presidio.segments/!KGRhc2hib2FyZCk/dashboard/presidio/__PAGE__.segment.rsc +10 -8
  99. package/app/.next-cli-build/server/app/dashboard/presidio.segments/_full.segment.rsc +5 -5
  100. package/app/.next-cli-build/server/app/dashboard/presidio.segments/_tree.segment.rsc +2 -2
  101. package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  102. package/app/.next-cli-build/server/app/dashboard/profile.rsc +6 -6
  103. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +11 -9
  104. package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
  105. package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
  106. package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  107. package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +19 -17
  108. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +11 -9
  109. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +19 -17
  110. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
  111. package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  112. package/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
  113. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +11 -9
  114. package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
  115. package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
  116. package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  117. package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
  118. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +11 -9
  119. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
  120. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
  121. package/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
  122. package/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +6 -6
  123. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +10 -9
  124. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +6 -6
  125. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +2 -2
  126. package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  127. package/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
  128. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +12 -10
  129. package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
  130. package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
  131. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  132. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  133. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  134. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  135. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  136. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +4 -4
  137. package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
  138. package/app/.next-cli-build/server/app/dashboard/skills.rsc +6 -6
  139. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +11 -9
  140. package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
  141. package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
  142. package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  143. package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +6 -6
  144. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +10 -9
  145. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +6 -6
  146. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +2 -2
  147. package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  148. package/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
  149. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +11 -9
  150. package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
  151. package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
  152. package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  153. package/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
  154. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +11 -9
  155. package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
  156. package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
  157. package/app/.next-cli-build/server/app/dashboard.html +1 -1
  158. package/app/.next-cli-build/server/app/dashboard.rsc +6 -6
  159. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +6 -6
  160. package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +6 -6
  161. package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +2 -2
  162. package/app/.next-cli-build/server/app/index.html +1 -1
  163. package/app/.next-cli-build/server/app/index.rsc +4 -4
  164. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  165. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  166. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
  167. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  168. package/app/.next-cli-build/server/app/landing.html +1 -1
  169. package/app/.next-cli-build/server/app/landing.rsc +4 -4
  170. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  171. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
  172. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
  173. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  174. package/app/.next-cli-build/server/app/login.html +1 -1
  175. package/app/.next-cli-build/server/app/login.rsc +5 -5
  176. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +5 -5
  177. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
  178. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +5 -5
  179. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  180. package/app/.next-cli-build/server/app-paths-manifest.json +8 -8
  181. package/app/.next-cli-build/server/chunks/2365.js +1 -1
  182. package/app/.next-cli-build/server/chunks/4315.js +1 -1
  183. package/app/.next-cli-build/server/chunks/4921.js +1 -1
  184. package/app/.next-cli-build/server/chunks/5330.js +2 -2
  185. package/app/.next-cli-build/server/chunks/5718.js +1 -1
  186. package/app/.next-cli-build/server/chunks/706.js +1 -1
  187. package/app/.next-cli-build/server/chunks/7153.js +1 -1
  188. package/app/.next-cli-build/server/chunks/8238.js +1 -1
  189. package/app/.next-cli-build/server/chunks/8361.js +2 -2
  190. package/app/.next-cli-build/server/chunks/8895.js +2 -2
  191. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  192. package/app/.next-cli-build/server/pages/404.html +1 -1
  193. package/app/.next-cli-build/server/pages/500.html +1 -1
  194. package/app/.next-cli-build/static/chunks/{1321-0363777901a09d88.js → 1321-d7f207e502227ef0.js} +1 -1
  195. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/{page-1c13f46a5c077d38.js → page-071c7098cf94202c.js} +3 -3
  196. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/profile/page-b7a83a5b300aa4ca.js +1 -0
  197. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-ea1a75b474ac9e70.js +1 -0
  198. package/app/.next-cli-build/static/css/{26165543159f6b3d.css → 9155b84281233d49.css} +1 -1
  199. package/app/cli/package.json +1 -1
  200. package/app/package.json +1 -1
  201. package/hooks/sqliteRuntime.js +28 -4
  202. package/package.json +1 -1
  203. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/profile/page-c4e51184b2bf8776.js +0 -1
  204. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-69f5c1cd75191fc4.js +0 -1
  205. /package/app/.next-cli-build/static/{Gy34OESmAYfO9bopbQ7KG → kUUhgVl8EwVCVpVfUCIJj}/_buildManifest.js +0 -0
  206. /package/app/.next-cli-build/static/{Gy34OESmAYfO9bopbQ7KG → kUUhgVl8EwVCVpVfUCIJj}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sifxprime/krouter",
3
- "version": "0.5.152",
3
+ "version": "0.5.153",
4
4
  "description": "kRouter (Kodelyth Router) CLI — Kodelyth AI Infrastructure",
5
5
  "homepage": "https://github.com/sifxprime/krouter",
6
6
  "repository": {
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "krouter-app",
3
- "version": "0.5.152",
3
+ "version": "0.5.153",
4
4
  "description": "kRouter (Kodelyth Router) web dashboard — Kodelyth AI Infrastructure",
5
5
  "private": true,
6
6
  "scripts": {
@@ -6,7 +6,13 @@ const fs = require("fs");
6
6
  const os = require("os");
7
7
  const path = require("path");
8
8
 
9
- const BETTER_SQLITE3_VERSION = "12.6.2";
9
+ // Gate the pinned version by Node major. 13.x is N-API and ships per-platform
10
+ // prebuilds inside the package, so it needs no ABI-specific download and no build
11
+ // tools; it requires Node >= 22. Older runtimes stay on 12.6.2, which fetches an
12
+ // ABI-specific binary via prebuild-install.
13
+ const [NODE_MAJOR] = process.versions.node.split(".").map(Number);
14
+ const USE_NAPI_BUILD = NODE_MAJOR >= 22;
15
+ const BETTER_SQLITE3_VERSION = USE_NAPI_BUILD ? "13.0.3" : "12.6.2";
10
16
 
11
17
  // Kept in sync with src/mitm/paths.js / src/lib/dataDir.js
12
18
  function getDataDir() {
@@ -46,9 +52,23 @@ function hasModule(name) {
46
52
  return fs.existsSync(path.join(getRuntimeNodeModules(), name, "package.json"));
47
53
  }
48
54
 
55
+ function isGlibcRuntime() {
56
+ try { return Boolean(process.report?.getReport()?.header?.glibcVersionRuntime); } catch { return true; }
57
+ }
58
+
59
+ // 12.x compiles or downloads into build/Release; 13.x ships prebuilds/<platform>-<arch>.node.
60
+ function getBetterSqliteBinary() {
61
+ const root = path.join(getRuntimeNodeModules(), "better-sqlite3");
62
+ const platform = process.platform === "linux" && !isGlibcRuntime() ? "linuxmusl" : process.platform;
63
+ return [
64
+ path.join(root, "build", "Release", "better_sqlite3.node"),
65
+ path.join(root, "prebuilds", `${platform}-${process.arch}.node`),
66
+ ].find((file) => fs.existsSync(file));
67
+ }
68
+
49
69
  function isBetterSqliteBinaryValid() {
50
- const binary = path.join(getRuntimeNodeModules(), "better-sqlite3", "build", "Release", "better_sqlite3.node");
51
- if (!fs.existsSync(binary)) return false;
70
+ const binary = getBetterSqliteBinary();
71
+ if (!binary) return false;
52
72
  try {
53
73
  const fd = fs.openSync(binary, "r");
54
74
  const buf = Buffer.alloc(4);
@@ -92,6 +112,7 @@ function runNpmInstall({ cwd, pkgs, extraArgs = [], timeout = 180000 }) {
92
112
  function npmInstall(pkgs, opts = {}) {
93
113
  const cwd = ensureRuntimeDir();
94
114
  const extra = opts.optional ? ["--no-save"] : [];
115
+ if (opts.ignoreScripts) extra.push("--ignore-scripts");
95
116
  if (!opts.silent) console.log("⏳ Installing SQLite engine (first run)...");
96
117
  const res = runNpmInstall({ cwd, pkgs, extraArgs: extra, timeout: opts.timeout || 180000 });
97
118
  if (!res.ok && !opts.silent) {
@@ -115,7 +136,10 @@ function ensureSqliteRuntime({ silent = false } = {}) {
115
136
  return { betterSqlite: true };
116
137
  }
117
138
 
118
- const ok = npmInstall([`better-sqlite3@${BETTER_SQLITE3_VERSION}`], { optional: true, silent });
139
+ // npm injects an implicit `node-gyp rebuild` for any package carrying a
140
+ // binding.gyp, which would demand build tools even though 13.x already bundles
141
+ // the binary -- skip scripts so the bundled prebuild is used as-is.
142
+ const ok = npmInstall([`better-sqlite3@${BETTER_SQLITE3_VERSION}`], { optional: true, silent, ignoreScripts: USE_NAPI_BUILD });
119
143
  return {
120
144
  betterSqlite: ok && hasModule("better-sqlite3") && isBetterSqliteBinaryValid(),
121
145
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sifxprime/krouter",
3
- "version": "0.5.152",
3
+ "version": "0.5.153",
4
4
  "description": "kRouter (Kodelyth Router) CLI — Kodelyth AI Infrastructure",
5
5
  "homepage": "https://github.com/sifxprime/krouter",
6
6
  "repository": {
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3471],{38048:(e,t,s)=>{Promise.resolve().then(s.bind(s,64561))},64561:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>u});var a=s(95155),r=s(12115),o=s(73321),l=s(35497),i=s(81127),n=s(21931),d=s(1620),c=s(31474),m=s(90620),x=s(93308),p=s(38202);function u(){let e=(0,o.useRouter)(),{theme:t,setTheme:s,isDark:u}=(0,d.D)(),[h,b]=(0,r.useState)("en"),[g,y]=(0,r.useState)(!1),[f,j]=(0,r.useState)(!1),[N,v]=(0,r.useState)(!1),[w,C]=(0,r.useState)({fallbackStrategy:"fill-first"}),[k,S]=(0,r.useState)(!0),[P,I]=(0,r.useState)({current:"",new:"",confirm:""}),[O,L]=(0,r.useState)({type:"",message:""}),[R,F]=(0,r.useState)(!1),[D,M]=(0,r.useState)(!1),[T,U]=(0,r.useState)({type:"",message:""}),[E,A]=(0,r.useState)({open:!1,mode:"",password:""}),$=(0,r.useRef)(null),[q,J]=(0,r.useState)({authMode:"password",oidcIssuerUrl:"",oidcClientId:"",oidcScopes:"openid profile email",oidcLoginLabel:"Sign in with OIDC"}),[_,H]=(0,r.useState)(""),[Z,K]=(0,r.useState)({type:"",message:""}),[W,z]=(0,r.useState)(!1),[B,Q]=(0,r.useState)(!1),[G,V]=(0,r.useState)({type:"",message:""}),[Y,X]=(0,r.useState)("/api/auth/oidc/callback"),[ee,et]=(0,r.useState)(!1),es=(0,r.useRef)(null),[ea,er]=(0,r.useState)({outboundProxyEnabled:!1,outboundProxyUrl:"",outboundNoProxy:""}),[eo,el]=(0,r.useState)({type:"",message:""}),[ei,en]=(0,r.useState)(!1),[ed,ec]=(0,r.useState)(!1);(0,r.useEffect)(()=>{b(function(){if("u"<typeof document)return"en";let e=document.cookie.split(";").find(e=>e.trim().startsWith(`${x.CL}=`)),t=e?decodeURIComponent(e.split("=")[1]):"en";return(0,x.QC)(t)}())},[g]),(0,r.useEffect)(()=>{fetch("/api/settings").then(e=>e.json()).then(e=>{C(e),J({authMode:e?.authMode||"password",oidcIssuerUrl:e?.oidcIssuerUrl||"",oidcClientId:e?.oidcClientId||"",oidcScopes:e?.oidcScopes||"openid profile email",oidcLoginLabel:e?.oidcLoginLabel||"Sign in with OIDC"}),H(""),(e?.authMode==="oidc"||e?.authMode==="both")&&et(!0),er({outboundProxyEnabled:e?.outboundProxyEnabled===!0,outboundProxyUrl:e?.outboundProxyUrl||"",outboundNoProxy:e?.outboundNoProxy||""}),S(!1)}).catch(e=>{console.error("Failed to fetch settings:",e),S(!1)})},[]),(0,r.useEffect)(()=>{X(`${window.location.origin}/api/auth/oidc/callback`)},[]);let em=async e=>{if(e.preventDefault(),!0===w.outboundProxyEnabled){en(!0),el({type:"",message:""});try{let e=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({outboundProxyUrl:ea.outboundProxyUrl,outboundNoProxy:ea.outboundNoProxy})}),t=await e.json();e.ok?(C(e=>({...e,...t})),el({type:"success",message:"Proxy settings applied"})):el({type:"error",message:t.error||"Failed to update proxy settings"})}catch(e){el({type:"error",message:"An error occurred"})}finally{en(!1)}}},ex=async()=>{if(!0!==w.outboundProxyEnabled)return;let e=(ea.outboundProxyUrl||"").trim();if(!e)return void el({type:"error",message:"Please enter a Proxy URL to test"});ec(!0),el({type:"",message:""});try{let t=await fetch("/api/settings/proxy-test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({proxyUrl:e})}),s=await t.json();t.ok&&s?.ok?el({type:"success",message:`Proxy test OK (${s.status}) in ${s.elapsedMs}ms`}):el({type:"error",message:s?.error||"Proxy test failed"})}catch(e){el({type:"error",message:"An error occurred"})}finally{ec(!1)}},ep=async e=>{en(!0),el({type:"",message:""});try{let t=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({outboundProxyEnabled:e})}),s=await t.json();t.ok?(C(e=>({...e,...s})),er(e=>({...e,outboundProxyEnabled:s?.outboundProxyEnabled===!0})),el({type:"success",message:e?"Proxy enabled":"Proxy disabled"})):el({type:"error",message:s.error||"Failed to update proxy settings"})}catch(e){el({type:"error",message:"An error occurred"})}finally{en(!1)}},eu=async e=>{if(e.preventDefault(),P.new!==P.confirm)return void L({type:"error",message:"Passwords do not match"});F(!0),L({type:"",message:""});try{let e=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({currentPassword:P.current,newPassword:P.new})}),t=await e.json();e.ok?(L({type:"success",message:"Password updated successfully"}),I({current:"",new:"",confirm:""})):L({type:"error",message:t.error||"Failed to update password"})}catch(e){L({type:"error",message:"An error occurred"})}finally{F(!1)}},eh=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({fallbackStrategy:e})})).ok&&C(t=>({...t,fallbackStrategy:e}))}catch(e){console.error("Failed to update settings:",e)}},eb=async(e,t)=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({[e]:t})})).ok&&C(s=>({...s,[e]:t}))}catch(t){console.error(`Failed to update ${e}:`,t)}},eg=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStrategy:e})})).ok&&C(t=>({...t,comboStrategy:e}))}catch(e){console.error("Failed to update combo strategy:",e)}},ey=async e=>{let t=parseInt(e,10);if(!isNaN(t)&&!(t<1))try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({stickyRoundRobinLimit:t})})).ok&&C(e=>({...e,stickyRoundRobinLimit:t}))}catch(e){console.error("Failed to update sticky limit:",e)}},ef=async e=>{let t=parseInt(e,10);if(!isNaN(t)&&!(t<1))try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStickyRoundRobinLimit:t})})).ok&&C(e=>({...e,comboStickyRoundRobinLimit:t}))}catch(e){console.error("Failed to update combo sticky limit:",e)}},ej=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({requireLogin:e})})).ok&&C(t=>({...t,requireLogin:e}))}catch(e){console.error("Failed to update require login:",e)}},eN=(e,t)=>{J(s=>({...s,[e]:t}))},ev=async(e=q.authMode||"password")=>{let t=q.oidcIssuerUrl.trim(),s=q.oidcClientId.trim(),a=q.oidcScopes.trim(),r=q.oidcLoginLabel.trim(),o=_.trim();if("password"!==e&&(!t||!s||!o)&&!w.oidcConfigured)return void K({type:"error",message:"Issuer URL, client ID, and client secret are required to enable OIDC."});z(!0),K({type:"",message:""}),V({type:"",message:""});try{let l={authMode:e,oidcIssuerUrl:t,oidcClientId:s,oidcScopes:a||"openid profile email",oidcLoginLabel:r||"Sign in with OIDC"};o&&(l.oidcClientSecret=o);let i=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}),n=await i.json();i.ok?(C(e=>({...e,...n})),J({authMode:n?.authMode||e,oidcIssuerUrl:n?.oidcIssuerUrl||t,oidcClientId:n?.oidcClientId||s,oidcScopes:n?.oidcScopes||a||"openid profile email",oidcLoginLabel:n?.oidcLoginLabel||r||"Sign in with OIDC"}),H(""),K({type:"success",message:"oidc"===e?"OIDC login enabled":"both"===e?"Password and OIDC login enabled":"OIDC settings saved"})):K({type:"error",message:n.error||"Failed to save OIDC settings"})}catch(e){K({type:"error",message:"An error occurred"})}finally{z(!1)}},ew=async()=>{let e=q.oidcIssuerUrl.trim(),t=q.oidcClientId.trim(),s=q.oidcScopes.trim(),a=_.trim();if(!e||!t)return void V({type:"error",message:"Issuer URL and client ID are required to test the connection."});Q(!0),K({type:"",message:""}),V({type:"",message:""});try{let r=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({authMode:q.authMode||w.authMode||"password",oidcIssuerUrl:e,oidcClientId:t,oidcScopes:s||"openid profile email",oidcLoginLabel:q.oidcLoginLabel.trim()||"Sign in with OIDC",...a?{oidcClientSecret:a}:{}})}),o=await r.json().catch(()=>({}));if(!r.ok)return void V({type:"error",message:o.error||"Failed to save OIDC settings before testing"});let l=await fetch("/api/auth/oidc/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({issuerUrl:o.oidcIssuerUrl||e,clientId:o.oidcClientId||t,scopes:o.oidcScopes||s||"openid profile email"})}),i=await l.json().catch(()=>({}));if(l.ok&&i?.ok){let e=i.clientSecretTested?!0===i.clientSecretValid?`Connection OK. Discovery loaded from ${i.issuerUrl}. Client secret validated too.`:`Connection OK. Discovery loaded from ${i.issuerUrl}. Client secret was not checked.`:`Connection OK. Discovery loaded from ${i.issuerUrl}.`;V({type:"success",message:e})}else V({type:"error",message:i.error||"OIDC connection test failed"})}catch(e){V({type:"error",message:"An error occurred"})}finally{Q(!1)}},eC=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enableObservability:e})})).ok&&C(t=>({...t,enableObservability:e}))}catch(e){console.error("Failed to update enableObservability:",e)}},ek=async()=>{try{let e=await fetch("/api/settings");if(!e.ok)return;let t=await e.json();C(t)}catch(e){console.error("Failed to reload settings:",e)}},eS=async e=>{M(!0),U({type:"",message:""});try{let t=await fetch("/api/settings/database",{headers:{"x-9r-password":e}});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error||"Failed to export database")}let s=await t.json(),a=JSON.stringify(s,null,2),r=new Blob([a],{type:"application/json"}),o=URL.createObjectURL(r),l=document.createElement("a"),i=new Date().toISOString().replace(/[.:]/g,"-");l.href=o,l.download=`krouter-backup-${i}.json`,document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(o),U({type:"success",message:"Database backup downloaded"})}catch(e){U({type:"error",message:e.message||"Failed to export database"})}finally{M(!1)}},eP=async e=>{let t=$.current;if(t){M(!0);try{let s=await t.text(),a=JSON.parse(s),r=await fetch("/api/settings/database",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...a,password:e})}),o=await r.json().catch(()=>({}));if(!r.ok)throw Error(o.error||"Failed to import database");await ek(),U({type:"success",message:"Database imported successfully"})}catch(e){U({type:"error",message:e.message||"Invalid backup file"})}finally{$.current=null,M(!1)}}},eI=async()=>{let{mode:e,password:t}=E;A({open:!1,mode:"",password:""}),"export"===e?await eS(t):"import"===e&&await eP(t)},eO=!0===w.enableObservability,eL=async()=>{v(!0);try{await fetch("/api/version/shutdown",{method:"POST"})}catch(e){}v(!1),j(!1)},eR=async()=>{try{(await fetch("/api/auth/logout",{method:"POST"})).ok&&(e.push("/login"),e.refresh())}catch(e){console.error("Failed to logout:",e)}};return(0,a.jsxs)("div",{className:"max-w-2xl mx-auto px-4 sm:px-0",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-6",children:[(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 sm:gap-4",children:[(0,a.jsx)("div",{className:"size-10 sm:size-12 rounded-lg bg-green-500/10 text-green-500 flex items-center justify-center shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-xl sm:text-2xl",children:"computer"})}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-lg sm:text-xl font-semibold",children:"Local Mode"}),(0,a.jsx)("p",{className:"text-sm text-text-muted",children:"Running on your machine"})]})]}),(0,a.jsx)("div",{className:"inline-flex p-1 rounded-lg bg-black/5 dark:bg-white/5 w-full sm:w-auto",children:["light","dark","system"].map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>s(e),className:(0,c.cn)("flex items-center justify-center gap-1 sm:gap-1.5 px-2 sm:px-3 py-1.5 rounded-md font-medium transition-all flex-1 sm:flex-initial",t===e?"bg-white dark:bg-white/10 text-text-main shadow-sm":"text-text-muted hover:text-text-main"),children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"light"===e?"light_mode":"dark"===e?"dark_mode":"contrast"}),(0,a.jsx)("span",{className:"capitalize text-xs sm:text-sm",children:e})]},e))})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-3 pt-4 border-t border-border",children:[(0,a.jsx)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between p-3 rounded-lg bg-bg border border-border gap-2",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Database Location"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted font-mono break-all",children:"~/.krouter/db/data.sqlite"})]})}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2",children:[(0,a.jsx)(l.$n,{variant:"secondary",icon:"download",onClick:()=>A({open:!0,mode:"export",password:""}),loading:D,className:"w-full sm:w-auto",children:"Download Backup"}),(0,a.jsx)(l.$n,{variant:"outline",icon:"upload",onClick:()=>es.current?.click(),disabled:D,className:"w-full sm:w-auto",children:"Import Backup"}),(0,a.jsx)("input",{ref:es,type:"file",accept:"application/json,.json",className:"hidden",onChange:e=>{let t=e.target.files?.[0];es.current&&(es.current.value=""),t&&($.current=t,U({type:"",message:""}),A({open:!0,mode:"import",password:""}))}})]}),T.message&&(0,a.jsx)("p",{className:`text-sm ${"error"===T.type?"text-red-500":"text-green-600 dark:text-green-400"}`,children:T.message})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"size-10 rounded-lg bg-blue-500/10 text-blue-500 flex items-center justify-center shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"language"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Language"})]}),(0,a.jsxs)("button",{onClick:()=>y(!0),className:"flex items-center justify-between w-full p-3 rounded-lg bg-bg border border-border hover:border-primary/50 transition-colors","data-i18n-skip":"true",children:[(0,a.jsx)("span",{className:"text-sm text-text-muted",children:"Display language"}),(0,a.jsx)("span",{className:"text-2xl",children:p.h[h]||"\uD83C\uDF10"})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-primary/10 text-primary shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"shield"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Security"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Require login"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"When ON, dashboard requires password. When OFF, access without login."})]}),(0,a.jsx)(l.lM,{checked:!0===w.requireLogin,onChange:()=>ej(!w.requireLogin),disabled:k})]}),!0===w.requireLogin&&(0,a.jsxs)("form",{onSubmit:eu,className:"flex flex-col gap-4 pt-4 border-t border-border/50",children:[w.hasPassword&&(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"Current Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Enter current password",value:P.current,onChange:e=>I({...P,current:e.target.value}),required:!0})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"New Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Enter new password",value:P.new,onChange:e=>I({...P,new:e.target.value}),required:!0})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"Confirm New Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Confirm new password",value:P.confirm,onChange:e=>I({...P,confirm:e.target.value}),required:!0})]})]}),O.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===O.type?"text-red-500":"text-green-500"}`,children:O.message}),(0,a.jsx)("div",{className:"pt-2",children:(0,a.jsx)(l.$n,{type:"submit",variant:"primary",loading:R,className:"w-full sm:w-auto",children:w.hasPassword?"Update Password":"Set Password"})})]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("button",{type:"button",onClick:()=>et(e=>!e),className:"w-full flex items-center gap-3 text-left",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-indigo-500/10 text-indigo-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"lock_open"})}),(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"OIDC Dashboard Login"}),(0,a.jsx)("p",{className:"text-xs text-text-muted",children:"oidc"===w.authMode?"OIDC active":"both"===w.authMode?"Password + OIDC active":"Optional SSO via Authentik/Keycloak/Google"})]}),(0,a.jsx)("span",{className:"material-symbols-outlined text-text-muted shrink-0",children:ee?"expand_less":"expand_more"})]}),ee&&(0,a.jsxs)("div",{className:"flex flex-col gap-4 mt-4",children:[(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Use Authentik or any OIDC provider to sign in to the dashboard. You can enable password-only, OIDC-only, or both for the dashboard; model API access still uses API keys."}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Auth Mode"}),(0,a.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-2",children:[{value:"password",title:"Password only",desc:"Keep the legacy password login."},{value:"oidc",title:"OIDC only",desc:"Require OIDC for dashboard access."},{value:"both",title:"Both",desc:"Allow either password or OIDC."}].map(e=>{let t=q.authMode===e.value;return(0,a.jsxs)("button",{type:"button",onClick:()=>eN("authMode",e.value),className:(0,c.cn)("text-left rounded-lg border p-3 transition-colors",t?"border-primary bg-primary/5":"border-border bg-bg hover:bg-black/5 dark:hover:bg-white/5"),disabled:k||W,children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:e.title}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted mt-1",children:e.desc})]},e.value)})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-4",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Issuer URL"}),(0,a.jsx)(l.pd,{placeholder:"https://auth.example.com/application/o/krouter/",value:q.oidcIssuerUrl,onChange:e=>eN("oidcIssuerUrl",e.target.value),disabled:k||W})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Client ID"}),(0,a.jsx)(l.pd,{placeholder:"krouter-dashboard",value:q.oidcClientId,onChange:e=>eN("oidcClientId",e.target.value),disabled:k||W})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Client Secret"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Leave blank to keep existing secret",value:_,onChange:e=>H(e.target.value),disabled:k||W}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"This value is write-only after saving."})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Scopes"}),(0,a.jsx)(l.pd,{placeholder:"openid profile email",value:q.oidcScopes,onChange:e=>eN("oidcScopes",e.target.value),disabled:k||W})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Login Button Label"}),(0,a.jsx)(l.pd,{placeholder:"Sign in with OIDC",value:q.oidcLoginLabel,onChange:e=>eN("oidcLoginLabel",e.target.value),disabled:k||W})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border border-border bg-bg p-3 text-xs sm:text-sm text-text-muted",children:[(0,a.jsx)("p",{className:"font-medium text-text-main mb-1",children:"Redirect URI"}),(0,a.jsx)("code",{className:"block break-all font-mono",children:Y})]}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2 pt-2 border-t border-border/50",children:[(0,a.jsx)(l.$n,{type:"button",variant:"primary",loading:W,onClick:()=>ev(),className:"w-full sm:w-auto",children:"Save auth mode"}),(0,a.jsx)(l.$n,{type:"button",variant:"outline",loading:B,onClick:ew,className:"w-full sm:w-auto",children:"Test connection"})]}),G.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===G.type?"text-red-500":"text-green-500"}`,children:G.message}),Z.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===Z.type?"text-red-500":"text-green-500"}`,children:Z.message}),"oidc"===w.authMode&&(0,a.jsx)("p",{className:"text-xs sm:text-sm text-amber-600 dark:text-amber-400",children:"OIDC login is currently active. Password login is disabled until you switch back."}),"both"===w.authMode&&(0,a.jsx)("p",{className:"text-xs sm:text-sm text-amber-600 dark:text-amber-400",children:"Password and OIDC login are both active."})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-blue-500/10 text-blue-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"route"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Routing Strategy"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Strategy"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"How kRouter picks the next available account"})]}),(0,a.jsx)(l.l6,{value:w.fallbackStrategy||"fill-first",onChange:e=>eh(e.target.value),disabled:k,className:"w-44 sm:w-56 shrink-0",options:[{value:"fill-first",label:"Fill First (default)"},{value:"round-robin",label:"Round Robin"},{value:"p2c",label:"P2C (Power of 2 Choices)"},{value:"random",label:"Random"}]})]}),"round-robin"===w.fallbackStrategy&&(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Sticky Limit"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Calls per account before switching"})]}),(0,a.jsx)(l.pd,{type:"number",min:"1",max:"10",value:w.stickyRoundRobinLimit||3,onChange:e=>ey(e.target.value),disabled:k,className:"w-16 sm:w-20 text-center shrink-0"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Combo Round Robin"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Cycle through providers in combos instead of always starting with first"})]}),(0,a.jsx)(l.lM,{checked:"round-robin"===w.comboStrategy,onChange:()=>eg("round-robin"===w.comboStrategy?"fallback":"round-robin"),disabled:k})]}),"round-robin"===w.comboStrategy&&(0,a.jsxs)("div",{className:"flex items-center justify-between pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium",children:"Combo Sticky Limit"}),(0,a.jsx)("p",{className:"text-sm text-text-muted",children:"Calls per combo model before switching"})]}),(0,a.jsx)(l.pd,{type:"number",min:"1",max:"100",value:w.comboStickyRoundRobinLimit||1,onChange:e=>ef(e.target.value),disabled:k,className:"w-20 text-center"})]}),(0,a.jsxs)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:["round-robin"===w.fallbackStrategy?`Distributing requests across all available accounts with ${w.stickyRoundRobinLimit||3} calls per account.`:"p2c"===w.fallbackStrategy?"Picking the healthier of 2 random accounts on each request (good for load-balancing equal-tier accounts).":"random"===w.fallbackStrategy?"Picking a uniformly random account on each request.":"Using accounts in priority order (Fill First).","round-robin"===w.comboStrategy?` Combos rotate after ${w.comboStickyRoundRobinLimit||1} call${1===(w.comboStickyRoundRobinLimit||1)?"":"s"} per model.`:" Combos always start with their first model."]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-purple-500/10 text-purple-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"psychology"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Task-Aware Routing"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Show intent suggestions in logs"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Classify every request as code / math / reasoning / creative / simple (9 languages) and log the suggested combo. Log-only; never overrides your chosen model."})]}),(0,a.jsx)(l.lM,{checked:!1!==w.routingIntelligenceEnabled,onChange:()=>eb("routingIntelligenceEnabled",!1===w.routingIntelligenceEnabled),disabled:k})]}),!1!==w.routingIntelligenceEnabled&&(0,a.jsxs)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:["Active — check the dev console for ",(0,a.jsx)("code",{children:"[ROUTING] intent=X complexity=Y score=N tier=Z"})," lines. Custom intent→combo overrides via ",(0,a.jsx)("code",{children:"taskAwareRouterMap"})," setting (JSON)."]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-amber-500/10 text-amber-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"emergency"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Emergency Fallback"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Redirect on budget exhaustion"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:'When an upstream returns 402 or "insufficient funds", transparently re-route the request to a free model so the user still gets a response.'})]}),(0,a.jsx)(l.lM,{checked:!!w.emergencyFallbackEnabled,onChange:()=>eb("emergencyFallbackEnabled",!w.emergencyFallbackEnabled),disabled:k})]}),w.emergencyFallbackEnabled&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-3 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Fallback provider"}),(0,a.jsxs)("p",{className:"text-xs sm:text-sm text-text-muted",children:["Provider ID used for the redirect (e.g. ",(0,a.jsx)("code",{children:"nvidia"}),", ",(0,a.jsx)("code",{children:"openrouter"}),", ",(0,a.jsx)("code",{children:"opencode"}),")"]})]}),(0,a.jsx)(l.pd,{type:"text",value:w.emergencyFallbackProvider||"nvidia",onChange:e=>eb("emergencyFallbackProvider",e.target.value.trim()),disabled:k,className:"w-32 sm:w-44 text-center shrink-0",placeholder:"nvidia"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-3 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Fallback model"}),(0,a.jsxs)("p",{className:"text-xs sm:text-sm text-text-muted",children:["Model ID at that provider. Default ",(0,a.jsx)("code",{children:"openai/gpt-oss-120b"})," is free on NVIDIA NIM."]})]}),(0,a.jsx)(l.pd,{type:"text",value:w.emergencyFallbackModel||"openai/gpt-oss-120b",onChange:e=>eb("emergencyFallbackModel",e.target.value.trim()),disabled:k,className:"w-40 sm:w-56 text-center shrink-0",placeholder:"openai/gpt-oss-120b"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-3 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Skip for tool requests"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Don't redirect when the request has tools — the free model may not support tool calling."})]}),(0,a.jsx)(l.lM,{checked:!1!==w.emergencyFallbackSkipForTools,onChange:()=>eb("emergencyFallbackSkipForTools",!1===w.emergencyFallbackSkipForTools),disabled:k})]}),(0,a.jsxs)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:["Currently redirecting 402 / budget errors to"," ",(0,a.jsxs)("code",{children:[w.emergencyFallbackProvider||"nvidia","/",w.emergencyFallbackModel||"openai/gpt-oss-120b"]}),"."]})]}),!w.emergencyFallbackEnabled&&(0,a.jsx)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:"Disabled — 402 / budget errors are returned to the user as-is."})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-cyan-500/10 text-cyan-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"database"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Cache Control"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Mode"}),(0,a.jsxs)("p",{className:"text-xs sm:text-sm text-text-muted",children:["Controls whether kRouter mutates ",(0,a.jsx)("code",{children:"cache_control"})," markers on Claude-shape requests. Anthropic's prompt cache is byte-keyed; any mutation busts the cache."]})]}),(0,a.jsxs)("select",{value:w.cacheControlMode||"auto",onChange:e=>eb("cacheControlMode",e.target.value),disabled:k,className:"w-32 sm:w-44 px-3 py-2 text-sm rounded border border-border bg-bg text-text-main shrink-0",children:[(0,a.jsx)("option",{value:"auto",children:"Auto (recommended)"}),(0,a.jsx)("option",{value:"always",children:"Always preserve"}),(0,a.jsx)("option",{value:"never",children:"Never preserve (legacy)"})]})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-3 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Quick toggle"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Got a fresh-turn 429 because your prompt is bigger than your tier's TPM? Click once to switch into legacy trimming, send your first turn, then click again to return to cache-preserve mode."})]}),(0,a.jsx)("button",{type:"button",onClick:()=>eb("cacheControlMode","never"===(w.cacheControlMode||"auto")?"auto":"never"),disabled:k,className:`w-32 sm:w-44 px-3 py-2 text-sm font-medium rounded shrink-0 transition-colors ${"never"===(w.cacheControlMode||"auto")?"bg-amber-500/15 text-amber-600 border border-amber-500/40 hover:bg-amber-500/25":"bg-cyan-500/15 text-cyan-600 border border-cyan-500/40 hover:bg-cyan-500/25"}`,children:"never"===(w.cacheControlMode||"auto")?"Restore cache preserve":"Emergency: trim prompt"})]}),(0,a.jsxs)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:["auto"===(w.cacheControlMode||"auto")&&(0,a.jsxs)(a.Fragment,{children:["Currently ",(0,a.jsx)("strong",{children:"auto"}),": preserves ",(0,a.jsx)("code",{children:"cache_control"})," only on Claude Desktop / Claude Code passthrough (",(0,a.jsx)("code",{children:'clientTool==="claude"'})," & ",(0,a.jsx)("code",{children:'provider==="claude"'}),"). All other paths mutate as before."]}),"always"===w.cacheControlMode&&(0,a.jsxs)(a.Fragment,{children:["Currently ",(0,a.jsx)("strong",{children:"always"}),": preserves ",(0,a.jsx)("code",{children:"cache_control"})," on any Claude-shape target (including ",(0,a.jsx)("code",{children:"anthropic-compatible-*"})," resellers and translated requests). Paranoid mode."]}),"never"===w.cacheControlMode&&(0,a.jsxs)(a.Fragment,{children:["Currently ",(0,a.jsx)("strong",{children:"never"}),": legacy 0.5.31-and-earlier behaviour — always strip and rewrite ",(0,a.jsx)("code",{children:"cache_control"}),". Escape hatch only."]})]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-purple-500/10 text-purple-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"wifi"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Network"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Outbound Proxy"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Enable proxy for OAuth + provider outbound requests."})]}),(0,a.jsx)(l.lM,{checked:!0===w.outboundProxyEnabled,onChange:()=>ep(!0!==w.outboundProxyEnabled),disabled:k||ei})]}),!0===w.outboundProxyEnabled&&(0,a.jsxs)("form",{onSubmit:em,className:"flex flex-col gap-4 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Proxy URL"}),(0,a.jsx)(l.pd,{placeholder:"http://127.0.0.1:7897",value:ea.outboundProxyUrl,onChange:e=>er(t=>({...t,outboundProxyUrl:e.target.value})),disabled:k||ei}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Leave empty to inherit existing env proxy (if any)."})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2 pt-2 border-t border-border/50",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"No Proxy"}),(0,a.jsx)(l.pd,{placeholder:"localhost,127.0.0.1",value:ea.outboundNoProxy,onChange:e=>er(t=>({...t,outboundNoProxy:e.target.value})),disabled:k||ei}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Comma-separated hostnames/domains to bypass the proxy."})]}),(0,a.jsxs)("div",{className:"pt-2 border-t border-border/50 flex flex-col sm:flex-row items-stretch sm:items-center gap-2",children:[(0,a.jsx)(l.$n,{type:"button",variant:"secondary",loading:ed,disabled:k||ei,onClick:ex,className:"w-full sm:w-auto",children:"Test proxy URL"}),(0,a.jsx)(l.$n,{type:"submit",variant:"primary",loading:ei,className:"w-full sm:w-auto",children:"Apply"})]})]}),eo.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===eo.type?"text-red-500":"text-green-500"} pt-2 border-t border-border/50`,children:eo.message})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-orange-500/10 text-orange-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"monitoring"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Observability"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Enable Observability"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Record request details for inspection in the logs view"})]}),(0,a.jsx)(l.lM,{checked:eO,onChange:eC,disabled:k})]})]}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2",children:[(0,a.jsx)(l.$n,{variant:"outline",fullWidth:!0,icon:"power_settings_new",onClick:()=>j(!0),className:"text-red-500 border-red-200 hover:bg-red-50 hover:border-red-300",children:"Shutdown"}),(0,a.jsx)(l.$n,{variant:"outline",fullWidth:!0,icon:"logout",onClick:eR,children:"Logout"})]}),(0,a.jsxs)("div",{className:"text-center text-xs sm:text-sm text-text-muted py-4",children:[(0,a.jsxs)("p",{children:[m.vQ.name," v",m.vQ.version]}),(0,a.jsx)("p",{className:"mt-1",children:"Local Mode - All data stored on your machine"})]})]}),(0,a.jsx)(n.default,{hideTrigger:!0,isOpen:g,onClose:e=>{y(!1),b(e)}}),(0,a.jsx)(i.ConfirmModal,{isOpen:f,onClose:()=>j(!1),onConfirm:eL,title:"Close Proxy",message:"Are you sure you want to close the proxy server?",confirmText:"Close",cancelText:"Cancel",variant:"danger",loading:N}),(0,a.jsxs)(i.default,{isOpen:E.open,onClose:()=>A({open:!1,mode:"",password:""}),title:"Confirm Password",size:"sm",footer:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(l.$n,{variant:"ghost",onClick:()=>A({open:!1,mode:"",password:""}),disabled:D,children:"Cancel"}),(0,a.jsx)(l.$n,{variant:"primary",onClick:eI,loading:D,disabled:!E.password,children:"Confirm"})]}),children:[(0,a.jsxs)("p",{className:"text-text-muted mb-3 text-sm",children:["Enter your current password to ","export"===E.mode?"export":"import"," the database."]}),(0,a.jsx)(l.pd,{type:"password",value:E.password,onChange:e=>A(t=>({...t,password:e.target.value})),onKeyDown:e=>{"Enter"===e.key&&E.password&&eI()},placeholder:"Current password",autoFocus:!0})]})]})}}},e=>{e.O(0,[7504,1321,5497,8441,3794,7358],()=>e(e.s=38048)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8460],{18160:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>v});var r=s(95155),a=s(12115),l=s(14051),i=s.n(l),n=s(35497),o=s(57250),d=s(90620),c=s(52679),m=s(98500),p=s.n(m);function x(){let[e,t]=(0,a.useState)({status:"idle"}),[s,l]=(0,a.useState)(!1),i=(0,a.useCallback)(async()=>{try{let e=await fetch("/api/providers/zenith",{cache:"no-store"}),s=await e.json();s.success?t({status:"ok",count:s.count,leaderboard:s.leaderboard,winner:s.winner}):t({status:"error",error:s.error})}catch{t({status:"error",error:"network"})}},[]);if((0,a.useEffect)(()=>{i();let e=setInterval(i,15e3);return()=>clearInterval(e)},[i]),"ok"!==e.status||!e.leaderboard?.length)return null;let o=e.leaderboard[0],d=e.leaderboard[e.leaderboard.length-1];return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"mb-4 flex flex-wrap items-center gap-2 rounded-xl border border-primary/20 bg-gradient-to-r from-primary/[0.06] via-primary/[0.02] to-transparent px-4 py-2.5 text-sm",children:[(0,r.jsxs)("span",{className:"inline-flex items-center gap-1.5 font-medium text-primary",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-base",children:"bolt"}),"Zenith"]}),(0,r.jsx)("span",{className:"text-text-muted",children:"\xb7"}),(0,r.jsxs)("span",{className:"text-text-main",children:[e.count," active"]}),(0,r.jsx)("span",{className:"text-text-muted",children:"\xb7"}),(0,r.jsxs)("span",{className:"text-text-main",children:["best ",(0,r.jsx)("span",{className:"font-mono text-green-600 dark:text-green-400",children:o.finalScore})," (",o.name,")"]}),e.count>1&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("span",{className:"text-text-muted",children:"\xb7"}),(0,r.jsxs)("span",{className:"text-text-main",children:["worst ",(0,r.jsx)("span",{className:`font-mono ${d.finalScore<400?"text-red-500":"text-amber-500"}`,children:d.finalScore})," (",d.name,")"]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsx)(n.$n,{size:"sm",variant:"ghost",onClick:()=>l(!0),children:"Leaderboard"})})]}),(0,r.jsx)(n.aF,{isOpen:s,title:"Zenith Leaderboard",onClose:()=>l(!1),children:(0,r.jsx)("div",{className:"max-h-[60vh] overflow-y-auto",children:(0,r.jsxs)("table",{className:"w-full text-sm",children:[(0,r.jsx)("thead",{className:"sticky top-0 bg-bg text-text-muted",children:(0,r.jsxs)("tr",{className:"text-left text-xs",children:[(0,r.jsx)("th",{className:"py-2 pr-2",children:"#"}),(0,r.jsx)("th",{className:"py-2 pr-2",children:"Connection"}),(0,r.jsx)("th",{className:"py-2 pr-2 text-right",children:"Health"}),(0,r.jsx)("th",{className:"py-2 pr-2 text-right",children:"Quota"}),(0,r.jsx)("th",{className:"py-2 pr-2 text-right",children:"Priority"}),(0,r.jsx)("th",{className:"py-2 pl-2 text-right",children:"Zenith"})]})}),(0,r.jsx)("tbody",{children:e.leaderboard.map(e=>(0,r.jsxs)("tr",{className:"border-t border-border/50",children:[(0,r.jsx)("td",{className:"py-1.5 pr-2 text-text-muted",children:e.rank}),(0,r.jsxs)("td",{className:"py-1.5 pr-2",children:[(0,r.jsx)("div",{className:"font-medium",children:e.name}),(0,r.jsx)("div",{className:"text-[10px] text-text-muted",children:e.provider})]}),(0,r.jsx)("td",{className:"py-1.5 pr-2 text-right font-mono text-xs",children:e.healthScore}),(0,r.jsxs)("td",{className:"py-1.5 pr-2 text-right font-mono text-xs",children:["\xd7",e.quotaFactor,null!=e.quotaRemainingPct&&(0,r.jsxs)("span",{className:"ml-1 text-text-muted",children:["(",e.quotaRemainingPct,"%)"]})]}),(0,r.jsxs)("td",{className:"py-1.5 pr-2 text-right font-mono text-xs",children:["+",e.priorityBonus]}),(0,r.jsx)("td",{className:"py-1.5 pl-2 text-right",children:(0,r.jsx)("span",{className:`inline-flex items-center rounded-md border px-1.5 py-0.5 font-mono text-[11px] ${e.finalScore>=750?"bg-green-500/10 text-green-700 dark:text-green-400 border-green-500/30":e.finalScore>=400?"bg-amber-500/10 text-amber-700 dark:text-amber-400 border-amber-500/30":"bg-red-500/10 text-red-700 dark:text-red-400 border-red-500/30"}`,children:e.finalScore})})]},e.connectionId))})]})})})]})}var h=s(65921),u=s(38003);let f={available:{icon:"check_circle",color:"#22c55e",label:"Available"},cooldown:{icon:"schedule",color:"#f59e0b",label:"Cooldown"},unavailable:{icon:"error",color:"#ef4444",label:"Unavailable"},unknown:{icon:"help",color:"#6b7280",label:"Unknown"}};function g(){let[e,t]=(0,a.useState)(null),[s,l]=(0,a.useState)(!0),[i,o]=(0,a.useState)(!1),[d,c]=(0,a.useState)(null),m=(0,a.useRef)(null),p=(0,h.i)(),x=(0,a.useCallback)(async()=>{try{let e=await fetch("/api/models/availability");if(e.ok){let s=await e.json();t(s)}}catch{}finally{l(!1)}},[]);(0,a.useEffect)(()=>{x();let e=setInterval(x,3e4);return()=>clearInterval(e)},[x]),(0,a.useEffect)(()=>{let e=e=>{m.current&&!m.current.contains(e.target)&&o(!1)};return i&&document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[i]);let u=async(e,t)=>{c(`${e}:${t}`);try{(await fetch("/api/models/availability",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"clearCooldown",provider:e,model:t})})).ok?(p.success(`Cooldown cleared for ${t}`),await x()):p.error("Failed to clear cooldown")}catch{p.error("Failed to clear cooldown")}finally{c(null)}};if(s)return null;let g=e?.models||[],b=0===(e?.unavailableCount||g.filter(e=>"available"!==e.status).length),v={};return g.forEach(e=>{if("available"===e.status)return;let t=e.provider||"unknown";v[t]||(v[t]=[]),v[t].push(e)}),(0,r.jsx)("div",{className:"relative",ref:m,children:i&&(0,r.jsxs)("div",{className:"absolute top-full right-0 mt-2 w-80 bg-surface border border-border rounded-xl shadow-2xl z-50 overflow-hidden",children:[(0,r.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border bg-bg",children:[(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[16px]",style:{color:b?"#22c55e":"#f59e0b"},children:b?"verified":"warning"}),(0,r.jsx)("span",{className:"text-sm font-semibold text-text-main",children:"Model Status"})]}),(0,r.jsx)("button",{onClick:x,className:"p-1 rounded-lg hover:bg-surface text-text-muted hover:text-text-main transition-colors",title:"Refresh",children:(0,r.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"refresh"})})]}),(0,r.jsx)("div",{className:"px-4 py-3 max-h-60 overflow-y-auto",children:b?(0,r.jsx)("p",{className:"text-sm text-text-muted text-center py-2",children:"All models are responding normally."}):(0,r.jsx)("div",{className:"flex flex-col gap-2.5",children:Object.entries(v).map(([e,t])=>(0,r.jsxs)("div",{children:[(0,r.jsx)("p",{className:"text-xs font-semibold text-text-main mb-1.5 capitalize",children:e}),(0,r.jsx)("div",{className:"flex flex-col gap-1",children:t.map(e=>{let t=f[e.status]||f.unknown,s=d===`${e.provider}:${e.model}`;return(0,r.jsxs)("div",{className:"flex items-center justify-between px-2.5 py-1.5 rounded-lg bg-surface/30",children:[(0,r.jsxs)("div",{className:"flex items-center gap-1.5 min-w-0",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[14px] shrink-0",style:{color:t.color},children:t.icon}),(0,r.jsx)("span",{className:"font-mono text-xs text-text-main truncate",children:e.model})]}),"cooldown"===e.status&&(0,r.jsx)(n.$n,{size:"sm",variant:"ghost",onClick:()=>u(e.provider,e.model),disabled:s,className:"text-[10px] px-1.5! py-0.5! ml-2",children:s?"...":"Clear"})]},`${e.provider}-${e.model}`)})})]},e))})})]})})}function b(e,t,s){let a=[];if(e>0&&a.push((0,r.jsxs)(n.Ex,{variant:"success",size:"sm",dot:!0,children:[e," Connected"]},"connected")),t>0){let e=s?`${t} Error (${s})`:`${t} Error`;a.push((0,r.jsx)(n.Ex,{variant:"error",size:"sm",dot:!0,children:e},"error"))}return 0===a.length?(0,r.jsx)("span",{className:"text-text-muted",children:"No connections"}):a}function v(){let e,t,[s,l]=(0,a.useState)([]),[i,o]=(0,a.useState)([]),[m,p]=(0,a.useState)(!0),[f,b]=(0,a.useState)(!1),[v,C]=(0,a.useState)(!1),[T,A]=(0,a.useState)(!1),[S,I]=(0,a.useState)(null),[$,E]=(0,a.useState)(null),R=(0,h.i)(),O=(0,u.C)(e=>e.query),U=(0,u.C)(e=>e.register),P=(0,u.C)(e=>e.unregister);(0,a.useEffect)(()=>(U("Search providers..."),()=>P()),[U,P]);let _=e=>!O.trim()||e.toLowerCase().includes(O.trim().toLowerCase());(0,a.useEffect)(()=>{(async()=>{try{let[e,t]=await Promise.all([fetch("/api/providers"),fetch("/api/provider-nodes")]),s=await e.json(),r=await t.json();e.ok&&l(s.connections||[]),t.ok&&o(r.nodes||[])}catch(e){console.log("Error fetching data:",e)}finally{p(!1)}})()},[]);let q=(e,t)=>{let r=s.filter(s=>s.provider===e&&s.authType===t),a=e=>{let t=Object.entries(e).some(([e,t])=>e.startsWith("modelLock_")&&t&&new Date(t).getTime()>Date.now());return"unavailable"!==e.testStatus||t?e.testStatus:"active"},l=r.filter(e=>{let t=a(e);return"active"===t||"success"===t}).length,i=r.filter(e=>{let t=a(e);return"error"===t||"expired"===t||"unavailable"===t}),n=i.length,o=r.length,d=o>0&&r.every(e=>!1===e.isActive),c=i.sort((e,t)=>new Date(t.lastErrorAt||0)-new Date(e.lastErrorAt||0))[0];return{connected:l,error:n,total:o,errorCode:c?function(e){if(!e)return null;let t=e.lastErrorType;if("runtime_error"===t)return"RUNTIME";if("upstream_auth_error"===t||"auth_missing"===t||"token_refresh_failed"===t||"token_expired"===t)return"AUTH";if("upstream_rate_limited"===t)return"429";if("upstream_unavailable"===t)return"5XX";if("network_error"===t)return"NET";let s=Number(e.errorCode);if(Number.isFinite(s)&&s>=400)return String(s);let r=function(e){if(!e)return null;let t=e.match(/\b([45]\d{2})\b/);return t?t[1]:"ERR"}(e.lastError);if("401"===r||"403"===r)return"AUTH";if(r&&"ERR"!==r)return r;let a=(e.lastError||"").toLowerCase();return a.includes("runtime")||a.includes("not runnable")||a.includes("not installed")?"RUNTIME":a.includes("invalid api key")||a.includes("token invalid")||a.includes("revoked")||a.includes("unauthorized")?"AUTH":"ERR"}(c):null,errorTime:c?.lastErrorAt?function(e){if(!e)return"";let t=Math.floor((Date.now()-new Date(e).getTime())/6e4);if(t<1)return"just now";if(t<60)return`${t}m ago`;let s=Math.floor(t/60);if(s<24)return`${s}h ago`;let r=Math.floor(s/24);return`${r}d ago`}(c.lastErrorAt):null,allDisabled:d}},z=async(e,t,r)=>{let a=s.filter(s=>s.provider===e&&s.authType===t);l(s=>s.map(s=>s.provider===e&&s.authType===t?{...s,isActive:r}:s));let i=(await Promise.allSettled(a.map(e=>fetch(`/api/providers/${e.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:r})})))).filter(e=>"fulfilled"!==e.status||!e.value?.ok).length;i>0&&(l(s),R.error(i===a.length?`Could not ${r?"enable":"disable"} ${e} — no changes were saved`:`${i} of ${a.length} ${e} connections could not be updated — reverted`))},D=async(e,t=null)=>{if(!S){I("provider"===e?t:e),E(null);try{let s=await fetch("/api/providers/test-batch",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mode:e,providerId:t})}),r=await s.json();if(E(r),r.summary){let{passed:e,failed:t,total:s}=r.summary;0===t?R.success(`All ${s} tests passed`):R.warning(`${e}/${s} passed, ${t} failed`)}}catch(e){E({error:"Test request failed"}),R.error("Provider test failed")}finally{I(null)}}},F=i.filter(e=>"openai-compatible"===e.type).map(e=>({id:e.id,name:e.name||"OpenAI Compatible",color:"#10A37F",textIcon:"OC",apiType:e.apiType})).filter(e=>_(e.name)),M=i.filter(e=>"anthropic-compatible"===e.type).map(e=>({id:e.id,name:e.name||"Anthropic Compatible",color:"#D97757",textIcon:"AC"})).filter(e=>_(e.name)),L=Object.entries(d.zN).filter(([,e])=>!e.hidden&&_(e.name)),K=Object.entries(c.IS).filter(([,e])=>!e.hidden&&_(e.name)),J=Object.entries(c.nJ).filter(([,e])=>!e.hidden&&_(e.name)),W=(e=Object.entries(d.fg).filter(([,e])=>!e.hidden&&(e.serviceKinds??["llm"]).includes("llm")&&_(e.name)),t="apikey",[...e].sort(([e,s],[r,a])=>{let l=q(e,t),i=q(r,t),n=+(l.connected>0),o=+(i.connected>0);return n!==o?o-n:(s.name||"").localeCompare(a.name||"")})),H=!!O.trim(),Z=H||f?W:W.slice(0,20),B=W.length-20;if(m)return(0,r.jsxs)("div",{className:"flex flex-col gap-8",children:[(0,r.jsx)(n.Qv,{}),(0,r.jsx)(n.Qv,{})]});let Q=L.length>0||K.length>0||J.length>0||W.length>0||F.length>0||M.length>0;return(0,r.jsxs)("div",{className:"flex min-w-0 flex-col gap-6 px-1 sm:px-0",children:[(0,r.jsx)(x,{}),!Q&&(0,r.jsxs)("div",{className:"text-center py-8 border border-dashed border-border rounded-xl",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[32px] text-text-muted mb-2",children:"search_off"}),(0,r.jsx)("p",{className:"text-text-muted text-sm",children:"No providers match your search"})]}),(0,r.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,r.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,r.jsxs)("div",{className:"min-w-0",children:[(0,r.jsx)("h2",{className:"text-[17px] sm:text-lg font-semibold leading-tight tracking-[-0.01em]",children:"Custom Providers"}),(0,r.jsx)("p",{className:"text-[13px] leading-5 text-text-muted mt-0.5",children:"OpenAI or Anthropic compatible endpoints"})]}),(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-2 sm:flex sm:w-auto sm:shrink-0",children:[(0,r.jsx)(n.$n,{size:"sm",icon:"add",onClick:()=>A(!0),className:"w-full sm:w-auto whitespace-nowrap",children:"Add Anthropic Compatible"}),(0,r.jsx)(n.$n,{size:"sm",variant:"secondary",icon:"add",onClick:()=>C(!0),className:"w-full sm:w-auto whitespace-nowrap",children:"Add OpenAI Compatible"})]})]}),0===F.length&&0===M.length?(0,r.jsxs)("div",{className:"flex items-center justify-center gap-2 py-2 border border-dashed border-border rounded-xl text-text-muted text-sm",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"extension"}),(0,r.jsx)("span",{children:"No custom providers — use buttons above to add OpenAI/Anthropic compatible endpoints"})]}):(0,r.jsx)("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 xl:grid-cols-4",children:[...F,...M].map(e=>(0,r.jsx)(y,{providerId:e.id,provider:e,stats:q(e.id,"apikey"),authType:"compatible",onToggle:t=>z(e.id,"apikey",t)},e.id))})]}),L.length>0&&(0,r.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,r.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,r.jsx)("h2",{className:"text-lg sm:text-xl font-semibold flex items-center gap-2 leading-tight",children:"OAuth Providers"}),(0,r.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,r.jsx)(g,{}),(0,r.jsxs)("button",{onClick:()=>D("oauth"),disabled:!!S,className:`flex w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-xs font-medium transition-colors sm:w-auto sm:py-1.5 ${"oauth"===S?"bg-primary/20 border-primary/40 text-primary animate-pulse":"bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"}`,title:"Test all OAuth connections","aria-label":"Test all OAuth connections",children:[(0,r.jsx)("span",{className:`material-symbols-outlined text-[14px]${"oauth"===S?" animate-spin":""}`,children:"play_arrow"}),"oauth"===S?"Testing...":"Test All"]})]})]}),(0,r.jsx)("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 xl:grid-cols-4",children:L.map(([e,t])=>(0,r.jsx)(j,{providerId:e,provider:t,stats:q(e,"oauth"),authType:"oauth",onToggle:t=>z(e,"oauth",t)},e))})]}),(K.length>0||J.length>0)&&(0,r.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,r.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,r.jsx)("h2",{className:"text-lg sm:text-xl font-semibold flex items-center gap-2 leading-tight",children:"Free Tier Providers"}),(0,r.jsxs)("button",{onClick:()=>D("free"),disabled:!!S,className:`flex w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-xs font-medium transition-colors sm:w-auto sm:py-1.5 ${"free"===S?"bg-primary/20 border-primary/40 text-primary animate-pulse":"bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"}`,title:"Test all Free connections","aria-label":"Test all Free provider connections",children:[(0,r.jsx)("span",{className:`material-symbols-outlined text-[14px]${"free"===S?" animate-spin":""}`,children:"play_arrow"}),"free"===S?"Testing...":"Test All"]})]}),(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 xl:grid-cols-4",children:[K.map(([e,t])=>(0,r.jsx)(j,{providerId:e,provider:t,stats:q(e,"oauth"),authType:"free",onToggle:t=>z(e,"oauth",t)},e)),J.map(([e,t])=>(0,r.jsx)(y,{providerId:e,provider:t,stats:q(e,"apikey"),authType:"apikey",onToggle:t=>z(e,"apikey",t)},e))]})]}),W.length>0&&(0,r.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,r.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,r.jsxs)("h2",{className:"text-lg sm:text-xl font-semibold flex items-center gap-2 leading-tight",children:["API Key Providers"," "]}),(0,r.jsxs)("button",{onClick:()=>D("apikey"),disabled:!!S,className:`flex w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-xs font-medium transition-colors sm:w-auto sm:py-1.5 ${"apikey"===S?"bg-primary/20 border-primary/40 text-primary animate-pulse":"bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"}`,title:"Test all API Key connections","aria-label":"Test all API Key connections",children:[(0,r.jsx)("span",{className:`material-symbols-outlined text-[14px]${"apikey"===S?" animate-spin":""}`,children:"play_arrow"}),"apikey"===S?"Testing...":"Test All"]})]}),(0,r.jsx)("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 xl:grid-cols-4",children:Z.map(([e,t])=>(0,r.jsx)(y,{providerId:e,provider:t,stats:q(e,"apikey"),authType:"apikey",onToggle:t=>z(e,"apikey",t)},e))}),!H&&!f&&B>0&&(0,r.jsxs)("button",{onClick:()=>b(!0),className:"flex w-full items-center justify-center gap-1.5 rounded-lg border border-dashed border-primary/40 px-3 py-2.5 text-sm font-medium text-primary transition-colors hover:border-primary hover:bg-primary/5",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"expand_more"}),"Show all ",W.length," providers"]})]}),(0,r.jsx)(N,{isOpen:v,onClose:()=>C(!1),onCreated:e=>{o(t=>[...t,e]),C(!1)}}),(0,r.jsx)(w,{isOpen:T,onClose:()=>A(!1),onCreated:e=>{o(t=>[...t,e]),A(!1)}}),$&&(0,r.jsxs)("div",{className:"fixed inset-0 z-50 flex items-start justify-center px-3 pt-[6vh] sm:pt-[10vh]",onClick:()=>E(null),children:[(0,r.jsx)("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm"}),(0,r.jsxs)("div",{className:"relative bg-surface border border-border rounded-xl w-full max-w-[600px] max-h-[86vh] sm:max-h-[80vh] overflow-y-auto shadow-2xl",onClick:e=>e.stopPropagation(),children:[(0,r.jsxs)("div",{className:"sticky top-0 z-10 flex items-center justify-between px-5 py-3 border-b border-border bg-surface/95 backdrop-blur-sm rounded-t-xl",children:[(0,r.jsx)("h3",{className:"font-semibold",children:"Test Results"}),(0,r.jsx)("button",{onClick:()=>E(null),className:"p-1 rounded-lg hover:bg-bg text-text-muted hover:text-text-main transition-colors","aria-label":"Close test results",children:(0,r.jsx)("span",{className:"material-symbols-outlined text-lg",children:"close"})})]}),(0,r.jsx)("div",{className:"p-5",children:(0,r.jsx)(k,{results:$})})]})]})]})}function j({providerId:e,provider:t,stats:s,authType:a,onToggle:l}){let{connected:i,error:d,errorCode:c,errorTime:m,allDisabled:x}=s,h=!!t.noAuth;return(0,r.jsx)(p(),{href:`/dashboard/providers/${e}`,className:"group min-w-0",children:(0,r.jsx)(n.Zp,{padding:"xs",className:`h-full hover:bg-black/[0.01] dark:hover:bg-white/[0.01] transition-colors cursor-pointer ${x?"opacity-50":""}`,children:(0,r.jsxs)("div",{className:"flex min-w-0 items-center justify-between gap-3",children:[(0,r.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,r.jsx)("div",{className:"size-8 shrink-0 rounded-lg flex items-center justify-center",style:{backgroundColor:`${t.color?.length>7?t.color:t.color+"15"}`},children:(0,r.jsx)(o.A,{src:`/providers/${t.id}.png`,alt:t.name,size:30,className:"object-contain rounded-lg max-w-[32px] max-h-[32px]",fallbackText:t.textIcon||t.id.slice(0,2).toUpperCase(),fallbackColor:t.color})}),(0,r.jsxs)("div",{className:"min-w-0",children:[(0,r.jsx)("h3",{className:"truncate font-semibold",children:t.name}),(0,r.jsx)("div",{className:"flex min-w-0 items-center gap-1.5 text-xs flex-wrap",children:x?(0,r.jsx)(n.Ex,{variant:"default",size:"sm",children:(0,r.jsxs)("span",{className:"flex items-center gap-1",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[12px]",children:"pause_circle"}),"Disabled"]})}):h?(0,r.jsx)(n.Ex,{variant:"success",size:"sm",dot:!0,children:"Ready"}):(0,r.jsxs)(r.Fragment,{children:[b(i,d,c),m&&(0,r.jsx)("span",{className:"text-text-muted",children:m})]})})]})]}),(0,r.jsx)("div",{className:"flex shrink-0 items-center gap-2",children:s.total>0&&(0,r.jsx)("div",{className:"opacity-100 transition-opacity sm:opacity-0 sm:group-hover:opacity-100",onClick:e=>{e.preventDefault(),e.stopPropagation(),l(!!x)},children:(0,r.jsx)(n.lM,{size:"sm",checked:!x,onChange:()=>{},title:x?"Enable provider":"Disable provider"})})})]})})})}function y({providerId:e,provider:t,stats:s,authType:a,onToggle:l}){let{connected:i,error:d,errorCode:m,errorTime:x,allDisabled:h}=s,u=e.startsWith(c.JH),f=e.startsWith(c.DI);return(0,r.jsx)(p(),{href:`/dashboard/providers/${e}`,className:"group min-w-0",children:(0,r.jsx)(n.Zp,{padding:"xs",className:`h-full hover:bg-black/[0.01] dark:hover:bg-white/[0.01] transition-colors cursor-pointer ${h?"opacity-50":""}`,children:(0,r.jsxs)("div",{className:"flex min-w-0 items-center justify-between gap-3",children:[(0,r.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,r.jsx)("div",{className:"size-8 shrink-0 rounded-lg flex items-center justify-center",style:{backgroundColor:`${t.color?.length>7?t.color:t.color+"15"}`},children:(0,r.jsx)(o.A,{src:u?"responses"===t.apiType?"/providers/oai-r.png":"/providers/oai-cc.png":f?"/providers/anthropic-m.png":`/providers/${t.id}.png`,alt:t.name,size:30,className:"object-contain rounded-lg max-w-[30px] max-h-[30px]",fallbackText:t.textIcon||t.id.slice(0,2).toUpperCase(),fallbackColor:t.color})}),(0,r.jsxs)("div",{className:"min-w-0",children:[(0,r.jsx)("h3",{className:"truncate font-semibold",children:t.name}),(0,r.jsx)("div",{className:"flex min-w-0 items-center gap-1.5 text-xs flex-wrap",children:h?(0,r.jsx)(n.Ex,{variant:"default",size:"sm",children:(0,r.jsxs)("span",{className:"flex items-center gap-1",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-[12px]",children:"pause_circle"}),"Disabled"]})}):(0,r.jsxs)(r.Fragment,{children:[b(i,d,m),u&&(0,r.jsx)(n.Ex,{variant:"default",size:"sm",children:"responses"===t.apiType?"Responses":"Chat"}),f&&(0,r.jsx)(n.Ex,{variant:"default",size:"sm",children:"Messages"}),x&&(0,r.jsx)("span",{className:"text-text-muted",children:x})]})})]})]}),(0,r.jsx)("div",{className:"flex shrink-0 items-center gap-2",children:s.total>0&&(0,r.jsx)("div",{className:"opacity-100 transition-opacity sm:opacity-0 sm:group-hover:opacity-100",onClick:e=>{e.preventDefault(),e.stopPropagation(),l(!!h)},children:(0,r.jsx)(n.lM,{size:"sm",checked:!h,onChange:()=>{},title:h?"Enable provider":"Disable provider"})})})]})})})}function N({isOpen:e,onClose:t,onCreated:s}){let[l,i]=(0,a.useState)({name:"",prefix:"",apiType:"chat",baseUrl:"https://api.openai.com/v1"}),[o,d]=(0,a.useState)(!1),[c,m]=(0,a.useState)(""),[p,x]=(0,a.useState)(""),[h,u]=(0,a.useState)(!1),[f,g]=(0,a.useState)(null);(0,a.useEffect)(()=>{i(e=>({...e,baseUrl:"https://api.openai.com/v1"}))},[l.apiType]);let b=async()=>{if(l.name.trim()&&l.prefix.trim()&&l.baseUrl.trim()){d(!0);try{let e=await fetch("/api/provider-nodes",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:l.name,prefix:l.prefix,apiType:l.apiType,baseUrl:l.baseUrl,type:"openai-compatible"})}),t=await e.json();e.ok&&(s(t.node),i({name:"",prefix:"",apiType:"chat",baseUrl:"https://api.openai.com/v1"}),m(""),g(null))}catch(e){console.log("Error creating OpenAI Compatible node:",e)}finally{d(!1)}}},v=async()=>{u(!0);try{let e=await fetch("/api/provider-nodes/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({baseUrl:l.baseUrl,apiKey:c,type:"openai-compatible",modelId:p.trim()||void 0})}),t=await e.json();g(t)}catch{g({valid:!1,error:"Network error"})}finally{u(!1)}};return(0,r.jsx)(n.aF,{isOpen:e,title:"Add OpenAI Compatible",onClose:t,children:(0,r.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,r.jsx)(n.pd,{label:"Name",value:l.name,onChange:e=>i({...l,name:e.target.value}),placeholder:"OpenAI Compatible (Prod)",hint:"Required. A friendly label for this node."}),(0,r.jsx)(n.pd,{label:"Prefix",value:l.prefix,onChange:e=>i({...l,prefix:e.target.value}),placeholder:"oc-prod",hint:"Required. Used as the provider prefix for model IDs."}),(0,r.jsx)(n.l6,{label:"API Type",options:[{value:"chat",label:"Chat Completions"},{value:"responses",label:"Responses API"}],value:l.apiType,onChange:e=>i({...l,apiType:e.target.value})}),(0,r.jsx)(n.pd,{label:"Base URL",value:l.baseUrl,onChange:e=>i({...l,baseUrl:e.target.value}),placeholder:"https://api.openai.com/v1",hint:"Use the base URL (ending in /v1) for your OpenAI-compatible API."}),(0,r.jsx)(n.pd,{label:"API Key (for Check)",type:"password",value:c,onChange:e=>m(e.target.value)}),(0,r.jsx)(n.pd,{label:"Model ID (optional)",value:p,onChange:e=>x(e.target.value),placeholder:"e.g. gpt-4, claude-3-opus",hint:"If provider lacks /models endpoint, enter a model ID to validate via chat/completions instead."}),(0,r.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[(0,r.jsx)(n.$n,{onClick:v,disabled:!c||h||!l.baseUrl.trim(),variant:"secondary",className:"w-full sm:w-auto",children:h?"Checking...":"Check"}),(()=>{if(!f)return null;let{valid:e,error:t,method:s}=f;return e?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.Ex,{variant:"success",children:"Valid"}),"chat"===s&&(0,r.jsx)("span",{className:"text-sm text-text-muted",children:"(via inference test)"})]}):(0,r.jsxs)("div",{className:"flex flex-col gap-1",children:[(0,r.jsx)(n.Ex,{variant:"error",children:"Invalid"}),t&&(0,r.jsx)("span",{className:"text-sm text-red-500",children:t})]})})()]}),(0,r.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row",children:[(0,r.jsx)(n.$n,{onClick:b,fullWidth:!0,disabled:!l.name.trim()||!l.prefix.trim()||!l.baseUrl.trim()||o,children:o?"Creating...":"Create"}),(0,r.jsx)(n.$n,{onClick:t,variant:"ghost",fullWidth:!0,children:"Cancel"})]})]})})}function w({isOpen:e,onClose:t,onCreated:s}){let[l,i]=(0,a.useState)({name:"",prefix:"",baseUrl:"https://api.anthropic.com/v1"}),[o,d]=(0,a.useState)(!1),[c,m]=(0,a.useState)(""),[p,x]=(0,a.useState)(""),[h,u]=(0,a.useState)(!1),[f,g]=(0,a.useState)(null);(0,a.useEffect)(()=>{e&&(g(null),m(""),x(""))},[e]);let b=async()=>{if(l.name.trim()&&l.prefix.trim()&&l.baseUrl.trim()){d(!0);try{let e=await fetch("/api/provider-nodes",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:l.name,prefix:l.prefix,baseUrl:l.baseUrl,type:"anthropic-compatible"})}),t=await e.json();e.ok&&(s(t.node),i({name:"",prefix:"",baseUrl:"https://api.anthropic.com/v1"}),m(""),g(null))}catch(e){console.log("Error creating Anthropic Compatible node:",e)}finally{d(!1)}}},v=async()=>{u(!0);try{let e=await fetch("/api/provider-nodes/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({baseUrl:l.baseUrl,apiKey:c,type:"anthropic-compatible",modelId:p.trim()||void 0})}),t=await e.json();g(t)}catch{g({valid:!1,error:"Network error"})}finally{u(!1)}};return(0,r.jsx)(n.aF,{isOpen:e,title:"Add Anthropic Compatible",onClose:t,children:(0,r.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,r.jsx)(n.pd,{label:"Name",value:l.name,onChange:e=>i({...l,name:e.target.value}),placeholder:"Anthropic Compatible (Prod)",hint:"Required. A friendly label for this node."}),(0,r.jsx)(n.pd,{label:"Prefix",value:l.prefix,onChange:e=>i({...l,prefix:e.target.value}),placeholder:"ac-prod",hint:"Required. Used as the provider prefix for model IDs."}),(0,r.jsx)(n.pd,{label:"Base URL",value:l.baseUrl,onChange:e=>i({...l,baseUrl:e.target.value}),placeholder:"https://api.anthropic.com/v1",hint:"Use the base URL (ending in /v1) for your Anthropic-compatible API. The system will append /messages."}),(0,r.jsx)(n.pd,{label:"API Key (for Check)",type:"password",value:c,onChange:e=>m(e.target.value)}),(0,r.jsx)(n.pd,{label:"Model ID (optional)",value:p,onChange:e=>x(e.target.value),placeholder:"e.g. claude-3-opus",hint:"If provider lacks /models endpoint, enter a model ID to validate via chat/completions instead."}),(0,r.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[(0,r.jsx)(n.$n,{onClick:v,disabled:!c||h||!l.baseUrl.trim(),variant:"secondary",className:"w-full sm:w-auto",children:h?"Checking...":"Check"}),(()=>{if(!f)return null;let{valid:e,error:t,method:s}=f;return e?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.Ex,{variant:"success",children:"Valid"}),"chat"===s&&(0,r.jsx)("span",{className:"text-sm text-text-muted",children:"(via inference test)"})]}):(0,r.jsxs)("div",{className:"flex flex-col gap-1",children:[(0,r.jsx)(n.Ex,{variant:"error",children:"Invalid"}),t&&(0,r.jsx)("span",{className:"text-sm text-red-500",children:t})]})})()]}),(0,r.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row",children:[(0,r.jsx)(n.$n,{onClick:b,fullWidth:!0,disabled:!l.name.trim()||!l.prefix.trim()||!l.baseUrl.trim()||o,children:o?"Creating...":"Create"}),(0,r.jsx)(n.$n,{onClick:t,variant:"ghost",fullWidth:!0,children:"Cancel"})]})]})})}function k({results:e}){if(e.error&&!e.results)return(0,r.jsxs)("div",{className:"text-center py-6",children:[(0,r.jsx)("span",{className:"material-symbols-outlined text-red-500 text-[32px] mb-2 block",children:"error"}),(0,r.jsx)("p",{className:"text-sm text-red-400",children:e.error})]});let{summary:t,mode:s}=e,a=e.results||[];return(0,r.jsxs)("div",{className:"flex min-w-0 flex-col gap-3",children:[t&&(0,r.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-xs mb-1 sm:gap-3",children:[(0,r.jsxs)("span",{className:"text-text-muted",children:[{oauth:"OAuth",free:"Free",apikey:"API Key",provider:"Provider",all:"All"}[s]||s," Test"]}),(0,r.jsxs)("span",{className:"px-2 py-0.5 rounded bg-emerald-500/15 text-emerald-400 font-medium",children:[t.passed," passed"]}),t.failed>0&&(0,r.jsxs)("span",{className:"px-2 py-0.5 rounded bg-red-500/15 text-red-400 font-medium",children:[t.failed," failed"]}),(0,r.jsxs)("span",{className:"text-text-muted sm:ml-auto",children:[t.total," tested"]})]}),a.map((e,t)=>(0,r.jsxs)("div",{className:"flex min-w-0 flex-wrap items-center gap-2 rounded-lg bg-black/[0.03] px-3 py-2 text-xs dark:bg-white/[0.03] sm:flex-nowrap",children:[(0,r.jsx)("span",{className:`material-symbols-outlined text-[16px] ${e.valid?"text-emerald-500":"text-red-500"}`,children:e.valid?"check_circle":"error"}),(0,r.jsxs)("div",{className:"min-w-0 flex-[1_1_160px]",children:[(0,r.jsx)("span",{className:"block truncate font-medium sm:inline",children:e.connectionName}),(0,r.jsxs)("span",{className:"block truncate text-text-muted sm:ml-1.5 sm:inline",children:["(",e.provider,")"]})]}),void 0!==e.latencyMs&&(0,r.jsxs)("span",{className:"shrink-0 text-text-muted font-mono tabular-nums",children:[e.latencyMs,"ms"]}),(0,r.jsx)("span",{className:`shrink-0 text-[10px] uppercase font-bold px-1.5 py-0.5 rounded ${e.valid?"bg-emerald-500/15 text-emerald-400":"bg-red-500/15 text-red-400"}`,children:e.valid?"OK":e.diagnosis?.type||"ERROR"})]},e.connectionId||t)),0===a.length&&(0,r.jsx)("div",{className:"text-center py-4 text-text-muted text-sm",children:"No active connections found for this group."})]})}j.propTypes={providerId:i().string.isRequired,provider:i().shape({id:i().string.isRequired,name:i().string.isRequired,color:i().string,textIcon:i().string}).isRequired,stats:i().shape({connected:i().number,error:i().number,errorCode:i().string,errorTime:i().string}).isRequired,authType:i().string,onToggle:i().func},y.propTypes={providerId:i().string.isRequired,provider:i().shape({id:i().string.isRequired,name:i().string.isRequired,color:i().string,textIcon:i().string,apiType:i().string}).isRequired,stats:i().shape({connected:i().number,error:i().number,errorCode:i().string,errorTime:i().string}).isRequired,authType:i().string,onToggle:i().func},N.propTypes={isOpen:i().bool.isRequired,onClose:i().func.isRequired,onCreated:i().func.isRequired},w.propTypes={isOpen:i().bool.isRequired,onClose:i().func.isRequired,onCreated:i().func.isRequired},k.propTypes={results:i().shape({mode:i().string,results:i().array,summary:i().shape({total:i().number,passed:i().number,failed:i().number}),error:i().string}).isRequired}},69343:(e,t,s)=>{Promise.resolve().then(s.bind(s,18160))}},e=>{e.O(0,[7504,1321,5497,8441,3794,7358],()=>e(e.s=69343)),_N_E=e.O()}]);