@jheavenknows/bluerouter 1.0.108 → 1.0.110

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 (434) 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/server/app/(dashboard)/dashboard/api-keys/page_client-reference-manifest.js +1 -1
  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.js.nft.json +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.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/prompt-logs/page.js +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page_client-reference-manifest.js +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/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/_global-error.segment.rsc +1 -1
  39. package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  40. package/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  41. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  42. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  43. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  44. package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  45. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  46. package/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  47. package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +4 -4
  48. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  49. package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  50. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  51. package/app/.next-cli-build/server/app/api/auth/ldap/test/route.js.nft.json +1 -1
  52. package/app/.next-cli-build/server/app/api/auth/ldap/users/route.js.nft.json +1 -1
  53. package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
  54. package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
  55. package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
  56. package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
  57. package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
  58. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  59. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  60. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  61. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/autostart/route.js.nft.json +1 -1
  62. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/prompt-log-db/route.js.nft.json +1 -1
  63. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/root-ca/route.js.nft.json +1 -1
  64. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  65. package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
  66. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  67. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  68. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  69. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/[id]/route.js.nft.json +1 -1
  70. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/options/route.js.nft.json +1 -1
  71. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/route.js.nft.json +1 -1
  72. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  73. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  74. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  75. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  76. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  77. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  78. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  79. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  80. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  81. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  82. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  83. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  84. package/app/.next-cli-build/server/app/api/models/route.js +1 -1
  85. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  86. package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  87. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  89. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  90. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  91. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  92. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  93. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  94. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  95. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  97. package/app/.next-cli-build/server/app/api/provider-health/route.js.nft.json +1 -1
  98. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  99. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  100. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  101. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  102. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  103. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  104. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  105. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  106. package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  107. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  108. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  109. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  110. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
  112. package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
  114. package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
  116. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
  118. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  119. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  120. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  121. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  122. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  123. package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
  124. package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
  125. package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
  126. package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
  127. package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
  128. package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
  129. package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
  130. package/app/.next-cli-build/server/app/api/tunnel/tailscale-login/route.js.nft.json +1 -1
  131. package/app/.next-cli-build/server/app/api/tunnel/tailscale-start-daemon/route.js.nft.json +1 -1
  132. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  133. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  134. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  135. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  136. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  137. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  139. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  141. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  143. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  144. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  145. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  147. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  149. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  151. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  153. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  154. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  155. package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
  156. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  157. package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  158. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  159. package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  160. package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
  161. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  162. package/app/.next-cli-build/server/app/callback.html +1 -1
  163. package/app/.next-cli-build/server/app/callback.rsc +4 -4
  164. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  165. package/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  166. package/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +4 -4
  167. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
  168. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  169. package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  170. package/app/.next-cli-build/server/app/dashboard/api-keys.html +1 -1
  171. package/app/.next-cli-build/server/app/dashboard/api-keys.rsc +6 -6
  172. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard/api-keys/__PAGE__.segment.rsc +2 -2
  173. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard/api-keys.segment.rsc +1 -1
  174. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  175. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  176. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_full.segment.rsc +6 -6
  177. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_head.segment.rsc +1 -1
  178. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_index.segment.rsc +4 -4
  179. package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_tree.segment.rsc +2 -2
  180. package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  181. package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
  182. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  183. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  184. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  185. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  186. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
  187. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  188. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +4 -4
  189. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
  190. package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  191. package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +6 -6
  192. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  193. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  194. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  195. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  196. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
  197. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  198. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +4 -4
  199. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
  200. package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  201. package/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
  202. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  203. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  204. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  205. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  206. package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
  207. package/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  208. package/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +4 -4
  209. package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
  210. package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  211. package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +7 -7
  212. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +3 -3
  213. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  214. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  215. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  216. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +7 -7
  217. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  218. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +4 -4
  219. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
  220. package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  221. package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +6 -6
  222. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  223. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  224. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  225. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  226. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  227. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
  228. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  229. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +4 -4
  230. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
  231. package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  232. package/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
  233. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  234. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  235. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  236. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  237. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
  238. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  239. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +4 -4
  240. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
  241. package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  242. package/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
  243. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +1 -1
  244. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  245. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  246. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  247. package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
  248. package/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  249. package/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +4 -4
  250. package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
  251. package/app/.next-cli-build/server/app/dashboard/prompt-logs.html +1 -1
  252. package/app/.next-cli-build/server/app/dashboard/prompt-logs.rsc +6 -6
  253. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs/__PAGE__.segment.rsc +2 -2
  254. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs.segment.rsc +1 -1
  255. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  256. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  257. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_full.segment.rsc +6 -6
  258. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_head.segment.rsc +1 -1
  259. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_index.segment.rsc +4 -4
  260. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_tree.segment.rsc +2 -2
  261. package/app/.next-cli-build/server/app/dashboard/provider-health.html +1 -1
  262. package/app/.next-cli-build/server/app/dashboard/provider-health.rsc +5 -5
  263. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health/__PAGE__.segment.rsc +1 -1
  264. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health.segment.rsc +1 -1
  265. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  266. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  267. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_full.segment.rsc +5 -5
  268. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_head.segment.rsc +1 -1
  269. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_index.segment.rsc +4 -4
  270. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_tree.segment.rsc +2 -2
  271. package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  272. package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +6 -6
  273. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  274. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  275. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  276. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  277. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  278. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
  279. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  280. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +4 -4
  281. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
  282. package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  283. package/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
  284. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  285. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  286. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  287. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  288. package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
  289. package/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  290. package/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +4 -4
  291. package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
  292. package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  293. package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
  294. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  295. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  296. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  297. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  298. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
  299. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  300. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +4 -4
  301. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
  302. package/app/.next-cli-build/server/app/dashboard/quota.html +1 -1
  303. package/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
  304. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  305. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  306. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  307. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  308. package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
  309. package/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  310. package/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +4 -4
  311. package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
  312. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  313. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  314. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  315. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  316. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  317. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +4 -4
  318. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  319. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  320. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  321. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  322. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  323. package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
  324. package/app/.next-cli-build/server/app/dashboard/skills.rsc +6 -6
  325. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
  326. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
  327. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  328. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  329. package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
  330. package/app/.next-cli-build/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
  331. package/app/.next-cli-build/server/app/dashboard/skills.segments/_index.segment.rsc +4 -4
  332. package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
  333. package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  334. package/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
  335. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  336. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  337. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  338. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  339. package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
  340. package/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  341. package/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +4 -4
  342. package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
  343. package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  344. package/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
  345. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  346. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  347. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  348. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  349. package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
  350. package/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  351. package/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +4 -4
  352. package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
  353. package/app/.next-cli-build/server/app/dashboard.html +1 -1
  354. package/app/.next-cli-build/server/app/dashboard.rsc +6 -6
  355. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  356. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  357. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  358. package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +6 -6
  359. package/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  360. package/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +4 -4
  361. package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +2 -2
  362. package/app/.next-cli-build/server/app/index.html +1 -1
  363. package/app/.next-cli-build/server/app/index.rsc +4 -4
  364. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  365. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  366. package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  367. package/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +4 -4
  368. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
  369. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  370. package/app/.next-cli-build/server/app/landing.html +1 -1
  371. package/app/.next-cli-build/server/app/landing.rsc +4 -4
  372. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  373. package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  374. package/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +4 -4
  375. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
  376. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  377. package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  378. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  379. package/app/.next-cli-build/server/app/login.html +1 -1
  380. package/app/.next-cli-build/server/app/login.rsc +4 -4
  381. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  382. package/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  383. package/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +4 -4
  384. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
  385. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  386. package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  387. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  388. package/app/.next-cli-build/server/app-paths-manifest.json +8 -8
  389. package/app/.next-cli-build/server/chunks/2496.js +1 -1
  390. package/app/.next-cli-build/server/chunks/3110.js +1 -1
  391. package/app/.next-cli-build/server/chunks/4746.js +1 -1
  392. package/app/.next-cli-build/server/chunks/7130.js +1 -1
  393. package/app/.next-cli-build/server/chunks/7153.js +1 -1
  394. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  395. package/app/.next-cli-build/server/pages/404.html +1 -1
  396. package/app/.next-cli-build/server/pages/500.html +1 -1
  397. package/app/.next-cli-build/static/chunks/1051-eec0f271123ef82f.js +64 -0
  398. package/app/.next-cli-build/static/chunks/{1321-689bd1da27e14b86.js → 1321-dbdd4435dd1ae93c.js} +1 -1
  399. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/api-keys/{page-7c41ca97da616da7.js → page-bec8eaff7440b8c7.js} +1 -1
  400. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/basic-chat/{page-782bbed51a1d07eb.js → page-1b2283499089d7dc.js} +1 -1
  401. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/cli-tools/[toolId]/{page-a292301b8b48ef83.js → page-1adaf9be4107d227.js} +1 -1
  402. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/cli-tools/{page-8ad96767b17e1927.js → page-85cb2bafe0526c5d.js} +1 -1
  403. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/combos/{page-eb9021fb6f29af9f.js → page-82be3137baaf2025.js} +1 -1
  404. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/console-log/{page-f1374ae2a282dad8.js → page-d26b9256cf41fb19.js} +1 -1
  405. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/endpoint/{page-3dbf8ec9932781b6.js → page-e0b4284d8e973996.js} +1 -1
  406. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/{page-6d9c6db190394765.js → page-4377fb8d824f5bde.js} +1 -1
  407. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/{page-752ab915a6ff4667.js → page-3cf8e9de4ed5bf33.js} +1 -1
  408. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/{page-7a79761f2d99ef4f.js → page-b2b612e7dedabef1.js} +1 -1
  409. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/web/{page-2bff0a674207059c.js → page-356120709e5a1a94.js} +1 -1
  410. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/mitm/{page-f05795e77fee5793.js → page-161edd90803b7184.js} +1 -1
  411. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/{page-22722a6c1a7dd8b1.js → page-5e2bec66810c6089.js} +1 -1
  412. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/prompt-logs/page-51f32ade40c03a33.js +1 -0
  413. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-2ec08f1b10de2d04.js → page-5e178086cce9f9f0.js} +1 -1
  414. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/new/{page-055466baadc14356.js → page-009821d1edc5606b.js} +1 -1
  415. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/{page-665d20d11df80056.js → page-0cf8abbb69a8a288.js} +1 -1
  416. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/proxy-pools/{page-45282c7ec724a7d4.js → page-0e356884dbb16e9e.js} +1 -1
  417. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/quota/{page-c391079554415d2f.js → page-383255c4b63ebf3b.js} +1 -1
  418. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/{page-506f34296b69aa15.js → page-de03c9c19092784e.js} +1 -1
  419. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/translator/{page-cf56a227a13523f9.js → page-fdac9423efa73ccd.js} +1 -1
  420. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/usage/{page-549cd9fef3803dcb.js → page-a4e4500cdae96c24.js} +1 -1
  421. package/app/.next-cli-build/static/chunks/app/(dashboard)/{layout-de1653c6da534801.js → layout-74847fe2e0e50a38.js} +1 -1
  422. package/app/.next-cli-build/static/css/8532f517e7c09566.css +1 -0
  423. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.108-to-1.0.109-1.0.109-20260609-200931/data.sqlite +0 -0
  424. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.109-to-1.0.110-1.0.110-20260609-203135/data.sqlite +0 -0
  425. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-shm +0 -0
  426. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-wal +0 -0
  427. package/app/package.json +1 -1
  428. package/package.json +1 -1
  429. package/app/.next-cli-build/static/chunks/4288-6abec21269cb069a.js +0 -64
  430. package/app/.next-cli-build/static/chunks/8500-f62a38ff68ab7f42.js +0 -1
  431. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/prompt-logs/page-8ac96eee4d4039bd.js +0 -1
  432. package/app/.next-cli-build/static/css/78a5a097d108e79a.css +0 -1
  433. /package/app/.next-cli-build/static/{jTA0XRD_TnPrWR_NaeYV9 → MlvjHH27O4l1jGGvqYaEB}/_buildManifest.js +0 -0
  434. /package/app/.next-cli-build/static/{jTA0XRD_TnPrWR_NaeYV9 → MlvjHH27O4l1jGGvqYaEB}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7593],{56484:(e,t,a)=>{"use strict";a.d(t,{default:()=>m});var s=a(95155),l=a(12115),r=a(35497),n=a(11059);function i(e){return String(e||"").trim().toLowerCase()}function d(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function o({models:e,emptyLabel:t="No model assigned"}){let a=d(e);return 0===a.length?(0,s.jsx)("span",{className:"rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700 dark:text-amber-300",children:t}):(0,s.jsxs)("div",{className:"flex flex-wrap gap-1.5",children:[a.slice(0,8).map(e=>(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 font-mono text-[11px] text-text-main",children:e},e)),a.length>8?(0,s.jsxs)("span",{className:"rounded-full bg-primary/10 px-2 py-1 text-[11px] text-primary",children:["+",a.length-8," more"]}):null]})}function c({open:e,keyName:t,models:a,setModels:n,activeProviders:i,modelAliases:o,onClose:m,onSave:x,saving:u}){let[h,p]=(0,l.useState)(!1),y=d(a),f=e=>{let t=e?.value||e?.name||e;n(e=>d(e).filter(e=>e!==t))};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.aF,{isOpen:e,onClose:m,title:`Edit model access${t?`: ${t}`:""}`,children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsx)("div",{className:"rounded-xl border border-blue-200 bg-blue-50 px-3 py-2 text-sm text-blue-700 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-300",children:"Select one or more models this API key may use. Empty model access is not allowed from this page."}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium text-text-main",children:"Allowed models"}),(0,s.jsxs)(r.$n,{variant:"secondary",onClick:()=>p(!0),children:[(0,s.jsx)("span",{className:"material-symbols-outlined mr-1 text-[18px]",children:"add"}),"Add model"]})]}),(0,s.jsx)("div",{className:"min-h-[76px] rounded-xl border border-border bg-background p-3",children:0===y.length?(0,s.jsx)("div",{className:"text-sm text-text-muted",children:"No models selected. Add at least one model before saving."}):(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:y.map(e=>(0,s.jsxs)("button",{type:"button",onClick:()=>f(e),className:"rounded-full border border-primary/30 bg-primary/10 px-2 py-1 font-mono text-xs text-primary transition hover:bg-red-500/10 hover:text-red-600",title:"Click to remove",children:[e," ",(0,s.jsx)("span",{className:"ml-1",children:"\xd7"})]},e))})})]}),(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(r.$n,{variant:"secondary",onClick:m,children:"Cancel"}),(0,s.jsx)(r.$n,{onClick:x,disabled:u||0===y.length,children:u?"Saving...":"Save models"})]})]})}),(0,s.jsx)(r.rq,{isOpen:h,onClose:()=>p(!1),onSelect:e=>{let t=e?.value||e?.name||e;t&&n(e=>d([...e,t]))},onDeselect:f,activeProviders:i,modelAliases:o,title:"Select allowed models",addedModelValues:y,closeOnSelect:!1})]})}function m(){let[e,t]=(0,l.useState)(null),[a,m]=(0,l.useState)([]),[x,u]=(0,l.useState)(!0),[h,p]=(0,l.useState)(""),[y,f]=(0,l.useState)(!1),[b,g]=(0,l.useState)(""),[j,v]=(0,l.useState)(""),[k,N]=(0,l.useState)(""),[w,C]=(0,l.useState)(""),[S,A]=(0,l.useState)(new Set),[P,$]=(0,l.useState)(null),[I,M]=(0,l.useState)([]),[D,O]=(0,l.useState)(""),[E,L]=(0,l.useState)(!1),[T,F]=(0,l.useState)(!1),[U,_]=(0,l.useState)(""),[K,B]=(0,l.useState)(""),[q,J]=(0,l.useState)(!1),[V,Z]=(0,l.useState)(!1),[H,R]=(0,l.useState)([]),[Y,z]=(0,l.useState)({}),[G,Q]=(0,l.useState)(null),[W,X]=(0,l.useState)([]),[ee,et]=(0,l.useState)(!1),{copied:ea,copy:es}=(0,n.C)(),el=e?.isAdmin!==!1,er=e?.userId||"",en=(0,l.useMemo)(()=>{let e=new Map;for(let t of I){let a=i(t.username||t.email||t.userPrincipalName||t.sAMAccountName);a&&e.set(a,{id:a,label:`${t.displayName||t.username||a}${t.email?` \xb7 ${t.email}`:""}`})}for(let t of a){let a=i(t.ownerUser||t.createdByUser);a&&!e.has(a)&&e.set(a,{id:a,label:a})}return er&&!e.has(er)&&e.set(er,{id:er,label:`${er} (me)`}),[...e.values()].sort((e,t)=>e.label.localeCompare(t.label))},[I,a,er]),ei=K!==U,ed=async()=>{let e=await fetch("/api/auth/status",{cache:"no-store"}),a=await e.json().catch(()=>({}));return t(a),!j&&a?.userId&&v(a.userId),a},eo=async()=>{u(!0),p("");try{let e=await fetch("/api/keys",{cache:"no-store"}),t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||"Failed to load API keys");m(t.keys||[]);let a=String(t.apiKeyDefaultModel||"").trim();_(a),B(a)}catch(e){p(e.message||"Failed to load API keys")}finally{u(!1)}},ec=async()=>{try{let[e,t]=await Promise.allSettled([fetch("/api/providers",{cache:"no-store"}),fetch("/api/models/alias",{cache:"no-store"})]);if("fulfilled"===e.status&&e.value.ok){let t=await e.value.json().catch(()=>({}));R(t.connections||[])}if("fulfilled"===t.status&&t.value.ok){let e=await t.value.json().catch(()=>({}));z(e.aliases||{})}}catch{}},em=async(e=D)=>{if(el){L(!0);try{let t=await fetch(`/api/auth/ldap/users?q=${encodeURIComponent(e||"")}`,{cache:"no-store"}),a=await t.json().catch(()=>({}));t.ok&&M(a.users||[])}catch{}finally{L(!1)}}};(0,l.useEffect)(()=>{let e=!1;return(async()=>{let t=await ed();e||await Promise.all([eo(),ec()]),e||t?.isAdmin===!1||await em("")})(),()=>{e=!0}},[]);let ex=async()=>{if(el&&K.trim()){J(!0),p("");try{let e=await fetch("/api/keys",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKeyDefaultModel:K.trim()})}),t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||"Failed to save default model");let a=String(t.apiKeyDefaultModel||"").trim();_(a),B(a)}catch(e){p(e.message||"Failed to save default model")}finally{J(!1)}}},eu=async()=>{if(b.trim()){if(!U.trim())return void p("Default API key model must be configured before creating API keys.");F(!0),p("");try{let e=el?i(k||j||er):void 0,t=await fetch("/api/keys",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:b.trim(),ownerUser:e})}),a=await t.json().catch(()=>({}));if(!t.ok)throw Error(a.error||"Failed to create key");C(a.key),g(""),N(""),f(!1),await eo()}catch(e){p(e.message||"Failed to create key")}finally{F(!1)}}},eh=async(e,t)=>{let a=await fetch(`/api/keys/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),s=await a.json().catch(()=>({}));return a.ok?(await eo(),!0):(p(s.error||"Failed to update key"),!1)},ep=async()=>{if(!G)return;let e=d(W);if(0===e.length)return void p("Select at least one model before saving API key access.");et(!0),p("");try{await eh(G.id,{allowedModels:e})&&(Q(null),X([]))}finally{et(!1)}},ey=T||!b.trim()||!U.trim();return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)("h1",{className:"flex items-center gap-2 text-3xl font-bold text-text-main",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-primary",children:"vpn_key"}),"API Key Management"]}),(0,s.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:el?"Admins can create API keys, assign owners, and control model access.":"You can manage API keys created by you or assigned to your account."})]}),(0,s.jsxs)(r.$n,{onClick:()=>f(!0),disabled:!U.trim(),children:[(0,s.jsx)("span",{className:"material-symbols-outlined mr-1 text-[18px]",children:"add"}),"Create API Key"]})]}),h?(0,s.jsx)("div",{className:"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300",children:h}):null,(0,s.jsx)(r.Zp,{children:(0,s.jsxs)("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",children:[(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 text-lg font-semibold text-text-main",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-primary",children:"rule"}),"Default model for new API keys"]}),(0,s.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"New API keys are restricted to this model by default. The default model must be set before anyone can create API keys."}),(0,s.jsx)("div",{className:"mt-3",children:U?(0,s.jsx)("span",{className:"rounded-full border border-primary/30 bg-primary/10 px-3 py-1 font-mono text-xs text-primary",children:U}):(0,s.jsx)("span",{className:"rounded-full bg-red-500/10 px-3 py-1 text-xs text-red-600",children:"No default model configured"})})]}),el?(0,s.jsxs)("div",{className:"flex flex-col gap-2 sm:min-w-[360px]",children:[(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)("button",{type:"button",onClick:()=>Z(!0),className:"min-w-0 flex-1 rounded-xl border border-border bg-background px-3 py-2 text-left font-mono text-xs text-text-main transition hover:border-primary/50",children:K||"Select default model..."}),(0,s.jsx)(r.$n,{onClick:ex,disabled:q||!K.trim()||!ei,children:q?"Saving...":"Save"})]}),(0,s.jsx)("p",{className:"text-xs text-text-muted",children:"Model picker includes provider models, custom models, aliases, and combos."})]}):null]})}),w?(0,s.jsx)(r.Zp,{className:"border-green-200 bg-green-50/60 dark:border-green-500/30 dark:bg-green-500/10",children:(0,s.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"font-semibold text-green-700 dark:text-green-300",children:"API key created"}),(0,s.jsx)("div",{className:"mt-1 break-all font-mono text-xs text-text-main",children:w}),(0,s.jsxs)("div",{className:"mt-1 text-xs text-text-muted",children:["Copy it now. New keys are restricted to ",U||"the default model"," unless an admin edits model access."]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>es(w,"created"),children:"created"===ea?"Copied":"Copy"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>C(""),children:"Dismiss"})]})]})}):null,(0,s.jsx)(r.Zp,{children:x?(0,s.jsxs)("div",{className:"py-10 text-center text-sm text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined mr-2 animate-spin align-middle",children:"progress_activity"}),"Loading API keys..."]}):0===a.length?(0,s.jsxs)("div",{className:"py-12 text-center text-sm text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined mb-2 block text-4xl",children:"vpn_key_off"}),"No API keys yet."]}):(0,s.jsx)("div",{className:"space-y-3",children:a.map(e=>{var t;let a=S.has(e.id),l=e.ownerUser||e.createdByUser||"unassigned",n=d(e.allowedModels);return(0,s.jsx)("div",{className:"rounded-2xl border border-border bg-background p-4",children:(0,s.jsxs)("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[(0,s.jsxs)("div",{className:"min-w-0 flex-1 space-y-2",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,s.jsx)("h3",{className:"font-semibold text-text-main",children:e.name||"API Key"}),(0,s.jsx)("span",{className:`rounded-full px-2 py-0.5 text-xs ${e.isActive?"bg-green-500/10 text-green-600":"bg-red-500/10 text-red-600"}`,children:e.isActive?"Active":"Disabled"}),(0,s.jsxs)("span",{className:"rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary",children:["Owner: ",l]}),n.length>0?(0,s.jsxs)("span",{className:"rounded-full bg-blue-500/10 px-2 py-0.5 text-xs text-blue-600",children:[n.length," model(s)"]}):(0,s.jsx)("span",{className:"rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700",children:"Legacy full access"})]}),(0,s.jsx)("div",{className:"break-all font-mono text-xs text-text-muted",children:a?e.key:(t=e.key)?t.length>12?`${t.slice(0,8)}...${t.slice(-4)}`:t:""}),(0,s.jsxs)("div",{className:"text-xs text-text-muted",children:["Created: ",e.createdAt?new Date(e.createdAt).toLocaleString():"unknown",e.createdByUser?` \xb7 Created by: ${e.createdByUser}`:""]}),(0,s.jsx)("div",{className:"pt-1",children:(0,s.jsx)(o,{models:n,emptyLabel:"Legacy full model access"})})]}),(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,s.jsx)(r.lM,{checked:!1!==e.isActive,onChange:t=>eh(e.id,{isActive:t})}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>{var t;return t=e.id,void A(e=>{let a=new Set(e);return a.has(t)?a.delete(t):a.add(t),a})},children:a?"Hide":"Show"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>es(e.key,e.id),children:ea===e.id?"Copied":"Copy"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>{var t;let a;return t=e.id,a=prompt("New API key name",e.name||""),void(a?.trim()&&eh(t,{name:a.trim()}))},children:"Rename"}),el?(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>{el&&(Q(e),X(d(e.allowedModels)))},children:"Models"}):null,el?(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>((e,t)=>{if(!el)return;let a=prompt("Assign owner username/email",t||er||"");null!==a&&eh(e,{ownerUser:i(a)})})(e.id,l),children:"Assign"}):null,(0,s.jsx)(r.$n,{variant:"danger",onClick:()=>{var t;return t=e.id,void $({title:"Delete API Key",message:"Delete this API key? This cannot be undone.",onConfirm:async()=>{$(null),(await fetch(`/api/keys/${t}`,{method:"DELETE"})).ok&&m(e=>e.filter(e=>e.id!==t))}})},children:"Delete"})]})]})},e.id)})})}),(0,s.jsx)(r.aF,{isOpen:y,onClose:()=>f(!1),title:"Create API Key",children:(0,s.jsxs)("div",{className:"space-y-4",children:[U.trim()?(0,s.jsxs)("div",{className:"rounded-xl border border-blue-200 bg-blue-50 px-3 py-2 text-sm text-blue-700 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-300",children:["This key will be created with access to the default model only: ",(0,s.jsx)("span",{className:"font-mono",children:U}),"."]}):(0,s.jsx)("div",{className:"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300",children:"Admin must set a default model before API keys can be created."}),(0,s.jsx)(r.pd,{label:"Name",value:b,onChange:e=>g(e.target.value),placeholder:"e.g. VSCode, LibreChat, team-user"}),el?(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium text-text-main",children:"Owner user"}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(r.pd,{value:D,onChange:e=>O(e.target.value),placeholder:"Search LDAP users"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>em(D),disabled:E,children:E?"Loading":"Load"})]}),(0,s.jsxs)("select",{value:j,onChange:e=>v(e.target.value),className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary",children:[(0,s.jsxs)("option",{value:er,children:["Assign to me (",er||"local",")"]}),en.map(e=>(0,s.jsx)("option",{value:e.id,children:e.label},e.id))]}),(0,s.jsx)(r.pd,{label:"Manual owner override",value:k,onChange:e=>N(e.target.value),placeholder:"username or email, optional",hint:"Use this if LDAP search is unavailable or the user is not listed."})]}):(0,s.jsxs)("div",{className:"rounded-xl bg-surface-2 px-3 py-2 text-sm text-text-muted",children:["Owner: ",er||"current user"]}),(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>f(!1),children:"Cancel"}),(0,s.jsx)(r.$n,{onClick:eu,disabled:ey,children:T?"Creating...":"Create"})]})]})}),(0,s.jsx)(c,{open:!!G,keyName:G?.name,models:W,setModels:X,activeProviders:H,modelAliases:Y,onClose:()=>{Q(null),X([])},onSave:ep,saving:ee}),(0,s.jsx)(r.rq,{isOpen:V,onClose:()=>Z(!1),onSelect:e=>{let t=String(e?.value||e?.name||e||"").trim();t&&(B(t),Z(!1))},activeProviders:H,modelAliases:Y,title:"Select default API key model",selectedModel:K,addedModelValues:K?[K]:[]}),P?(0,s.jsx)(r.uo,{isOpen:!0,onClose:()=>$(null),onConfirm:P.onConfirm,title:P.title,message:P.message,confirmText:"Delete",cancelText:"Cancel",variant:"danger"}):null]})}},84223:(e,t,a)=>{Promise.resolve().then(a.bind(a,56484))}},e=>{e.O(0,[2574,3862,8500,4288,1321,5497,8441,3794,7358],()=>e(e.s=84223)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7593],{56484:(e,t,a)=>{"use strict";a.d(t,{default:()=>m});var s=a(95155),l=a(12115),r=a(35497),n=a(11059);function i(e){return String(e||"").trim().toLowerCase()}function d(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function o({models:e,emptyLabel:t="No model assigned"}){let a=d(e);return 0===a.length?(0,s.jsx)("span",{className:"rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700 dark:text-amber-300",children:t}):(0,s.jsxs)("div",{className:"flex flex-wrap gap-1.5",children:[a.slice(0,8).map(e=>(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 font-mono text-[11px] text-text-main",children:e},e)),a.length>8?(0,s.jsxs)("span",{className:"rounded-full bg-primary/10 px-2 py-1 text-[11px] text-primary",children:["+",a.length-8," more"]}):null]})}function c({open:e,keyName:t,models:a,setModels:n,activeProviders:i,modelAliases:o,onClose:m,onSave:x,saving:u}){let[h,p]=(0,l.useState)(!1),y=d(a),f=e=>{let t=e?.value||e?.name||e;n(e=>d(e).filter(e=>e!==t))};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.aF,{isOpen:e,onClose:m,title:`Edit model access${t?`: ${t}`:""}`,children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsx)("div",{className:"rounded-xl border border-blue-200 bg-blue-50 px-3 py-2 text-sm text-blue-700 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-300",children:"Select one or more models this API key may use. Empty model access is not allowed from this page."}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium text-text-main",children:"Allowed models"}),(0,s.jsxs)(r.$n,{variant:"secondary",onClick:()=>p(!0),children:[(0,s.jsx)("span",{className:"material-symbols-outlined mr-1 text-[18px]",children:"add"}),"Add model"]})]}),(0,s.jsx)("div",{className:"min-h-[76px] rounded-xl border border-border bg-background p-3",children:0===y.length?(0,s.jsx)("div",{className:"text-sm text-text-muted",children:"No models selected. Add at least one model before saving."}):(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:y.map(e=>(0,s.jsxs)("button",{type:"button",onClick:()=>f(e),className:"rounded-full border border-primary/30 bg-primary/10 px-2 py-1 font-mono text-xs text-primary transition hover:bg-red-500/10 hover:text-red-600",title:"Click to remove",children:[e," ",(0,s.jsx)("span",{className:"ml-1",children:"\xd7"})]},e))})})]}),(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(r.$n,{variant:"secondary",onClick:m,children:"Cancel"}),(0,s.jsx)(r.$n,{onClick:x,disabled:u||0===y.length,children:u?"Saving...":"Save models"})]})]})}),(0,s.jsx)(r.rq,{isOpen:h,onClose:()=>p(!1),onSelect:e=>{let t=e?.value||e?.name||e;t&&n(e=>d([...e,t]))},onDeselect:f,activeProviders:i,modelAliases:o,title:"Select allowed models",addedModelValues:y,closeOnSelect:!1})]})}function m(){let[e,t]=(0,l.useState)(null),[a,m]=(0,l.useState)([]),[x,u]=(0,l.useState)(!0),[h,p]=(0,l.useState)(""),[y,f]=(0,l.useState)(!1),[b,g]=(0,l.useState)(""),[j,v]=(0,l.useState)(""),[k,N]=(0,l.useState)(""),[w,C]=(0,l.useState)(""),[S,A]=(0,l.useState)(new Set),[P,$]=(0,l.useState)(null),[I,M]=(0,l.useState)([]),[D,O]=(0,l.useState)(""),[E,L]=(0,l.useState)(!1),[T,F]=(0,l.useState)(!1),[U,_]=(0,l.useState)(""),[K,B]=(0,l.useState)(""),[q,J]=(0,l.useState)(!1),[V,Z]=(0,l.useState)(!1),[H,R]=(0,l.useState)([]),[Y,z]=(0,l.useState)({}),[G,Q]=(0,l.useState)(null),[W,X]=(0,l.useState)([]),[ee,et]=(0,l.useState)(!1),{copied:ea,copy:es}=(0,n.C)(),el=e?.isAdmin!==!1,er=e?.userId||"",en=(0,l.useMemo)(()=>{let e=new Map;for(let t of I){let a=i(t.username||t.email||t.userPrincipalName||t.sAMAccountName);a&&e.set(a,{id:a,label:`${t.displayName||t.username||a}${t.email?` \xb7 ${t.email}`:""}`})}for(let t of a){let a=i(t.ownerUser||t.createdByUser);a&&!e.has(a)&&e.set(a,{id:a,label:a})}return er&&!e.has(er)&&e.set(er,{id:er,label:`${er} (me)`}),[...e.values()].sort((e,t)=>e.label.localeCompare(t.label))},[I,a,er]),ei=K!==U,ed=async()=>{let e=await fetch("/api/auth/status",{cache:"no-store"}),a=await e.json().catch(()=>({}));return t(a),!j&&a?.userId&&v(a.userId),a},eo=async()=>{u(!0),p("");try{let e=await fetch("/api/keys",{cache:"no-store"}),t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||"Failed to load API keys");m(t.keys||[]);let a=String(t.apiKeyDefaultModel||"").trim();_(a),B(a)}catch(e){p(e.message||"Failed to load API keys")}finally{u(!1)}},ec=async()=>{try{let[e,t]=await Promise.allSettled([fetch("/api/providers",{cache:"no-store"}),fetch("/api/models/alias",{cache:"no-store"})]);if("fulfilled"===e.status&&e.value.ok){let t=await e.value.json().catch(()=>({}));R(t.connections||[])}if("fulfilled"===t.status&&t.value.ok){let e=await t.value.json().catch(()=>({}));z(e.aliases||{})}}catch{}},em=async(e=D)=>{if(el){L(!0);try{let t=await fetch(`/api/auth/ldap/users?q=${encodeURIComponent(e||"")}`,{cache:"no-store"}),a=await t.json().catch(()=>({}));t.ok&&M(a.users||[])}catch{}finally{L(!1)}}};(0,l.useEffect)(()=>{let e=!1;return(async()=>{let t=await ed();e||await Promise.all([eo(),ec()]),e||t?.isAdmin===!1||await em("")})(),()=>{e=!0}},[]);let ex=async()=>{if(el&&K.trim()){J(!0),p("");try{let e=await fetch("/api/keys",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKeyDefaultModel:K.trim()})}),t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||"Failed to save default model");let a=String(t.apiKeyDefaultModel||"").trim();_(a),B(a)}catch(e){p(e.message||"Failed to save default model")}finally{J(!1)}}},eu=async()=>{if(b.trim()){if(!U.trim())return void p("Default API key model must be configured before creating API keys.");F(!0),p("");try{let e=el?i(k||j||er):void 0,t=await fetch("/api/keys",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:b.trim(),ownerUser:e})}),a=await t.json().catch(()=>({}));if(!t.ok)throw Error(a.error||"Failed to create key");C(a.key),g(""),N(""),f(!1),await eo()}catch(e){p(e.message||"Failed to create key")}finally{F(!1)}}},eh=async(e,t)=>{let a=await fetch(`/api/keys/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),s=await a.json().catch(()=>({}));return a.ok?(await eo(),!0):(p(s.error||"Failed to update key"),!1)},ep=async()=>{if(!G)return;let e=d(W);if(0===e.length)return void p("Select at least one model before saving API key access.");et(!0),p("");try{await eh(G.id,{allowedModels:e})&&(Q(null),X([]))}finally{et(!1)}},ey=T||!b.trim()||!U.trim();return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)("h1",{className:"flex items-center gap-2 text-3xl font-bold text-text-main",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-primary",children:"vpn_key"}),"API Key Management"]}),(0,s.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:el?"Admins can create API keys, assign owners, and control model access.":"You can manage API keys created by you or assigned to your account."})]}),(0,s.jsxs)(r.$n,{onClick:()=>f(!0),disabled:!U.trim(),children:[(0,s.jsx)("span",{className:"material-symbols-outlined mr-1 text-[18px]",children:"add"}),"Create API Key"]})]}),h?(0,s.jsx)("div",{className:"rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300",children:h}):null,(0,s.jsx)(r.Zp,{children:(0,s.jsxs)("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",children:[(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 text-lg font-semibold text-text-main",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-primary",children:"rule"}),"Default model for new API keys"]}),(0,s.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"New API keys are restricted to this model by default. The default model must be set before anyone can create API keys."}),(0,s.jsx)("div",{className:"mt-3",children:U?(0,s.jsx)("span",{className:"rounded-full border border-primary/30 bg-primary/10 px-3 py-1 font-mono text-xs text-primary",children:U}):(0,s.jsx)("span",{className:"rounded-full bg-red-500/10 px-3 py-1 text-xs text-red-600",children:"No default model configured"})})]}),el?(0,s.jsxs)("div",{className:"flex flex-col gap-2 sm:min-w-[360px]",children:[(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)("button",{type:"button",onClick:()=>Z(!0),className:"min-w-0 flex-1 rounded-xl border border-border bg-background px-3 py-2 text-left font-mono text-xs text-text-main transition hover:border-primary/50",children:K||"Select default model..."}),(0,s.jsx)(r.$n,{onClick:ex,disabled:q||!K.trim()||!ei,children:q?"Saving...":"Save"})]}),(0,s.jsx)("p",{className:"text-xs text-text-muted",children:"Model picker includes provider models, custom models, aliases, and combos."})]}):null]})}),w?(0,s.jsx)(r.Zp,{className:"border-green-200 bg-green-50/60 dark:border-green-500/30 dark:bg-green-500/10",children:(0,s.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"font-semibold text-green-700 dark:text-green-300",children:"API key created"}),(0,s.jsx)("div",{className:"mt-1 break-all font-mono text-xs text-text-main",children:w}),(0,s.jsxs)("div",{className:"mt-1 text-xs text-text-muted",children:["Copy it now. New keys are restricted to ",U||"the default model"," unless an admin edits model access."]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>es(w,"created"),children:"created"===ea?"Copied":"Copy"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>C(""),children:"Dismiss"})]})]})}):null,(0,s.jsx)(r.Zp,{children:x?(0,s.jsxs)("div",{className:"py-10 text-center text-sm text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined mr-2 animate-spin align-middle",children:"progress_activity"}),"Loading API keys..."]}):0===a.length?(0,s.jsxs)("div",{className:"py-12 text-center text-sm text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined mb-2 block text-4xl",children:"vpn_key_off"}),"No API keys yet."]}):(0,s.jsx)("div",{className:"space-y-3",children:a.map(e=>{var t;let a=S.has(e.id),l=e.ownerUser||e.createdByUser||"unassigned",n=d(e.allowedModels);return(0,s.jsx)("div",{className:"rounded-2xl border border-border bg-background p-4",children:(0,s.jsxs)("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[(0,s.jsxs)("div",{className:"min-w-0 flex-1 space-y-2",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,s.jsx)("h3",{className:"font-semibold text-text-main",children:e.name||"API Key"}),(0,s.jsx)("span",{className:`rounded-full px-2 py-0.5 text-xs ${e.isActive?"bg-green-500/10 text-green-600":"bg-red-500/10 text-red-600"}`,children:e.isActive?"Active":"Disabled"}),(0,s.jsxs)("span",{className:"rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary",children:["Owner: ",l]}),n.length>0?(0,s.jsxs)("span",{className:"rounded-full bg-blue-500/10 px-2 py-0.5 text-xs text-blue-600",children:[n.length," model(s)"]}):(0,s.jsx)("span",{className:"rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700",children:"Legacy full access"})]}),(0,s.jsx)("div",{className:"break-all font-mono text-xs text-text-muted",children:a?e.key:(t=e.key)?t.length>12?`${t.slice(0,8)}...${t.slice(-4)}`:t:""}),(0,s.jsxs)("div",{className:"text-xs text-text-muted",children:["Created: ",e.createdAt?new Date(e.createdAt).toLocaleString():"unknown",e.createdByUser?` \xb7 Created by: ${e.createdByUser}`:""]}),(0,s.jsx)("div",{className:"pt-1",children:(0,s.jsx)(o,{models:n,emptyLabel:"Legacy full model access"})})]}),(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,s.jsx)(r.lM,{checked:!1!==e.isActive,onChange:t=>eh(e.id,{isActive:t})}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>{var t;return t=e.id,void A(e=>{let a=new Set(e);return a.has(t)?a.delete(t):a.add(t),a})},children:a?"Hide":"Show"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>es(e.key,e.id),children:ea===e.id?"Copied":"Copy"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>{var t;let a;return t=e.id,a=prompt("New API key name",e.name||""),void(a?.trim()&&eh(t,{name:a.trim()}))},children:"Rename"}),el?(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>{el&&(Q(e),X(d(e.allowedModels)))},children:"Models"}):null,el?(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>((e,t)=>{if(!el)return;let a=prompt("Assign owner username/email",t||er||"");null!==a&&eh(e,{ownerUser:i(a)})})(e.id,l),children:"Assign"}):null,(0,s.jsx)(r.$n,{variant:"danger",onClick:()=>{var t;return t=e.id,void $({title:"Delete API Key",message:"Delete this API key? This cannot be undone.",onConfirm:async()=>{$(null),(await fetch(`/api/keys/${t}`,{method:"DELETE"})).ok&&m(e=>e.filter(e=>e.id!==t))}})},children:"Delete"})]})]})},e.id)})})}),(0,s.jsx)(r.aF,{isOpen:y,onClose:()=>f(!1),title:"Create API Key",children:(0,s.jsxs)("div",{className:"space-y-4",children:[U.trim()?(0,s.jsxs)("div",{className:"rounded-xl border border-blue-200 bg-blue-50 px-3 py-2 text-sm text-blue-700 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-300",children:["This key will be created with access to the default model only: ",(0,s.jsx)("span",{className:"font-mono",children:U}),"."]}):(0,s.jsx)("div",{className:"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300",children:"Admin must set a default model before API keys can be created."}),(0,s.jsx)(r.pd,{label:"Name",value:b,onChange:e=>g(e.target.value),placeholder:"e.g. VSCode, LibreChat, team-user"}),el?(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium text-text-main",children:"Owner user"}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(r.pd,{value:D,onChange:e=>O(e.target.value),placeholder:"Search LDAP users"}),(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>em(D),disabled:E,children:E?"Loading":"Load"})]}),(0,s.jsxs)("select",{value:j,onChange:e=>v(e.target.value),className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary",children:[(0,s.jsxs)("option",{value:er,children:["Assign to me (",er||"local",")"]}),en.map(e=>(0,s.jsx)("option",{value:e.id,children:e.label},e.id))]}),(0,s.jsx)(r.pd,{label:"Manual owner override",value:k,onChange:e=>N(e.target.value),placeholder:"username or email, optional",hint:"Use this if LDAP search is unavailable or the user is not listed."})]}):(0,s.jsxs)("div",{className:"rounded-xl bg-surface-2 px-3 py-2 text-sm text-text-muted",children:["Owner: ",er||"current user"]}),(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(r.$n,{variant:"secondary",onClick:()=>f(!1),children:"Cancel"}),(0,s.jsx)(r.$n,{onClick:eu,disabled:ey,children:T?"Creating...":"Create"})]})]})}),(0,s.jsx)(c,{open:!!G,keyName:G?.name,models:W,setModels:X,activeProviders:H,modelAliases:Y,onClose:()=>{Q(null),X([])},onSave:ep,saving:ee}),(0,s.jsx)(r.rq,{isOpen:V,onClose:()=>Z(!1),onSelect:e=>{let t=String(e?.value||e?.name||e||"").trim();t&&(B(t),Z(!1))},activeProviders:H,modelAliases:Y,title:"Select default API key model",selectedModel:K,addedModelValues:K?[K]:[]}),P?(0,s.jsx)(r.uo,{isOpen:!0,onClose:()=>$(null),onConfirm:P.onConfirm,title:P.title,message:P.message,confirmText:"Delete",cancelText:"Cancel",variant:"danger"}):null]})}},84223:(e,t,a)=>{Promise.resolve().then(a.bind(a,56484))}},e=>{e.O(0,[2574,3862,1051,1321,5497,8441,3794,7358],()=>e(e.s=84223)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4465],{35911:(e,t,r)=>{Promise.resolve().then(r.bind(r,88512))},88512:(e,t,r)=>{"use strict";r.d(t,{default:()=>g});var s=r(95155),a=r(12115),i=r(35497),l=r(28777),n=r(52679);let o="basic-chat.sessions",d="basic-chat.activeSessionId",c="basic-chat.activeProviderId",m="basic-chat.draft";function u(){return globalThis.crypto?.randomUUID?globalThis.crypto.randomUUID():`chat_${Date.now()}_${Math.random().toString(16).slice(2)}`}function p(e){if("string"==typeof e)return e;if(null==e)return"";if(Array.isArray(e))return e.map(p).filter(Boolean).join(" ");if("object"==typeof e){if("string"==typeof e.message)return e.message;if("string"==typeof e.error)return e.error;try{return JSON.stringify(e)}catch{}}return String(e)}function h(e=""){let t=p(e).replace(/\s+/g," ").trim();return t?t.length>52?`${t.slice(0,52).trimEnd()}…`:t:"New chat"}async function x(e){return await new Promise((t,r)=>{let s=new FileReader;s.onload=()=>t(String(s.result||"")),s.onerror=()=>r(s.error||Error("Failed to read file")),s.readAsDataURL(e)})}function f(e){return e?.name||function(e=""){return String(e).replace(/[-_]/g," ").replace(/\b\w/g,e=>e.toUpperCase()).trim()||"Unknown"}(e?.provider||e?.id||"provider")}function g(){let[e,t]=(0,a.useState)([]),[r,g]=(0,a.useState)(!0),[w,v]=(0,a.useState)(""),[b,N]=(0,a.useState)(()=>{try{let e=function(e,t){try{return JSON.parse(e)}catch{return t}}(globalThis.localStorage.getItem(o),[]);return Array.isArray(e)?e.map(e=>({...e,messages:Array.isArray(e.messages)?e.messages:[]})):[]}catch{return[]}}),[y,j]=(0,a.useState)(()=>globalThis.localStorage.getItem(d)||""),[S,I]=(0,a.useState)(()=>globalThis.localStorage.getItem(c)||""),[A,k]=(0,a.useState)(""),[D,O]=(0,a.useState)(()=>globalThis.localStorage.getItem(m)||""),[$,C]=(0,a.useState)([]),[_,M]=(0,a.useState)(!1),[E,T]=(0,a.useState)(""),[U,R]=(0,a.useState)(""),[z,q]=(0,a.useState)(!1),[P,J]=(0,a.useState)(!1),[B,F]=(0,a.useState)(!1),K=(0,a.useRef)(null),L=(0,a.useRef)(null),W=(0,a.useRef)(!1),H=(0,a.useRef)(null),Y=(0,a.useRef)(null);(0,a.useEffect)(()=>{q(!0)},[]),(0,a.useEffect)(()=>{let e=!1;return async function(){g(!0),v("");try{let r=await fetch("/api/providers",{cache:"no-store"}),s=await r.json().catch(()=>({})),a=Array.isArray(s.connections)?s.connections.filter(e=>e?.isActive!==!1):[];if(0===a.length){e||(t([]),v("No providers connected yet."));return}let i=new Map;for(let e of a){let t=e.provider||e.id,r=f(e),s=(0,n.mq)(t)?"openai-compatible":(0,n.gb)(t)?"anthropic-compatible":t;i.has(t)||i.set(t,{providerId:t,providerName:r,providerType:s,connections:[],models:[]});let a=i.get(t);a.providerName=a.providerName||r,a.providerType=a.providerType||s,a.connections.push(e);let o=(0,l.KC)(t).map(t=>t?.id?{id:`${e.provider}/${t.id}`,requestModel:`${e.provider}/${t.id}`,name:t.name||t.id,providerId:e.provider,providerName:f(e),source:"static"}:null).filter(Boolean);a.models.push(...o)}for(let e of(await Promise.all(a.map(async e=>{try{let t=await fetch(`/api/providers/${e.id}/models`,{cache:"no-store"}),r=await t.json().catch(()=>({}));if(!t.ok)return{connection:e,models:[]};let s=(Array.isArray(r?.models)?r.models:Array.isArray(r?.data)?r.data:Array.isArray(r?.results)?r.results:Array.isArray(r)?r:[]).map(t=>(function(e,t){let r="string"==typeof e?e:e?.id||e?.name||e?.model||"";if(!r)return null;let s="string"==typeof e?e:e?.name||e?.displayName||r,a=r;return((0,n.mq)(t.provider)||(0,n.gb)(t.provider))&&!r.includes("/")&&(a=`${t.provider}/${r}`),{id:a,requestModel:a,name:s,providerId:t.provider,providerName:f(t),source:"live"}})(t,e)).filter(Boolean);return{connection:e,models:s}}catch{return{connection:e,models:[]}}})))){let t=e.connection.provider||e.connection.id,r=i.get(t);r&&r.models.push(...e.models)}let o=Array.from(i.values()).map(e=>({...e,models:(function(e){let t=new Map;for(let r of e)r?.id&&(t.has(r.id)||t.set(r.id,r));return Array.from(t.values())})(e.models).sort((e,t)=>e.name.localeCompare(t.name))})).filter(e=>e.models.length>0).sort((e,t)=>e.providerName.localeCompare(t.providerName));e||(t(o),0===o.length&&v("Providers connected but no models available."))}catch(r){e||(v(p(r?.message)||"Failed to load providers/models."),t([]))}finally{e||g(!1)}}(),()=>{e=!0}},[]),(0,a.useEffect)(()=>{let e=e=>{H.current&&!H.current.contains(e.target)&&J(!1),Y.current&&!Y.current.contains(e.target)&&F(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let G=(0,a.useMemo)(()=>{let t=new Map;for(let r of e)for(let e of r.models)t.set(e.id,{...e,providerId:r.providerId,providerName:r.providerName});return t},[e]),Q=(0,a.useMemo)(()=>e.find(e=>e.providerId===S)||e[0]||null,[e,S]),V=(0,a.useMemo)(()=>{if(A&&G.has(A))return G.get(A);if(y){let e=b.find(e=>e.id===y);if(e?.modelId&&G.has(e.modelId))return G.get(e.modelId)}return Q?.models?.[0]||null},[A,G,Q,b,y]),X=(0,a.useMemo)(()=>b.find(e=>e.id===y)||null,[b,y]),Z=X?.messages||[],ee=(0,a.useMemo)(()=>[...b].sort((e,t)=>new Date(t.updatedAt).getTime()-new Date(e.updatedAt).getTime()),[b]),et=!_&&!!V&&(D.trim().length>0||$.length>0);(0,a.useEffect)(()=>{if(z)try{globalThis.localStorage.setItem(o,JSON.stringify(b)),globalThis.localStorage.setItem(d,y),globalThis.localStorage.setItem(c,S),globalThis.localStorage.setItem(m,D)}catch{}},[z,b,y,S,D]),(0,a.useEffect)(()=>{if(!z||r||W.current||0===e.length)return;let t=e.find(e=>e.providerId===S)||e[0],s=A&&G.has(A)?G.get(A):t.models[0];if(b.length>0){let e=b.find(e=>e.id===y)||b[0],r=e?.modelId&&G.has(e.modelId)?G.get(e.modelId):s;W.current=!0,j(e.id),I(r?.providerId||t.providerId),k(r?.id||s.id);return}let a={id:u(),title:"New chat",providerId:t.providerId,providerName:t.providerName,modelId:s.id,modelName:s.name,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),messages:[]};W.current=!0,N([a]),j(a.id),I(t.providerId),k(s.id)},[z,r,e,G,b,y,S,A]);let er=(e,t)=>{N(r=>r.map(r=>r.id===e?t({...r,messages:Array.isArray(r.messages)?r.messages.map(e=>({...e})):[]}):r))},es=e=>e?{id:u(),title:"New chat",providerId:e.providerId,providerName:e.providerName,modelId:e.id,modelName:e.name,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),messages:[]}:null,ea=async e=>{let t=Array.from(e.target.files||[]);if(0===t.length)return;let r=t.filter(e=>e.type.startsWith("image/"));if(0===r.length){e.target.value="";return}let s=await Promise.all(r.map(async e=>({id:u(),name:e.name,type:e.type,size:e.size,dataUrl:await x(e)})));C(e=>[...e,...s]),e.target.value=""},ei=async()=>{let e=V||Q?.models?.[0]||null;if(!e)return;let t=D.trim();if(!t&&0===$.length)return;let r=y,s=b.find(e=>e.id===r);if(!s){if(!(s=es(e)))return;r=s.id,N(e=>[s,...e]),j(r)}let a={id:u(),role:"user",content:t,attachments:$.map(e=>({id:e.id,name:e.name,type:e.type,dataUrl:e.dataUrl})),createdAt:new Date().toISOString()},i=u(),l={id:i,role:"assistant",content:"",createdAt:new Date().toISOString(),status:"streaming"},n=[...s.messages||[],a,l];N(s=>s.map(s=>s.id===r?{...s,providerId:e.providerId,providerName:e.providerName,modelId:e.id,modelName:e.name,messages:n,updatedAt:new Date().toISOString(),title:"New chat"===s.title?h(t):s.title}:s)),O(""),C([]),M(!0),T(i),R(""),L.current?.abort(),L.current=new AbortController;let o=n.filter(e=>"assistant"!==e.role||e.id!==i).map(e=>({role:e.role,content:"user"===e.role?function(e){let t=p(e.content).trim(),r=Array.isArray(e.attachments)?e.attachments:[];if(0===r.length)return t;let s=[];for(let e of(t&&s.push({type:"text",text:t}),r))e?.dataUrl&&s.push({type:"image_url",image_url:{url:e.dataUrl}});return s.length>0?s:t}(e):e.content}));try{var d;let s,a=await fetch("/api/dashboard/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify({model:e.requestModel||e.id,messages:o,stream:!0}),signal:L.current.signal});if(!a.ok){let e=await a.json().catch(()=>({}));throw Error(p(e.error||e.message||`Request failed (${a.status})`))}let l=a.body?.getReader();if(!l){let e=await a.json().catch(()=>({})),t=p(e?.choices?.[0]?.message?.content||e?.output_text||e?.error||e?.message||"");er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:t,status:"done"}:e),updatedAt:new Date().toISOString()}));return}let n=new TextDecoder,c="",m="";for(;;){let{value:e,done:t}=await l.read();if(t)break;let s=(c+=n.decode(e,{stream:!0})).split(/\r?\n/);for(let e of(c=s.pop()||"",s)){let t=e.trim();if(!t.startsWith("data:"))continue;let s=t.slice(5).trim();if(s&&"[DONE]"!==s)try{let e=JSON.parse(s),t=function(e){if(!e||"object"!=typeof e)return"";let t=e.choices?.[0];return[(t?.delta||{}).content,t?.message?.content,e.output_text,e.text].map(p).filter(Boolean)[0]||""}(e);if(!t)continue;m+=t,R(m),er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:m,status:"streaming"}:e),updatedAt:new Date().toISOString()}))}catch{}}}er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:m||e.content,status:"done"}:e),updatedAt:new Date().toISOString()})),d=r,s=h(t),er(d,e=>({...e,title:"New chat"===e.title?s:e.title,updatedAt:new Date().toISOString()}))}catch(e){if("AbortError"!==e.name){let t=p(e?.message||e);er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:e.content||`Error: ${t}`,status:"error"}:e),updatedAt:new Date().toISOString()})),v(t||"Failed to send message.")}}finally{M(!1),T(""),R(""),L.current=null}},el=V?`${V.name}`:"Select model",en=V?V.requestModel:"Choose from connected providers";return(0,s.jsx)("div",{className:"relative flex-1 flex flex-col h-full min-h-0 min-w-0 bg-[#212121] text-white overflow-hidden",children:(0,s.jsxs)("div",{className:"relative mx-auto flex flex-1 h-full min-h-0 w-full max-w-4xl flex-col",children:[(0,s.jsxs)("div",{className:"flex shrink-0 items-center justify-between gap-3 px-4 py-3 lg:px-6",children:[(0,s.jsxs)("div",{ref:H,className:"relative",children:[(0,s.jsx)("button",{type:"button",onClick:()=>J(e=>!e),className:"flex items-center gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-left transition hover:bg-white/8",children:(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-sm font-semibold text-white",children:el}),(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] text-white/70",children:"expand_more"})]}),(0,s.jsx)("p",{className:"truncate text-xs text-white/55",children:en})]})}),P?(0,s.jsxs)("div",{className:"absolute left-0 top-[calc(100%+10px)] z-30 w-[min(520px,calc(100vw-2rem))] overflow-hidden rounded-[20px] border border-white/10 bg-[#262626] shadow-2xl shadow-black/50",children:[(0,s.jsxs)("div",{className:"border-b border-white/10 px-4 py-3",children:[(0,s.jsx)("p",{className:"text-xs uppercase tracking-[0.22em] text-white/45",children:"Models"}),(0,s.jsx)("p",{className:"text-sm text-white/75",children:"Only from connected providers"})]}),(0,s.jsx)("div",{className:"max-h-[60vh] overflow-y-auto p-2 custom-scrollbar",children:e.map(e=>(0,s.jsxs)("div",{className:"mb-2 rounded-[16px] border border-white/10 bg-black/20 p-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-2 py-2",children:[(0,s.jsx)("p",{className:"text-sm font-semibold text-white",children:e.providerName}),(0,s.jsx)(i.Ex,{size:"sm",variant:"default",children:e.models.length})]}),(0,s.jsx)("div",{className:"grid gap-2 sm:grid-cols-2",children:e.models.map(e=>{let t=e.id===A;return(0,s.jsx)("button",{type:"button",onClick:()=>(e=>{let t=G.get(e);if(!t)return;let r=b.find(e=>e.id===y);if(r&&r.messages.length>0){let e=es(t);if(!e)return;N(t=>[e,...t]),j(e.id)}else if(r)N(e=>e.map(e=>e.id===r.id?{...e,providerId:t.providerId,providerName:t.providerName,modelId:t.id,modelName:t.name}:e)),j(r.id);else{let e=es(t);if(!e)return;N(t=>[e,...t]),j(e.id)}I(t.providerId),k(t.id),J(!1)})(e.id),className:`rounded-[14px] border px-3 py-3 text-left transition ${t?"border-blue-400/40 bg-blue-500/15":"border-white/10 bg-white/5 hover:bg-white/8"}`,children:(0,s.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsx)("p",{className:"truncate text-sm font-medium text-white",children:e.name}),(0,s.jsx)("p",{className:"truncate text-[11px] text-white/45",children:e.requestModel})]}),t?(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] text-blue-300",children:"check_circle"}):null]})},e.id)})})]},e.providerId))})]}):null]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{type:"button",onClick:()=>F(e=>!e),className:"rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white/80 transition hover:bg-white/8",children:"History"}),(0,s.jsx)(i.$n,{variant:"ghost",size:"sm",icon:"delete",onClick:()=>{if(!y)return;let e=b.filter(e=>e.id!==y),t=e[0]||null;N(e),t?(j(t.id),I(t.providerId),k(t.modelId)):(j(""),I(""),k(""))},disabled:!y||0===b.length,children:"Clear"})]})]}),B?(0,s.jsxs)("div",{ref:Y,className:"absolute right-4 top-[72px] z-20 w-[min(360px,calc(100vw-2rem))] rounded-[20px] border border-white/10 bg-[#262626] p-2 shadow-2xl shadow-black/50 lg:right-6",children:[(0,s.jsx)("div",{className:"px-3 py-2",children:(0,s.jsx)("p",{className:"text-xs uppercase tracking-[0.22em] text-white/45",children:"Recent chats"})}),(0,s.jsx)("div",{className:"max-h-[48vh] space-y-2 overflow-y-auto p-1 custom-scrollbar",children:0===ee.length?(0,s.jsx)("div",{className:"rounded-[16px] border border-dashed border-white/10 bg-white/5 p-4 text-sm text-white/55",children:"No conversations yet."}):ee.map(e=>{let t=e.id===y,r=[...e.messages||[]].reverse().find(e=>"user"===e.role)||e.messages?.[0];return(0,s.jsx)("button",{type:"button",onClick:()=>{var t;let r;return t=e.id,void((r=b.find(e=>e.id===t))&&(j(t),I(r.providerId||S),k(r.modelId||A),F(!1)))},className:`w-full rounded-[16px] border px-3 py-3 text-left transition ${t?"border-blue-400/40 bg-blue-500/15":"border-white/10 bg-white/5 hover:bg-white/8"}`,children:(0,s.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,s.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,s.jsx)("p",{className:"truncate text-sm font-medium text-white",children:e.title}),(0,s.jsx)("p",{className:"mt-1 truncate text-xs text-white/50",children:p(r?.content)||"Empty chat"})]}),(0,s.jsx)("span",{className:"text-[10px] text-white/40 shrink-0",children:function(e){if(!e)return"Now";let t=new Date(e).getTime();if(Number.isNaN(t))return"Now";let r=Math.max(1,Math.round((Date.now()-t)/6e4));if(r<60)return`${r}m`;let s=Math.round(r/60);return s<24?`${s}h`:`${Math.round(s/24)}d`}(e.updatedAt)})]})},e.id)})})]}):null,w?(0,s.jsx)("div",{className:"mt-4 rounded-[18px] border border-rose-500/20 bg-rose-500/10 px-4 py-3 text-rose-100",children:(0,s.jsxs)("div",{className:"flex items-start gap-3",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"error"}),(0,s.jsx)("p",{className:"text-sm leading-6",children:w})]})}):null,(0,s.jsxs)("div",{className:"flex flex-1 flex-col min-h-0",children:[(0,s.jsxs)("div",{className:"flex-1 overflow-y-auto py-4 custom-scrollbar",children:[0===Z.length?(0,s.jsx)("div",{className:"flex min-h-[50vh] items-center justify-center px-4 text-center",children:(0,s.jsxs)("div",{className:"max-w-xl space-y-4",children:[(0,s.jsx)("div",{className:"mx-auto flex size-16 items-center justify-center rounded-[20px] border border-white/10 bg-white/5 text-white/80",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[30px]",children:"chat"})}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("h2",{className:"text-2xl font-semibold text-white",children:"Start a conversation"}),(0,s.jsx)("p",{className:"text-sm leading-6 text-white/60",children:"Simple chat interface to interact with any AI model from connected providers. Select a model and start chatting!"})]})]})}):null,(0,s.jsx)("div",{className:"mx-auto flex w-full max-w-3xl flex-col gap-4 px-4",children:Z.map(e=>{let t="user"===e.role,r="assistant"===e.role,a=r&&e.id===E&&"streaming"===e.status,i=p(e.content)||(r?U:"");return(0,s.jsx)("div",{className:`flex w-full ${t?"justify-end":"justify-start"} mb-6`,children:(0,s.jsxs)("div",{className:`max-w-[min(88%,42rem)] ${t?"rounded-3xl bg-[#2f2f2f] px-5 py-3.5 text-white":"text-white/90"}`,children:[(0,s.jsx)("div",{className:"mb-1 flex items-center justify-between gap-3",children:(0,s.jsx)("span",{className:"text-xs font-semibold",children:t?"You":V?.name||"Assistant"})}),e.attachments?.length?(0,s.jsx)("div",{className:"mb-3 grid grid-cols-2 gap-2 sm:grid-cols-3 mt-2",children:e.attachments.map(e=>(0,s.jsx)("a",{href:e.dataUrl,target:"_blank",rel:"noreferrer",className:"overflow-hidden rounded-[18px] border border-white/10 bg-black/20",children:(0,s.jsx)("img",{src:e.dataUrl,alt:e.name,className:"h-28 w-full object-cover"})},e.id))}):null,(0,s.jsxs)("div",{className:"whitespace-pre-wrap break-words text-[15px] leading-7",children:[i,r&&a&&!U?(0,s.jsx)("span",{className:"inline-block animate-pulse",children:"▋"}):null]})]})},e.id)})})]}),(0,s.jsxs)("div",{className:"shrink-0 pt-2",children:[$.length>0?(0,s.jsx)("div",{className:"mx-auto mb-3 flex w-full max-w-3xl flex-wrap gap-2 px-4",children:$.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-2",children:[(0,s.jsx)("span",{className:"text-xs text-white/80 max-w-[12rem] truncate",children:e.name}),(0,s.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void C(e=>e.filter(e=>e.id!==t))},className:"text-white/55 hover:text-white","aria-label":"Remove attachment",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"close"})})]},e.id))}):null,(0,s.jsx)("div",{className:"mx-auto w-full max-w-3xl px-4 pb-2",children:(0,s.jsxs)("div",{className:"rounded-[26px] bg-[#2f2f2f] px-3 pt-3 pb-2 shadow-[0_0_15px_rgba(0,0,0,0.10)] ring-1 ring-white/5",children:[(0,s.jsx)("textarea",{value:D,onChange:e=>O(e.target.value),onKeyDown:e=>{"Enter"===e.key&&!e.shiftKey&&(e.preventDefault(),et&&ei())},placeholder:"Message AI",rows:1,className:"w-full resize-none bg-transparent px-2 text-[15px] leading-6 text-white outline-none placeholder:text-white/40 custom-scrollbar max-h-[25vh] overflow-y-auto"}),(0,s.jsxs)("div",{className:"mt-2 flex items-center justify-between gap-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{type:"button",onClick:()=>K.current?.click(),disabled:!V||r,className:"p-2 text-white/50 hover:text-white transition rounded-full hover:bg-white/5",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"attach_file"})}),(0,s.jsx)("input",{ref:K,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:ea}),(0,s.jsx)("span",{className:"text-xs font-medium text-white/30 truncate max-w-[120px]",children:V?V.name:"No model"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[_?(0,s.jsx)("button",{type:"button",onClick:()=>{L.current?.abort()},className:"p-2 text-white bg-white/10 hover:bg-white/20 transition rounded-full h-8 w-8 flex items-center justify-center",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"stop"})}):null,(0,s.jsx)("button",{onClick:ei,disabled:!et,className:`h-8 w-8 rounded-full flex items-center justify-center transition ${et?"bg-white text-black hover:opacity-90":"bg-white/10 text-white/30 cursor-not-allowed"}`,children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"arrow_upward"})})]})]})]})})]}),(0,s.jsx)("p",{className:"mx-auto mt-2 max-w-3xl px-4 pb-4 text-center text-[11px] text-white/30",children:"Model list is filtered from connected providers."})]})]})})}}},e=>{e.O(0,[2574,3862,8500,4288,1321,5497,8441,3794,7358],()=>e(e.s=35911)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4465],{35911:(e,t,r)=>{Promise.resolve().then(r.bind(r,88512))},88512:(e,t,r)=>{"use strict";r.d(t,{default:()=>g});var s=r(95155),a=r(12115),i=r(35497),l=r(28777),n=r(52679);let o="basic-chat.sessions",d="basic-chat.activeSessionId",c="basic-chat.activeProviderId",m="basic-chat.draft";function u(){return globalThis.crypto?.randomUUID?globalThis.crypto.randomUUID():`chat_${Date.now()}_${Math.random().toString(16).slice(2)}`}function p(e){if("string"==typeof e)return e;if(null==e)return"";if(Array.isArray(e))return e.map(p).filter(Boolean).join(" ");if("object"==typeof e){if("string"==typeof e.message)return e.message;if("string"==typeof e.error)return e.error;try{return JSON.stringify(e)}catch{}}return String(e)}function h(e=""){let t=p(e).replace(/\s+/g," ").trim();return t?t.length>52?`${t.slice(0,52).trimEnd()}…`:t:"New chat"}async function x(e){return await new Promise((t,r)=>{let s=new FileReader;s.onload=()=>t(String(s.result||"")),s.onerror=()=>r(s.error||Error("Failed to read file")),s.readAsDataURL(e)})}function f(e){return e?.name||function(e=""){return String(e).replace(/[-_]/g," ").replace(/\b\w/g,e=>e.toUpperCase()).trim()||"Unknown"}(e?.provider||e?.id||"provider")}function g(){let[e,t]=(0,a.useState)([]),[r,g]=(0,a.useState)(!0),[w,v]=(0,a.useState)(""),[b,N]=(0,a.useState)(()=>{try{let e=function(e,t){try{return JSON.parse(e)}catch{return t}}(globalThis.localStorage.getItem(o),[]);return Array.isArray(e)?e.map(e=>({...e,messages:Array.isArray(e.messages)?e.messages:[]})):[]}catch{return[]}}),[y,j]=(0,a.useState)(()=>globalThis.localStorage.getItem(d)||""),[S,I]=(0,a.useState)(()=>globalThis.localStorage.getItem(c)||""),[A,k]=(0,a.useState)(""),[D,O]=(0,a.useState)(()=>globalThis.localStorage.getItem(m)||""),[$,C]=(0,a.useState)([]),[_,M]=(0,a.useState)(!1),[E,T]=(0,a.useState)(""),[U,R]=(0,a.useState)(""),[z,q]=(0,a.useState)(!1),[P,J]=(0,a.useState)(!1),[B,F]=(0,a.useState)(!1),K=(0,a.useRef)(null),L=(0,a.useRef)(null),W=(0,a.useRef)(!1),H=(0,a.useRef)(null),Y=(0,a.useRef)(null);(0,a.useEffect)(()=>{q(!0)},[]),(0,a.useEffect)(()=>{let e=!1;return async function(){g(!0),v("");try{let r=await fetch("/api/providers",{cache:"no-store"}),s=await r.json().catch(()=>({})),a=Array.isArray(s.connections)?s.connections.filter(e=>e?.isActive!==!1):[];if(0===a.length){e||(t([]),v("No providers connected yet."));return}let i=new Map;for(let e of a){let t=e.provider||e.id,r=f(e),s=(0,n.mq)(t)?"openai-compatible":(0,n.gb)(t)?"anthropic-compatible":t;i.has(t)||i.set(t,{providerId:t,providerName:r,providerType:s,connections:[],models:[]});let a=i.get(t);a.providerName=a.providerName||r,a.providerType=a.providerType||s,a.connections.push(e);let o=(0,l.KC)(t).map(t=>t?.id?{id:`${e.provider}/${t.id}`,requestModel:`${e.provider}/${t.id}`,name:t.name||t.id,providerId:e.provider,providerName:f(e),source:"static"}:null).filter(Boolean);a.models.push(...o)}for(let e of(await Promise.all(a.map(async e=>{try{let t=await fetch(`/api/providers/${e.id}/models`,{cache:"no-store"}),r=await t.json().catch(()=>({}));if(!t.ok)return{connection:e,models:[]};let s=(Array.isArray(r?.models)?r.models:Array.isArray(r?.data)?r.data:Array.isArray(r?.results)?r.results:Array.isArray(r)?r:[]).map(t=>(function(e,t){let r="string"==typeof e?e:e?.id||e?.name||e?.model||"";if(!r)return null;let s="string"==typeof e?e:e?.name||e?.displayName||r,a=r;return((0,n.mq)(t.provider)||(0,n.gb)(t.provider))&&!r.includes("/")&&(a=`${t.provider}/${r}`),{id:a,requestModel:a,name:s,providerId:t.provider,providerName:f(t),source:"live"}})(t,e)).filter(Boolean);return{connection:e,models:s}}catch{return{connection:e,models:[]}}})))){let t=e.connection.provider||e.connection.id,r=i.get(t);r&&r.models.push(...e.models)}let o=Array.from(i.values()).map(e=>({...e,models:(function(e){let t=new Map;for(let r of e)r?.id&&(t.has(r.id)||t.set(r.id,r));return Array.from(t.values())})(e.models).sort((e,t)=>e.name.localeCompare(t.name))})).filter(e=>e.models.length>0).sort((e,t)=>e.providerName.localeCompare(t.providerName));e||(t(o),0===o.length&&v("Providers connected but no models available."))}catch(r){e||(v(p(r?.message)||"Failed to load providers/models."),t([]))}finally{e||g(!1)}}(),()=>{e=!0}},[]),(0,a.useEffect)(()=>{let e=e=>{H.current&&!H.current.contains(e.target)&&J(!1),Y.current&&!Y.current.contains(e.target)&&F(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let G=(0,a.useMemo)(()=>{let t=new Map;for(let r of e)for(let e of r.models)t.set(e.id,{...e,providerId:r.providerId,providerName:r.providerName});return t},[e]),Q=(0,a.useMemo)(()=>e.find(e=>e.providerId===S)||e[0]||null,[e,S]),V=(0,a.useMemo)(()=>{if(A&&G.has(A))return G.get(A);if(y){let e=b.find(e=>e.id===y);if(e?.modelId&&G.has(e.modelId))return G.get(e.modelId)}return Q?.models?.[0]||null},[A,G,Q,b,y]),X=(0,a.useMemo)(()=>b.find(e=>e.id===y)||null,[b,y]),Z=X?.messages||[],ee=(0,a.useMemo)(()=>[...b].sort((e,t)=>new Date(t.updatedAt).getTime()-new Date(e.updatedAt).getTime()),[b]),et=!_&&!!V&&(D.trim().length>0||$.length>0);(0,a.useEffect)(()=>{if(z)try{globalThis.localStorage.setItem(o,JSON.stringify(b)),globalThis.localStorage.setItem(d,y),globalThis.localStorage.setItem(c,S),globalThis.localStorage.setItem(m,D)}catch{}},[z,b,y,S,D]),(0,a.useEffect)(()=>{if(!z||r||W.current||0===e.length)return;let t=e.find(e=>e.providerId===S)||e[0],s=A&&G.has(A)?G.get(A):t.models[0];if(b.length>0){let e=b.find(e=>e.id===y)||b[0],r=e?.modelId&&G.has(e.modelId)?G.get(e.modelId):s;W.current=!0,j(e.id),I(r?.providerId||t.providerId),k(r?.id||s.id);return}let a={id:u(),title:"New chat",providerId:t.providerId,providerName:t.providerName,modelId:s.id,modelName:s.name,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),messages:[]};W.current=!0,N([a]),j(a.id),I(t.providerId),k(s.id)},[z,r,e,G,b,y,S,A]);let er=(e,t)=>{N(r=>r.map(r=>r.id===e?t({...r,messages:Array.isArray(r.messages)?r.messages.map(e=>({...e})):[]}):r))},es=e=>e?{id:u(),title:"New chat",providerId:e.providerId,providerName:e.providerName,modelId:e.id,modelName:e.name,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),messages:[]}:null,ea=async e=>{let t=Array.from(e.target.files||[]);if(0===t.length)return;let r=t.filter(e=>e.type.startsWith("image/"));if(0===r.length){e.target.value="";return}let s=await Promise.all(r.map(async e=>({id:u(),name:e.name,type:e.type,size:e.size,dataUrl:await x(e)})));C(e=>[...e,...s]),e.target.value=""},ei=async()=>{let e=V||Q?.models?.[0]||null;if(!e)return;let t=D.trim();if(!t&&0===$.length)return;let r=y,s=b.find(e=>e.id===r);if(!s){if(!(s=es(e)))return;r=s.id,N(e=>[s,...e]),j(r)}let a={id:u(),role:"user",content:t,attachments:$.map(e=>({id:e.id,name:e.name,type:e.type,dataUrl:e.dataUrl})),createdAt:new Date().toISOString()},i=u(),l={id:i,role:"assistant",content:"",createdAt:new Date().toISOString(),status:"streaming"},n=[...s.messages||[],a,l];N(s=>s.map(s=>s.id===r?{...s,providerId:e.providerId,providerName:e.providerName,modelId:e.id,modelName:e.name,messages:n,updatedAt:new Date().toISOString(),title:"New chat"===s.title?h(t):s.title}:s)),O(""),C([]),M(!0),T(i),R(""),L.current?.abort(),L.current=new AbortController;let o=n.filter(e=>"assistant"!==e.role||e.id!==i).map(e=>({role:e.role,content:"user"===e.role?function(e){let t=p(e.content).trim(),r=Array.isArray(e.attachments)?e.attachments:[];if(0===r.length)return t;let s=[];for(let e of(t&&s.push({type:"text",text:t}),r))e?.dataUrl&&s.push({type:"image_url",image_url:{url:e.dataUrl}});return s.length>0?s:t}(e):e.content}));try{var d;let s,a=await fetch("/api/dashboard/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify({model:e.requestModel||e.id,messages:o,stream:!0}),signal:L.current.signal});if(!a.ok){let e=await a.json().catch(()=>({}));throw Error(p(e.error||e.message||`Request failed (${a.status})`))}let l=a.body?.getReader();if(!l){let e=await a.json().catch(()=>({})),t=p(e?.choices?.[0]?.message?.content||e?.output_text||e?.error||e?.message||"");er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:t,status:"done"}:e),updatedAt:new Date().toISOString()}));return}let n=new TextDecoder,c="",m="";for(;;){let{value:e,done:t}=await l.read();if(t)break;let s=(c+=n.decode(e,{stream:!0})).split(/\r?\n/);for(let e of(c=s.pop()||"",s)){let t=e.trim();if(!t.startsWith("data:"))continue;let s=t.slice(5).trim();if(s&&"[DONE]"!==s)try{let e=JSON.parse(s),t=function(e){if(!e||"object"!=typeof e)return"";let t=e.choices?.[0];return[(t?.delta||{}).content,t?.message?.content,e.output_text,e.text].map(p).filter(Boolean)[0]||""}(e);if(!t)continue;m+=t,R(m),er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:m,status:"streaming"}:e),updatedAt:new Date().toISOString()}))}catch{}}}er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:m||e.content,status:"done"}:e),updatedAt:new Date().toISOString()})),d=r,s=h(t),er(d,e=>({...e,title:"New chat"===e.title?s:e.title,updatedAt:new Date().toISOString()}))}catch(e){if("AbortError"!==e.name){let t=p(e?.message||e);er(r,e=>({...e,messages:e.messages.map(e=>e.id===i?{...e,content:e.content||`Error: ${t}`,status:"error"}:e),updatedAt:new Date().toISOString()})),v(t||"Failed to send message.")}}finally{M(!1),T(""),R(""),L.current=null}},el=V?`${V.name}`:"Select model",en=V?V.requestModel:"Choose from connected providers";return(0,s.jsx)("div",{className:"relative flex-1 flex flex-col h-full min-h-0 min-w-0 bg-[#212121] text-white overflow-hidden",children:(0,s.jsxs)("div",{className:"relative mx-auto flex flex-1 h-full min-h-0 w-full max-w-4xl flex-col",children:[(0,s.jsxs)("div",{className:"flex shrink-0 items-center justify-between gap-3 px-4 py-3 lg:px-6",children:[(0,s.jsxs)("div",{ref:H,className:"relative",children:[(0,s.jsx)("button",{type:"button",onClick:()=>J(e=>!e),className:"flex items-center gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-left transition hover:bg-white/8",children:(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-sm font-semibold text-white",children:el}),(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] text-white/70",children:"expand_more"})]}),(0,s.jsx)("p",{className:"truncate text-xs text-white/55",children:en})]})}),P?(0,s.jsxs)("div",{className:"absolute left-0 top-[calc(100%+10px)] z-30 w-[min(520px,calc(100vw-2rem))] overflow-hidden rounded-[20px] border border-white/10 bg-[#262626] shadow-2xl shadow-black/50",children:[(0,s.jsxs)("div",{className:"border-b border-white/10 px-4 py-3",children:[(0,s.jsx)("p",{className:"text-xs uppercase tracking-[0.22em] text-white/45",children:"Models"}),(0,s.jsx)("p",{className:"text-sm text-white/75",children:"Only from connected providers"})]}),(0,s.jsx)("div",{className:"max-h-[60vh] overflow-y-auto p-2 custom-scrollbar",children:e.map(e=>(0,s.jsxs)("div",{className:"mb-2 rounded-[16px] border border-white/10 bg-black/20 p-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-2 py-2",children:[(0,s.jsx)("p",{className:"text-sm font-semibold text-white",children:e.providerName}),(0,s.jsx)(i.Ex,{size:"sm",variant:"default",children:e.models.length})]}),(0,s.jsx)("div",{className:"grid gap-2 sm:grid-cols-2",children:e.models.map(e=>{let t=e.id===A;return(0,s.jsx)("button",{type:"button",onClick:()=>(e=>{let t=G.get(e);if(!t)return;let r=b.find(e=>e.id===y);if(r&&r.messages.length>0){let e=es(t);if(!e)return;N(t=>[e,...t]),j(e.id)}else if(r)N(e=>e.map(e=>e.id===r.id?{...e,providerId:t.providerId,providerName:t.providerName,modelId:t.id,modelName:t.name}:e)),j(r.id);else{let e=es(t);if(!e)return;N(t=>[e,...t]),j(e.id)}I(t.providerId),k(t.id),J(!1)})(e.id),className:`rounded-[14px] border px-3 py-3 text-left transition ${t?"border-blue-400/40 bg-blue-500/15":"border-white/10 bg-white/5 hover:bg-white/8"}`,children:(0,s.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsx)("p",{className:"truncate text-sm font-medium text-white",children:e.name}),(0,s.jsx)("p",{className:"truncate text-[11px] text-white/45",children:e.requestModel})]}),t?(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] text-blue-300",children:"check_circle"}):null]})},e.id)})})]},e.providerId))})]}):null]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{type:"button",onClick:()=>F(e=>!e),className:"rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white/80 transition hover:bg-white/8",children:"History"}),(0,s.jsx)(i.$n,{variant:"ghost",size:"sm",icon:"delete",onClick:()=>{if(!y)return;let e=b.filter(e=>e.id!==y),t=e[0]||null;N(e),t?(j(t.id),I(t.providerId),k(t.modelId)):(j(""),I(""),k(""))},disabled:!y||0===b.length,children:"Clear"})]})]}),B?(0,s.jsxs)("div",{ref:Y,className:"absolute right-4 top-[72px] z-20 w-[min(360px,calc(100vw-2rem))] rounded-[20px] border border-white/10 bg-[#262626] p-2 shadow-2xl shadow-black/50 lg:right-6",children:[(0,s.jsx)("div",{className:"px-3 py-2",children:(0,s.jsx)("p",{className:"text-xs uppercase tracking-[0.22em] text-white/45",children:"Recent chats"})}),(0,s.jsx)("div",{className:"max-h-[48vh] space-y-2 overflow-y-auto p-1 custom-scrollbar",children:0===ee.length?(0,s.jsx)("div",{className:"rounded-[16px] border border-dashed border-white/10 bg-white/5 p-4 text-sm text-white/55",children:"No conversations yet."}):ee.map(e=>{let t=e.id===y,r=[...e.messages||[]].reverse().find(e=>"user"===e.role)||e.messages?.[0];return(0,s.jsx)("button",{type:"button",onClick:()=>{var t;let r;return t=e.id,void((r=b.find(e=>e.id===t))&&(j(t),I(r.providerId||S),k(r.modelId||A),F(!1)))},className:`w-full rounded-[16px] border px-3 py-3 text-left transition ${t?"border-blue-400/40 bg-blue-500/15":"border-white/10 bg-white/5 hover:bg-white/8"}`,children:(0,s.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,s.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,s.jsx)("p",{className:"truncate text-sm font-medium text-white",children:e.title}),(0,s.jsx)("p",{className:"mt-1 truncate text-xs text-white/50",children:p(r?.content)||"Empty chat"})]}),(0,s.jsx)("span",{className:"text-[10px] text-white/40 shrink-0",children:function(e){if(!e)return"Now";let t=new Date(e).getTime();if(Number.isNaN(t))return"Now";let r=Math.max(1,Math.round((Date.now()-t)/6e4));if(r<60)return`${r}m`;let s=Math.round(r/60);return s<24?`${s}h`:`${Math.round(s/24)}d`}(e.updatedAt)})]})},e.id)})})]}):null,w?(0,s.jsx)("div",{className:"mt-4 rounded-[18px] border border-rose-500/20 bg-rose-500/10 px-4 py-3 text-rose-100",children:(0,s.jsxs)("div",{className:"flex items-start gap-3",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"error"}),(0,s.jsx)("p",{className:"text-sm leading-6",children:w})]})}):null,(0,s.jsxs)("div",{className:"flex flex-1 flex-col min-h-0",children:[(0,s.jsxs)("div",{className:"flex-1 overflow-y-auto py-4 custom-scrollbar",children:[0===Z.length?(0,s.jsx)("div",{className:"flex min-h-[50vh] items-center justify-center px-4 text-center",children:(0,s.jsxs)("div",{className:"max-w-xl space-y-4",children:[(0,s.jsx)("div",{className:"mx-auto flex size-16 items-center justify-center rounded-[20px] border border-white/10 bg-white/5 text-white/80",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[30px]",children:"chat"})}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("h2",{className:"text-2xl font-semibold text-white",children:"Start a conversation"}),(0,s.jsx)("p",{className:"text-sm leading-6 text-white/60",children:"Simple chat interface to interact with any AI model from connected providers. Select a model and start chatting!"})]})]})}):null,(0,s.jsx)("div",{className:"mx-auto flex w-full max-w-3xl flex-col gap-4 px-4",children:Z.map(e=>{let t="user"===e.role,r="assistant"===e.role,a=r&&e.id===E&&"streaming"===e.status,i=p(e.content)||(r?U:"");return(0,s.jsx)("div",{className:`flex w-full ${t?"justify-end":"justify-start"} mb-6`,children:(0,s.jsxs)("div",{className:`max-w-[min(88%,42rem)] ${t?"rounded-3xl bg-[#2f2f2f] px-5 py-3.5 text-white":"text-white/90"}`,children:[(0,s.jsx)("div",{className:"mb-1 flex items-center justify-between gap-3",children:(0,s.jsx)("span",{className:"text-xs font-semibold",children:t?"You":V?.name||"Assistant"})}),e.attachments?.length?(0,s.jsx)("div",{className:"mb-3 grid grid-cols-2 gap-2 sm:grid-cols-3 mt-2",children:e.attachments.map(e=>(0,s.jsx)("a",{href:e.dataUrl,target:"_blank",rel:"noreferrer",className:"overflow-hidden rounded-[18px] border border-white/10 bg-black/20",children:(0,s.jsx)("img",{src:e.dataUrl,alt:e.name,className:"h-28 w-full object-cover"})},e.id))}):null,(0,s.jsxs)("div",{className:"whitespace-pre-wrap break-words text-[15px] leading-7",children:[i,r&&a&&!U?(0,s.jsx)("span",{className:"inline-block animate-pulse",children:"▋"}):null]})]})},e.id)})})]}),(0,s.jsxs)("div",{className:"shrink-0 pt-2",children:[$.length>0?(0,s.jsx)("div",{className:"mx-auto mb-3 flex w-full max-w-3xl flex-wrap gap-2 px-4",children:$.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-2",children:[(0,s.jsx)("span",{className:"text-xs text-white/80 max-w-[12rem] truncate",children:e.name}),(0,s.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void C(e=>e.filter(e=>e.id!==t))},className:"text-white/55 hover:text-white","aria-label":"Remove attachment",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"close"})})]},e.id))}):null,(0,s.jsx)("div",{className:"mx-auto w-full max-w-3xl px-4 pb-2",children:(0,s.jsxs)("div",{className:"rounded-[26px] bg-[#2f2f2f] px-3 pt-3 pb-2 shadow-[0_0_15px_rgba(0,0,0,0.10)] ring-1 ring-white/5",children:[(0,s.jsx)("textarea",{value:D,onChange:e=>O(e.target.value),onKeyDown:e=>{"Enter"===e.key&&!e.shiftKey&&(e.preventDefault(),et&&ei())},placeholder:"Message AI",rows:1,className:"w-full resize-none bg-transparent px-2 text-[15px] leading-6 text-white outline-none placeholder:text-white/40 custom-scrollbar max-h-[25vh] overflow-y-auto"}),(0,s.jsxs)("div",{className:"mt-2 flex items-center justify-between gap-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{type:"button",onClick:()=>K.current?.click(),disabled:!V||r,className:"p-2 text-white/50 hover:text-white transition rounded-full hover:bg-white/5",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"attach_file"})}),(0,s.jsx)("input",{ref:K,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:ea}),(0,s.jsx)("span",{className:"text-xs font-medium text-white/30 truncate max-w-[120px]",children:V?V.name:"No model"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[_?(0,s.jsx)("button",{type:"button",onClick:()=>{L.current?.abort()},className:"p-2 text-white bg-white/10 hover:bg-white/20 transition rounded-full h-8 w-8 flex items-center justify-center",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"stop"})}):null,(0,s.jsx)("button",{onClick:ei,disabled:!et,className:`h-8 w-8 rounded-full flex items-center justify-center transition ${et?"bg-white text-black hover:opacity-90":"bg-white/10 text-white/30 cursor-not-allowed"}`,children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"arrow_upward"})})]})]})]})})]}),(0,s.jsx)("p",{className:"mx-auto mt-2 max-w-3xl px-4 pb-4 text-center text-[11px] text-white/30",children:"Model list is filtered from connected providers."})]})]})})}}},e=>{e.O(0,[2574,3862,1051,1321,5497,8441,3794,7358],()=>e(e.s=35911)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3554],{22843:(e,t,a)=>{Promise.resolve().then(a.bind(a,85309))},85309:(e,t,a)=>{"use strict";a.d(t,{default:()=>v});var s=a(95155),l=a(12115),r=a(98500),i=a.n(r),n=a(35497),o=a(3534),c=a(28777),d=a(38719);let u=a(41463).env.NEXT_PUBLIC_CLOUD_URL;function v({toolId:e,machineId:t}){let a=o.dM[e],[r,x]=(0,l.useState)([]),[h,p]=(0,l.useState)(!0),[b,f]=(0,l.useState)({}),[m,E]=(0,l.useState)(!1),[j,P]=(0,l.useState)(!1),[k,w]=(0,l.useState)(""),[g,N]=(0,l.useState)(!1),[S,_]=(0,l.useState)(""),[A,U]=(0,l.useState)([]);(0,l.useEffect)(()=>{let e=!0;return(async()=>{try{let[t,a,s,l]=await Promise.all([fetch("/api/providers"),fetch("/api/settings"),fetch("/api/tunnel/status"),fetch("/api/keys")]);if(!e)return;if(t.ok){let e=await t.json();x(e.connections||[])}if(a.ok){let e=await a.json();E(e.cloudEnabled||!1)}if(s.ok){let e=await s.json();P(!!(e.tunnel?.enabled||e.tunnel?.settingsEnabled)),w(e.tunnel?.publicUrl||""),N(!!(e.tailscale?.enabled||e.tailscale?.settingsEnabled)),_(e.tailscale?.tunnelUrl||"")}if(l.ok){let e=await l.json();U(e.keys||[])}}catch(e){console.log("Error loading tool data:",e)}finally{e&&p(!1)}})(),()=>{e=!1}},[]);let y=()=>r.filter(e=>!1!==e.isActive),C=(0,l.useCallback)((e,t,a)=>{f(s=>s[e]?.[t]===a?s:{...s,[e]:{...s[e],[t]:a}})},[]);return(0,s.jsxs)("div",{className:"mx-auto flex w-full max-w-5xl flex-col gap-4 px-1 sm:px-0",children:[(0,s.jsxs)(i(),{href:"/dashboard/cli-tools",className:"inline-flex items-center gap-1 text-sm text-text-muted hover:text-primary w-fit",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"arrow_back"}),"Back to CLI Tools"]}),(0,s.jsxs)("div",{className:"flex flex-col gap-1",children:[(0,s.jsx)("h1",{className:"text-xl font-semibold text-text-main sm:text-2xl",children:a.name}),(0,s.jsx)("p",{className:"text-sm text-text-muted",children:a.description})]}),h?(0,s.jsx)(n.Qv,{}):(()=>{let t,l,r,i=(t=y(),l=[],r=new Set,t.forEach(e=>{let t=c.Xg[e.provider]||e.provider;(0,c.KC)(e.provider).forEach(a=>{let s=`${t}/${a.id}`;r.has(s)||(r.add(s),l.push({value:s,label:`${t}/${a.id}`,provider:e.provider,alias:t,connectionName:e.name,modelId:a.id}))})}),l).length>0,n={tool:a,isExpanded:!0,onToggle:()=>{},baseUrl:j&&k?k:m&&u?u:window.location.origin,apiKeys:A,tunnelEnabled:j,tunnelPublicUrl:k,tailscaleEnabled:g,tailscaleUrl:S};switch(e){case"claude":return(0,s.jsx)(d.Tk,{...n,activeProviders:y(),modelMappings:b[e]||{},onModelMappingChange:(t,a)=>C(e,t,a),hasActiveProviders:i,cloudEnabled:m});case"codex":return(0,s.jsx)(d.Ah,{...n,activeProviders:y(),cloudEnabled:m});case"opencode":return(0,s.jsx)(d.qO,{...n,activeProviders:y(),cloudEnabled:m});case"cowork":return(0,s.jsx)(d.Q6,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m,cloudUrl:u,tunnelEnabled:j,tunnelPublicUrl:k,tailscaleEnabled:g,tailscaleUrl:S});case"droid":return(0,s.jsx)(d.ZM,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"openclaw":return(0,s.jsx)(d.yZ,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"hermes":return(0,s.jsx)(d.RF,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"copilot":return(0,s.jsx)(d.h1,{...n,activeProviders:y(),cloudEnabled:m});case"cline":return(0,s.jsx)(d.aG,{...n,activeProviders:y(),cloudEnabled:m});case"kilo":return(0,s.jsx)(d.c9,{...n,activeProviders:y(),cloudEnabled:m});case"deepseek-tui":return(0,s.jsx)(d.lF,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"jcode":return(0,s.jsx)(d.mW,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});default:return(0,s.jsx)(d.a7,{toolId:e,...n,activeProviders:y(),cloudEnabled:m,tunnelEnabled:j})}})()]})}}},e=>{e.O(0,[2574,3862,8500,4288,5772,1321,5497,4404,8441,3794,7358],()=>e(e.s=22843)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3554],{22843:(e,t,a)=>{Promise.resolve().then(a.bind(a,85309))},85309:(e,t,a)=>{"use strict";a.d(t,{default:()=>v});var s=a(95155),l=a(12115),r=a(98500),i=a.n(r),n=a(35497),o=a(3534),c=a(28777),d=a(38719);let u=a(41463).env.NEXT_PUBLIC_CLOUD_URL;function v({toolId:e,machineId:t}){let a=o.dM[e],[r,x]=(0,l.useState)([]),[h,p]=(0,l.useState)(!0),[b,f]=(0,l.useState)({}),[m,E]=(0,l.useState)(!1),[j,P]=(0,l.useState)(!1),[k,w]=(0,l.useState)(""),[g,N]=(0,l.useState)(!1),[S,_]=(0,l.useState)(""),[A,U]=(0,l.useState)([]);(0,l.useEffect)(()=>{let e=!0;return(async()=>{try{let[t,a,s,l]=await Promise.all([fetch("/api/providers"),fetch("/api/settings"),fetch("/api/tunnel/status"),fetch("/api/keys")]);if(!e)return;if(t.ok){let e=await t.json();x(e.connections||[])}if(a.ok){let e=await a.json();E(e.cloudEnabled||!1)}if(s.ok){let e=await s.json();P(!!(e.tunnel?.enabled||e.tunnel?.settingsEnabled)),w(e.tunnel?.publicUrl||""),N(!!(e.tailscale?.enabled||e.tailscale?.settingsEnabled)),_(e.tailscale?.tunnelUrl||"")}if(l.ok){let e=await l.json();U(e.keys||[])}}catch(e){console.log("Error loading tool data:",e)}finally{e&&p(!1)}})(),()=>{e=!1}},[]);let y=()=>r.filter(e=>!1!==e.isActive),C=(0,l.useCallback)((e,t,a)=>{f(s=>s[e]?.[t]===a?s:{...s,[e]:{...s[e],[t]:a}})},[]);return(0,s.jsxs)("div",{className:"mx-auto flex w-full max-w-5xl flex-col gap-4 px-1 sm:px-0",children:[(0,s.jsxs)(i(),{href:"/dashboard/cli-tools",className:"inline-flex items-center gap-1 text-sm text-text-muted hover:text-primary w-fit",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"arrow_back"}),"Back to CLI Tools"]}),(0,s.jsxs)("div",{className:"flex flex-col gap-1",children:[(0,s.jsx)("h1",{className:"text-xl font-semibold text-text-main sm:text-2xl",children:a.name}),(0,s.jsx)("p",{className:"text-sm text-text-muted",children:a.description})]}),h?(0,s.jsx)(n.Qv,{}):(()=>{let t,l,r,i=(t=y(),l=[],r=new Set,t.forEach(e=>{let t=c.Xg[e.provider]||e.provider;(0,c.KC)(e.provider).forEach(a=>{let s=`${t}/${a.id}`;r.has(s)||(r.add(s),l.push({value:s,label:`${t}/${a.id}`,provider:e.provider,alias:t,connectionName:e.name,modelId:a.id}))})}),l).length>0,n={tool:a,isExpanded:!0,onToggle:()=>{},baseUrl:j&&k?k:m&&u?u:window.location.origin,apiKeys:A,tunnelEnabled:j,tunnelPublicUrl:k,tailscaleEnabled:g,tailscaleUrl:S};switch(e){case"claude":return(0,s.jsx)(d.Tk,{...n,activeProviders:y(),modelMappings:b[e]||{},onModelMappingChange:(t,a)=>C(e,t,a),hasActiveProviders:i,cloudEnabled:m});case"codex":return(0,s.jsx)(d.Ah,{...n,activeProviders:y(),cloudEnabled:m});case"opencode":return(0,s.jsx)(d.qO,{...n,activeProviders:y(),cloudEnabled:m});case"cowork":return(0,s.jsx)(d.Q6,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m,cloudUrl:u,tunnelEnabled:j,tunnelPublicUrl:k,tailscaleEnabled:g,tailscaleUrl:S});case"droid":return(0,s.jsx)(d.ZM,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"openclaw":return(0,s.jsx)(d.yZ,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"hermes":return(0,s.jsx)(d.RF,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"copilot":return(0,s.jsx)(d.h1,{...n,activeProviders:y(),cloudEnabled:m});case"cline":return(0,s.jsx)(d.aG,{...n,activeProviders:y(),cloudEnabled:m});case"kilo":return(0,s.jsx)(d.c9,{...n,activeProviders:y(),cloudEnabled:m});case"deepseek-tui":return(0,s.jsx)(d.lF,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});case"jcode":return(0,s.jsx)(d.mW,{...n,activeProviders:y(),hasActiveProviders:i,cloudEnabled:m});default:return(0,s.jsx)(d.a7,{toolId:e,...n,activeProviders:y(),cloudEnabled:m,tunnelEnabled:j})}})()]})}}},e=>{e.O(0,[2574,3862,1051,5772,1321,5497,4404,8441,3794,7358],()=>e(e.s=22843)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2326],{4987:(e,s,l)=>{Promise.resolve().then(l.bind(l,53501))},53501:(e,s,l)=>{"use strict";l.d(s,{default:()=>m});var t=l(95155),a=l(12115),r=l(35497),i=l(3534),c=l(38719),n=l(98500),o=l.n(n),d=l(5772);function x({toolId:e,tool:s,status:l}){let a=l?l.installed?l.hasBluerouter?{label:"Connected",cls:"bg-green-500/10 text-green-600 dark:text-green-400"}:{label:"Not configured",cls:"bg-yellow-500/10 text-yellow-600 dark:text-yellow-400"}:{label:"Not installed",cls:"bg-red-500/10 text-red-600 dark:text-red-400"}:{label:"Unknown",cls:"bg-gray-500/10 text-gray-500"};return(0,t.jsx)(o(),{href:`/dashboard/cli-tools/${e}`,className:"block",children:(0,t.jsx)(r.Zp,{padding:"sm",className:"h-full overflow-hidden hover:border-primary/50 transition-colors cursor-pointer",children:(0,t.jsxs)("div",{className:"flex h-full flex-col gap-2",children:[(0,t.jsxs)("div",{className:"flex items-start gap-3",children:[(0,t.jsx)("div",{className:"size-8 flex items-center justify-center shrink-0",children:s.image?(0,t.jsx)(d.default,{src:s.image,alt:s.name,width:32,height:32,className:"size-8 object-contain rounded-lg",sizes:"32px",onError:e=>{e.target.style.display="none"}}):s.icon?(0,t.jsx)("span",{className:"material-symbols-outlined text-[28px]",style:{color:s.color},children:s.icon}):null}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("h3",{className:"font-medium text-sm truncate",children:s.name}),(0,t.jsx)("span",{className:`inline-block mt-0.5 px-1.5 py-0.5 text-[10px] font-medium rounded-full ${a.cls}`,children:a.label})]}),(0,t.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[18px] shrink-0",children:"chevron_right"})]}),(0,t.jsx)("p",{className:"text-xs text-text-muted line-clamp-2",children:s.description})]})})})}function m({machineId:e}){let[s,l]=(0,a.useState)(!0),[n,o]=(0,a.useState)({});if((0,a.useEffect)(()=>{let e=!0;return(async()=>{try{let s=await fetch("/api/cli-tools/all-statuses");s.ok&&e&&o(await s.json())}catch(e){console.log("Error fetching tool statuses:",e)}finally{e&&l(!1)}})(),()=>{e=!1}},[]),s)return(0,t.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",children:[(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{})]});let d=Object.entries(i.dM),g=Object.entries(i.wn);return(0,t.jsxs)("div",{className:"mx-auto flex w-full max-w-5xl flex-col gap-6 px-1 sm:px-0",children:[(0,t.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",children:d.map(([e,s])=>(0,t.jsx)(x,{toolId:e,tool:s,status:n[e]},e))}),(0,t.jsxs)("div",{className:"flex flex-col gap-3 sm:gap-4",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,t.jsx)("span",{className:"material-symbols-outlined text-[18px] text-primary",children:"security"}),(0,t.jsx)("h2",{className:"text-sm font-semibold text-text-main",children:"MITM Tools"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",children:g.map(([e,s])=>(0,t.jsx)(c.gY,{tool:s},e))})]})]})}}},e=>{e.O(0,[2574,3862,8500,4288,5772,1321,5497,4404,8441,3794,7358],()=>e(e.s=4987)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2326],{4987:(e,s,l)=>{Promise.resolve().then(l.bind(l,53501))},53501:(e,s,l)=>{"use strict";l.d(s,{default:()=>m});var t=l(95155),a=l(12115),r=l(35497),i=l(3534),c=l(38719),n=l(98500),o=l.n(n),d=l(5772);function x({toolId:e,tool:s,status:l}){let a=l?l.installed?l.hasBluerouter?{label:"Connected",cls:"bg-green-500/10 text-green-600 dark:text-green-400"}:{label:"Not configured",cls:"bg-yellow-500/10 text-yellow-600 dark:text-yellow-400"}:{label:"Not installed",cls:"bg-red-500/10 text-red-600 dark:text-red-400"}:{label:"Unknown",cls:"bg-gray-500/10 text-gray-500"};return(0,t.jsx)(o(),{href:`/dashboard/cli-tools/${e}`,className:"block",children:(0,t.jsx)(r.Zp,{padding:"sm",className:"h-full overflow-hidden hover:border-primary/50 transition-colors cursor-pointer",children:(0,t.jsxs)("div",{className:"flex h-full flex-col gap-2",children:[(0,t.jsxs)("div",{className:"flex items-start gap-3",children:[(0,t.jsx)("div",{className:"size-8 flex items-center justify-center shrink-0",children:s.image?(0,t.jsx)(d.default,{src:s.image,alt:s.name,width:32,height:32,className:"size-8 object-contain rounded-lg",sizes:"32px",onError:e=>{e.target.style.display="none"}}):s.icon?(0,t.jsx)("span",{className:"material-symbols-outlined text-[28px]",style:{color:s.color},children:s.icon}):null}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("h3",{className:"font-medium text-sm truncate",children:s.name}),(0,t.jsx)("span",{className:`inline-block mt-0.5 px-1.5 py-0.5 text-[10px] font-medium rounded-full ${a.cls}`,children:a.label})]}),(0,t.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[18px] shrink-0",children:"chevron_right"})]}),(0,t.jsx)("p",{className:"text-xs text-text-muted line-clamp-2",children:s.description})]})})})}function m({machineId:e}){let[s,l]=(0,a.useState)(!0),[n,o]=(0,a.useState)({});if((0,a.useEffect)(()=>{let e=!0;return(async()=>{try{let s=await fetch("/api/cli-tools/all-statuses");s.ok&&e&&o(await s.json())}catch(e){console.log("Error fetching tool statuses:",e)}finally{e&&l(!1)}})(),()=>{e=!1}},[]),s)return(0,t.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",children:[(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{}),(0,t.jsx)(r.Qv,{})]});let d=Object.entries(i.dM),g=Object.entries(i.wn);return(0,t.jsxs)("div",{className:"mx-auto flex w-full max-w-5xl flex-col gap-6 px-1 sm:px-0",children:[(0,t.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",children:d.map(([e,s])=>(0,t.jsx)(x,{toolId:e,tool:s,status:n[e]},e))}),(0,t.jsxs)("div",{className:"flex flex-col gap-3 sm:gap-4",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,t.jsx)("span",{className:"material-symbols-outlined text-[18px] text-primary",children:"security"}),(0,t.jsx)("h2",{className:"text-sm font-semibold text-text-main",children:"MITM Tools"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",children:g.map(([e,s])=>(0,t.jsx)(c.gY,{tool:s},e))})]})]})}}},e=>{e.O(0,[2574,3862,1051,5772,1321,5497,4404,8441,3794,7358],()=>e(e.s=4987)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3649],{20061:(e,t,a)=>{Promise.resolve().then(a.bind(a,47295))},47295:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>A});var l=a(95155),r=a(12115),n=a(44923),s=a(87256),o=a(39768),i=a(82639),d=a(35497),c=a(11059),m=a(28777),u=a(52679);let x=/^[a-zA-Z0-9_.\-]+$/,b=[{value:"global",label:"Global / current behavior",description:"Keep the existing behavior: every request advances the combo rotation globally."},{value:"client_ip",label:"Client IP",description:"Keep the same starting model for the same client IP until TTL expires."},{value:"client_session",label:"Client IP + chat session",description:"Best for chat tools. Keeps the same model for the same machine and chat session."}],p=[{value:"fallback",label:"Fallback priority",description:"Current behavior: try combo models in the order shown, then fallback on failure."},{value:"round-robin",label:"Round Robin",description:"Rotate which active model starts first. Sticky options below still apply."},{value:"least-latency",label:"Least latency",description:"Prefer the target with the best health/latency score. Useful for LAN Ollama."},{value:"p2c",label:"P2C",description:"Power of Two Choices: sample two healthy targets and pick the less busy one."}];function h(e={}){return Array.isArray(e.disabledModels)?[...new Set(e.disabledModels.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function g(e={}){let t=e.fallbackStrategy||"fallback";return{...e,fallbackStrategy:t,stickyScope:e.stickyScope||"global",stickyTtlMinutes:Number(e.stickyTtlMinutes||120),stickyFallbackToClientIp:!1!==e.stickyFallbackToClientIp,lanHealthEnabled:!1!==e.lanHealthEnabled,healthCheckPath:e.healthCheckPath||"/api/tags",healthCheckIntervalMs:Number(e.healthCheckIntervalMs||15e3),requiredTags:Array.isArray(e.requiredTags)?e.requiredTags:[],modelTagRules:e.modelTagRules||e.modelTags||e.tagRules||{},disabledModels:h(e)}}function f(e=[]){return Array.isArray(e)?e.join(", "):String(e||"")}function y(e=""){return String(e||"").split(/[\n,;]+/).map(e=>e.trim()).filter(Boolean)}function v(e={}){return e&&"object"==typeof e?Object.entries(e).map(([e,t])=>`${e}: ${Array.isArray(t)?t.join(", "):String(t||"")}`).join("\n"):""}function j(e){return String(e||"").trim()}function k(e){return"string"==typeof e?e:e&&"object"==typeof e&&(e.value||e.model||e.id)||""}function N(e={}){let t=j(e.provider);return j(e.providerSpecificData?.prefix)||j(e.prefix)||j((0,u.wG)(t))||t}function w(e={}){return j(e.email)||j(e.accountName)||j(e.displayName)||j(e.name)||j(e.providerSpecificData?.nodeName)||j(e.id)}function C(e){return e&&"object"==typeof e?j(e.connectionId||e.connection_id):""}function S(e){let t=k(e),a=C(e);return t?a?`${t}@@${a}`:t:""}function T(e){return"string"==typeof e?e:e&&"object"==typeof e?j(e.label)||j(e.displayName)||j(e.name)||k(e):""}function $(e){if(!e||"object"!=typeof e)return k(e);let t=k(e);return t?Object.fromEntries(Object.entries({model:t,connectionId:C(e)||void 0,label:T(e)||void 0,provider:j(e.provider)||void 0,accountName:j(e.accountName||e.account_name)||void 0,weight:Number(e.weight||0)>0?Number(e.weight):void 0}).filter(([,e])=>void 0!==e&&""!==e)):""}function E(e,t=!0){let a=$(e),l=S(a);return{value:l,enabled:t,target:a,label:T(a)||l,subtitle:function(e){if(!e||"object"!=typeof e)return"";let t=C(e),a=k(e);return t?`Pinned account • ${t}${a?` • ${a}`:""}`:""}(a)}}function M(e={}){return j(e.defaultModel)||j(e.providerSpecificData?.defaultModel)||j(e.model)||""}function O(e,t,a,l=""){let r=j(a);if(!r)return;let n=j(l)||r;t.has(r)||(t.add(r),e.push({value:r,label:n}))}function _(e={},t={}){let a=[],l=new Set,r=j(e.provider),n=[...new Set([N(e),j((0,u.wG)(r)),r].filter(Boolean))];for(let e of(0,m.KC)(r)||[])e?.type&&"llm"!==e.type||O(a,l,e.id,e.name||e.id);for(let[e,r]of Object.entries(t||{})){let t=j(r),s=n.find(e=>e&&t.startsWith(`${e}/`));if(!s)continue;let o=t.slice(s.length+1);O(a,l,o,e||o)}return O(a,l,M(e),"Default model"),a}function P(e={},t=[]){let a={...e},l=[...new Set((t||[]).map(e=>String(e||"").trim()).filter(Boolean))];return l.length>0?a.disabledModels=l:delete a.disabledModels,Object.keys(a).length?a:null}function A(){let[e,t]=(0,r.useState)([]),[a,n]=(0,r.useState)(!0),[s,o]=(0,r.useState)(!1),[i,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]),[b,p]=(0,r.useState)({}),[f,y]=(0,r.useState)(null),{copied:v,copy:j}=(0,c.C)();(0,r.useEffect)(()=>{k()},[]);let k=async()=>{try{let[e,a,l]=await Promise.all([fetch("/api/combos"),fetch("/api/providers"),fetch("/api/settings")]),r=await e.json(),n=await a.json(),s=l.ok?await l.json():{};e.ok&&t((r.combos||[]).filter(e=>!e.kind)),a.ok&&x(n.connections||[]),p(s.comboStrategies||{})}catch(e){console.log("Error fetching data:",e)}finally{n(!1)}},N=async e=>{await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStrategies:e})}),p(e)},w=async(e,t)=>{let a={...b},l=P(a[e]||{},t);l?a[e]=l:delete a[e],await N(a)},C=async e=>{let{disabledModels:t=[],...a}=e;try{let e=await fetch("/api/combos",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(e.ok)t.length>0&&await w(a.name,t),await k(),o(!1);else{let t=await e.json();alert(t.error||"Failed to create combo")}}catch(e){console.log("Error creating combo:",e)}},S=async(e,t)=>{let{disabledModels:a=[],...l}=t,r=i?.name;try{let t=await fetch(`/api/combos/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(t.ok){let e={...b};r&&r!==l.name&&e[r]&&(e[l.name]=e[r],delete e[r]);let t=P(e[l.name]||{},a);t?e[l.name]=t:delete e[l.name],await N(e),await k(),m(null)}else{let e=await t.json();alert(e.error||"Failed to update combo")}}catch(e){console.log("Error updating combo:",e)}},T=async a=>{let l=e.find(e=>e.id===a);y({title:"Delete Combo",message:"Delete this combo?",onConfirm:async()=>{y(null);try{if((await fetch(`/api/combos/${a}`,{method:"DELETE"})).ok){if(l?.name&&b[l.name]){let e={...b};delete e[l.name],await N(e)}t(e.filter(e=>e.id!==a))}}catch(e){console.log("Error deleting combo:",e)}}})},$=async(e,t)=>{try{let a={...b},l=function(e={}){let t={...e};return t.disabledModels=h(e),"fallback"===(t.fallbackStrategy||"fallback")&&delete t.fallbackStrategy,t.disabledModels.length||delete t.disabledModels,t.requiredTags?.length||delete t.requiredTags,t.modelTagRules&&0!==Object.keys(t.modelTagRules).length||delete t.modelTagRules,"/api/tags"===t.healthCheckPath&&delete t.healthCheckPath,15e3===Number(t.healthCheckIntervalMs)&&delete t.healthCheckIntervalMs,!0===t.lanHealthEnabled&&delete t.lanHealthEnabled,Object.keys(t).length?t:null}({...g(a[e]),...t});l?a[e]=l:delete a[e],await N(a)}catch(e){console.log("Error updating combo routing settings:",e)}};return a?(0,l.jsx)("div",{className:"space-y-6",children:[1,2,3].map(e=>(0,l.jsx)("div",{className:"h-40 animate-pulse rounded-2xl bg-surface"},e))}):(0,l.jsxs)("div",{className:"space-y-8",children:[(0,l.jsxs)("div",{className:"flex items-start justify-between gap-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h1",{className:"text-2xl font-semibold text-text-main",children:"Combos"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create model combos with fallback, round-robin, least-latency, P2C, and LAN Ollama health-aware routing."})]}),(0,l.jsxs)("button",{type:"button",onClick:()=>o(!0),className:"inline-flex items-center justify-center gap-2 rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Create Combo"]})]}),0===e.length?(0,l.jsxs)("div",{className:"rounded-2xl border border-dashed border-border p-10 text-center",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-4xl text-text-muted",children:"layers"}),(0,l.jsx)("h2",{className:"mt-3 text-lg font-semibold text-text-main",children:"No combos yet"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create model combos with fallback support."}),(0,l.jsx)("button",{type:"button",onClick:()=>o(!0),className:"mt-4 rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90",children:"Create Combo"})]}):(0,l.jsx)("div",{className:"grid gap-5 md:grid-cols-2 xl:grid-cols-3",children:e.map(e=>(0,l.jsx)(I,{combo:e,copied:v,onCopy:j,onEdit:()=>m(e),onDelete:()=>T(e.id),comboStrategy:b[e.name]||{},onUpdateComboStrategy:t=>$(e.name,t)},e.id))}),(0,l.jsx)(q,{isOpen:s,onClose:()=>o(!1),onSave:C,activeProviders:u}),(0,l.jsx)(q,{isOpen:!!i,combo:i,comboStrategy:i&&b[i.name]||{},onClose:()=>m(null),onSave:e=>S(i.id,e),activeProviders:u}),(0,l.jsx)(d.uo,{isOpen:!!f,onClose:()=>y(null),onConfirm:f?.onConfirm,title:f?.title||"Confirm",message:f?.message,variant:"danger"})]})}function I({combo:e,copied:t,onCopy:a,onEdit:n,onDelete:s,comboStrategy:o={},onUpdateComboStrategy:i}){let d=g(o||{}),c=d.fallbackStrategy||"fallback",m=p.find(e=>e.value===c)||p[0],u=d.stickyScope||"global",x=b.find(e=>e.value===u)||b[0],j=h(o),[N,w]=(0,r.useState)(f(d.requiredTags)),[C,$]=(0,r.useState)(v(d.modelTagRules));return(0,r.useEffect)(()=>{w(f(d.requiredTags)),$(v(d.modelTagRules))},[e.name,JSON.stringify(d.requiredTags||[]),JSON.stringify(d.modelTagRules||{})]),(0,l.jsxs)("div",{className:"rounded-2xl border border-border bg-background p-5 shadow-sm",children:[(0,l.jsxs)("div",{className:"mb-4 flex items-start justify-between gap-3",children:[(0,l.jsxs)("div",{className:"min-w-0",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-primary",children:"layers"}),(0,l.jsx)("h3",{className:"truncate text-lg font-semibold text-text-main",children:e.name})]}),(0,l.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[e.models.length," active model(s)",j.length>0?` • ${j.length} disabled`:""]})]}),(0,l.jsxs)("div",{className:"flex items-center gap-1",children:[(0,l.jsx)(R,{icon:t===`combo-${e.id}`?"check":"content_copy",title:"Copy combo name",onClick:()=>a(e.name,`combo-${e.id}`)}),(0,l.jsx)(R,{icon:"edit",title:"Edit",onClick:n}),(0,l.jsx)(R,{icon:"delete",title:"Delete",onClick:s,danger:!0})]})]}),(0,l.jsxs)("div",{className:"mb-4 flex flex-wrap gap-2",children:[0===e.models.length?(0,l.jsx)("span",{className:"rounded-lg border border-border px-3 py-1 text-xs text-text-muted",children:"No active models"}):e.models.slice(0,5).map(e=>(0,l.jsx)("span",{className:"rounded-lg border border-border bg-surface px-3 py-1 font-mono text-xs text-text-main",title:k(e),children:T(e)},S(e))),e.models.length>5&&(0,l.jsxs)("span",{className:"rounded-lg border border-border px-3 py-1 text-xs text-text-muted",children:["+",e.models.length-5," more"]}),j.length>0&&(0,l.jsxs)("span",{className:"rounded-lg border border-red-200 bg-red-50 px-3 py-1 text-xs font-medium text-red-600 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300",children:[j.length," disabled"]})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border bg-surface/50 p-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h4",{className:"font-semibold text-text-main",children:"Routing Strategy"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:m.description})]}),(0,l.jsx)("span",{className:"rounded-lg border border-primary/20 bg-primary/10 px-2 py-1 text-[11px] font-semibold text-primary",children:m.label})]}),(0,l.jsxs)("label",{className:"mb-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Strategy"}),(0,l.jsx)("select",{value:c,onChange:e=>i({fallbackStrategy:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-2 py-2 text-sm text-text-main outline-none focus:border-primary",children:p.map(e=>(0,l.jsx)("option",{value:e.value,children:e.label},e.value))})]}),("least-latency"===c||"p2c"===c)&&(0,l.jsxs)("div",{className:"mb-3 rounded-xl border border-emerald-500/20 bg-emerald-500/5 p-3",children:[(0,l.jsxs)("div",{className:"mb-2 flex items-center gap-2 text-sm font-semibold text-emerald-600 dark:text-emerald-300",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"monitor_heart"}),"LAN health aware routing"]}),(0,l.jsxs)("label",{className:"mb-3 flex items-start gap-2 text-xs text-text-muted",children:[(0,l.jsx)("input",{type:"checkbox",checked:!1!==d.lanHealthEnabled,onChange:e=>i({lanHealthEnabled:e.target.checked}),className:"mt-0.5 h-3.5 w-3.5 accent-primary"}),"Use active health state and circuit breaker data when ranking combo targets."]}),(0,l.jsxs)("div",{className:"grid gap-2 sm:grid-cols-2",children:[(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Health path"}),(0,l.jsx)("input",{value:d.healthCheckPath||"/api/tags",onChange:e=>i({healthCheckPath:e.target.value||"/api/tags"}),placeholder:"/api/tags",className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"})]}),(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Check interval ms"}),(0,l.jsx)("input",{type:"number",min:"1000",value:d.healthCheckIntervalMs||15e3,onChange:e=>i({healthCheckIntervalMs:Number(e.target.value)||15e3}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary"})]})]}),(0,l.jsxs)("label",{className:"mt-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Required endpoint tags"}),(0,l.jsx)("input",{value:N,onChange:e=>w(e.target.value),onBlur:()=>i({requiredTags:y(N)}),onKeyDown:e=>"Enter"===e.key&&e.currentTarget.blur(),placeholder:"gpu, vram:8gb",className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"Optional. Every routed endpoint must contain these tags."})]}),(0,l.jsxs)("label",{className:"mt-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Model tag rules"}),(0,l.jsx)("textarea",{value:C,onChange:e=>$(e.target.value),onBlur:()=>i({modelTagRules:function(e=""){let t={};for(let a of String(e||"").split(/\n+/)){let e=a.trim();if(!e)continue;let l=e.indexOf(":");if(-1===l)continue;let r=e.slice(0,l).trim(),n=y(e.slice(l+1));r&&n.length&&(t[r]=n)}return t}(C)}),placeholder:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b",rows:3,className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"One rule per line: model: tag1, tag2. Large models can be forced to GPU/VRAM endpoints."})]})]}),"round-robin"===c&&(0,l.jsxs)("div",{className:"mt-4 rounded-xl border border-primary/15 bg-background p-3",children:[(0,l.jsxs)("div",{className:"mb-3 flex items-center gap-2 text-sm font-semibold text-primary",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"sticky_note_2"}),"Sticky Round Robin"]}),(0,l.jsx)("p",{className:"mb-3 text-xs text-text-muted",children:"Optional sticky behavior for this combo only. Leave it on Global to keep the current behavior."}),(0,l.jsxs)("label",{className:"mb-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Sticky mode"}),(0,l.jsx)("select",{value:u,onChange:e=>i({stickyScope:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary",children:b.map(e=>(0,l.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:x.description})]}),(0,l.jsxs)("label",{className:"mb-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Sticky TTL minutes"}),(0,l.jsx)("input",{type:"number",min:"1",value:d.stickyTtlMinutes||120,onChange:e=>i({stickyTtlMinutes:Number(e.target.value)||120}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary"}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"Sticky assignments are in-memory and expire after this time. 120 minutes is recommended."})]}),(0,l.jsxs)("label",{className:"flex items-start gap-2 text-xs text-text-muted",children:[(0,l.jsx)("input",{type:"checkbox",checked:!1!==d.stickyFallbackToClientIp,onChange:e=>i({stickyFallbackToClientIp:e.target.checked}),className:"mt-0.5 h-3.5 w-3.5 accent-primary"}),"If chat session id is missing, fall back to Client IP instead of global rotation."]})]})]})]})}function R({icon:e,title:t,onClick:a,danger:r=!1}){return(0,l.jsx)("button",{type:"button",onClick:e=>{e.stopPropagation(),a?.()},className:`rounded-lg p-2 transition ${r?"text-red-500 hover:bg-red-500/10":"text-text-muted hover:bg-background hover:text-primary"}`,title:t,"aria-label":t,children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:e})})}function D({id:e,index:t,model:a,subtitle:n="",enabled:i,isFirst:d,isLast:c,onEdit:m,onMoveUp:u,onMoveDown:x,onRemove:b,onToggleEnabled:p}){let{attributes:h,listeners:g,setNodeRef:f,transform:y,isDragging:v}=(0,s.gl)({id:e}),j={transform:o.Ks.Transform.toString(y),opacity:v?.4:1,zIndex:v?999:void 0},[k,N]=(0,r.useState)(!1),[w,C]=(0,r.useState)(a);(0,r.useEffect)(()=>{C(a)},[a]);let S=()=>{let e=w.trim();e&&e!==a?m(e):C(a),N(!1)};return(0,l.jsxs)("div",{ref:f,style:j,className:`flex items-center gap-3 rounded-xl border p-3 transition ${i?"border-border bg-background":"border-red-200 bg-red-50/70 opacity-75 dark:border-red-500/30 dark:bg-red-500/10"}`,children:[(0,l.jsx)("button",{type:"button",className:"cursor-grab text-text-muted active:cursor-grabbing",...h,...g,title:"Drag to reorder",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"drag_indicator"})}),(0,l.jsx)("span",{className:`flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-xs font-semibold ${i?"bg-primary/10 text-primary":"bg-red-100 text-red-600 dark:bg-red-500/20 dark:text-red-300"}`,children:t+1}),k?(0,l.jsx)("input",{autoFocus:!0,value:w,onChange:e=>C(e.target.value),onBlur:S,onKeyDown:e=>{"Enter"===e.key&&S(),"Escape"===e.key&&(C(a),N(!1))},className:"min-w-0 flex-1 rounded border border-primary/40 bg-background px-2 py-1 font-mono text-xs text-text-main outline-none"}):(0,l.jsxs)("button",{type:"button",onClick:()=>N(!0),className:"min-w-0 flex-1 text-left",title:"Click to edit model",children:[(0,l.jsx)("span",{className:`block truncate font-mono text-xs ${i?"text-text-main":"text-text-muted line-through"}`,children:a}),n?(0,l.jsx)("span",{className:"mt-0.5 block truncate text-[11px] text-text-muted",children:n}):null]}),(0,l.jsx)("button",{type:"button",onClick:p,className:`rounded-lg p-1.5 transition ${i?"text-green-600 hover:bg-green-500/10":"text-red-500 hover:bg-red-500/10"}`,title:i?"Disable this model in combo":"Enable this model in combo",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:i?"toggle_on":"toggle_off"})}),(0,l.jsx)("button",{type:"button",onClick:u,disabled:d,className:"rounded-lg p-1.5 text-text-muted transition hover:bg-surface disabled:opacity-30",title:"Move up",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"arrow_upward"})}),(0,l.jsx)("button",{type:"button",onClick:x,disabled:c,className:"rounded-lg p-1.5 text-text-muted transition hover:bg-surface disabled:opacity-30",title:"Move down",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"arrow_downward"})}),(0,l.jsx)("button",{type:"button",onClick:b,className:"rounded-lg p-1.5 text-red-500 transition hover:bg-red-500/10",title:"Remove",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"close"})})]})}function q({isOpen:e,combo:t,comboStrategy:a={},onClose:o,onSave:c,activeProviders:m,kindFilter:b=null}){let[p,g]=(0,r.useState)(t?.name||""),[f,y]=(0,r.useState)([]),[v,k]=(0,r.useState)(!1),[C,T]=(0,r.useState)(!1),[O,P]=(0,r.useState)(""),[A,I]=(0,r.useState)({}),[R,F]=(0,r.useState)(""),[B,L]=(0,r.useState)(""),H=a||{},z=(0,n.FR)((0,n.MS)(n.AN,{activationConstraint:{distance:5}}),(0,n.MS)(n.uN,{coordinateGetter:s.JR}));(0,r.useEffect)(()=>{e&&(g(t?.name||""),y(function(e,t={}){let a=(e?.models||[]).map(e=>E(e,!0)).filter(e=>e.value),l=new Set(a.map(e=>e.value));return[...a,...h(t).filter(e=>!l.has(e)).map(e=>E(e,!1)).filter(e=>e.value)]}(t,H)),P(""),F(""),L(""))},[e,t?.id,t?.name]),(0,r.useEffect)(()=>{e&&G()},[e]);let G=async()=>{try{let e=await fetch("/api/models/alias");if(!e.ok)return;let t=await e.json();I(t.aliases||{})}catch(e){console.error("Error fetching modal data:",e)}},K=f.map((e,t)=>({uid:`item-${t}-${e.value}`,row:e})),J=f.map(e=>e.value),U=f.filter(e=>e.enabled).length,V=f.filter(e=>!e.enabled).length,W=(m||[]).filter(e=>e?.isActive!==!1),Z=W.find(e=>e.id===R)||null,Q=Z?_(Z,A):[],X=Q[0]?.value||(Z?M(Z):""),Y=e=>e.trim()?x.test(e)?(P(""),!0):(P("Only letters, numbers, -, _ and . allowed"),!1):(P("Name is required"),!1),ee=async()=>{if(!Y(p))return;let{models:e,disabledModels:t}=function(e=[]){let t=[],a=new Set;for(let l of e){let e=j(l?.value||S(l?.target));!e||a.has(e)||(a.add(e),t.push({...l,value:e,enabled:l?.enabled!==!1,target:$(l?.target||l?.value)}))}return{models:t.filter(e=>e.enabled).map(e=>e.target).filter(Boolean),disabledModels:t.filter(e=>!e.enabled).map(e=>e.value)}}(f);T(!0),await c({name:p.trim(),models:e,disabledModels:t}),T(!1)};if(!e)return null;let et=!!t;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("div",{className:"fixed inset-0 z-[100] flex items-center justify-center bg-black/45 p-4 backdrop-blur-[1px]",children:(0,l.jsxs)("div",{className:"flex max-h-[88vh] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-border bg-white shadow-2xl dark:bg-zinc-950",children:[(0,l.jsxs)("div",{className:"flex items-start justify-between border-b border-border px-5 py-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h2",{className:"text-xl font-semibold text-text-main",children:et?"Edit Combo":"Create Combo"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Choose models, disable temporarily, and order active fallback priority."})]}),(0,l.jsx)("button",{type:"button",onClick:o,className:"rounded-lg p-1 text-text-muted transition hover:bg-surface hover:text-text-main",children:(0,l.jsx)("span",{className:"material-symbols-outlined",children:"close"})})]}),(0,l.jsxs)("div",{className:"min-h-0 flex-1 space-y-5 overflow-y-auto bg-white px-5 py-4 dark:bg-zinc-950",children:[(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-2 block text-sm font-semibold text-text-main",children:"Name"}),(0,l.jsx)("input",{value:p,onChange:e=>{let t=e.target.value;g(t),t?Y(t):P("")},placeholder:"premium-coding",className:`w-full rounded-xl border bg-white px-4 py-2.5 text-text-main outline-none transition focus:border-primary dark:bg-zinc-900 ${O?"border-red-400":"border-border"}`}),(0,l.jsx)("span",{className:`mt-1 block text-xs ${O?"text-red-500":"text-text-muted"}`,children:O||"Only letters, numbers, -, _ and . allowed"})]}),(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"mb-3 flex items-center justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Models"}),(0,l.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:[U," active",V>0?`, ${V} disabled`:"",". Disabled models stay in this combo but are not routed."]})]}),(0,l.jsxs)("button",{type:"button",onClick:()=>k(!0),className:"inline-flex items-center gap-1 rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-primary hover:border-primary/50",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Add Model"]})]}),(0,l.jsxs)("div",{className:"mb-4 rounded-xl border border-primary/15 bg-primary/5 p-3",children:[(0,l.jsxs)("div",{className:"mb-2 flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-primary",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"account_tree"}),"Add Provider Account Target"]}),(0,l.jsx)("p",{className:"mb-3 text-xs text-text-muted",children:"Pin this combo step to a specific provider account. Models come from the provider; the account only pins routing/load balancing."}),(0,l.jsxs)("div",{className:"grid gap-2 md:grid-cols-[minmax(0,1.5fr)_minmax(0,1fr)_auto]",children:[(0,l.jsxs)("select",{value:R,onChange:e=>{let t=e.target.value,a=W.find(e=>e.id===t),l=a?_(a,A):[];F(t),L(l[0]?.value||M(a||{})||"")},className:"min-w-0 rounded-lg border border-border bg-background px-3 py-2 text-xs text-text-main outline-none focus:border-primary",children:[(0,l.jsx)("option",{value:"",children:"Select provider account"}),W.map(e=>{let t=N(e),a=w(e),r=a&&a!==t?`${t} / ${a}`:t;return(0,l.jsx)("option",{value:e.id,children:r},e.id)})]}),(0,l.jsxs)("select",{value:B,onChange:e=>L(e.target.value),disabled:!R||0===Q.length,className:"min-w-0 rounded-lg border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary disabled:cursor-not-allowed disabled:opacity-60",children:[(0,l.jsx)("option",{value:"",children:R?Q.length>0?"Select model":"No provider models found":"Select account first"}),Q.map(e=>(0,l.jsx)("option",{value:e.value,children:e.label},`${e.value}-${e.label}`))]}),(0,l.jsxs)("button",{type:"button",onClick:()=>{if(!Z)return;let e=function(e,t){let a=N(e),l=function(e={}){let t=j(e.provider),a=N(e);return(0,u.mq)(t)||(0,u.gb)(t)?a||t:t||a}(e),r=w(e),n=j(t||M(e));if(!a||!e?.id||!n)return null;let s=n.includes("/"),o=s?n:`${a}/${n}`,i=s&&n.startsWith(`${a}/`)?n.slice(a.length+1):n,d=r&&r!==l?`${l}/${r}/${i}`:`${l}/${i}`;return{model:o,connectionId:e.id,provider:l||a,accountName:r||void 0,label:d}}(Z,B||X);if(!e)return void alert("Select a provider account and model for this pinned target.");let t=E(e,!0);y(e=>{let a=e.findIndex(e=>e.value===t.value);if(-1!==a){let l=[...e];return l[a]={...l[a],...t,enabled:!0},l}return[...e,t]}),L("")},disabled:!R||!B,className:"inline-flex items-center justify-center gap-1 rounded-lg bg-primary px-3 py-2 text-xs font-semibold text-white disabled:opacity-50",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add_link"}),"Add Account"]})]})]}),0===f.length?(0,l.jsxs)("div",{className:"rounded-xl border border-dashed border-border p-8 text-center text-text-muted",children:[(0,l.jsx)("span",{className:"material-symbols-outlined",children:"layers"}),(0,l.jsx)("p",{className:"mt-2 text-sm",children:"No models added yet"})]}):(0,l.jsx)(n.Mp,{sensors:z,collisionDetection:n.fp,modifiers:[i.FN,i.gj],onDragEnd:e=>{let{active:t,over:a}=e;if(a&&t.id!==a.id){let e=K.findIndex(e=>e.uid===t.id),l=K.findIndex(e=>e.uid===a.id);-1!==e&&-1!==l&&y(t=>(0,s.be)(t,e,l))}},children:(0,l.jsx)(s.gB,{items:K.map(e=>e.uid),strategy:s._G,children:(0,l.jsx)("div",{className:"space-y-3",children:K.map(({uid:e,row:t},a)=>(0,l.jsx)(D,{id:e,index:a,model:t.label||t.value,subtitle:t.subtitle,enabled:t.enabled,isFirst:0===a,isLast:a===f.length-1,onEdit:e=>{let t=e.trim();if(!t)return;let l=[...f],r=l[a];if(r?.target&&"object"==typeof r.target){let e=$({...r.target,model:t});l[a]=E(e,!1!==r.enabled)}else l[a]=E(t,r?.enabled!==!1);y(l)},onMoveUp:()=>{if(0===a)return;let e=[...f];[e[a-1],e[a]]=[e[a],e[a-1]],y(e)},onMoveDown:()=>{if(a===f.length-1)return;let e=[...f];[e[a],e[a+1]]=[e[a+1],e[a]],y(e)},onToggleEnabled:()=>{let e=[...f];e[a]={...e[a],enabled:!e[a].enabled},y(e)},onRemove:()=>y(f.filter((e,t)=>t!==a))},e))})})})]})]}),(0,l.jsxs)("div",{className:"flex justify-end gap-3 border-t border-border bg-white px-5 py-4 dark:bg-zinc-950",children:[(0,l.jsx)("button",{type:"button",onClick:o,className:"rounded-xl border border-border px-4 py-2 text-sm font-medium text-text-main hover:bg-surface",children:"Cancel"}),(0,l.jsx)("button",{type:"button",onClick:ee,disabled:C,className:"rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90 disabled:opacity-50",children:C?"Saving...":et?"Save":"Create"})]})]})}),(0,l.jsx)(d.rq,{isOpen:v,onClose:()=>k(!1),onSelect:e=>{let t=e.value;y(e=>{let a=e.findIndex(e=>e.value===t);if(-1!==a){let t=[...e];return t[a]={...t[a],enabled:!0},t}return[...e,E(t,!0)]})},onDeselect:e=>{y(t=>t.filter(t=>t.value!==e.value))},activeProviders:m,modelAliases:A,title:"Add Model to Combo",kindFilter:b,addedModelValues:J,closeOnSelect:!1})]})}}},e=>{e.O(0,[2574,3862,8500,4288,7055,1321,5497,8441,3794,7358],()=>e(e.s=20061)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3649],{20061:(e,t,a)=>{Promise.resolve().then(a.bind(a,47295))},47295:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>A});var l=a(95155),r=a(12115),n=a(44923),s=a(87256),o=a(39768),i=a(82639),d=a(35497),c=a(11059),m=a(28777),u=a(52679);let x=/^[a-zA-Z0-9_.\-]+$/,b=[{value:"global",label:"Global / current behavior",description:"Keep the existing behavior: every request advances the combo rotation globally."},{value:"client_ip",label:"Client IP",description:"Keep the same starting model for the same client IP until TTL expires."},{value:"client_session",label:"Client IP + chat session",description:"Best for chat tools. Keeps the same model for the same machine and chat session."}],p=[{value:"fallback",label:"Fallback priority",description:"Current behavior: try combo models in the order shown, then fallback on failure."},{value:"round-robin",label:"Round Robin",description:"Rotate which active model starts first. Sticky options below still apply."},{value:"least-latency",label:"Least latency",description:"Prefer the target with the best health/latency score. Useful for LAN Ollama."},{value:"p2c",label:"P2C",description:"Power of Two Choices: sample two healthy targets and pick the less busy one."}];function h(e={}){return Array.isArray(e.disabledModels)?[...new Set(e.disabledModels.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function g(e={}){let t=e.fallbackStrategy||"fallback";return{...e,fallbackStrategy:t,stickyScope:e.stickyScope||"global",stickyTtlMinutes:Number(e.stickyTtlMinutes||120),stickyFallbackToClientIp:!1!==e.stickyFallbackToClientIp,lanHealthEnabled:!1!==e.lanHealthEnabled,healthCheckPath:e.healthCheckPath||"/api/tags",healthCheckIntervalMs:Number(e.healthCheckIntervalMs||15e3),requiredTags:Array.isArray(e.requiredTags)?e.requiredTags:[],modelTagRules:e.modelTagRules||e.modelTags||e.tagRules||{},disabledModels:h(e)}}function f(e=[]){return Array.isArray(e)?e.join(", "):String(e||"")}function y(e=""){return String(e||"").split(/[\n,;]+/).map(e=>e.trim()).filter(Boolean)}function v(e={}){return e&&"object"==typeof e?Object.entries(e).map(([e,t])=>`${e}: ${Array.isArray(t)?t.join(", "):String(t||"")}`).join("\n"):""}function j(e){return String(e||"").trim()}function k(e){return"string"==typeof e?e:e&&"object"==typeof e&&(e.value||e.model||e.id)||""}function N(e={}){let t=j(e.provider);return j(e.providerSpecificData?.prefix)||j(e.prefix)||j((0,u.wG)(t))||t}function w(e={}){return j(e.email)||j(e.accountName)||j(e.displayName)||j(e.name)||j(e.providerSpecificData?.nodeName)||j(e.id)}function C(e){return e&&"object"==typeof e?j(e.connectionId||e.connection_id):""}function S(e){let t=k(e),a=C(e);return t?a?`${t}@@${a}`:t:""}function T(e){return"string"==typeof e?e:e&&"object"==typeof e?j(e.label)||j(e.displayName)||j(e.name)||k(e):""}function $(e){if(!e||"object"!=typeof e)return k(e);let t=k(e);return t?Object.fromEntries(Object.entries({model:t,connectionId:C(e)||void 0,label:T(e)||void 0,provider:j(e.provider)||void 0,accountName:j(e.accountName||e.account_name)||void 0,weight:Number(e.weight||0)>0?Number(e.weight):void 0}).filter(([,e])=>void 0!==e&&""!==e)):""}function E(e,t=!0){let a=$(e),l=S(a);return{value:l,enabled:t,target:a,label:T(a)||l,subtitle:function(e){if(!e||"object"!=typeof e)return"";let t=C(e),a=k(e);return t?`Pinned account • ${t}${a?` • ${a}`:""}`:""}(a)}}function M(e={}){return j(e.defaultModel)||j(e.providerSpecificData?.defaultModel)||j(e.model)||""}function O(e,t,a,l=""){let r=j(a);if(!r)return;let n=j(l)||r;t.has(r)||(t.add(r),e.push({value:r,label:n}))}function _(e={},t={}){let a=[],l=new Set,r=j(e.provider),n=[...new Set([N(e),j((0,u.wG)(r)),r].filter(Boolean))];for(let e of(0,m.KC)(r)||[])e?.type&&"llm"!==e.type||O(a,l,e.id,e.name||e.id);for(let[e,r]of Object.entries(t||{})){let t=j(r),s=n.find(e=>e&&t.startsWith(`${e}/`));if(!s)continue;let o=t.slice(s.length+1);O(a,l,o,e||o)}return O(a,l,M(e),"Default model"),a}function P(e={},t=[]){let a={...e},l=[...new Set((t||[]).map(e=>String(e||"").trim()).filter(Boolean))];return l.length>0?a.disabledModels=l:delete a.disabledModels,Object.keys(a).length?a:null}function A(){let[e,t]=(0,r.useState)([]),[a,n]=(0,r.useState)(!0),[s,o]=(0,r.useState)(!1),[i,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]),[b,p]=(0,r.useState)({}),[f,y]=(0,r.useState)(null),{copied:v,copy:j}=(0,c.C)();(0,r.useEffect)(()=>{k()},[]);let k=async()=>{try{let[e,a,l]=await Promise.all([fetch("/api/combos"),fetch("/api/providers"),fetch("/api/settings")]),r=await e.json(),n=await a.json(),s=l.ok?await l.json():{};e.ok&&t((r.combos||[]).filter(e=>!e.kind)),a.ok&&x(n.connections||[]),p(s.comboStrategies||{})}catch(e){console.log("Error fetching data:",e)}finally{n(!1)}},N=async e=>{await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStrategies:e})}),p(e)},w=async(e,t)=>{let a={...b},l=P(a[e]||{},t);l?a[e]=l:delete a[e],await N(a)},C=async e=>{let{disabledModels:t=[],...a}=e;try{let e=await fetch("/api/combos",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(e.ok)t.length>0&&await w(a.name,t),await k(),o(!1);else{let t=await e.json();alert(t.error||"Failed to create combo")}}catch(e){console.log("Error creating combo:",e)}},S=async(e,t)=>{let{disabledModels:a=[],...l}=t,r=i?.name;try{let t=await fetch(`/api/combos/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(t.ok){let e={...b};r&&r!==l.name&&e[r]&&(e[l.name]=e[r],delete e[r]);let t=P(e[l.name]||{},a);t?e[l.name]=t:delete e[l.name],await N(e),await k(),m(null)}else{let e=await t.json();alert(e.error||"Failed to update combo")}}catch(e){console.log("Error updating combo:",e)}},T=async a=>{let l=e.find(e=>e.id===a);y({title:"Delete Combo",message:"Delete this combo?",onConfirm:async()=>{y(null);try{if((await fetch(`/api/combos/${a}`,{method:"DELETE"})).ok){if(l?.name&&b[l.name]){let e={...b};delete e[l.name],await N(e)}t(e.filter(e=>e.id!==a))}}catch(e){console.log("Error deleting combo:",e)}}})},$=async(e,t)=>{try{let a={...b},l=function(e={}){let t={...e};return t.disabledModels=h(e),"fallback"===(t.fallbackStrategy||"fallback")&&delete t.fallbackStrategy,t.disabledModels.length||delete t.disabledModels,t.requiredTags?.length||delete t.requiredTags,t.modelTagRules&&0!==Object.keys(t.modelTagRules).length||delete t.modelTagRules,"/api/tags"===t.healthCheckPath&&delete t.healthCheckPath,15e3===Number(t.healthCheckIntervalMs)&&delete t.healthCheckIntervalMs,!0===t.lanHealthEnabled&&delete t.lanHealthEnabled,Object.keys(t).length?t:null}({...g(a[e]),...t});l?a[e]=l:delete a[e],await N(a)}catch(e){console.log("Error updating combo routing settings:",e)}};return a?(0,l.jsx)("div",{className:"space-y-6",children:[1,2,3].map(e=>(0,l.jsx)("div",{className:"h-40 animate-pulse rounded-2xl bg-surface"},e))}):(0,l.jsxs)("div",{className:"space-y-8",children:[(0,l.jsxs)("div",{className:"flex items-start justify-between gap-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h1",{className:"text-2xl font-semibold text-text-main",children:"Combos"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create model combos with fallback, round-robin, least-latency, P2C, and LAN Ollama health-aware routing."})]}),(0,l.jsxs)("button",{type:"button",onClick:()=>o(!0),className:"inline-flex items-center justify-center gap-2 rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Create Combo"]})]}),0===e.length?(0,l.jsxs)("div",{className:"rounded-2xl border border-dashed border-border p-10 text-center",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-4xl text-text-muted",children:"layers"}),(0,l.jsx)("h2",{className:"mt-3 text-lg font-semibold text-text-main",children:"No combos yet"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create model combos with fallback support."}),(0,l.jsx)("button",{type:"button",onClick:()=>o(!0),className:"mt-4 rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90",children:"Create Combo"})]}):(0,l.jsx)("div",{className:"grid gap-5 md:grid-cols-2 xl:grid-cols-3",children:e.map(e=>(0,l.jsx)(I,{combo:e,copied:v,onCopy:j,onEdit:()=>m(e),onDelete:()=>T(e.id),comboStrategy:b[e.name]||{},onUpdateComboStrategy:t=>$(e.name,t)},e.id))}),(0,l.jsx)(q,{isOpen:s,onClose:()=>o(!1),onSave:C,activeProviders:u}),(0,l.jsx)(q,{isOpen:!!i,combo:i,comboStrategy:i&&b[i.name]||{},onClose:()=>m(null),onSave:e=>S(i.id,e),activeProviders:u}),(0,l.jsx)(d.uo,{isOpen:!!f,onClose:()=>y(null),onConfirm:f?.onConfirm,title:f?.title||"Confirm",message:f?.message,variant:"danger"})]})}function I({combo:e,copied:t,onCopy:a,onEdit:n,onDelete:s,comboStrategy:o={},onUpdateComboStrategy:i}){let d=g(o||{}),c=d.fallbackStrategy||"fallback",m=p.find(e=>e.value===c)||p[0],u=d.stickyScope||"global",x=b.find(e=>e.value===u)||b[0],j=h(o),[N,w]=(0,r.useState)(f(d.requiredTags)),[C,$]=(0,r.useState)(v(d.modelTagRules));return(0,r.useEffect)(()=>{w(f(d.requiredTags)),$(v(d.modelTagRules))},[e.name,JSON.stringify(d.requiredTags||[]),JSON.stringify(d.modelTagRules||{})]),(0,l.jsxs)("div",{className:"rounded-2xl border border-border bg-background p-5 shadow-sm",children:[(0,l.jsxs)("div",{className:"mb-4 flex items-start justify-between gap-3",children:[(0,l.jsxs)("div",{className:"min-w-0",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-primary",children:"layers"}),(0,l.jsx)("h3",{className:"truncate text-lg font-semibold text-text-main",children:e.name})]}),(0,l.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[e.models.length," active model(s)",j.length>0?` • ${j.length} disabled`:""]})]}),(0,l.jsxs)("div",{className:"flex items-center gap-1",children:[(0,l.jsx)(R,{icon:t===`combo-${e.id}`?"check":"content_copy",title:"Copy combo name",onClick:()=>a(e.name,`combo-${e.id}`)}),(0,l.jsx)(R,{icon:"edit",title:"Edit",onClick:n}),(0,l.jsx)(R,{icon:"delete",title:"Delete",onClick:s,danger:!0})]})]}),(0,l.jsxs)("div",{className:"mb-4 flex flex-wrap gap-2",children:[0===e.models.length?(0,l.jsx)("span",{className:"rounded-lg border border-border px-3 py-1 text-xs text-text-muted",children:"No active models"}):e.models.slice(0,5).map(e=>(0,l.jsx)("span",{className:"rounded-lg border border-border bg-surface px-3 py-1 font-mono text-xs text-text-main",title:k(e),children:T(e)},S(e))),e.models.length>5&&(0,l.jsxs)("span",{className:"rounded-lg border border-border px-3 py-1 text-xs text-text-muted",children:["+",e.models.length-5," more"]}),j.length>0&&(0,l.jsxs)("span",{className:"rounded-lg border border-red-200 bg-red-50 px-3 py-1 text-xs font-medium text-red-600 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300",children:[j.length," disabled"]})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border bg-surface/50 p-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h4",{className:"font-semibold text-text-main",children:"Routing Strategy"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:m.description})]}),(0,l.jsx)("span",{className:"rounded-lg border border-primary/20 bg-primary/10 px-2 py-1 text-[11px] font-semibold text-primary",children:m.label})]}),(0,l.jsxs)("label",{className:"mb-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Strategy"}),(0,l.jsx)("select",{value:c,onChange:e=>i({fallbackStrategy:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-2 py-2 text-sm text-text-main outline-none focus:border-primary",children:p.map(e=>(0,l.jsx)("option",{value:e.value,children:e.label},e.value))})]}),("least-latency"===c||"p2c"===c)&&(0,l.jsxs)("div",{className:"mb-3 rounded-xl border border-emerald-500/20 bg-emerald-500/5 p-3",children:[(0,l.jsxs)("div",{className:"mb-2 flex items-center gap-2 text-sm font-semibold text-emerald-600 dark:text-emerald-300",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"monitor_heart"}),"LAN health aware routing"]}),(0,l.jsxs)("label",{className:"mb-3 flex items-start gap-2 text-xs text-text-muted",children:[(0,l.jsx)("input",{type:"checkbox",checked:!1!==d.lanHealthEnabled,onChange:e=>i({lanHealthEnabled:e.target.checked}),className:"mt-0.5 h-3.5 w-3.5 accent-primary"}),"Use active health state and circuit breaker data when ranking combo targets."]}),(0,l.jsxs)("div",{className:"grid gap-2 sm:grid-cols-2",children:[(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Health path"}),(0,l.jsx)("input",{value:d.healthCheckPath||"/api/tags",onChange:e=>i({healthCheckPath:e.target.value||"/api/tags"}),placeholder:"/api/tags",className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"})]}),(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Check interval ms"}),(0,l.jsx)("input",{type:"number",min:"1000",value:d.healthCheckIntervalMs||15e3,onChange:e=>i({healthCheckIntervalMs:Number(e.target.value)||15e3}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary"})]})]}),(0,l.jsxs)("label",{className:"mt-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Required endpoint tags"}),(0,l.jsx)("input",{value:N,onChange:e=>w(e.target.value),onBlur:()=>i({requiredTags:y(N)}),onKeyDown:e=>"Enter"===e.key&&e.currentTarget.blur(),placeholder:"gpu, vram:8gb",className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"Optional. Every routed endpoint must contain these tags."})]}),(0,l.jsxs)("label",{className:"mt-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Model tag rules"}),(0,l.jsx)("textarea",{value:C,onChange:e=>$(e.target.value),onBlur:()=>i({modelTagRules:function(e=""){let t={};for(let a of String(e||"").split(/\n+/)){let e=a.trim();if(!e)continue;let l=e.indexOf(":");if(-1===l)continue;let r=e.slice(0,l).trim(),n=y(e.slice(l+1));r&&n.length&&(t[r]=n)}return t}(C)}),placeholder:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b",rows:3,className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"One rule per line: model: tag1, tag2. Large models can be forced to GPU/VRAM endpoints."})]})]}),"round-robin"===c&&(0,l.jsxs)("div",{className:"mt-4 rounded-xl border border-primary/15 bg-background p-3",children:[(0,l.jsxs)("div",{className:"mb-3 flex items-center gap-2 text-sm font-semibold text-primary",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"sticky_note_2"}),"Sticky Round Robin"]}),(0,l.jsx)("p",{className:"mb-3 text-xs text-text-muted",children:"Optional sticky behavior for this combo only. Leave it on Global to keep the current behavior."}),(0,l.jsxs)("label",{className:"mb-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Sticky mode"}),(0,l.jsx)("select",{value:u,onChange:e=>i({stickyScope:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary",children:b.map(e=>(0,l.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:x.description})]}),(0,l.jsxs)("label",{className:"mb-3 block",children:[(0,l.jsx)("span",{className:"mb-1 block text-[11px] font-semibold uppercase tracking-wide text-text-muted",children:"Sticky TTL minutes"}),(0,l.jsx)("input",{type:"number",min:"1",value:d.stickyTtlMinutes||120,onChange:e=>i({stickyTtlMinutes:Number(e.target.value)||120}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary"}),(0,l.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"Sticky assignments are in-memory and expire after this time. 120 minutes is recommended."})]}),(0,l.jsxs)("label",{className:"flex items-start gap-2 text-xs text-text-muted",children:[(0,l.jsx)("input",{type:"checkbox",checked:!1!==d.stickyFallbackToClientIp,onChange:e=>i({stickyFallbackToClientIp:e.target.checked}),className:"mt-0.5 h-3.5 w-3.5 accent-primary"}),"If chat session id is missing, fall back to Client IP instead of global rotation."]})]})]})]})}function R({icon:e,title:t,onClick:a,danger:r=!1}){return(0,l.jsx)("button",{type:"button",onClick:e=>{e.stopPropagation(),a?.()},className:`rounded-lg p-2 transition ${r?"text-red-500 hover:bg-red-500/10":"text-text-muted hover:bg-background hover:text-primary"}`,title:t,"aria-label":t,children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:e})})}function D({id:e,index:t,model:a,subtitle:n="",enabled:i,isFirst:d,isLast:c,onEdit:m,onMoveUp:u,onMoveDown:x,onRemove:b,onToggleEnabled:p}){let{attributes:h,listeners:g,setNodeRef:f,transform:y,isDragging:v}=(0,s.gl)({id:e}),j={transform:o.Ks.Transform.toString(y),opacity:v?.4:1,zIndex:v?999:void 0},[k,N]=(0,r.useState)(!1),[w,C]=(0,r.useState)(a);(0,r.useEffect)(()=>{C(a)},[a]);let S=()=>{let e=w.trim();e&&e!==a?m(e):C(a),N(!1)};return(0,l.jsxs)("div",{ref:f,style:j,className:`flex items-center gap-3 rounded-xl border p-3 transition ${i?"border-border bg-background":"border-red-200 bg-red-50/70 opacity-75 dark:border-red-500/30 dark:bg-red-500/10"}`,children:[(0,l.jsx)("button",{type:"button",className:"cursor-grab text-text-muted active:cursor-grabbing",...h,...g,title:"Drag to reorder",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"drag_indicator"})}),(0,l.jsx)("span",{className:`flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-xs font-semibold ${i?"bg-primary/10 text-primary":"bg-red-100 text-red-600 dark:bg-red-500/20 dark:text-red-300"}`,children:t+1}),k?(0,l.jsx)("input",{autoFocus:!0,value:w,onChange:e=>C(e.target.value),onBlur:S,onKeyDown:e=>{"Enter"===e.key&&S(),"Escape"===e.key&&(C(a),N(!1))},className:"min-w-0 flex-1 rounded border border-primary/40 bg-background px-2 py-1 font-mono text-xs text-text-main outline-none"}):(0,l.jsxs)("button",{type:"button",onClick:()=>N(!0),className:"min-w-0 flex-1 text-left",title:"Click to edit model",children:[(0,l.jsx)("span",{className:`block truncate font-mono text-xs ${i?"text-text-main":"text-text-muted line-through"}`,children:a}),n?(0,l.jsx)("span",{className:"mt-0.5 block truncate text-[11px] text-text-muted",children:n}):null]}),(0,l.jsx)("button",{type:"button",onClick:p,className:`rounded-lg p-1.5 transition ${i?"text-green-600 hover:bg-green-500/10":"text-red-500 hover:bg-red-500/10"}`,title:i?"Disable this model in combo":"Enable this model in combo",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:i?"toggle_on":"toggle_off"})}),(0,l.jsx)("button",{type:"button",onClick:u,disabled:d,className:"rounded-lg p-1.5 text-text-muted transition hover:bg-surface disabled:opacity-30",title:"Move up",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"arrow_upward"})}),(0,l.jsx)("button",{type:"button",onClick:x,disabled:c,className:"rounded-lg p-1.5 text-text-muted transition hover:bg-surface disabled:opacity-30",title:"Move down",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"arrow_downward"})}),(0,l.jsx)("button",{type:"button",onClick:b,className:"rounded-lg p-1.5 text-red-500 transition hover:bg-red-500/10",title:"Remove",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"close"})})]})}function q({isOpen:e,combo:t,comboStrategy:a={},onClose:o,onSave:c,activeProviders:m,kindFilter:b=null}){let[p,g]=(0,r.useState)(t?.name||""),[f,y]=(0,r.useState)([]),[v,k]=(0,r.useState)(!1),[C,T]=(0,r.useState)(!1),[O,P]=(0,r.useState)(""),[A,I]=(0,r.useState)({}),[R,F]=(0,r.useState)(""),[B,L]=(0,r.useState)(""),H=a||{},z=(0,n.FR)((0,n.MS)(n.AN,{activationConstraint:{distance:5}}),(0,n.MS)(n.uN,{coordinateGetter:s.JR}));(0,r.useEffect)(()=>{e&&(g(t?.name||""),y(function(e,t={}){let a=(e?.models||[]).map(e=>E(e,!0)).filter(e=>e.value),l=new Set(a.map(e=>e.value));return[...a,...h(t).filter(e=>!l.has(e)).map(e=>E(e,!1)).filter(e=>e.value)]}(t,H)),P(""),F(""),L(""))},[e,t?.id,t?.name]),(0,r.useEffect)(()=>{e&&G()},[e]);let G=async()=>{try{let e=await fetch("/api/models/alias");if(!e.ok)return;let t=await e.json();I(t.aliases||{})}catch(e){console.error("Error fetching modal data:",e)}},K=f.map((e,t)=>({uid:`item-${t}-${e.value}`,row:e})),J=f.map(e=>e.value),U=f.filter(e=>e.enabled).length,V=f.filter(e=>!e.enabled).length,W=(m||[]).filter(e=>e?.isActive!==!1),Z=W.find(e=>e.id===R)||null,Q=Z?_(Z,A):[],X=Q[0]?.value||(Z?M(Z):""),Y=e=>e.trim()?x.test(e)?(P(""),!0):(P("Only letters, numbers, -, _ and . allowed"),!1):(P("Name is required"),!1),ee=async()=>{if(!Y(p))return;let{models:e,disabledModels:t}=function(e=[]){let t=[],a=new Set;for(let l of e){let e=j(l?.value||S(l?.target));!e||a.has(e)||(a.add(e),t.push({...l,value:e,enabled:l?.enabled!==!1,target:$(l?.target||l?.value)}))}return{models:t.filter(e=>e.enabled).map(e=>e.target).filter(Boolean),disabledModels:t.filter(e=>!e.enabled).map(e=>e.value)}}(f);T(!0),await c({name:p.trim(),models:e,disabledModels:t}),T(!1)};if(!e)return null;let et=!!t;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("div",{className:"fixed inset-0 z-[100] flex items-center justify-center bg-black/45 p-4 backdrop-blur-[1px]",children:(0,l.jsxs)("div",{className:"flex max-h-[88vh] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-border bg-white shadow-2xl dark:bg-zinc-950",children:[(0,l.jsxs)("div",{className:"flex items-start justify-between border-b border-border px-5 py-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h2",{className:"text-xl font-semibold text-text-main",children:et?"Edit Combo":"Create Combo"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Choose models, disable temporarily, and order active fallback priority."})]}),(0,l.jsx)("button",{type:"button",onClick:o,className:"rounded-lg p-1 text-text-muted transition hover:bg-surface hover:text-text-main",children:(0,l.jsx)("span",{className:"material-symbols-outlined",children:"close"})})]}),(0,l.jsxs)("div",{className:"min-h-0 flex-1 space-y-5 overflow-y-auto bg-white px-5 py-4 dark:bg-zinc-950",children:[(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-2 block text-sm font-semibold text-text-main",children:"Name"}),(0,l.jsx)("input",{value:p,onChange:e=>{let t=e.target.value;g(t),t?Y(t):P("")},placeholder:"premium-coding",className:`w-full rounded-xl border bg-white px-4 py-2.5 text-text-main outline-none transition focus:border-primary dark:bg-zinc-900 ${O?"border-red-400":"border-border"}`}),(0,l.jsx)("span",{className:`mt-1 block text-xs ${O?"text-red-500":"text-text-muted"}`,children:O||"Only letters, numbers, -, _ and . allowed"})]}),(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"mb-3 flex items-center justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Models"}),(0,l.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:[U," active",V>0?`, ${V} disabled`:"",". Disabled models stay in this combo but are not routed."]})]}),(0,l.jsxs)("button",{type:"button",onClick:()=>k(!0),className:"inline-flex items-center gap-1 rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-primary hover:border-primary/50",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Add Model"]})]}),(0,l.jsxs)("div",{className:"mb-4 rounded-xl border border-primary/15 bg-primary/5 p-3",children:[(0,l.jsxs)("div",{className:"mb-2 flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-primary",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"account_tree"}),"Add Provider Account Target"]}),(0,l.jsx)("p",{className:"mb-3 text-xs text-text-muted",children:"Pin this combo step to a specific provider account. Models come from the provider; the account only pins routing/load balancing."}),(0,l.jsxs)("div",{className:"grid gap-2 md:grid-cols-[minmax(0,1.5fr)_minmax(0,1fr)_auto]",children:[(0,l.jsxs)("select",{value:R,onChange:e=>{let t=e.target.value,a=W.find(e=>e.id===t),l=a?_(a,A):[];F(t),L(l[0]?.value||M(a||{})||"")},className:"min-w-0 rounded-lg border border-border bg-background px-3 py-2 text-xs text-text-main outline-none focus:border-primary",children:[(0,l.jsx)("option",{value:"",children:"Select provider account"}),W.map(e=>{let t=N(e),a=w(e),r=a&&a!==t?`${t} / ${a}`:t;return(0,l.jsx)("option",{value:e.id,children:r},e.id)})]}),(0,l.jsxs)("select",{value:B,onChange:e=>L(e.target.value),disabled:!R||0===Q.length,className:"min-w-0 rounded-lg border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary disabled:cursor-not-allowed disabled:opacity-60",children:[(0,l.jsx)("option",{value:"",children:R?Q.length>0?"Select model":"No provider models found":"Select account first"}),Q.map(e=>(0,l.jsx)("option",{value:e.value,children:e.label},`${e.value}-${e.label}`))]}),(0,l.jsxs)("button",{type:"button",onClick:()=>{if(!Z)return;let e=function(e,t){let a=N(e),l=function(e={}){let t=j(e.provider),a=N(e);return(0,u.mq)(t)||(0,u.gb)(t)?a||t:t||a}(e),r=w(e),n=j(t||M(e));if(!a||!e?.id||!n)return null;let s=n.includes("/"),o=s?n:`${a}/${n}`,i=s&&n.startsWith(`${a}/`)?n.slice(a.length+1):n,d=r&&r!==l?`${l}/${r}/${i}`:`${l}/${i}`;return{model:o,connectionId:e.id,provider:l||a,accountName:r||void 0,label:d}}(Z,B||X);if(!e)return void alert("Select a provider account and model for this pinned target.");let t=E(e,!0);y(e=>{let a=e.findIndex(e=>e.value===t.value);if(-1!==a){let l=[...e];return l[a]={...l[a],...t,enabled:!0},l}return[...e,t]}),L("")},disabled:!R||!B,className:"inline-flex items-center justify-center gap-1 rounded-lg bg-primary px-3 py-2 text-xs font-semibold text-white disabled:opacity-50",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add_link"}),"Add Account"]})]})]}),0===f.length?(0,l.jsxs)("div",{className:"rounded-xl border border-dashed border-border p-8 text-center text-text-muted",children:[(0,l.jsx)("span",{className:"material-symbols-outlined",children:"layers"}),(0,l.jsx)("p",{className:"mt-2 text-sm",children:"No models added yet"})]}):(0,l.jsx)(n.Mp,{sensors:z,collisionDetection:n.fp,modifiers:[i.FN,i.gj],onDragEnd:e=>{let{active:t,over:a}=e;if(a&&t.id!==a.id){let e=K.findIndex(e=>e.uid===t.id),l=K.findIndex(e=>e.uid===a.id);-1!==e&&-1!==l&&y(t=>(0,s.be)(t,e,l))}},children:(0,l.jsx)(s.gB,{items:K.map(e=>e.uid),strategy:s._G,children:(0,l.jsx)("div",{className:"space-y-3",children:K.map(({uid:e,row:t},a)=>(0,l.jsx)(D,{id:e,index:a,model:t.label||t.value,subtitle:t.subtitle,enabled:t.enabled,isFirst:0===a,isLast:a===f.length-1,onEdit:e=>{let t=e.trim();if(!t)return;let l=[...f],r=l[a];if(r?.target&&"object"==typeof r.target){let e=$({...r.target,model:t});l[a]=E(e,!1!==r.enabled)}else l[a]=E(t,r?.enabled!==!1);y(l)},onMoveUp:()=>{if(0===a)return;let e=[...f];[e[a-1],e[a]]=[e[a],e[a-1]],y(e)},onMoveDown:()=>{if(a===f.length-1)return;let e=[...f];[e[a],e[a+1]]=[e[a+1],e[a]],y(e)},onToggleEnabled:()=>{let e=[...f];e[a]={...e[a],enabled:!e[a].enabled},y(e)},onRemove:()=>y(f.filter((e,t)=>t!==a))},e))})})})]})]}),(0,l.jsxs)("div",{className:"flex justify-end gap-3 border-t border-border bg-white px-5 py-4 dark:bg-zinc-950",children:[(0,l.jsx)("button",{type:"button",onClick:o,className:"rounded-xl border border-border px-4 py-2 text-sm font-medium text-text-main hover:bg-surface",children:"Cancel"}),(0,l.jsx)("button",{type:"button",onClick:ee,disabled:C,className:"rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90 disabled:opacity-50",children:C?"Saving...":et?"Save":"Create"})]})]})}),(0,l.jsx)(d.rq,{isOpen:v,onClose:()=>k(!1),onSelect:e=>{let t=e.value;y(e=>{let a=e.findIndex(e=>e.value===t);if(-1!==a){let t=[...e];return t[a]={...t[a],enabled:!0},t}return[...e,E(t,!0)]})},onDeselect:e=>{y(t=>t.filter(t=>t.value!==e.value))},activeProviders:m,modelAliases:A,title:"Add Model to Combo",kindFilter:b,addedModelValues:J,closeOnSelect:!1})]})}}},e=>{e.O(0,[2574,3862,1051,7055,1321,5497,8441,3794,7358],()=>e(e.s=20061)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[712],{44493:(e,t,l)=>{"use strict";l.d(t,{default:()=>o});var s=l(95155),n=l(12115),r=l(35497),a=l(90620);let c={LOG:"text-green-400",INFO:"text-blue-400",WARN:"text-yellow-400",ERROR:"text-red-400",DEBUG:"text-purple-400"};function o(){let[e,t]=(0,n.useState)([]),[l,o]=(0,n.useState)(!1),i=(0,n.useRef)(null),u=async()=>{try{await fetch("/api/translator/console-logs",{method:"DELETE"})}catch(e){console.error("Failed to clear console logs:",e)}};return(0,n.useEffect)(()=>{let e=new EventSource("/api/translator/console-logs/stream");return e.onopen=()=>o(!0),e.onmessage=e=>{let l=JSON.parse(e.data);"init"===l.type?t(l.logs.slice(-a.UY.maxLines)):"line"===l.type?t(e=>{let t=[...e,l.line];return t.length>a.UY.maxLines?t.slice(-a.UY.maxLines):t}):"clear"===l.type&&t([])},e.onerror=()=>o(!1),()=>e.close()},[]),(0,n.useEffect)(()=>{i.current&&(i.current.scrollTop=i.current.scrollHeight)},[e]),(0,s.jsx)("div",{className:"",children:(0,s.jsxs)(r.Zp,{children:[(0,s.jsx)("div",{className:"flex items-center justify-end px-4 pt-3 pb-2",children:(0,s.jsx)(r.$n,{size:"sm",variant:"outline",icon:"delete",onClick:u,children:"Clear"})}),(0,s.jsx)("div",{ref:i,className:"bg-black rounded-b-lg p-4 text-xs font-mono h-[calc(100vh-220px)] overflow-y-auto",children:0===e.length?(0,s.jsx)("span",{className:"text-text-muted",children:"No console logs yet."}):(0,s.jsx)("div",{className:"space-y-0.5",children:e.map((e,t)=>{let l,n;return(0,s.jsx)("div",{children:(n=c[(l=e.match(/\[(\w+)\]/g))?l[1]?.replace(/\[|\]/g,""):null]||"text-green-400",(0,s.jsx)("span",{className:n,children:e}))},t)})})})]})})}},68678:(e,t,l)=>{Promise.resolve().then(l.bind(l,44493))}},e=>{e.O(0,[2574,3862,8500,4288,1321,5497,8441,3794,7358],()=>e(e.s=68678)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[712],{44493:(e,t,l)=>{"use strict";l.d(t,{default:()=>o});var s=l(95155),n=l(12115),r=l(35497),a=l(90620);let c={LOG:"text-green-400",INFO:"text-blue-400",WARN:"text-yellow-400",ERROR:"text-red-400",DEBUG:"text-purple-400"};function o(){let[e,t]=(0,n.useState)([]),[l,o]=(0,n.useState)(!1),i=(0,n.useRef)(null),u=async()=>{try{await fetch("/api/translator/console-logs",{method:"DELETE"})}catch(e){console.error("Failed to clear console logs:",e)}};return(0,n.useEffect)(()=>{let e=new EventSource("/api/translator/console-logs/stream");return e.onopen=()=>o(!0),e.onmessage=e=>{let l=JSON.parse(e.data);"init"===l.type?t(l.logs.slice(-a.UY.maxLines)):"line"===l.type?t(e=>{let t=[...e,l.line];return t.length>a.UY.maxLines?t.slice(-a.UY.maxLines):t}):"clear"===l.type&&t([])},e.onerror=()=>o(!1),()=>e.close()},[]),(0,n.useEffect)(()=>{i.current&&(i.current.scrollTop=i.current.scrollHeight)},[e]),(0,s.jsx)("div",{className:"",children:(0,s.jsxs)(r.Zp,{children:[(0,s.jsx)("div",{className:"flex items-center justify-end px-4 pt-3 pb-2",children:(0,s.jsx)(r.$n,{size:"sm",variant:"outline",icon:"delete",onClick:u,children:"Clear"})}),(0,s.jsx)("div",{ref:i,className:"bg-black rounded-b-lg p-4 text-xs font-mono h-[calc(100vh-220px)] overflow-y-auto",children:0===e.length?(0,s.jsx)("span",{className:"text-text-muted",children:"No console logs yet."}):(0,s.jsx)("div",{className:"space-y-0.5",children:e.map((e,t)=>{let l,n;return(0,s.jsx)("div",{children:(n=c[(l=e.match(/\[(\w+)\]/g))?l[1]?.replace(/\[|\]/g,""):null]||"text-green-400",(0,s.jsx)("span",{className:n,children:e}))},t)})})})]})})}},68678:(e,t,l)=>{Promise.resolve().then(l.bind(l,44493))}},e=>{e.O(0,[2574,3862,1051,1321,5497,8441,3794,7358],()=>e(e.s=68678)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6099],{7535:(e,s,t)=>{"use strict";t.d(s,{default:()=>c});var l=t(95155),a=t(12115),n=t(35497),r=t(11059);function o(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function d({models:e,max:s=8}){let t=o(e);return 0===t.length?(0,l.jsx)("span",{className:"rounded-full border border-green-500/30 bg-green-500/10 px-2 py-1 text-xs font-medium text-green-700 dark:text-green-300",children:"Full model access"}):(0,l.jsxs)("div",{className:"flex flex-wrap gap-1.5",children:[t.slice(0,s).map(e=>(0,l.jsx)("span",{className:"rounded-full border border-border bg-background px-2 py-1 font-mono text-[11px] text-text-main",children:e},e)),t.length>s&&(0,l.jsxs)("span",{className:"rounded-full border border-border bg-background px-2 py-1 text-[11px] text-text-muted",children:["+",t.length-s," more"]})]})}function i({open:e,title:s,name:t,setName:r,models:c,setModels:m,activeProviders:x,modelAliases:h,onClose:u,onSave:p,saving:y,showName:j=!0}){let[b,g]=(0,a.useState)(!1);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.aF,{isOpen:e,onClose:u,title:s,footer:null,size:"lg",children:(0,l.jsxs)("div",{className:"space-y-4",children:[j&&(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1 block text-sm font-medium text-text-main",children:"API key name"}),(0,l.jsx)(n.pd,{value:t,onChange:e=>r(e.target.value),placeholder:"Production Key"})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border bg-background/60 p-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Allowed models"}),(0,l.jsx)("p",{className:"mt-1 text-xs leading-relaxed text-text-muted",children:"Empty selection means this key can use all models. Select one or more models to restrict this API key."})]}),(0,l.jsxs)("div",{className:"flex shrink-0 gap-2",children:[(0,l.jsxs)(n.$n,{variant:"secondary",size:"sm",onClick:()=>g(!0),children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"add"}),"Add model"]}),(0,l.jsx)(n.$n,{variant:"ghost",size:"sm",onClick:()=>m([]),children:"Full access"})]})]}),0===c.length?(0,l.jsxs)("div",{className:"rounded-xl border border-dashed border-green-500/30 bg-green-500/5 p-5 text-center",children:[(0,l.jsx)("span",{className:"material-symbols-outlined mb-1 text-2xl text-green-600",children:"verified_user"}),(0,l.jsx)("p",{className:"text-sm font-medium text-text-main",children:"Full model access"}),(0,l.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:"No model restriction is saved for this key."})]}):(0,l.jsxs)("div",{className:"space-y-3",children:[(0,l.jsx)(d,{models:c,max:1e3}),(0,l.jsx)("button",{type:"button",onClick:()=>m([]),className:"text-xs font-medium text-primary hover:underline",children:"Clear selected models and make this key full access"})]})]}),(0,l.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,l.jsx)(n.$n,{variant:"ghost",onClick:u,children:"Cancel"}),(0,l.jsx)(n.$n,{onClick:p,disabled:y||j&&!t.trim(),children:y?"Saving...":"Save"})]})]})}),(0,l.jsx)(n.rq,{isOpen:b,onClose:()=>g(!1),onSelect:e=>{let s=e?.value||e?.name||e;s&&m(e=>o([...e,s]))},onDeselect:e=>{let s=e?.value||e?.name||e;m(e=>o(e).filter(e=>e!==s))},activeProviders:x,modelAliases:h,title:"Select allowed models",addedModelValues:c,closeOnSelect:!1})]})}function c(){let[e,s]=(0,a.useState)([]),[t,c]=(0,a.useState)([]),[m,x]=(0,a.useState)({}),[h,u]=(0,a.useState)(!0),[p,y]=(0,a.useState)(!1),[j,b]=(0,a.useState)(""),[g,f]=(0,a.useState)([]),[k,v]=(0,a.useState)(null),[N,w]=(0,a.useState)(!1),[C,S]=(0,a.useState)(null),[A,P]=(0,a.useState)([]),[E,M]=(0,a.useState)(!1),[$,I]=(0,a.useState)(null),{copied:_,copy:O}=(0,r.C)(),F=(0,a.useMemo)(()=>e.map(e=>({...e,allowedModels:o(e.allowedModels)})),[e]),D=async()=>{try{let[e,t,l]=await Promise.all([fetch("/api/keys",{cache:"no-store"}),fetch("/api/providers",{cache:"no-store"}),fetch("/api/models/alias",{cache:"no-store"})]),a=await e.json(),n=await t.json(),r=await l.json();e.ok&&s(a.keys||[]),t.ok&&c(n.connections||[]),l.ok&&x(r.aliases||{})}catch(e){console.log("Error loading API key model access:",e)}finally{u(!1)}};(0,a.useEffect)(()=>{D()},[]);let T=async()=>{if(j.trim()){w(!0);try{let e=await fetch("/api/keys",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:j.trim(),allowedModels:o(g)})}),s=await e.json();e.ok?(v(s.key),y(!1),await D()):alert(s.error||"Failed to create key")}catch(e){console.log("Error creating scoped API key:",e)}finally{w(!1)}}},z=async()=>{if(C){M(!0);try{let e=await fetch(`/api/keys/${C.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({allowedModels:o(A)})}),s=await e.json();e.ok?(S(null),P([]),await D()):alert(s.error||"Failed to update key model access")}catch(e){console.log("Error updating API key model access:",e)}finally{M(!1)}}},K=async(e,t)=>{try{(await fetch(`/api/keys/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:t})})).ok&&s(s=>s.map(s=>s.id===e?{...s,isActive:t}:s))}catch(e){console.log("Error toggling key:",e)}};return h?(0,l.jsx)(n.Zp,{children:(0,l.jsx)("div",{className:"h-24 animate-pulse rounded-xl bg-surface-2"})}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(n.Zp,{children:[(0,l.jsxs)("div",{className:"mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("h2",{className:"flex items-center gap-2 text-lg font-semibold",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-primary",children:"rule"}),"API Key Model Access"]}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Restrict each API key to specific models. Keys with no selected models keep full model access."})]}),(0,l.jsxs)(n.$n,{onClick:()=>{b(""),f([]),y(!0)},children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Create scoped key"]})]}),0===F.length?(0,l.jsxs)("div",{className:"rounded-xl border border-dashed border-border p-8 text-center",children:[(0,l.jsx)("span",{className:"material-symbols-outlined mb-2 block text-3xl text-text-muted",children:"vpn_key"}),(0,l.jsx)("p",{className:"font-medium text-text-main",children:"No API keys yet"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create a scoped key to limit model access per client."})]}):(0,l.jsx)("div",{className:"space-y-3",children:F.map(e=>(0,l.jsx)("div",{className:"rounded-xl border border-border bg-background/60 p-4",children:(0,l.jsxs)("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[(0,l.jsxs)("div",{className:"min-w-0",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:e.name}),!1===e.isActive&&(0,l.jsx)("span",{className:"rounded-full bg-red-500/10 px-2 py-0.5 text-xs font-medium text-red-600",children:"Paused"}),e.allowedModels.length>0&&(0,l.jsxs)("span",{className:"rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary",children:[e.allowedModels.length," model(s)"]})]}),(0,l.jsxs)("p",{className:"mt-1 font-mono text-xs text-text-muted",children:[e.key?.slice(0,8),"..."]}),(0,l.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:["Created ",new Date(e.createdAt).toLocaleDateString()]}),(0,l.jsx)("div",{className:"mt-3",children:(0,l.jsx)(d,{models:e.allowedModels})})]}),(0,l.jsxs)("div",{className:"flex shrink-0 items-center gap-2",children:[(0,l.jsx)(n.$n,{variant:"secondary",size:"sm",onClick:()=>{S(e),P(o(e.allowedModels))},children:"Edit models"}),(0,l.jsx)("button",{type:"button",onClick:()=>K(e.id,!1===e.isActive),title:!1!==e.isActive?"Pause key":"Resume key",className:"rounded-lg p-2 text-text-muted transition hover:bg-surface hover:text-primary",children:(0,l.jsx)(n.lM,{checked:!1!==e.isActive,onChange:s=>K(e.id,s)})}),(0,l.jsx)("button",{type:"button",onClick:()=>{I({title:"Delete API Key",message:`Delete API key "${e.name}"?`,onConfirm:async()=>{I(null);try{(await fetch(`/api/keys/${e.id}`,{method:"DELETE"})).ok&&await D()}catch(e){console.log("Error deleting key:",e)}}})},className:"rounded-lg p-2 text-red-500 transition hover:bg-red-500/10",title:"Delete key",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"delete"})})]})]})},e.id))})]}),(0,l.jsx)(i,{open:p,title:"Create scoped API key",name:j,setName:b,models:g,setModels:f,activeProviders:t,modelAliases:m,onClose:()=>y(!1),onSave:T,saving:N}),(0,l.jsx)(i,{open:!!C,title:C?`Edit model access: ${C.name}`:"Edit model access",name:C?.name||"",setName:()=>{},models:A,setModels:P,activeProviders:t,modelAliases:m,onClose:()=>{S(null),P([])},onSave:z,saving:E,showName:!1}),(0,l.jsx)(n.aF,{isOpen:!!k,onClose:()=>v(null),title:"API key created",footer:null,children:(0,l.jsxs)("div",{className:"space-y-4",children:[(0,l.jsx)("div",{className:"rounded-xl border border-yellow-500/30 bg-yellow-500/10 p-3 text-sm text-yellow-700 dark:text-yellow-300",children:"Save this key now. This is the only time you will see it."}),(0,l.jsx)("code",{className:"block break-all rounded-xl border border-border bg-background p-3 font-mono text-sm",children:k}),(0,l.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,l.jsx)(n.$n,{variant:"secondary",onClick:()=>O(k,"scoped_created_key"),children:"scoped_created_key"===_?"Copied!":"Copy"}),(0,l.jsx)(n.$n,{onClick:()=>v(null),children:"Done"})]})]})}),(0,l.jsx)(n.uo,{isOpen:!!$,onClose:()=>I(null),onConfirm:$?.onConfirm,title:$?.title||"Confirm",message:$?.message,variant:"danger"})]})}},82969:(e,s,t)=>{Promise.resolve().then(t.bind(t,7535)),Promise.resolve().then(t.bind(t,95907))}},e=>{e.O(0,[2574,3862,8500,4288,1321,5497,5907,8441,3794,7358],()=>e(e.s=82969)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6099],{7535:(e,s,t)=>{"use strict";t.d(s,{default:()=>c});var l=t(95155),a=t(12115),n=t(35497),r=t(11059);function o(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function d({models:e,max:s=8}){let t=o(e);return 0===t.length?(0,l.jsx)("span",{className:"rounded-full border border-green-500/30 bg-green-500/10 px-2 py-1 text-xs font-medium text-green-700 dark:text-green-300",children:"Full model access"}):(0,l.jsxs)("div",{className:"flex flex-wrap gap-1.5",children:[t.slice(0,s).map(e=>(0,l.jsx)("span",{className:"rounded-full border border-border bg-background px-2 py-1 font-mono text-[11px] text-text-main",children:e},e)),t.length>s&&(0,l.jsxs)("span",{className:"rounded-full border border-border bg-background px-2 py-1 text-[11px] text-text-muted",children:["+",t.length-s," more"]})]})}function i({open:e,title:s,name:t,setName:r,models:c,setModels:m,activeProviders:x,modelAliases:h,onClose:u,onSave:p,saving:y,showName:j=!0}){let[b,g]=(0,a.useState)(!1);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.aF,{isOpen:e,onClose:u,title:s,footer:null,size:"lg",children:(0,l.jsxs)("div",{className:"space-y-4",children:[j&&(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1 block text-sm font-medium text-text-main",children:"API key name"}),(0,l.jsx)(n.pd,{value:t,onChange:e=>r(e.target.value),placeholder:"Production Key"})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border bg-background/60 p-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Allowed models"}),(0,l.jsx)("p",{className:"mt-1 text-xs leading-relaxed text-text-muted",children:"Empty selection means this key can use all models. Select one or more models to restrict this API key."})]}),(0,l.jsxs)("div",{className:"flex shrink-0 gap-2",children:[(0,l.jsxs)(n.$n,{variant:"secondary",size:"sm",onClick:()=>g(!0),children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[16px]",children:"add"}),"Add model"]}),(0,l.jsx)(n.$n,{variant:"ghost",size:"sm",onClick:()=>m([]),children:"Full access"})]})]}),0===c.length?(0,l.jsxs)("div",{className:"rounded-xl border border-dashed border-green-500/30 bg-green-500/5 p-5 text-center",children:[(0,l.jsx)("span",{className:"material-symbols-outlined mb-1 text-2xl text-green-600",children:"verified_user"}),(0,l.jsx)("p",{className:"text-sm font-medium text-text-main",children:"Full model access"}),(0,l.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:"No model restriction is saved for this key."})]}):(0,l.jsxs)("div",{className:"space-y-3",children:[(0,l.jsx)(d,{models:c,max:1e3}),(0,l.jsx)("button",{type:"button",onClick:()=>m([]),className:"text-xs font-medium text-primary hover:underline",children:"Clear selected models and make this key full access"})]})]}),(0,l.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,l.jsx)(n.$n,{variant:"ghost",onClick:u,children:"Cancel"}),(0,l.jsx)(n.$n,{onClick:p,disabled:y||j&&!t.trim(),children:y?"Saving...":"Save"})]})]})}),(0,l.jsx)(n.rq,{isOpen:b,onClose:()=>g(!1),onSelect:e=>{let s=e?.value||e?.name||e;s&&m(e=>o([...e,s]))},onDeselect:e=>{let s=e?.value||e?.name||e;m(e=>o(e).filter(e=>e!==s))},activeProviders:x,modelAliases:h,title:"Select allowed models",addedModelValues:c,closeOnSelect:!1})]})}function c(){let[e,s]=(0,a.useState)([]),[t,c]=(0,a.useState)([]),[m,x]=(0,a.useState)({}),[h,u]=(0,a.useState)(!0),[p,y]=(0,a.useState)(!1),[j,b]=(0,a.useState)(""),[g,f]=(0,a.useState)([]),[k,v]=(0,a.useState)(null),[N,w]=(0,a.useState)(!1),[C,S]=(0,a.useState)(null),[A,P]=(0,a.useState)([]),[E,M]=(0,a.useState)(!1),[$,I]=(0,a.useState)(null),{copied:_,copy:O}=(0,r.C)(),F=(0,a.useMemo)(()=>e.map(e=>({...e,allowedModels:o(e.allowedModels)})),[e]),D=async()=>{try{let[e,t,l]=await Promise.all([fetch("/api/keys",{cache:"no-store"}),fetch("/api/providers",{cache:"no-store"}),fetch("/api/models/alias",{cache:"no-store"})]),a=await e.json(),n=await t.json(),r=await l.json();e.ok&&s(a.keys||[]),t.ok&&c(n.connections||[]),l.ok&&x(r.aliases||{})}catch(e){console.log("Error loading API key model access:",e)}finally{u(!1)}};(0,a.useEffect)(()=>{D()},[]);let T=async()=>{if(j.trim()){w(!0);try{let e=await fetch("/api/keys",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:j.trim(),allowedModels:o(g)})}),s=await e.json();e.ok?(v(s.key),y(!1),await D()):alert(s.error||"Failed to create key")}catch(e){console.log("Error creating scoped API key:",e)}finally{w(!1)}}},z=async()=>{if(C){M(!0);try{let e=await fetch(`/api/keys/${C.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({allowedModels:o(A)})}),s=await e.json();e.ok?(S(null),P([]),await D()):alert(s.error||"Failed to update key model access")}catch(e){console.log("Error updating API key model access:",e)}finally{M(!1)}}},K=async(e,t)=>{try{(await fetch(`/api/keys/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:t})})).ok&&s(s=>s.map(s=>s.id===e?{...s,isActive:t}:s))}catch(e){console.log("Error toggling key:",e)}};return h?(0,l.jsx)(n.Zp,{children:(0,l.jsx)("div",{className:"h-24 animate-pulse rounded-xl bg-surface-2"})}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(n.Zp,{children:[(0,l.jsxs)("div",{className:"mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("h2",{className:"flex items-center gap-2 text-lg font-semibold",children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-primary",children:"rule"}),"API Key Model Access"]}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Restrict each API key to specific models. Keys with no selected models keep full model access."})]}),(0,l.jsxs)(n.$n,{onClick:()=>{b(""),f([]),y(!0)},children:[(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Create scoped key"]})]}),0===F.length?(0,l.jsxs)("div",{className:"rounded-xl border border-dashed border-border p-8 text-center",children:[(0,l.jsx)("span",{className:"material-symbols-outlined mb-2 block text-3xl text-text-muted",children:"vpn_key"}),(0,l.jsx)("p",{className:"font-medium text-text-main",children:"No API keys yet"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create a scoped key to limit model access per client."})]}):(0,l.jsx)("div",{className:"space-y-3",children:F.map(e=>(0,l.jsx)("div",{className:"rounded-xl border border-border bg-background/60 p-4",children:(0,l.jsxs)("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[(0,l.jsxs)("div",{className:"min-w-0",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:e.name}),!1===e.isActive&&(0,l.jsx)("span",{className:"rounded-full bg-red-500/10 px-2 py-0.5 text-xs font-medium text-red-600",children:"Paused"}),e.allowedModels.length>0&&(0,l.jsxs)("span",{className:"rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary",children:[e.allowedModels.length," model(s)"]})]}),(0,l.jsxs)("p",{className:"mt-1 font-mono text-xs text-text-muted",children:[e.key?.slice(0,8),"..."]}),(0,l.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:["Created ",new Date(e.createdAt).toLocaleDateString()]}),(0,l.jsx)("div",{className:"mt-3",children:(0,l.jsx)(d,{models:e.allowedModels})})]}),(0,l.jsxs)("div",{className:"flex shrink-0 items-center gap-2",children:[(0,l.jsx)(n.$n,{variant:"secondary",size:"sm",onClick:()=>{S(e),P(o(e.allowedModels))},children:"Edit models"}),(0,l.jsx)("button",{type:"button",onClick:()=>K(e.id,!1===e.isActive),title:!1!==e.isActive?"Pause key":"Resume key",className:"rounded-lg p-2 text-text-muted transition hover:bg-surface hover:text-primary",children:(0,l.jsx)(n.lM,{checked:!1!==e.isActive,onChange:s=>K(e.id,s)})}),(0,l.jsx)("button",{type:"button",onClick:()=>{I({title:"Delete API Key",message:`Delete API key "${e.name}"?`,onConfirm:async()=>{I(null);try{(await fetch(`/api/keys/${e.id}`,{method:"DELETE"})).ok&&await D()}catch(e){console.log("Error deleting key:",e)}}})},className:"rounded-lg p-2 text-red-500 transition hover:bg-red-500/10",title:"Delete key",children:(0,l.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"delete"})})]})]})},e.id))})]}),(0,l.jsx)(i,{open:p,title:"Create scoped API key",name:j,setName:b,models:g,setModels:f,activeProviders:t,modelAliases:m,onClose:()=>y(!1),onSave:T,saving:N}),(0,l.jsx)(i,{open:!!C,title:C?`Edit model access: ${C.name}`:"Edit model access",name:C?.name||"",setName:()=>{},models:A,setModels:P,activeProviders:t,modelAliases:m,onClose:()=>{S(null),P([])},onSave:z,saving:E,showName:!1}),(0,l.jsx)(n.aF,{isOpen:!!k,onClose:()=>v(null),title:"API key created",footer:null,children:(0,l.jsxs)("div",{className:"space-y-4",children:[(0,l.jsx)("div",{className:"rounded-xl border border-yellow-500/30 bg-yellow-500/10 p-3 text-sm text-yellow-700 dark:text-yellow-300",children:"Save this key now. This is the only time you will see it."}),(0,l.jsx)("code",{className:"block break-all rounded-xl border border-border bg-background p-3 font-mono text-sm",children:k}),(0,l.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,l.jsx)(n.$n,{variant:"secondary",onClick:()=>O(k,"scoped_created_key"),children:"scoped_created_key"===_?"Copied!":"Copy"}),(0,l.jsx)(n.$n,{onClick:()=>v(null),children:"Done"})]})]})}),(0,l.jsx)(n.uo,{isOpen:!!$,onClose:()=>I(null),onConfirm:$?.onConfirm,title:$?.title||"Confirm",message:$?.message,variant:"danger"})]})}},82969:(e,s,t)=>{Promise.resolve().then(t.bind(t,7535)),Promise.resolve().then(t.bind(t,95907))}},e=>{e.O(0,[2574,3862,1051,1321,5497,5907,8441,3794,7358],()=>e(e.s=82969)),_N_E=e.O()}]);
@@ -56,4 +56,4 @@
56
56
  -F "temperature=${k}"`:""}${h.includes("prompt")&&v?` \\
57
57
  -F "prompt=${v}"`:""}`,Q=async()=>{if(!b||!G)return;D(!0),q(""),K(null);let e=Date.now();try{let t=new FormData;t.append("file",b),t.append("model",G),h.includes("language")&&g&&t.append("language",g),h.includes("response_format")&&t.append("response_format",w),h.includes("temperature")&&k&&t.append("temperature",k),h.includes("prompt")&&v&&t.append("prompt",v);let s={};$&&(s.Authorization=`Bearer ${$}`);let a=await fetch("/api/v1/audio/transcriptions",{method:"POST",headers:s,body:t});B(Date.now()-e);let r=(a.headers.get("content-type")||"").includes("application/json")?await a.json():await a.text();if(!a.ok)return void q(r?.error?.message||r?.error||r||`HTTP ${a.status}`);K(r)}catch(e){q(e.message||"Network error")}finally{D(!1)}},Z="string"==typeof M?M:M?JSON.stringify(M,null,2):`{
58
58
  "text": "Hello world..."
59
- }`;return(0,a.jsxs)(i.Zp,{children:[(0,a.jsx)("h2",{className:"text-lg font-semibold mb-4",children:"Example"}),(0,a.jsxs)("div",{className:"flex flex-col gap-2.5",children:[l.length>0?(0,a.jsx)(S,{label:"Model",children:(0,a.jsx)("select",{value:d,onChange:e=>u(e.target.value),className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",children:l.map(e=>(0,a.jsx)("option",{value:e.id,children:e.name||e.id},e.id))})}):(0,a.jsx)(S,{label:"Model",children:(0,a.jsx)("input",{value:d,onChange:e=>u(e.target.value),placeholder:"Enter model id",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary font-mono"})}),(0,a.jsx)(S,{label:"Endpoint",children:(0,a.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,a.jsxs)("span",{className:"w-full min-w-0 flex-1 px-3 py-1.5 text-sm font-mono text-text-main bg-sidebar rounded-lg truncate",children:[W,"/v1/audio/transcriptions"]}),E&&(0,a.jsxs)("button",{onClick:()=>A(e=>!e),title:P?"Using tunnel":"Using local",className:`flex items-center gap-1 text-xs px-2 py-1.5 rounded-lg border shrink-0 transition-colors ${P?"border-primary/40 bg-primary/10 text-primary":"border-border text-text-muted hover:text-primary"}`,children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"wifi_tethering"}),"Tunnel"]})]})}),(0,a.jsx)(S,{label:"API Key",children:(0,a.jsx)("span",{className:"px-3 py-1.5 text-sm font-mono text-text-main bg-sidebar rounded-lg truncate block",children:$?`${$.slice(0,8)}${"•".repeat(Math.min(20,$.length-8))}`:(0,a.jsx)("span",{className:"text-text-muted italic",children:"No key configured"})})}),(0,a.jsx)(S,{label:"Audio File",children:(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("input",{type:"file",accept:"audio/*,video/mp4,.m4a,.mp3,.wav,.ogg,.flac,.webm,.opus",onChange:e=>f(e.target.files?.[0]||null),className:"w-full text-xs text-text-muted file:mr-2 file:py-1 file:px-2.5 file:rounded-lg file:border file:border-border file:bg-background file:text-text-main hover:file:bg-sidebar file:cursor-pointer"}),b&&(0,a.jsxs)("span",{className:"text-xs text-text-muted font-mono",children:[b.name," \xb7 ",(b.size/1024).toFixed(1)," KB"]})]})}),h.includes("language")&&(0,a.jsx)(S,{label:"Language",children:(0,a.jsx)("input",{value:g,onChange:e=>y(e.target.value),placeholder:"e.g. en, vi, ja (auto-detect if empty)",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary font-mono"})}),h.includes("prompt")&&(0,a.jsx)(S,{label:"Prompt",children:(0,a.jsx)("input",{value:v,onChange:e=>j(e.target.value),placeholder:"optional context to improve accuracy",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary"})}),h.includes("temperature")&&(0,a.jsx)(S,{label:"Temperature",children:(0,a.jsx)("input",{type:"number",step:"0.1",min:"0",max:"1",value:k,onChange:e=>C(e.target.value),placeholder:"0 - 1 (default 0)",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary"})}),h.includes("response_format")&&(0,a.jsx)(S,{label:"Response Format",children:(0,a.jsxs)("select",{value:w,onChange:e=>N(e.target.value),className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",children:[(0,a.jsx)("option",{value:"json",children:"json"}),(0,a.jsx)("option",{value:"text",children:"text"}),(0,a.jsx)("option",{value:"srt",children:"srt"}),(0,a.jsx)("option",{value:"verbose_json",children:"verbose_json"}),(0,a.jsx)("option",{value:"vtt",children:"vtt"})]})}),(0,a.jsxs)("div",{className:"mt-1",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between mb-1.5",children:[(0,a.jsx)("span",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider",children:"Request"}),(0,a.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,a.jsxs)("button",{onClick:()=>z(Y),className:"inline-flex items-center gap-1 text-xs text-text-muted hover:text-primary transition-colors",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:J?"check":"content_copy"}),J?"Copied":"Copy"]}),(0,a.jsxs)("button",{onClick:Q,disabled:U||!b||!G,className:"flex w-full sm:w-auto items-center justify-center gap-1.5 px-3 py-1 rounded-lg bg-primary text-white text-xs font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",style:U?{animation:"spin 1s linear infinite"}:void 0,children:"play_arrow"}),U?"Transcribing...":"Run"]})]})]}),(0,a.jsx)("pre",{className:"bg-sidebar rounded-lg px-3 py-2.5 text-xs font-mono text-text-main overflow-x-auto whitespace-pre-wrap break-all",children:Y})]}),F&&(0,a.jsx)("p",{className:"text-xs text-red-500 break-words",children:F}),(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between mb-1.5",children:[(0,a.jsxs)("span",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider",children:["Response ",M&&L&&(0,a.jsxs)("span",{className:"font-normal normal-case",children:["⚡ ",L,"ms"]})]}),M&&(0,a.jsxs)("button",{onClick:()=>H(Z),className:"inline-flex items-center gap-1 text-xs text-text-muted hover:text-primary transition-colors",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:V?"check":"content_copy"}),V?"Copied":"Copy"]})]}),(0,a.jsx)("pre",{className:"bg-sidebar rounded-lg px-3 py-2.5 text-xs font-mono text-text-main overflow-x-auto whitespace-pre-wrap break-all opacity-70",children:Z})]})]})]})}function O(){let{kind:e,id:t}=(0,r.useParams)(),s=(0,r.useRouter)(),o=c.rj.find(t=>t.id===e),m=(0,c.gC)(t)&&"embedding"===e,p=async()=>{if(confirm("Delete this Custom Embedding node?"))try{(await fetch(`/api/provider-nodes/${t}`,{method:"DELETE"})).ok&&s.push(`/dashboard/media-providers/${e}`)}catch(e){console.log("Error deleting custom embedding node:",e)}},[u,x]=(0,n.useState)(null),[h,b]=(0,n.useState)(m),[f,y]=(0,n.useState)(!1);if((0,n.useEffect)(()=>{if(!m)return;let e=!1;return fetch("/api/provider-nodes",{cache:"no-store"}).then(e=>e.json()).then(s=>{e||(x((s.nodes||[]).find(e=>e.id===t)||null),b(!1))}).catch(()=>{e||b(!1)}),()=>{e=!0}},[t,m]),!o)return(0,r.notFound)();let v=c.Q2[t],w=m?u?{id:t,name:u.name||"Custom Embedding",color:"#6366F1",textIcon:"CE"}:null:v;if(!m&&!v||m&&!h&&!u)return(0,r.notFound)();if(m&&h)return(0,a.jsx)("div",{className:"text-text-muted text-sm py-12 text-center",children:"Loading..."});let N=m?["embedding"]:w.serviceKinds??["llm"];return m||N.includes(e)?(0,a.jsxs)("div",{className:"flex flex-col gap-8",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)(l(),{href:`/dashboard/media-providers/${e}`,className:"inline-flex items-center gap-1 text-sm text-text-muted hover:text-primary transition-colors mb-4",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-lg",children:"arrow_back"}),o.label]}),(0,a.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4",children:[(0,a.jsx)("div",{className:"size-12 rounded-lg flex items-center justify-center shrink-0",style:{backgroundColor:`${w.color}15`},children:(0,a.jsx)(d.A,{src:`/providers/${w.id}.png`,alt:w.name,size:48,className:"object-contain rounded-lg max-w-[48px] max-h-[48px]",fallbackText:w.textIcon||w.id.slice(0,2).toUpperCase(),fallbackColor:w.color})}),(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2 sm:gap-3",children:[(0,a.jsx)("h1",{className:"text-3xl font-semibold tracking-tight",children:w.name}),!m&&w.notice?.apiKeyUrl&&(0,a.jsxs)("a",{href:w.notice.apiKeyUrl,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline inline-flex items-center gap-1",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-sm",children:"open_in_new"}),"Get API Key"]})]}),(0,a.jsxs)("div",{className:"flex items-center gap-1.5 mt-1 flex-wrap",children:[m&&(0,a.jsxs)(i.Ex,{variant:"default",size:"sm",children:["Custom \xb7 ",u?.prefix]}),N.map(t=>(0,a.jsx)(i.Ex,{variant:t===e?"primary":"default",size:"sm",children:t.toUpperCase()},t))]})]}),m&&(0,a.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,a.jsx)(i.$n,{size:"sm",variant:"secondary",icon:"edit",onClick:()=>y(!0),children:"Edit"}),(0,a.jsx)(i.$n,{size:"sm",variant:"secondary",icon:"delete",onClick:p,children:"Delete"})]})]})]}),!m&&w.kindNotice?.[e]&&(0,a.jsxs)("div",{className:"flex items-start gap-3 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/30 text-amber-700 dark:text-amber-400",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px] mt-0.5",children:"warning"}),(0,a.jsx)("p",{className:"text-sm",children:w.kindNotice[e]})]}),!m&&w.notice?.text&&!w.deprecated&&(0,a.jsxs)("div",{className:"flex flex-col gap-2 rounded-lg border border-blue-500/30 bg-blue-500/10 px-3 py-2 sm:flex-row sm:items-center",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[16px] text-blue-500 shrink-0",children:"info"}),(0,a.jsx)("p",{className:"min-w-0 flex-1 text-xs leading-relaxed text-blue-600 dark:text-blue-400",children:w.notice.text}),w.notice.apiKeyUrl&&(0,a.jsx)("a",{href:w.notice.apiKeyUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-flex justify-center rounded bg-blue-500 px-2 py-1 text-xs font-medium text-white transition-colors hover:bg-blue-600 sm:py-0.5",children:"Get API Key →"})]}),!m&&w.noAuth?(0,a.jsx)(i.gw,{providerId:t}):(0,a.jsx)(g,{providerId:t,isOAuth:!1}),"tts"!==e&&"webSearch"!==e&&"webFetch"!==e&&(0,a.jsx)(j,{providerId:t,kindFilter:e,providerAliasOverride:m?u?.prefix:void 0}),!m&&(w.searchConfig||w.fetchConfig||w.ttsConfig||w.sttConfig||w.embeddingConfig||w.searchViaChat)&&(0,a.jsx)(i.Wx,{config:"webFetch"===e?w.fetchConfig:"tts"===e?w.ttsConfig:"stt"===e?w.sttConfig:"embedding"===e?w.embeddingConfig:w.searchConfig||{mode:"chat-completions",defaultModel:w.searchViaChat?.defaultModel,pricingUrl:w.searchViaChat?.pricingUrl,freeTier:w.searchViaChat?.freeTier},provider:w,title:`${o.label} Config`}),"embedding"===e&&(0,a.jsx)(T,{providerId:t,customAlias:u?.prefix}),"tts"===e&&(0,a.jsx)(I,{providerId:t}),"stt"===e&&!m&&(0,a.jsx)(R,{providerId:t}),!m&&A[e]&&(0,a.jsx)(E,{providerId:t,kind:e}),m&&(0,a.jsx)(i.x0,{isOpen:f,node:u,onClose:()=>y(!1),onSaved:e=>{x(e),y(!1)}})]}):(0,r.notFound)()}},95364:(e,t,s)=>{Promise.resolve().then(s.bind(s,94588))}},e=>{e.O(0,[2574,3862,8500,4288,1321,5497,8441,3794,7358],()=>e(e.s=95364)),_N_E=e.O()}]);
59
+ }`;return(0,a.jsxs)(i.Zp,{children:[(0,a.jsx)("h2",{className:"text-lg font-semibold mb-4",children:"Example"}),(0,a.jsxs)("div",{className:"flex flex-col gap-2.5",children:[l.length>0?(0,a.jsx)(S,{label:"Model",children:(0,a.jsx)("select",{value:d,onChange:e=>u(e.target.value),className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",children:l.map(e=>(0,a.jsx)("option",{value:e.id,children:e.name||e.id},e.id))})}):(0,a.jsx)(S,{label:"Model",children:(0,a.jsx)("input",{value:d,onChange:e=>u(e.target.value),placeholder:"Enter model id",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary font-mono"})}),(0,a.jsx)(S,{label:"Endpoint",children:(0,a.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,a.jsxs)("span",{className:"w-full min-w-0 flex-1 px-3 py-1.5 text-sm font-mono text-text-main bg-sidebar rounded-lg truncate",children:[W,"/v1/audio/transcriptions"]}),E&&(0,a.jsxs)("button",{onClick:()=>A(e=>!e),title:P?"Using tunnel":"Using local",className:`flex items-center gap-1 text-xs px-2 py-1.5 rounded-lg border shrink-0 transition-colors ${P?"border-primary/40 bg-primary/10 text-primary":"border-border text-text-muted hover:text-primary"}`,children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"wifi_tethering"}),"Tunnel"]})]})}),(0,a.jsx)(S,{label:"API Key",children:(0,a.jsx)("span",{className:"px-3 py-1.5 text-sm font-mono text-text-main bg-sidebar rounded-lg truncate block",children:$?`${$.slice(0,8)}${"•".repeat(Math.min(20,$.length-8))}`:(0,a.jsx)("span",{className:"text-text-muted italic",children:"No key configured"})})}),(0,a.jsx)(S,{label:"Audio File",children:(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("input",{type:"file",accept:"audio/*,video/mp4,.m4a,.mp3,.wav,.ogg,.flac,.webm,.opus",onChange:e=>f(e.target.files?.[0]||null),className:"w-full text-xs text-text-muted file:mr-2 file:py-1 file:px-2.5 file:rounded-lg file:border file:border-border file:bg-background file:text-text-main hover:file:bg-sidebar file:cursor-pointer"}),b&&(0,a.jsxs)("span",{className:"text-xs text-text-muted font-mono",children:[b.name," \xb7 ",(b.size/1024).toFixed(1)," KB"]})]})}),h.includes("language")&&(0,a.jsx)(S,{label:"Language",children:(0,a.jsx)("input",{value:g,onChange:e=>y(e.target.value),placeholder:"e.g. en, vi, ja (auto-detect if empty)",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary font-mono"})}),h.includes("prompt")&&(0,a.jsx)(S,{label:"Prompt",children:(0,a.jsx)("input",{value:v,onChange:e=>j(e.target.value),placeholder:"optional context to improve accuracy",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary"})}),h.includes("temperature")&&(0,a.jsx)(S,{label:"Temperature",children:(0,a.jsx)("input",{type:"number",step:"0.1",min:"0",max:"1",value:k,onChange:e=>C(e.target.value),placeholder:"0 - 1 (default 0)",className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary"})}),h.includes("response_format")&&(0,a.jsx)(S,{label:"Response Format",children:(0,a.jsxs)("select",{value:w,onChange:e=>N(e.target.value),className:"w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary",children:[(0,a.jsx)("option",{value:"json",children:"json"}),(0,a.jsx)("option",{value:"text",children:"text"}),(0,a.jsx)("option",{value:"srt",children:"srt"}),(0,a.jsx)("option",{value:"verbose_json",children:"verbose_json"}),(0,a.jsx)("option",{value:"vtt",children:"vtt"})]})}),(0,a.jsxs)("div",{className:"mt-1",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between mb-1.5",children:[(0,a.jsx)("span",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider",children:"Request"}),(0,a.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,a.jsxs)("button",{onClick:()=>z(Y),className:"inline-flex items-center gap-1 text-xs text-text-muted hover:text-primary transition-colors",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:J?"check":"content_copy"}),J?"Copied":"Copy"]}),(0,a.jsxs)("button",{onClick:Q,disabled:U||!b||!G,className:"flex w-full sm:w-auto items-center justify-center gap-1.5 px-3 py-1 rounded-lg bg-primary text-white text-xs font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",style:U?{animation:"spin 1s linear infinite"}:void 0,children:"play_arrow"}),U?"Transcribing...":"Run"]})]})]}),(0,a.jsx)("pre",{className:"bg-sidebar rounded-lg px-3 py-2.5 text-xs font-mono text-text-main overflow-x-auto whitespace-pre-wrap break-all",children:Y})]}),F&&(0,a.jsx)("p",{className:"text-xs text-red-500 break-words",children:F}),(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between mb-1.5",children:[(0,a.jsxs)("span",{className:"text-xs font-semibold text-text-muted uppercase tracking-wider",children:["Response ",M&&L&&(0,a.jsxs)("span",{className:"font-normal normal-case",children:["⚡ ",L,"ms"]})]}),M&&(0,a.jsxs)("button",{onClick:()=>H(Z),className:"inline-flex items-center gap-1 text-xs text-text-muted hover:text-primary transition-colors",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:V?"check":"content_copy"}),V?"Copied":"Copy"]})]}),(0,a.jsx)("pre",{className:"bg-sidebar rounded-lg px-3 py-2.5 text-xs font-mono text-text-main overflow-x-auto whitespace-pre-wrap break-all opacity-70",children:Z})]})]})]})}function O(){let{kind:e,id:t}=(0,r.useParams)(),s=(0,r.useRouter)(),o=c.rj.find(t=>t.id===e),m=(0,c.gC)(t)&&"embedding"===e,p=async()=>{if(confirm("Delete this Custom Embedding node?"))try{(await fetch(`/api/provider-nodes/${t}`,{method:"DELETE"})).ok&&s.push(`/dashboard/media-providers/${e}`)}catch(e){console.log("Error deleting custom embedding node:",e)}},[u,x]=(0,n.useState)(null),[h,b]=(0,n.useState)(m),[f,y]=(0,n.useState)(!1);if((0,n.useEffect)(()=>{if(!m)return;let e=!1;return fetch("/api/provider-nodes",{cache:"no-store"}).then(e=>e.json()).then(s=>{e||(x((s.nodes||[]).find(e=>e.id===t)||null),b(!1))}).catch(()=>{e||b(!1)}),()=>{e=!0}},[t,m]),!o)return(0,r.notFound)();let v=c.Q2[t],w=m?u?{id:t,name:u.name||"Custom Embedding",color:"#6366F1",textIcon:"CE"}:null:v;if(!m&&!v||m&&!h&&!u)return(0,r.notFound)();if(m&&h)return(0,a.jsx)("div",{className:"text-text-muted text-sm py-12 text-center",children:"Loading..."});let N=m?["embedding"]:w.serviceKinds??["llm"];return m||N.includes(e)?(0,a.jsxs)("div",{className:"flex flex-col gap-8",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)(l(),{href:`/dashboard/media-providers/${e}`,className:"inline-flex items-center gap-1 text-sm text-text-muted hover:text-primary transition-colors mb-4",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-lg",children:"arrow_back"}),o.label]}),(0,a.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4",children:[(0,a.jsx)("div",{className:"size-12 rounded-lg flex items-center justify-center shrink-0",style:{backgroundColor:`${w.color}15`},children:(0,a.jsx)(d.A,{src:`/providers/${w.id}.png`,alt:w.name,size:48,className:"object-contain rounded-lg max-w-[48px] max-h-[48px]",fallbackText:w.textIcon||w.id.slice(0,2).toUpperCase(),fallbackColor:w.color})}),(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2 sm:gap-3",children:[(0,a.jsx)("h1",{className:"text-3xl font-semibold tracking-tight",children:w.name}),!m&&w.notice?.apiKeyUrl&&(0,a.jsxs)("a",{href:w.notice.apiKeyUrl,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline inline-flex items-center gap-1",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-sm",children:"open_in_new"}),"Get API Key"]})]}),(0,a.jsxs)("div",{className:"flex items-center gap-1.5 mt-1 flex-wrap",children:[m&&(0,a.jsxs)(i.Ex,{variant:"default",size:"sm",children:["Custom \xb7 ",u?.prefix]}),N.map(t=>(0,a.jsx)(i.Ex,{variant:t===e?"primary":"default",size:"sm",children:t.toUpperCase()},t))]})]}),m&&(0,a.jsxs)("div",{className:"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center",children:[(0,a.jsx)(i.$n,{size:"sm",variant:"secondary",icon:"edit",onClick:()=>y(!0),children:"Edit"}),(0,a.jsx)(i.$n,{size:"sm",variant:"secondary",icon:"delete",onClick:p,children:"Delete"})]})]})]}),!m&&w.kindNotice?.[e]&&(0,a.jsxs)("div",{className:"flex items-start gap-3 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/30 text-amber-700 dark:text-amber-400",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px] mt-0.5",children:"warning"}),(0,a.jsx)("p",{className:"text-sm",children:w.kindNotice[e]})]}),!m&&w.notice?.text&&!w.deprecated&&(0,a.jsxs)("div",{className:"flex flex-col gap-2 rounded-lg border border-blue-500/30 bg-blue-500/10 px-3 py-2 sm:flex-row sm:items-center",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[16px] text-blue-500 shrink-0",children:"info"}),(0,a.jsx)("p",{className:"min-w-0 flex-1 text-xs leading-relaxed text-blue-600 dark:text-blue-400",children:w.notice.text}),w.notice.apiKeyUrl&&(0,a.jsx)("a",{href:w.notice.apiKeyUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-flex justify-center rounded bg-blue-500 px-2 py-1 text-xs font-medium text-white transition-colors hover:bg-blue-600 sm:py-0.5",children:"Get API Key →"})]}),!m&&w.noAuth?(0,a.jsx)(i.gw,{providerId:t}):(0,a.jsx)(g,{providerId:t,isOAuth:!1}),"tts"!==e&&"webSearch"!==e&&"webFetch"!==e&&(0,a.jsx)(j,{providerId:t,kindFilter:e,providerAliasOverride:m?u?.prefix:void 0}),!m&&(w.searchConfig||w.fetchConfig||w.ttsConfig||w.sttConfig||w.embeddingConfig||w.searchViaChat)&&(0,a.jsx)(i.Wx,{config:"webFetch"===e?w.fetchConfig:"tts"===e?w.ttsConfig:"stt"===e?w.sttConfig:"embedding"===e?w.embeddingConfig:w.searchConfig||{mode:"chat-completions",defaultModel:w.searchViaChat?.defaultModel,pricingUrl:w.searchViaChat?.pricingUrl,freeTier:w.searchViaChat?.freeTier},provider:w,title:`${o.label} Config`}),"embedding"===e&&(0,a.jsx)(T,{providerId:t,customAlias:u?.prefix}),"tts"===e&&(0,a.jsx)(I,{providerId:t}),"stt"===e&&!m&&(0,a.jsx)(R,{providerId:t}),!m&&A[e]&&(0,a.jsx)(E,{providerId:t,kind:e}),m&&(0,a.jsx)(i.x0,{isOpen:f,node:u,onClose:()=>y(!1),onSaved:e=>{x(e),y(!1)}})]}):(0,r.notFound)()}},95364:(e,t,s)=>{Promise.resolve().then(s.bind(s,94588))}},e=>{e.O(0,[2574,3862,1051,1321,5497,8441,3794,7358],()=>e(e.s=95364)),_N_E=e.O()}]);