@jheavenknows/bluerouter 1.0.65 → 1.0.67

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 (510) hide show
  1. package/app/.next-cli-build/BUILD_ID +1 -1
  2. package/app/.next-cli-build/app-path-routes-manifest.json +6 -6
  3. package/app/.next-cli-build/build-manifest.json +2 -2
  4. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +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.js.nft.json +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ollama-nodes/page.js.nft.json +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ollama-nodes/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page.js.nft.json +1 -1
  33. package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page_client-reference-manifest.js +1 -1
  34. package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page.js.nft.json +1 -1
  35. package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page_client-reference-manifest.js +1 -1
  36. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
  37. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  38. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
  39. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  40. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
  41. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  42. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +1 -1
  43. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  44. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
  45. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  46. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
  47. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  48. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
  49. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  50. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
  51. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  52. package/app/.next-cli-build/server/app/(dashboard)/dashboard/virtual-combos/page.js +2 -2
  53. package/app/.next-cli-build/server/app/(dashboard)/dashboard/virtual-combos/page.js.nft.json +1 -1
  54. package/app/.next-cli-build/server/app/(dashboard)/dashboard/virtual-combos/page_client-reference-manifest.js +1 -1
  55. package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
  56. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  57. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  58. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  59. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
  66. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  67. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  68. package/app/.next-cli-build/server/app/_not-found.rsc +3 -3
  69. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
  70. package/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  71. package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
  72. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  73. package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  74. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  75. package/app/.next-cli-build/server/app/api/auth/ldap/test/route.js.nft.json +1 -1
  76. package/app/.next-cli-build/server/app/api/auth/ldap/users/route.js.nft.json +1 -1
  77. package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
  78. package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
  79. package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
  80. package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
  81. package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
  82. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  83. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  84. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  85. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/autostart/route.js.nft.json +1 -1
  86. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/prompt-log-db/route.js.nft.json +1 -1
  87. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/root-ca/route.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  89. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
  90. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
  91. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
  92. package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
  93. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
  94. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
  95. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
  97. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
  98. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
  99. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
  100. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
  101. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
  102. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
  103. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  104. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  105. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/[id]/route.js.nft.json +1 -1
  106. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/route.js.nft.json +1 -1
  107. package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
  108. package/app/.next-cli-build/server/app/api/init/route.js.nft.json +1 -1
  109. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  110. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
  112. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  114. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  116. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  118. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
  119. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  120. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  121. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  122. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  123. package/app/.next-cli-build/server/app/api/models/route.js +1 -1
  124. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  125. package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  126. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  127. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  128. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  129. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  130. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  131. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  132. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  133. package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
  134. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  135. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
  136. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  137. package/app/.next-cli-build/server/app/api/ollama-model-memory/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/install/route.js +2 -2
  139. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/install/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/reservations/route.js +1 -1
  141. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/reservations/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/route.js +1 -1
  143. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/route.js.nft.json +1 -1
  144. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/status/route.js +1 -1
  145. package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/status/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/ollama-nodes/route.js +1 -1
  147. package/app/.next-cli-build/server/app/api/ollama-nodes/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/ollama-routing-targets/route.js +1 -1
  149. package/app/.next-cli-build/server/app/api/ollama-routing-targets/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  151. package/app/.next-cli-build/server/app/api/provider-health/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  153. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  154. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
  155. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  156. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  157. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  158. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  159. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  160. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  161. package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
  162. package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  163. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  164. package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
  165. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  166. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  167. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
  168. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
  169. package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
  170. package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
  171. package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
  172. package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
  173. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  174. package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
  175. package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
  176. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  177. package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
  178. package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
  179. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  180. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
  181. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  182. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
  183. package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
  184. package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
  185. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  186. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  187. package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
  188. package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
  189. package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
  190. package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
  191. package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
  192. package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
  193. package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
  194. package/app/.next-cli-build/server/app/api/tunnel/tailscale-login/route.js.nft.json +1 -1
  195. package/app/.next-cli-build/server/app/api/tunnel/tailscale-start-daemon/route.js.nft.json +1 -1
  196. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  197. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  198. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  199. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  200. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  201. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  202. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  203. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  204. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js +1 -1
  205. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  206. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  207. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  208. package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
  209. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js +1 -1
  210. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  211. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  212. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  213. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
  214. package/app/.next-cli-build/server/app/api/v1/messages/route.js +1 -1
  215. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  216. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  217. package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
  218. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  219. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js +1 -1
  220. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  221. package/app/.next-cli-build/server/app/api/v1/responses/route.js +1 -1
  222. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  223. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  224. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  225. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  226. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js +1 -1
  227. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  228. package/app/.next-cli-build/server/app/api/v1beta/models/route.js +1 -1
  229. package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
  230. package/app/.next-cli-build/server/app/api/version/restart/route.js.nft.json +1 -1
  231. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  232. package/app/.next-cli-build/server/app/api/version/route.js.nft.json +1 -1
  233. package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  234. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  235. package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  236. package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
  237. package/app/.next-cli-build/server/app/api/virtual-combos/[id]/route.js +1 -1
  238. package/app/.next-cli-build/server/app/api/virtual-combos/[id]/route.js.nft.json +1 -1
  239. package/app/.next-cli-build/server/app/api/virtual-combos/preview/route.js +1 -1
  240. package/app/.next-cli-build/server/app/api/virtual-combos/preview/route.js.nft.json +1 -1
  241. package/app/.next-cli-build/server/app/api/virtual-combos/route.js +1 -1
  242. package/app/.next-cli-build/server/app/api/virtual-combos/route.js.nft.json +1 -1
  243. package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
  244. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  245. package/app/.next-cli-build/server/app/callback.html +1 -1
  246. package/app/.next-cli-build/server/app/callback.rsc +3 -3
  247. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
  248. package/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  249. package/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
  250. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  251. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  252. package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  253. package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  254. package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
  255. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  256. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  257. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  258. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  259. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
  260. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  261. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
  262. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  263. package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  264. package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
  265. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  266. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  267. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  268. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  269. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
  270. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  271. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  272. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
  273. package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  274. package/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
  275. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  276. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  277. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  278. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  279. package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
  280. package/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  281. package/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  282. package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  283. package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  284. package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
  285. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +3 -3
  286. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  287. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  288. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  289. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
  290. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  291. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  292. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  293. package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  294. package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
  295. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  296. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  297. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  298. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  299. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  300. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
  301. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  302. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
  303. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  304. package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  305. package/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
  306. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  307. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  308. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  309. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  310. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
  311. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  312. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
  313. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  314. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.html +1 -1
  315. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.rsc +5 -5
  316. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard/ollama-nodes/__PAGE__.segment.rsc +2 -2
  317. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard/ollama-nodes.segment.rsc +1 -1
  318. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  319. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  320. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_full.segment.rsc +5 -5
  321. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_head.segment.rsc +1 -1
  322. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_index.segment.rsc +3 -3
  323. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_tree.segment.rsc +1 -1
  324. package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  325. package/app/.next-cli-build/server/app/dashboard/profile.rsc +4 -4
  326. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +1 -1
  327. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  328. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  329. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  330. package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +4 -4
  331. package/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  332. package/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  333. package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  334. package/app/.next-cli-build/server/app/dashboard/prompt-logs.html +1 -1
  335. package/app/.next-cli-build/server/app/dashboard/prompt-logs.rsc +4 -4
  336. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs/__PAGE__.segment.rsc +1 -1
  337. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs.segment.rsc +1 -1
  338. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  339. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  340. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_full.segment.rsc +4 -4
  341. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_head.segment.rsc +1 -1
  342. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_index.segment.rsc +3 -3
  343. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_tree.segment.rsc +1 -1
  344. package/app/.next-cli-build/server/app/dashboard/provider-health.html +1 -1
  345. package/app/.next-cli-build/server/app/dashboard/provider-health.rsc +4 -4
  346. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health/__PAGE__.segment.rsc +1 -1
  347. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health.segment.rsc +1 -1
  348. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  349. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  350. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_full.segment.rsc +4 -4
  351. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_head.segment.rsc +1 -1
  352. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_index.segment.rsc +3 -3
  353. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_tree.segment.rsc +1 -1
  354. package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  355. package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
  356. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  357. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  358. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  359. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  360. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  361. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
  362. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  363. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  364. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  365. package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  366. package/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
  367. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  368. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  369. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  370. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  371. package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
  372. package/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  373. package/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  374. package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
  375. package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  376. package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
  377. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  378. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  379. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  380. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  381. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
  382. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  383. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
  384. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  385. package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  386. package/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
  387. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  388. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  389. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  390. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  391. package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
  392. package/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  393. package/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
  394. package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  395. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
  396. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  397. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  398. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
  399. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
  400. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  401. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  402. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  403. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  404. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  405. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  406. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  407. package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
  408. package/app/.next-cli-build/server/app/dashboard/skills.rsc +5 -5
  409. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
  410. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
  411. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  412. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  413. package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +5 -5
  414. package/app/.next-cli-build/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
  415. package/app/.next-cli-build/server/app/dashboard/skills.segments/_index.segment.rsc +3 -3
  416. package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
  417. package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  418. package/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
  419. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  420. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  421. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  422. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  423. package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
  424. package/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  425. package/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  426. package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  427. package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  428. package/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
  429. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  430. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  431. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  432. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  433. package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
  434. package/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  435. package/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  436. package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  437. package/app/.next-cli-build/server/app/dashboard/virtual-combos.html +1 -1
  438. package/app/.next-cli-build/server/app/dashboard/virtual-combos.rsc +5 -5
  439. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard/virtual-combos/__PAGE__.segment.rsc +2 -2
  440. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard/virtual-combos.segment.rsc +1 -1
  441. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  442. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  443. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_full.segment.rsc +5 -5
  444. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_head.segment.rsc +1 -1
  445. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_index.segment.rsc +3 -3
  446. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_tree.segment.rsc +1 -1
  447. package/app/.next-cli-build/server/app/dashboard.html +1 -1
  448. package/app/.next-cli-build/server/app/dashboard.rsc +5 -5
  449. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  450. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  451. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  452. package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
  453. package/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  454. package/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
  455. package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  456. package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +1 -1
  457. package/app/.next-cli-build/server/app/index.html +1 -1
  458. package/app/.next-cli-build/server/app/index.rsc +3 -3
  459. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  460. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
  461. package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  462. package/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
  463. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  464. package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
  465. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  466. package/app/.next-cli-build/server/app/landing.html +1 -1
  467. package/app/.next-cli-build/server/app/landing.rsc +3 -3
  468. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
  469. package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  470. package/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
  471. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  472. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  473. package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  474. package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
  475. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  476. package/app/.next-cli-build/server/app/login.html +1 -1
  477. package/app/.next-cli-build/server/app/login.rsc +3 -3
  478. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +3 -3
  479. package/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  480. package/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
  481. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  482. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  483. package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  484. package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  485. package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
  486. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  487. package/app/.next-cli-build/server/app-paths-manifest.json +6 -6
  488. package/app/.next-cli-build/server/chunks/1807.js +1 -1
  489. package/app/.next-cli-build/server/chunks/3110.js +1 -1
  490. package/app/.next-cli-build/server/chunks/4746.js +1 -1
  491. package/app/.next-cli-build/server/chunks/6774.js +1 -0
  492. package/app/.next-cli-build/server/chunks/7130.js +1 -1
  493. package/app/.next-cli-build/server/chunks/7153.js +1 -1
  494. package/app/.next-cli-build/server/chunks/8255.js +1 -1
  495. package/app/.next-cli-build/server/chunks/9253.js +1 -1
  496. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  497. package/app/.next-cli-build/server/pages/404.html +1 -1
  498. package/app/.next-cli-build/server/pages/500.html +1 -1
  499. package/app/.next-cli-build/static/chunks/{1321-aee41561605fce5d.js → 1321-be4987849d0d77ef.js} +1 -1
  500. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/virtual-combos/page-4fba37a81c92fe67.js +15 -0
  501. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.65-to-1.0.66-1.0.66-20260528-095206/data.sqlite +0 -0
  502. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.66-to-1.0.67-1.0.67-20260528-100724/data.sqlite +0 -0
  503. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-shm +0 -0
  504. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-wal +0 -0
  505. package/app/package.json +1 -1
  506. package/package.json +1 -1
  507. package/app/.next-cli-build/server/chunks/1661.js +0 -1
  508. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/virtual-combos/page-606188fef0d6c05c.js +0 -15
  509. /package/app/.next-cli-build/static/{E9eCxEkATqY52-r92l_3- → 3Q8AwccjLy8JolXgCc7Xe}/_buildManifest.js +0 -0
  510. /package/app/.next-cli-build/static/{E9eCxEkATqY52-r92l_3- → 3Q8AwccjLy8JolXgCc7Xe}/_ssgManifest.js +0 -0
@@ -0,0 +1,15 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6967],{53677:(e,l,t)=>{"use strict";t.r(l),t.d(l,{default:()=>w});var a=t(95155),o=t(12115);let r=[{value:"virtual",label:"Provider / LAN target combo"},{value:"ollama-local",label:"Ollama Local Combo"}],s=[{value:"fallback",label:"Fallback priority"},{value:"least-latency",label:"Least latency"},{value:"p2c",label:"P2C"}],n=[{value:"best-fit",label:"Best fit"},{value:"loaded-first",label:"Loaded first"},{value:"lowest-latency",label:"Lowest latency"},{value:"balanced",label:"Balanced"}],d=`qwen3-coder:30b | priority=100
2
+ qwen3-coder:latest | priority=95
3
+ qwen2.5-coder:14b | priority=80
4
+ deepseek-coder:6.7b | priority=60`,i={"auto/offline-fast":{name:"auto/offline-fast",exposedModel:"auto/offline-fast",description:"Fast local Ollama chat models.",modelPatternsText:`glm-4.7-flash:latest | priority=100
5
+ gemma4:e4b | priority=90
6
+ gemma:7b | priority=80
7
+ llama3.1:8b | priority=70`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!1,allowCpuFallback:!0,allowMultiGpuSplit:!1,maxWakeVramMb:"12000",maxWakeRamMb:"16384",selectionPolicy:"loaded-first"},"auto/offline-coding":{name:"auto/offline-coding",exposedModel:"auto/offline-coding",description:"Local coding models with RAM/VRAM preflight.",modelPatternsText:d,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!0,allowCpuFallback:!1,allowMultiGpuSplit:!1,maxWakeVramMb:"28000",maxWakeRamMb:"32768",selectionPolicy:"best-fit"},"auto/offline-vision":{name:"auto/offline-vision",exposedModel:"auto/offline-vision",description:"Local vision models.",modelPatternsText:`qwen2.5vl:7b | priority=100
8
+ qwen2.5vl:latest | priority=95
9
+ llama3.2-vision:latest | priority=80`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!0,allowCpuFallback:!1,allowMultiGpuSplit:!1,maxWakeVramMb:"18000",maxWakeRamMb:"24576",selectionPolicy:"best-fit"},"auto/offline-translate":{name:"auto/offline-translate",exposedModel:"auto/offline-translate",description:"Local translation models.",modelPatternsText:`qwen3-jp-vi-translate:latest | priority=100
10
+ qwen3-jp-vi-k2-translate-f16:latest | priority=95
11
+ qwen3-ijs-k4-translate:latest | priority=90
12
+ qwen3-ijs-k4-translate-vn2jp:latest | priority=85
13
+ qwen3-mail-translate-f16:latest | priority=80
14
+ qwen3-prc-sc-k2-translate-jp2vn:latest | priority=75`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!1,allowCpuFallback:!0,allowMultiGpuSplit:!1,maxWakeVramMb:"24000",maxWakeRamMb:"32768",selectionPolicy:"loaded-first"},"auto/offline-embed":{name:"auto/offline-embed",exposedModel:"auto/offline-embed",description:"Local embedding models.",modelPatternsText:`bge-m3:latest | priority=100
15
+ mxbai-embed-large:latest | priority=90`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!1,allowCpuFallback:!0,allowMultiGpuSplit:!1,maxWakeVramMb:"4096",maxWakeRamMb:"8192",selectionPolicy:"lowest-latency"}};function c(e){return String(e||"").trim()}let m=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function x(e){return m.test(c(e))}function u(e={}){for(let l of[e.exposedModel,e.model,e.name,e.id]){let e=c(l);if(e&&!x(e))return e}return""}function p(e={}){return e?.type==="ollama-local"?u(e)||"Missing exposed model":c(e.name||e.exposedModel||e.model||e.id)||"Unnamed combo"}function b(e={}){let l=c(e.id||e.name);return x(l)?l:""}function g(e){return Array.isArray(e)?e.join(", "):c(e)}function f(e=""){return[...new Set(String(e||"").split(/[\n,;]+/).map(e=>e.trim()).filter(Boolean))]}function h(e){let l=String(e||"").split("|").map(e=>e.trim()).filter(Boolean),t=c(l.shift());if(!t)return null;let a={model:t,label:t,tags:[]};for(let e of l){let l=e.indexOf("=");if(l<=0)continue;let t=e.slice(0,l).trim().toLowerCase(),o=e.slice(l+1).trim();"connection"===t||"connectionid"===t||"account"===t?a.connectionId=o:"label"===t||"name"===t?a.label=o:"endpoint"===t||"url"===t||"baseurl"===t?a.endpoint=o:"tags"===t||"labels"===t?a.tags=f(o):"max"===t||"maxinflight"===t?a.maxInFlight=Number(o)||void 0:"provider"===t&&(a.provider=o)}return a}let y={type:"virtual",name:"",exposedModel:"",enabled:!0,strategy:"least-latency",requiredTagsText:"",modelRulesText:"",targetsText:"",description:"",modelPatternsText:d,allowedNodeIdsText:"",allowedPortsText:"",preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!0,allowCpuFallback:!1,allowMultiGpuSplit:!1,maxWakeVramMb:"28000",maxWakeRamMb:"32768",fallbackCombo:"",selectionPolicy:"best-fit"};function j(e){let l="ollama-local"===e.type,t=c(e.exposedModel||e.name),a=l?t:c(e.name),o={id:a,name:a,exposedModel:l?t:c(e.exposedModel||e.name),enabled:!1!==e.enabled,type:e.type||"virtual",strategy:e.strategy||"least-latency",requiredTags:f(e.requiredTagsText),modelTagRules:function(e=""){let l={};for(let t of String(e||"").split(/\n+/)){let e=t.trim();if(!e)continue;let a=e.indexOf(":");if(a<=0)continue;let o=e.slice(0,a).trim(),r=f(e.slice(a+1));o&&r.length&&(l[o]=r)}return l}(e.modelRulesText),targets:"ollama-local"===e.type?[]:function(e=""){return String(e||"").split(/\n+/).map(h).filter(Boolean)}(e.targetsText),description:c(e.description)};return"ollama-local"===e.type&&(o.localOllama={modelPatterns:function(e=""){return String(e||"").split(/\n+/).map((e,l)=>{let t=e.split("|").map(e=>e.trim()).filter(Boolean),a=t.shift();if(!a)return null;let o={pattern:a,priority:Math.max(1,100-5*l),enabled:!0};for(let e of t){let[l,...t]=e.split("="),a=l.trim().toLowerCase(),r=t.join("=").trim();("priority"===a||"prio"===a)&&(o.priority=Number(r)||o.priority),"enabled"===a&&(o.enabled="false"!==r&&"0"!==r),("notes"===a||"note"===a)&&(o.notes=r)}return o}).filter(Boolean)}(e.modelPatternsText),allowedNodeIds:f(e.allowedNodeIdsText),allowedPorts:f(e.allowedPortsText).map(Number).filter(e=>Number.isFinite(e)&&e>0),preferLoaded:!1!==e.preferLoaded,allowWakeSleeping:!1!==e.allowWakeSleeping,requireGpu:!0===e.requireGpu,allowCpuFallback:!0===e.allowCpuFallback,allowMultiGpuSplit:!0===e.allowMultiGpuSplit,maxWakeVramMb:Number(e.maxWakeVramMb||0)||0,maxWakeRamMb:Number(e.maxWakeRamMb||0)||0,fallbackCombo:c(e.fallbackCombo),selectionPolicy:e.selectionPolicy||"best-fit"}),o}function v({label:e,description:l,checked:t,onChange:o}){return(0,a.jsxs)("label",{className:"flex items-start gap-3 rounded-xl border border-border bg-surface-1 p-3",children:[(0,a.jsx)("input",{type:"checkbox",checked:t,onChange:e=>o(e.target.checked),className:"mt-1 h-4 w-4 accent-primary"}),(0,a.jsxs)("span",{children:[(0,a.jsx)("span",{className:"block text-sm font-medium text-text-main",children:e}),l?(0,a.jsx)("span",{className:"mt-0.5 block text-xs text-text-muted",children:l}):null]})]})}function k({children:e}){return(0,a.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:e})}function N({preview:e}){if(!e)return null;let l=e.selected;return(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Routing Preview"}),e.error?(0,a.jsx)("p",{className:"mt-2 text-sm text-red-600",children:e.error}):null,l?(0,a.jsxs)("div",{className:"mt-3 rounded-xl border border-green-200 bg-green-50 p-3 text-sm text-green-900 dark:border-green-500/30 dark:bg-green-500/10 dark:text-green-100",children:[(0,a.jsxs)("div",{className:"font-semibold",children:["Selected: ",l.nodeName,":",l.port," / ",l.model]}),(0,a.jsxs)("div",{className:"mt-1 text-xs",children:[l.reason," \xb7 score ",l.score," \xb7 ",l.loaded?"loaded":"sleeping"," \xb7 ",l.endpoint]}),(0,a.jsxs)("div",{className:"mt-1 text-xs",children:["GPU scope: ",(l.gpuIndices||[]).length?l.gpuIndices.map(e=>`GPU ${e}`).join(", "):"none"," \xb7 VRAM free ",l.vramFreeMb||0,"MB"]})]}):(0,a.jsx)("p",{className:"mt-2 text-sm text-text-muted",children:"No eligible local target selected."}),(0,a.jsxs)("div",{className:"mt-3 grid gap-3 md:grid-cols-2",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"text-xs font-semibold uppercase text-text-muted",children:["Eligible (",e.eligible?.length||0,")"]}),(0,a.jsx)("div",{className:"mt-2 max-h-48 space-y-2 overflow-auto",children:(e.eligible||[]).slice(0,12).map(e=>(0,a.jsxs)("div",{className:"rounded-lg bg-background p-2 text-xs text-text-main",children:[(0,a.jsxs)("b",{children:[e.nodeName,":",e.port]})," ",e.model," \xb7 ",e.reason," \xb7 score ",e.score]},e.id))})]}),(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"text-xs font-semibold uppercase text-text-muted",children:["Rejected (",e.rejected?.length||0,")"]}),(0,a.jsx)("div",{className:"mt-2 max-h-48 space-y-2 overflow-auto",children:(e.rejected||[]).slice(0,20).map(e=>(0,a.jsxs)("div",{className:"rounded-lg bg-background p-2 text-xs text-text-muted",children:[(0,a.jsxs)("b",{children:[e.nodeName,":",e.port]})," ",e.model," \xb7 ",e.reason]},`${e.id}-${e.reason}`))})]})]})]})}function w(){let[e,l]=(0,o.useState)([]),[t,c]=(0,o.useState)(!0),[m,x]=(0,o.useState)(null),[f,h]=(0,o.useState)(y),[w,M]=(0,o.useState)(!1),[C,P]=(0,o.useState)(""),[T,S]=(0,o.useState)(null),[q,R]=(0,o.useState)(!1),O=(0,o.useMemo)(()=>e.filter(e=>!1!==e.enabled),[e]),W=(0,o.useMemo)(()=>e.filter(e=>"ollama-local"===e.type),[e]);(0,o.useEffect)(()=>{G()},[]);let G=async()=>{c(!0);try{let e=await fetch("/api/virtual-combos",{cache:"no-store"}),t=await e.json();e.ok?l(t.virtualCombos||[]):P(t.error||"Failed to load virtual combos")}catch(e){P(e?.message||"Failed to load virtual combos")}finally{c(!1)}},L=(e="virtual")=>{x(null),"ollama-local"===e?h({...y,type:"ollama-local",name:"auto/offline-coding",exposedModel:"auto/offline-coding"}):h({...y,type:"virtual",targetsText:"oc/qwen3:8b | tags=gpu,model_support:qwen3:8b\noc/qwen3:8b | connection=CONNECTION_ID | tags=gpu,vram:8gb",modelRulesText:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b"}),S(null),P("")},A=async()=>{let e=j(f);if(!e.name||!e.exposedModel)return void P("Name and exposed model are required.");if("ollama-local"===e.type&&!e.localOllama.modelPatterns.length)return void P("Ollama Local Combo requires at least one model pattern.");if("ollama-local"!==e.type&&0===e.targets.length)return void P("Provider/LAN virtual combo requires at least one target.");M(!0),P("");try{let l=m?encodeURIComponent(m.name||m.id||m.exposedModel):"",t=await fetch(m?`/api/virtual-combos/${l}`:"/api/virtual-combos",{method:m?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),a=await t.json().catch(()=>({}));if(!t.ok)return void P(a.error||"Save failed");x(null),h(y),S(null),await G()}catch(e){P(e?.message||"Save failed")}finally{M(!1)}},F=async()=>{if("ollama-local"===f.type){R(!0),P("");try{let e=await fetch("/api/virtual-combos/preview",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({combo:j(f),maxAgeMs:5e3})}),l=await e.json();if(!e.ok)return void P(l.error||"Preview failed");S(l)}catch(e){P(e?.message||"Preview failed")}finally{R(!1)}}},U=async e=>{if(!confirm(`Delete virtual combo ${p(e)}?`))return;let l=encodeURIComponent(e.name||e.id||e.exposedModel),t=await fetch(`/api/virtual-combos/${l}`,{method:"DELETE"});t.ok?await G():alert((await t.json().catch(()=>({}))).error||"Delete failed")},I=f!==y||m,V=I?f.type||(m?.type==="ollama-local"?"ollama-local":"virtual")||"virtual":"",$=e=>["rounded-xl border px-4 py-2 text-sm font-medium transition-all focus:outline-none focus:ring-2 focus:ring-primary/40 focus:ring-offset-1",V===e?"border-primary bg-primary text-white shadow-sm ring-2 ring-primary/20":"border-border bg-background text-text-main hover:border-primary/50 hover:bg-surface-2 hover:text-primary"].join(" ");return(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"text-2xl font-semibold text-text-main",children:"Virtual Combos"}),(0,a.jsx)("p",{className:"mt-1 max-w-3xl text-sm text-text-muted",children:"Expose one virtual model name and route it to provider targets or hardware-aware local Ollama model selectors."})]}),(0,a.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,a.jsxs)("button",{type:"button",onClick:()=>L("virtual"),className:$("virtual"),"aria-pressed":"virtual"===V,children:["virtual"===V?"✓ ":"","New Provider Combo"]}),(0,a.jsxs)("button",{type:"button",onClick:()=>L("ollama-local"),className:$("ollama-local"),"aria-pressed":"ollama-local"===V,children:["ollama-local"===V?"✓ ":"","New Ollama Local Combo"]})]})]}),C?(0,a.jsx)("div",{className:"rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200",children:C}):null,(0,a.jsx)("div",{className:"grid gap-3 md:grid-cols-5",children:Object.keys(i).map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>{let l;(l=i[e])&&(h({...y,type:"ollama-local",...l}),x(null),S(null),P(""))},className:"rounded-2xl border border-border bg-surface-1 p-3 text-left hover:bg-surface-2",children:[(0,a.jsx)("div",{className:"text-sm font-semibold text-text-main",children:e}),(0,a.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:"Load preset"})]},e))}),t?(0,a.jsx)("div",{className:"rounded-2xl border border-border bg-surface-1 p-8 text-sm text-text-muted",children:"Loading..."}):0===e.length?(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-8 text-center",children:[(0,a.jsx)("span",{className:"material-icons text-4xl text-text-muted",children:"hub"}),(0,a.jsx)("h2",{className:"mt-2 text-lg font-semibold text-text-main",children:"No virtual combos yet"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create a provider combo or a local Ollama combo."})]}):(0,a.jsx)("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:e.map(e=>(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,a.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:p(e)}),(0,a.jsxs)("p",{className:"font-mono text-xs text-text-muted",children:["model: ",u(e)||"missing exposed model"]}),b(e)?(0,a.jsxs)("p",{className:"mt-0.5 font-mono text-[10px] text-amber-600",children:["internal id: ",b(e)]}):null]}),(0,a.jsx)("span",{className:`rounded-full px-2 py-1 text-xs ${!1!==e.enabled?"bg-green-100 text-green-700 dark:bg-green-500/10 dark:text-green-300":"bg-surface-2 text-text-muted"}`,children:!1!==e.enabled?"enabled":"disabled"})]}),(0,a.jsxs)("div",{className:"mt-3 flex flex-wrap gap-2 text-xs text-text-muted",children:[(0,a.jsx)("span",{className:"rounded-full bg-surface-2 px-2 py-1",children:"ollama-local"===e.type?"Ollama Local Combo":"Provider Combo"}),"ollama-local"===e.type?(0,a.jsxs)("span",{className:"rounded-full bg-surface-2 px-2 py-1",children:[e.localOllama?.modelPatterns?.length||0," pattern(s)"]}):(0,a.jsxs)("span",{className:"rounded-full bg-surface-2 px-2 py-1",children:[e.strategy||"least-latency"," \xb7 ",e.targets?.length||0," target(s)"]})]}),"ollama-local"===e.type?(0,a.jsx)("div",{className:"mt-3 space-y-1 text-xs text-text-muted",children:(e.localOllama?.modelPatterns||[]).slice(0,5).map(e=>(0,a.jsxs)("div",{className:"font-mono",children:[e.pattern," \xb7 p",e.priority]},e.pattern))}):(0,a.jsx)("div",{className:"mt-3 space-y-1 text-xs text-text-muted",children:(e.targets||[]).slice(0,4).map((e,l)=>(0,a.jsx)("div",{className:"font-mono",children:e.label||e.model},`${e.model}-${l}`))}),(0,a.jsxs)("div",{className:"mt-4 flex gap-2",children:[(0,a.jsx)("button",{onClick:()=>{x(e),h(function(e){if(!e)return y;let l=e.localOllama||{},t="ollama-local"===e.type;return{...y,type:t?"ollama-local":"virtual",name:t?u(e)||"":e.name||"",exposedModel:u(e)||e.exposedModel||e.model||e.name||"",enabled:!1!==e.enabled,strategy:e.strategy||e.fallbackStrategy||"least-latency",requiredTagsText:g(e.requiredTags||e.tags||[]),modelRulesText:function(e={}){return Object.entries(e||{}).map(([e,l])=>`${e}: ${Array.isArray(l)?l.join(", "):l}`).join("\n")}(e.modelTagRules||{}),targetsText:function(e=[]){return(e||[]).map(e=>{let l=[e.model||""];return e.connectionId&&l.push(`connection=${e.connectionId}`),e.label&&l.push(`label=${e.label}`),e.endpoint&&l.push(`endpoint=${e.endpoint}`),e.tags?.length&&l.push(`tags=${e.tags.join(",")}`),e.maxInFlight&&l.push(`max=${e.maxInFlight}`),l.filter(Boolean).join(" | ")}).join("\n")}(e.targets||e.endpoints||e.models||[]),description:e.description||"",modelPatternsText:function(e=[]){return(e||[]).map((e,l)=>{if("string"==typeof e)return`${e} | priority=${Math.max(1,100-5*l)}`;let t=[e.pattern||e.model||e.name||""];return t.push(`priority=${Number(e.priority||Math.max(1,100-5*l))}`),!1===e.enabled&&t.push("enabled=false"),e.notes&&t.push(`notes=${e.notes}`),t.filter(Boolean).join(" | ")}).join("\n")}(l.modelPatterns||[]),allowedNodeIdsText:g(l.allowedNodeIds||[]),allowedPortsText:Array.isArray(l.allowedPorts)?l.allowedPorts.join(","):"",preferLoaded:!1!==l.preferLoaded,allowWakeSleeping:!1!==l.allowWakeSleeping,requireGpu:!0===l.requireGpu,allowCpuFallback:!1!==l.allowCpuFallback,allowMultiGpuSplit:!0===l.allowMultiGpuSplit,maxWakeVramMb:String(l.maxWakeVramMb||""),maxWakeRamMb:String(l.maxWakeRamMb||""),fallbackCombo:l.fallbackCombo||"",selectionPolicy:l.selectionPolicy||"best-fit"}}(e)),S(null),P("")},className:"rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-text-main hover:bg-surface",children:"Edit"}),(0,a.jsx)("button",{onClick:()=>U(e),className:"rounded-lg border border-red-200 px-3 py-1.5 text-xs font-medium text-red-600 hover:bg-red-50 dark:border-red-500/30 dark:hover:bg-red-500/10",children:"Delete"})]})]},e.name||e.id))}),I?(0,a.jsxs)("div",{className:"grid gap-4 xl:grid-cols-[minmax(0,1fr)_420px]",children:[(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-5",children:[(0,a.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:m?"Edit Virtual Combo":"Create Virtual Combo"}),(0,a.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[O.length," active combo(s), ",W.length," local Ollama combo(s)."]}),(0,a.jsxs)("div",{className:"mt-5 grid gap-4 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Type"}),(0,a.jsx)("select",{value:f.type,onChange:e=>h({...f,type: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:r.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Enabled"}),(0,a.jsxs)("label",{className:"flex h-[42px] items-center gap-2 rounded-xl border border-border bg-background px-3 text-sm text-text-main",children:[(0,a.jsx)("input",{type:"checkbox",checked:f.enabled,onChange:e=>h({...f,enabled:e.target.checked}),className:"h-4 w-4 accent-primary"})," Enabled"]})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Name / ID"}),(0,a.jsx)("input",{value:f.name,onChange:e=>h({...f,name:e.target.value,exposedModel:f.exposedModel||e.target.value}),placeholder:"auto/offline-coding",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Unique combo ID. The slash format is supported, for example auto/offline-coding."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Exposed model"}),(0,a.jsx)("input",{value:f.exposedModel,onChange:e=>h({...f,exposedModel:e.target.value}),placeholder:"auto/offline-coding",className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Clients call this model name. BlueRouter resolves it to an upstream provider model or an Ollama instance target."})]})]}),"ollama-local"===f.type?(0,a.jsx)("div",{className:"mt-5 space-y-5",children:(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-background p-4",children:[(0,a.jsx)("h3",{className:"font-semibold text-text-main",children:"Ollama Local Combo"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"This combo stores model patterns only. At request time BlueRouter selects the best node, port, model, and GPU scope using the Ollama Node reports."}),(0,a.jsxs)("div",{className:"mt-4 grid gap-4 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block md:col-span-2",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Model patterns + priority"}),(0,a.jsx)("textarea",{value:f.modelPatternsText,onChange:e=>h({...f,modelPatternsText:e.target.value}),rows:8,placeholder:d,className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"One model per line. Syntax: model-pattern | priority=100. Wildcards like qwen3-coder:* are allowed."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Allowed nodes"}),(0,a.jsx)("input",{value:f.allowedNodeIdsText,onChange:e=>h({...f,allowedNodeIdsText:e.target.value}),placeholder:"empty = all nodes",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Comma-separated node IDs. Empty means all enabled Ollama nodes."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Allowed instance ports"}),(0,a.jsx)("input",{value:f.allowedPortsText,onChange:e=>h({...f,allowedPortsText:e.target.value}),placeholder:"11434,11435 or empty",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Limit this combo to specific Ollama ports. Empty means all enabled instances."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Selection policy"}),(0,a.jsx)("select",{value:f.selectionPolicy,onChange:e=>h({...f,selectionPolicy: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:n.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,a.jsx)(k,{children:"Best fit filters by memory and scores loaded status, model priority, GPU scope, free VRAM/RAM, latency and errors."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Fallback combo"}),(0,a.jsx)("input",{value:f.fallbackCombo,onChange:e=>h({...f,fallbackCombo:e.target.value}),placeholder:"empty = local only",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Optional combo/model to call if no local target is eligible. Empty means fail local-only."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Max wake VRAM MB"}),(0,a.jsx)("input",{value:f.maxWakeVramMb,onChange:e=>h({...f,maxWakeVramMb:e.target.value}),placeholder:"0 = no cap",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Cap for sleeping model wake cost. Loaded models use loaded overhead instead."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Max wake RAM MB"}),(0,a.jsx)("input",{value:f.maxWakeRamMb,onChange:e=>h({...f,maxWakeRamMb:e.target.value}),placeholder:"0 = no cap",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(k,{children:"Cap host RAM cost when waking sleeping models."})]})]}),(0,a.jsxs)("div",{className:"mt-4 grid gap-3 md:grid-cols-2",children:[(0,a.jsx)(v,{label:"Prefer loaded models",checked:f.preferLoaded,onChange:e=>h({...f,preferLoaded:e}),description:"Prefer /api/ps loaded models to avoid wake latency and OOM risk."}),(0,a.jsx)(v,{label:"Allow wake sleeping models",checked:f.allowWakeSleeping,onChange:e=>h({...f,allowWakeSleeping:e}),description:"When off, only already-loaded local models are eligible."}),(0,a.jsx)(v,{label:"Require GPU",checked:f.requireGpu,onChange:e=>h({...f,requireGpu:e}),description:"Reject CPU-only or no-GPU-scope targets."}),(0,a.jsx)(v,{label:"Allow CPU fallback",checked:f.allowCpuFallback,onChange:e=>h({...f,allowCpuFallback:e}),description:"Allow CPU route if GPU is unavailable. Usually off for large coding/vision models."}),(0,a.jsx)(v,{label:"Allow multi-GPU split",checked:f.allowMultiGpuSplit,onChange:e=>h({...f,allowMultiGpuSplit:e}),description:"Only enable when the instance/model can split VRAM across GPUs."})]})]})}):(0,a.jsxs)("div",{className:"mt-5 grid gap-4 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Strategy"}),(0,a.jsx)("select",{value:f.strategy,onChange:e=>h({...f,strategy: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:s.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Required tags"}),(0,a.jsx)("input",{value:f.requiredTagsText,onChange:e=>h({...f,requiredTagsText:e.target.value}),placeholder:"gpu, vram:8gb",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"})]}),(0,a.jsxs)("label",{className:"block md:col-span-2",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Model tag rules"}),(0,a.jsx)("textarea",{value:f.modelRulesText,onChange:e=>h({...f,modelRulesText:e.target.value}),rows:3,placeholder:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b",className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary"})]}),(0,a.jsxs)("label",{className:"block md:col-span-2",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Targets"}),(0,a.jsx)("textarea",{value:f.targetsText,onChange:e=>h({...f,targetsText:e.target.value}),rows:8,placeholder:"oc/qwen3:8b | connection=abc123 | tags=gpu,vram:8gb\noc/qwen3:8b | tags=cpu",className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary"})]})]}),(0,a.jsxs)("label",{className:"mt-4 block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Description"}),(0,a.jsx)("input",{value:f.description,onChange:e=>h({...f,description: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"})]}),(0,a.jsxs)("div",{className:"mt-5 flex flex-wrap gap-2",children:[(0,a.jsx)("button",{type:"button",onClick:A,disabled:w,className:"rounded-xl bg-primary px-5 py-2 text-sm font-medium text-white hover:opacity-90 disabled:opacity-50",children:w?"Saving...":m?"Save":"Create"}),"ollama-local"===f.type?(0,a.jsx)("button",{type:"button",onClick:F,disabled:q,className:"rounded-xl border border-border px-5 py-2 text-sm font-medium text-text-main hover:bg-surface",children:q?"Previewing...":"Preview routing"}):null,(0,a.jsx)("button",{type:"button",onClick:()=>{x(null),h(y),S(null),P("")},className:"rounded-xl border border-border px-5 py-2 text-sm font-medium text-text-main hover:bg-surface",children:"Clear"})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Field meanings"}),(0,a.jsxs)("dl",{className:"mt-3 space-y-2 text-xs text-text-muted",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Model patterns"}),(0,a.jsx)("dd",{children:"Allowed local model names or wildcards. Priority decides model preference after hardware filtering."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Allowed nodes / ports"}),(0,a.jsx)("dd",{children:"Optional constraints. Empty means all enabled Ollama nodes and instances."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Prefer loaded"}),(0,a.jsx)("dd",{children:"Boosts models already in /api/ps to avoid waking large models."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Allow wake"}),(0,a.jsx)("dd",{children:"If disabled, sleeping models are rejected even if RAM/VRAM is enough."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Require GPU / CPU fallback"}),(0,a.jsx)("dd",{children:"Controls whether CPU-only/no-GPU-scope targets are eligible."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Multi-GPU split"}),(0,a.jsx)("dd",{children:"Allows aggregate VRAM only when you know that instance can split across GPUs."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Fallback combo"}),(0,a.jsx)("dd",{children:"Optional cloud/provider fallback. Empty keeps the combo local-only."})]})]})]}),(0,a.jsx)(N,{preview:T})]})]}):null]})}},67711:(e,l,t)=>{Promise.resolve().then(t.bind(t,53677))}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=67711)),_N_E=e.O()}]);
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bluerouter-app",
3
- "version": "1.0.65",
3
+ "version": "1.0.67",
4
4
  "description": "Router web dashboard",
5
5
  "private": false,
6
6
  "scripts": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jheavenknows/bluerouter",
3
- "version": "1.0.65",
3
+ "version": "1.0.67",
4
4
  "description": "Bluerouter CLI - Start and manage Bluerouter server",
5
5
  "bin": {
6
6
  "bluerouter": "./cli.js"
@@ -1 +0,0 @@
1
- "use strict";exports.id=1661,exports.ids=[1661],exports.modules={6774:(a,b,c)=>{c.d(b,{U1:()=>v,Vs:()=>w,YT:()=>z,iJ:()=>y,op:()=>A,ri:()=>x});var d=c(79748),e=c.n(d),f=c(33873),g=c.n(f),h=c(55511),i=c.n(h),j=c(21820),k=c.n(j),l=c(55013);let m=process.env.DATA_DIR||process.env.BLUEROUTER_DATA_DIR||g().join(k().homedir(),".bluerouter"),n=g().join(m,"ollama-nodes.json");async function o(){await e().mkdir(m,{recursive:!0});try{await e().access(n)}catch{await e().writeFile(n,JSON.stringify({nodes:[]},null,2))}}async function p(){await o();try{let a=await e().readFile(n,"utf8"),b=JSON.parse(a||"{}");return{nodes:Array.isArray(b.nodes)?b.nodes:[]}}catch{return{nodes:[]}}}async function q(a){await e().mkdir(m,{recursive:!0}),await e().writeFile(n,JSON.stringify({nodes:a.nodes||[]},null,2))}function r(){return new Date().toISOString()}function s(a,b={}){if(!a)return b;if("object"==typeof a&&!Array.isArray(a))return a;try{let c=JSON.parse(String(a));return c&&"object"==typeof c&&!Array.isArray(c)?c:b}catch{return b}}function t(a){return a?{...a,sshPassword:void 0,sudoPassword:void 0}:null}function u(a={},b={}){var c;let d=String(a.host??b.host??"").trim(),e=Number(a.agentPort??b.agentPort??19999)||19999,f=Array.isArray(c=a.ollamaPorts??b.ollamaPorts??[11434])?[...new Set(c.map(a=>Number(a)).filter(a=>Number.isFinite(a)&&a>0))]:[...new Set(String(c||"11434").split(/[\s,;]+/).map(a=>Number(a.trim())).filter(a=>Number.isFinite(a)&&a>0))],g=s(a.modelMemoryRequirements??b.modelMemoryRequirements,b.modelMemoryRequirements||{}),h=(0,l.nw)(g,{partial:!0,preserveEnabled:!0}),j=b.id||a.id||i().randomUUID(),k=String(a.agentToken??b.agentToken??i().randomBytes(24).toString("hex")).trim(),m=function(a,b,c={}){let d=new Map((Array.isArray(c.instances)?c.instances:[]).map(a=>[Number(a.port),a])),e=new Map((Array.isArray(a)?a:[]).map(a=>[Number(a.port),a]));return b.map(a=>(function(a={},b={}){var c;let d=Number(a.port??b.port??11434)||11434;return{id:String(a.id??b.id??`ollama-${d}`).trim()||`ollama-${d}`,name:String(a.name??b.name??`Ollama :${d}`).trim()||`Ollama :${d}`,port:d,enabled:a.enabled??b.enabled??!0,gpuMode:["auto","cpu","specific","all"].includes(a.gpuMode??b.gpuMode)?a.gpuMode??b.gpuMode:"auto",gpuIndices:Array.isArray(c=a.gpuIndices??b.gpuIndices??[])?[...new Set(c.map(a=>Number(a)).filter(a=>Number.isInteger(a)&&a>=0))]:[...new Set(String(c||"").split(/[\s,;]+/).map(a=>Number(a)).filter(a=>Number.isInteger(a)&&a>=0))],allowMultiGpuSplit:a.allowMultiGpuSplit??b.allowMultiGpuSplit??!1,tags:Array.isArray(a.tags??b.tags)?(a.tags??b.tags).map(a=>String(a).trim()).filter(Boolean):[],modelMemoryRequirements:(0,l.nw)(s(a.modelMemoryRequirements??b.modelMemoryRequirements,b.modelMemoryRequirements||{}),{partial:!0,preserveEnabled:!0})}})(e.get(Number(a))||{},d.get(Number(a))||{port:a}))}(a.instances??b.instances,f.length?f:[11434],b);return{id:j,name:String(a.name??b.name??d??"Ollama Node").trim()||d||"Ollama Node",host:d,sshPort:Number(a.sshPort??b.sshPort??22)||22,sshUser:String(a.sshUser??b.sshUser??"root").trim()||"root",useSudo:a.useSudo??b.useSudo??!1,agentPort:e,agentToken:k,ollamaPorts:f.length?f:[11434],instances:m,refreshIntervalMs:Math.max(5e3,Number(a.refreshIntervalMs??b.refreshIntervalMs??15e3)||15e3),enabled:a.enabled??b.enabled??!0,ufwAllowFrom:String(a.ufwAllowFrom??b.ufwAllowFrom??"").trim(),useGlobalModelMemory:a.useGlobalModelMemory??b.useGlobalModelMemory??!0,modelMemoryRequirements:h,notes:String(a.notes??b.notes??"").trim(),lastStatus:b.lastStatus||null,lastEvaluation:b.lastEvaluation||null,lastStatusAt:b.lastStatusAt||null,lastError:b.lastError||null,lastInstallAt:b.lastInstallAt||null,lastInstallOk:b.lastInstallOk||!1,lastInstallLog:b.lastInstallLog||"",createdAt:b.createdAt||r(),updatedAt:r()}}async function v(){return(await p()).nodes.map(a=>t(u(a,a)))}async function w(a){let b=(await p()).nodes.find(b=>b.id===a)||null;return b?u(b,b):null}async function x(a){let b=await p(),c=u(a);return b.nodes.push(c),await q(b),t(c)}async function y(a,b){let c=await p(),d=c.nodes.findIndex(b=>b.id===a);if(d<0)return null;let e=u(b,c.nodes[d]);return c.nodes[d]=e,await q(c),t(e)}async function z(a,b){let c=await p(),d=c.nodes.findIndex(b=>b.id===a);return d<0?null:(c.nodes[d]={...c.nodes[d],...b,updatedAt:r()},await q(c),t(u(c.nodes[d],c.nodes[d])))}async function A(a){let b=await p(),c=b.nodes.length;return b.nodes=b.nodes.filter(b=>b.id!==a),await q(b),b.nodes.length!==c}},35448:(a,b,c)=>{c.d(b,{Hj:()=>w,_:()=>t,lz:()=>u,y3:()=>v});var d=c(79748),e=c.n(d),f=c(33873),g=c.n(f),h=c(55511),i=c.n(h),j=c(21820),k=c.n(j);let l=process.env.DATA_DIR||process.env.BLUEROUTER_DATA_DIR||g().join(k().homedir(),".bluerouter"),m=g().join(l,"ollama-memory-reservations.json");async function n(){await e().mkdir(l,{recursive:!0});try{await e().access(m)}catch{await e().writeFile(m,JSON.stringify({reservations:[]},null,2))}}async function o(){await n();try{let a=await e().readFile(m,"utf8"),b=JSON.parse(a||"{}");return{reservations:Array.isArray(b.reservations)?b.reservations:[]}}catch{return{reservations:[]}}}async function p(a){await e().mkdir(l,{recursive:!0}),await e().writeFile(m,JSON.stringify({reservations:a.reservations||[]},null,2))}function q(){return Date.now()}function r(a){let b=new Date(a.expiresAt).getTime();return Number.isFinite(b)&&b>q()}async function s(){let a=await o(),b=a.reservations.filter(r);return b.length!==a.reservations.length&&(a.reservations=b,await p(a)),b}async function t(a={}){return(await s()).filter(b=>(!a.nodeId||b.nodeId===a.nodeId)&&(!a.instanceId||b.instanceId===a.instanceId)&&(!a.port||Number(b.port)===Number(a.port)))}async function u(a){let b=await o();b.reservations=b.reservations.filter(r);let c=function(a={}){let b=Math.max(1e3,Number(a.ttlMs||6e4)),c=q();return{id:a.id||i().randomUUID(),nodeId:String(a.nodeId||"").trim(),instanceId:String(a.instanceId||"").trim(),port:Number(a.port||0)||null,model:String(a.model||"").trim(),ramMb:Math.max(0,Number(a.ramMb||0)),vramMb:Math.max(0,Number(a.vramMb||0)),gpuIndices:Array.isArray(a.gpuIndices)?a.gpuIndices.map(Number).filter(a=>Number.isInteger(a)&&a>=0):[],reason:String(a.reason||"wake-model").trim(),createdAt:new Date(c).toISOString(),expiresAt:new Date(c+b).toISOString()}}(a);return b.reservations.push(c),await p(b),c}async function v(a){let b=await o(),c=b.reservations.length;return b.reservations=b.reservations.filter(b=>b.id!==a),await p(b),b.reservations.length!==c}function w(a=[]){let b={ramMb:0,vramByGpu:{},vramUnscopedMb:0};for(let c of a)if(b.ramMb+=Number(c.ramMb||0),Array.isArray(c.gpuIndices)&&c.gpuIndices.length){let a=Number(c.vramMb||0)/c.gpuIndices.length;for(let d of c.gpuIndices)b.vramByGpu[d]=(b.vramByGpu[d]||0)+a}else b.vramUnscopedMb+=Number(c.vramMb||0);return b}},55013:(a,b,c)=>{c.d(b,{LM:()=>v,LQ:()=>u,MW:()=>s,dV:()=>l,eY:()=>t,iP:()=>m,nw:()=>o});var d=c(79748),e=c.n(d),f=c(33873),g=c.n(f),h=c(21820),i=c.n(h);let j=process.env.DATA_DIR||process.env.BLUEROUTER_DATA_DIR||g().join(i().homedir(),".bluerouter"),k=g().join(j,"ollama-model-memory.json"),l={"qwen3:1.7b":{minRamFreeMb:2048,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"small text model"},"qwen3:4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:512,notes:"small/medium text model"},"qwen3:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"8B text model"},"qwen3:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"14B class model"},"qwen3:32b":{minRamFreeMb:4096,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"32B class model, GPU preferred"},"qwen3-coder:30b":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"30B coder"},"qwen3-coder:latest":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"qwen3 coder latest, treat as 30B unless overridden"},"qwen2.5-coder:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"14B coder"},"qwen2.5vl:7b":{minRamFreeMb:8192,minVramFreeMb:8e3,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"7B vision-language"},"qwen2.5vl:latest":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"vision-language latest"},"bge-m3:latest":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"embedding model"},"deepseek-coder:6.7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"6.7B coder"},"gemma4:e4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"small Gemma variant"},"gemma:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"7B text model"},"glm-4.7-flash:latest":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"flash/local text model"},"gpt-oss:20b":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"20B class model"},"llama3.1:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"8B text model"},"llama3.2-vision:latest":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"vision model"},"qwen3-*-translate-f16:*":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom Qwen3 f16 translate wildcard"},"qwen3-*-translate*:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom Qwen3 translate wildcard"},"bge-m3:*":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"embedding model wildcard"},"gemma*:e4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"Gemma E4B wildcard"},"gemma*:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"Gemma 7B wildcard"},"*:1.7b":{minRamFreeMb:2048,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"generic 1.7B fallback"},"*:4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:512,notes:"generic 4B fallback"},"*:6.7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 6-7B fallback"},"*:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 7B fallback"},"*:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 8B fallback"},"*:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"generic 14B fallback"},"*:20b":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"generic 20B fallback"},"*:30b":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"generic 30B fallback"},"*:32b":{minRamFreeMb:4096,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"generic 32B fallback"}},m=["minRamFreeMb","minVramFreeMb","loadedRamFreeMb","loadedVramFreeMb","safetyMarginMb"];function n(a,b=0){let c=Number(a);return Number.isFinite(c)&&c>=0?c:b}function o(a={},b={}){let c={};if(!a||"object"!=typeof a||Array.isArray(a))return c;for(let[d,e]of Object.entries(a)){let a=String(d||"").trim();if(!a||!e||"object"!=typeof e||Array.isArray(e))continue;let f=function(a,{partial:b=!1,preserveEnabled:c=!1}={}){let d={};for(let c of m)if(b){var e;null!=(e=a?.[c])&&""!==String(e).trim()&&(d[c]=n(a[c],0))}else d[c]=n(a?.[c],0);let f=String(a?.notes||"").trim();return f&&(d.notes=f),c&&a&&Object.prototype.hasOwnProperty.call(a,"enabled")&&(d.enabled=!1!==a.enabled),d}(e,b),g=m.some(a=>Object.prototype.hasOwnProperty.call(f,a)),h=b.preserveEnabled&&Object.prototype.hasOwnProperty.call(f,"enabled");(g||f.notes||h)&&(c[a]=f)}return c}async function p(){await e().mkdir(j,{recursive:!0});try{await e().access(k)}catch{await e().writeFile(k,JSON.stringify({requirements:l,updatedAt:new Date().toISOString()},null,2))}}async function q(){await p();try{let a=await e().readFile(k,"utf8"),b=JSON.parse(a||"{}");return{requirements:function(a={}){return o({...l,...a})}(b.requirements||{}),updatedAt:b.updatedAt||null}}catch{return{requirements:o(l),updatedAt:null}}}async function r(a){await e().mkdir(j,{recursive:!0});let b={requirements:o(a),updatedAt:new Date().toISOString()};return await e().writeFile(k,JSON.stringify(b,null,2)),b}async function s(){return(await q()).requirements}async function t(){return q()}async function u(a){return r(a)}async function v(){return r(l)}}};
@@ -1,15 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6967],{53677:(e,l,t)=>{"use strict";t.r(l),t.d(l,{default:()=>y});var a=t(95155),o=t(12115);let r=[{value:"virtual",label:"Provider / LAN target combo"},{value:"ollama-local",label:"Ollama Local Combo"}],s=[{value:"fallback",label:"Fallback priority"},{value:"least-latency",label:"Least latency"},{value:"p2c",label:"P2C"}],n=[{value:"best-fit",label:"Best fit"},{value:"loaded-first",label:"Loaded first"},{value:"lowest-latency",label:"Lowest latency"},{value:"balanced",label:"Balanced"}],d=`qwen3-coder:30b | priority=100
2
- qwen3-coder:latest | priority=95
3
- qwen2.5-coder:14b | priority=80
4
- deepseek-coder:6.7b | priority=60`,i={"auto/offline-fast":{name:"auto/offline-fast",exposedModel:"auto/offline-fast",description:"Fast local Ollama chat models.",modelPatternsText:`glm-4.7-flash:latest | priority=100
5
- gemma4:e4b | priority=90
6
- gemma:7b | priority=80
7
- llama3.1:8b | priority=70`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!1,allowCpuFallback:!0,allowMultiGpuSplit:!1,maxWakeVramMb:"12000",maxWakeRamMb:"16384",selectionPolicy:"loaded-first"},"auto/offline-coding":{name:"auto/offline-coding",exposedModel:"auto/offline-coding",description:"Local coding models with RAM/VRAM preflight.",modelPatternsText:d,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!0,allowCpuFallback:!1,allowMultiGpuSplit:!1,maxWakeVramMb:"28000",maxWakeRamMb:"32768",selectionPolicy:"best-fit"},"auto/offline-vision":{name:"auto/offline-vision",exposedModel:"auto/offline-vision",description:"Local vision models.",modelPatternsText:`qwen2.5vl:7b | priority=100
8
- qwen2.5vl:latest | priority=95
9
- llama3.2-vision:latest | priority=80`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!0,allowCpuFallback:!1,allowMultiGpuSplit:!1,maxWakeVramMb:"18000",maxWakeRamMb:"24576",selectionPolicy:"best-fit"},"auto/offline-translate":{name:"auto/offline-translate",exposedModel:"auto/offline-translate",description:"Local translation models.",modelPatternsText:`qwen3-jp-vi-translate:latest | priority=100
10
- qwen3-jp-vi-k2-translate-f16:latest | priority=95
11
- qwen3-ijs-k4-translate:latest | priority=90
12
- qwen3-ijs-k4-translate-vn2jp:latest | priority=85
13
- qwen3-mail-translate-f16:latest | priority=80
14
- qwen3-prc-sc-k2-translate-jp2vn:latest | priority=75`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!1,allowCpuFallback:!0,allowMultiGpuSplit:!1,maxWakeVramMb:"24000",maxWakeRamMb:"32768",selectionPolicy:"loaded-first"},"auto/offline-embed":{name:"auto/offline-embed",exposedModel:"auto/offline-embed",description:"Local embedding models.",modelPatternsText:`bge-m3:latest | priority=100
15
- mxbai-embed-large:latest | priority=90`,preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!1,allowCpuFallback:!0,allowMultiGpuSplit:!1,maxWakeVramMb:"4096",maxWakeRamMb:"8192",selectionPolicy:"lowest-latency"}};function c(e){return String(e||"").trim()}function m(e){return Array.isArray(e)?e.join(", "):c(e)}function x(e=""){return[...new Set(String(e||"").split(/[\n,;]+/).map(e=>e.trim()).filter(Boolean))]}function u(e){let l=String(e||"").split("|").map(e=>e.trim()).filter(Boolean),t=c(l.shift());if(!t)return null;let a={model:t,label:t,tags:[]};for(let e of l){let l=e.indexOf("=");if(l<=0)continue;let t=e.slice(0,l).trim().toLowerCase(),o=e.slice(l+1).trim();"connection"===t||"connectionid"===t||"account"===t?a.connectionId=o:"label"===t||"name"===t?a.label=o:"endpoint"===t||"url"===t||"baseurl"===t?a.endpoint=o:"tags"===t||"labels"===t?a.tags=x(o):"max"===t||"maxinflight"===t?a.maxInFlight=Number(o)||void 0:"provider"===t&&(a.provider=o)}return a}let p={type:"virtual",name:"",exposedModel:"",enabled:!0,strategy:"least-latency",requiredTagsText:"",modelRulesText:"",targetsText:"",description:"",modelPatternsText:d,allowedNodeIdsText:"",allowedPortsText:"",preferLoaded:!0,allowWakeSleeping:!0,requireGpu:!0,allowCpuFallback:!1,allowMultiGpuSplit:!1,maxWakeVramMb:"28000",maxWakeRamMb:"32768",fallbackCombo:"",selectionPolicy:"best-fit"};function b(e){let l={id:c(e.name),name:c(e.name),exposedModel:c(e.exposedModel||e.name),enabled:!1!==e.enabled,type:e.type||"virtual",strategy:e.strategy||"least-latency",requiredTags:x(e.requiredTagsText),modelTagRules:function(e=""){let l={};for(let t of String(e||"").split(/\n+/)){let e=t.trim();if(!e)continue;let a=e.indexOf(":");if(a<=0)continue;let o=e.slice(0,a).trim(),r=x(e.slice(a+1));o&&r.length&&(l[o]=r)}return l}(e.modelRulesText),targets:"ollama-local"===e.type?[]:function(e=""){return String(e||"").split(/\n+/).map(u).filter(Boolean)}(e.targetsText),description:c(e.description)};return"ollama-local"===e.type&&(l.localOllama={modelPatterns:function(e=""){return String(e||"").split(/\n+/).map((e,l)=>{let t=e.split("|").map(e=>e.trim()).filter(Boolean),a=t.shift();if(!a)return null;let o={pattern:a,priority:Math.max(1,100-5*l),enabled:!0};for(let e of t){let[l,...t]=e.split("="),a=l.trim().toLowerCase(),r=t.join("=").trim();("priority"===a||"prio"===a)&&(o.priority=Number(r)||o.priority),"enabled"===a&&(o.enabled="false"!==r&&"0"!==r),("notes"===a||"note"===a)&&(o.notes=r)}return o}).filter(Boolean)}(e.modelPatternsText),allowedNodeIds:x(e.allowedNodeIdsText),allowedPorts:x(e.allowedPortsText).map(Number).filter(e=>Number.isFinite(e)&&e>0),preferLoaded:!1!==e.preferLoaded,allowWakeSleeping:!1!==e.allowWakeSleeping,requireGpu:!0===e.requireGpu,allowCpuFallback:!0===e.allowCpuFallback,allowMultiGpuSplit:!0===e.allowMultiGpuSplit,maxWakeVramMb:Number(e.maxWakeVramMb||0)||0,maxWakeRamMb:Number(e.maxWakeRamMb||0)||0,fallbackCombo:c(e.fallbackCombo),selectionPolicy:e.selectionPolicy||"best-fit"}),l}function g({label:e,description:l,checked:t,onChange:o}){return(0,a.jsxs)("label",{className:"flex items-start gap-3 rounded-xl border border-border bg-surface-1 p-3",children:[(0,a.jsx)("input",{type:"checkbox",checked:t,onChange:e=>o(e.target.checked),className:"mt-1 h-4 w-4 accent-primary"}),(0,a.jsxs)("span",{children:[(0,a.jsx)("span",{className:"block text-sm font-medium text-text-main",children:e}),l?(0,a.jsx)("span",{className:"mt-0.5 block text-xs text-text-muted",children:l}):null]})]})}function f({children:e}){return(0,a.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:e})}function h({preview:e}){if(!e)return null;let l=e.selected;return(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Routing Preview"}),e.error?(0,a.jsx)("p",{className:"mt-2 text-sm text-red-600",children:e.error}):null,l?(0,a.jsxs)("div",{className:"mt-3 rounded-xl border border-green-200 bg-green-50 p-3 text-sm text-green-900 dark:border-green-500/30 dark:bg-green-500/10 dark:text-green-100",children:[(0,a.jsxs)("div",{className:"font-semibold",children:["Selected: ",l.nodeName,":",l.port," / ",l.model]}),(0,a.jsxs)("div",{className:"mt-1 text-xs",children:[l.reason," \xb7 score ",l.score," \xb7 ",l.loaded?"loaded":"sleeping"," \xb7 ",l.endpoint]}),(0,a.jsxs)("div",{className:"mt-1 text-xs",children:["GPU scope: ",(l.gpuIndices||[]).length?l.gpuIndices.map(e=>`GPU ${e}`).join(", "):"none"," \xb7 VRAM free ",l.vramFreeMb||0,"MB"]})]}):(0,a.jsx)("p",{className:"mt-2 text-sm text-text-muted",children:"No eligible local target selected."}),(0,a.jsxs)("div",{className:"mt-3 grid gap-3 md:grid-cols-2",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"text-xs font-semibold uppercase text-text-muted",children:["Eligible (",e.eligible?.length||0,")"]}),(0,a.jsx)("div",{className:"mt-2 max-h-48 space-y-2 overflow-auto",children:(e.eligible||[]).slice(0,12).map(e=>(0,a.jsxs)("div",{className:"rounded-lg bg-background p-2 text-xs text-text-main",children:[(0,a.jsxs)("b",{children:[e.nodeName,":",e.port]})," ",e.model," \xb7 ",e.reason," \xb7 score ",e.score]},e.id))})]}),(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"text-xs font-semibold uppercase text-text-muted",children:["Rejected (",e.rejected?.length||0,")"]}),(0,a.jsx)("div",{className:"mt-2 max-h-48 space-y-2 overflow-auto",children:(e.rejected||[]).slice(0,20).map(e=>(0,a.jsxs)("div",{className:"rounded-lg bg-background p-2 text-xs text-text-muted",children:[(0,a.jsxs)("b",{children:[e.nodeName,":",e.port]})," ",e.model," \xb7 ",e.reason]},`${e.id}-${e.reason}`))})]})]})]})}function y(){let[e,l]=(0,o.useState)([]),[t,c]=(0,o.useState)(!0),[x,u]=(0,o.useState)(null),[y,j]=(0,o.useState)(p),[v,k]=(0,o.useState)(!1),[N,w]=(0,o.useState)(""),[C,M]=(0,o.useState)(null),[P,T]=(0,o.useState)(!1),S=(0,o.useMemo)(()=>e.filter(e=>!1!==e.enabled),[e]),q=(0,o.useMemo)(()=>e.filter(e=>"ollama-local"===e.type),[e]);(0,o.useEffect)(()=>{R()},[]);let R=async()=>{c(!0);try{let e=await fetch("/api/virtual-combos",{cache:"no-store"}),t=await e.json();e.ok?l(t.virtualCombos||[]):w(t.error||"Failed to load virtual combos")}catch(e){w(e?.message||"Failed to load virtual combos")}finally{c(!1)}},O=(e="virtual")=>{u(null),"ollama-local"===e?j({...p,type:"ollama-local",name:"auto/offline-coding",exposedModel:"auto/offline-coding"}):j({...p,type:"virtual",targetsText:"oc/qwen3:8b | tags=gpu,model_support:qwen3:8b\noc/qwen3:8b | connection=CONNECTION_ID | tags=gpu,vram:8gb",modelRulesText:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b"}),M(null),w("")},W=async()=>{let e=b(y);if(!e.name||!e.exposedModel)return void w("Name and exposed model are required.");if("ollama-local"===e.type&&!e.localOllama.modelPatterns.length)return void w("Ollama Local Combo requires at least one model pattern.");if("ollama-local"!==e.type&&0===e.targets.length)return void w("Provider/LAN virtual combo requires at least one target.");k(!0),w("");try{let l=x?encodeURIComponent(x.name||x.id||x.exposedModel):"",t=await fetch(x?`/api/virtual-combos/${l}`:"/api/virtual-combos",{method:x?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),a=await t.json().catch(()=>({}));if(!t.ok)return void w(a.error||"Save failed");u(null),j(p),M(null),await R()}catch(e){w(e?.message||"Save failed")}finally{k(!1)}},G=async()=>{if("ollama-local"===y.type){T(!0),w("");try{let e=await fetch("/api/virtual-combos/preview",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({combo:b(y),maxAgeMs:5e3})}),l=await e.json();if(!e.ok)return void w(l.error||"Preview failed");M(l)}catch(e){w(e?.message||"Preview failed")}finally{T(!1)}}},L=async e=>{if(!confirm(`Delete virtual combo ${e.name}?`))return;let l=encodeURIComponent(e.name||e.id||e.exposedModel),t=await fetch(`/api/virtual-combos/${l}`,{method:"DELETE"});t.ok?await R():alert((await t.json().catch(()=>({}))).error||"Delete failed")},A=y!==p||x,F=A?y.type||(x?.type==="ollama-local"?"ollama-local":"virtual")||"virtual":"",I=e=>["rounded-xl border px-4 py-2 text-sm font-medium transition-all focus:outline-none focus:ring-2 focus:ring-primary/40 focus:ring-offset-1",F===e?"border-primary bg-primary text-white shadow-sm ring-2 ring-primary/20":"border-border bg-background text-text-main hover:border-primary/50 hover:bg-surface-2 hover:text-primary"].join(" ");return(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"text-2xl font-semibold text-text-main",children:"Virtual Combos"}),(0,a.jsx)("p",{className:"mt-1 max-w-3xl text-sm text-text-muted",children:"Expose one virtual model name and route it to provider targets or hardware-aware local Ollama model selectors."})]}),(0,a.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,a.jsxs)("button",{type:"button",onClick:()=>O("virtual"),className:I("virtual"),"aria-pressed":"virtual"===F,children:["virtual"===F?"✓ ":"","New Provider Combo"]}),(0,a.jsxs)("button",{type:"button",onClick:()=>O("ollama-local"),className:I("ollama-local"),"aria-pressed":"ollama-local"===F,children:["ollama-local"===F?"✓ ":"","New Ollama Local Combo"]})]})]}),N?(0,a.jsx)("div",{className:"rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200",children:N}):null,(0,a.jsx)("div",{className:"grid gap-3 md:grid-cols-5",children:Object.keys(i).map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>{let l;(l=i[e])&&(j({...p,type:"ollama-local",...l}),u(null),M(null),w(""))},className:"rounded-2xl border border-border bg-surface-1 p-3 text-left hover:bg-surface-2",children:[(0,a.jsx)("div",{className:"text-sm font-semibold text-text-main",children:e}),(0,a.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:"Load preset"})]},e))}),t?(0,a.jsx)("div",{className:"rounded-2xl border border-border bg-surface-1 p-8 text-sm text-text-muted",children:"Loading..."}):0===e.length?(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-8 text-center",children:[(0,a.jsx)("span",{className:"material-icons text-4xl text-text-muted",children:"hub"}),(0,a.jsx)("h2",{className:"mt-2 text-lg font-semibold text-text-main",children:"No virtual combos yet"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Create a provider combo or a local Ollama combo."})]}):(0,a.jsx)("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:e.map(e=>(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,a.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:e.name}),(0,a.jsxs)("p",{className:"font-mono text-xs text-text-muted",children:["model: ",e.exposedModel]})]}),(0,a.jsx)("span",{className:`rounded-full px-2 py-1 text-xs ${!1!==e.enabled?"bg-green-100 text-green-700 dark:bg-green-500/10 dark:text-green-300":"bg-surface-2 text-text-muted"}`,children:!1!==e.enabled?"enabled":"disabled"})]}),(0,a.jsxs)("div",{className:"mt-3 flex flex-wrap gap-2 text-xs text-text-muted",children:[(0,a.jsx)("span",{className:"rounded-full bg-surface-2 px-2 py-1",children:"ollama-local"===e.type?"Ollama Local Combo":"Provider Combo"}),"ollama-local"===e.type?(0,a.jsxs)("span",{className:"rounded-full bg-surface-2 px-2 py-1",children:[e.localOllama?.modelPatterns?.length||0," pattern(s)"]}):(0,a.jsxs)("span",{className:"rounded-full bg-surface-2 px-2 py-1",children:[e.strategy||"least-latency"," \xb7 ",e.targets?.length||0," target(s)"]})]}),"ollama-local"===e.type?(0,a.jsx)("div",{className:"mt-3 space-y-1 text-xs text-text-muted",children:(e.localOllama?.modelPatterns||[]).slice(0,5).map(e=>(0,a.jsxs)("div",{className:"font-mono",children:[e.pattern," \xb7 p",e.priority]},e.pattern))}):(0,a.jsx)("div",{className:"mt-3 space-y-1 text-xs text-text-muted",children:(e.targets||[]).slice(0,4).map((e,l)=>(0,a.jsx)("div",{className:"font-mono",children:e.label||e.model},`${e.model}-${l}`))}),(0,a.jsxs)("div",{className:"mt-4 flex gap-2",children:[(0,a.jsx)("button",{onClick:()=>{u(e),j(function(e){if(!e)return p;let l=e.localOllama||{},t="ollama-local"===e.type;return{...p,type:t?"ollama-local":"virtual",name:e.name||"",exposedModel:e.exposedModel||e.model||e.name||"",enabled:!1!==e.enabled,strategy:e.strategy||e.fallbackStrategy||"least-latency",requiredTagsText:m(e.requiredTags||e.tags||[]),modelRulesText:function(e={}){return Object.entries(e||{}).map(([e,l])=>`${e}: ${Array.isArray(l)?l.join(", "):l}`).join("\n")}(e.modelTagRules||{}),targetsText:function(e=[]){return(e||[]).map(e=>{let l=[e.model||""];return e.connectionId&&l.push(`connection=${e.connectionId}`),e.label&&l.push(`label=${e.label}`),e.endpoint&&l.push(`endpoint=${e.endpoint}`),e.tags?.length&&l.push(`tags=${e.tags.join(",")}`),e.maxInFlight&&l.push(`max=${e.maxInFlight}`),l.filter(Boolean).join(" | ")}).join("\n")}(e.targets||e.endpoints||e.models||[]),description:e.description||"",modelPatternsText:function(e=[]){return(e||[]).map((e,l)=>{if("string"==typeof e)return`${e} | priority=${Math.max(1,100-5*l)}`;let t=[e.pattern||e.model||e.name||""];return t.push(`priority=${Number(e.priority||Math.max(1,100-5*l))}`),!1===e.enabled&&t.push("enabled=false"),e.notes&&t.push(`notes=${e.notes}`),t.filter(Boolean).join(" | ")}).join("\n")}(l.modelPatterns||[]),allowedNodeIdsText:m(l.allowedNodeIds||[]),allowedPortsText:Array.isArray(l.allowedPorts)?l.allowedPorts.join(","):"",preferLoaded:!1!==l.preferLoaded,allowWakeSleeping:!1!==l.allowWakeSleeping,requireGpu:!0===l.requireGpu,allowCpuFallback:!1!==l.allowCpuFallback,allowMultiGpuSplit:!0===l.allowMultiGpuSplit,maxWakeVramMb:String(l.maxWakeVramMb||""),maxWakeRamMb:String(l.maxWakeRamMb||""),fallbackCombo:l.fallbackCombo||"",selectionPolicy:l.selectionPolicy||"best-fit"}}(e)),M(null),w("")},className:"rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-text-main hover:bg-surface",children:"Edit"}),(0,a.jsx)("button",{onClick:()=>L(e),className:"rounded-lg border border-red-200 px-3 py-1.5 text-xs font-medium text-red-600 hover:bg-red-50 dark:border-red-500/30 dark:hover:bg-red-500/10",children:"Delete"})]})]},e.name||e.id))}),A?(0,a.jsxs)("div",{className:"grid gap-4 xl:grid-cols-[minmax(0,1fr)_420px]",children:[(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-5",children:[(0,a.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:x?"Edit Virtual Combo":"Create Virtual Combo"}),(0,a.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[S.length," active combo(s), ",q.length," local Ollama combo(s)."]}),(0,a.jsxs)("div",{className:"mt-5 grid gap-4 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Type"}),(0,a.jsx)("select",{value:y.type,onChange:e=>j({...y,type: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:r.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Enabled"}),(0,a.jsxs)("label",{className:"flex h-[42px] items-center gap-2 rounded-xl border border-border bg-background px-3 text-sm text-text-main",children:[(0,a.jsx)("input",{type:"checkbox",checked:y.enabled,onChange:e=>j({...y,enabled:e.target.checked}),className:"h-4 w-4 accent-primary"})," Enabled"]})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Name / ID"}),(0,a.jsx)("input",{value:y.name,onChange:e=>j({...y,name:e.target.value,exposedModel:y.exposedModel||e.target.value}),placeholder:"auto/offline-coding",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Unique combo ID. The slash format is supported, for example auto/offline-coding."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Exposed model"}),(0,a.jsx)("input",{value:y.exposedModel,onChange:e=>j({...y,exposedModel:e.target.value}),placeholder:"auto/offline-coding",className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Clients call this model name. BlueRouter resolves it to an upstream provider model or an Ollama instance target."})]})]}),"ollama-local"===y.type?(0,a.jsx)("div",{className:"mt-5 space-y-5",children:(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-background p-4",children:[(0,a.jsx)("h3",{className:"font-semibold text-text-main",children:"Ollama Local Combo"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"This combo stores model patterns only. At request time BlueRouter selects the best node, port, model, and GPU scope using the Ollama Node reports."}),(0,a.jsxs)("div",{className:"mt-4 grid gap-4 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block md:col-span-2",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Model patterns + priority"}),(0,a.jsx)("textarea",{value:y.modelPatternsText,onChange:e=>j({...y,modelPatternsText:e.target.value}),rows:8,placeholder:d,className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"One model per line. Syntax: model-pattern | priority=100. Wildcards like qwen3-coder:* are allowed."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Allowed nodes"}),(0,a.jsx)("input",{value:y.allowedNodeIdsText,onChange:e=>j({...y,allowedNodeIdsText:e.target.value}),placeholder:"empty = all nodes",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Comma-separated node IDs. Empty means all enabled Ollama nodes."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Allowed instance ports"}),(0,a.jsx)("input",{value:y.allowedPortsText,onChange:e=>j({...y,allowedPortsText:e.target.value}),placeholder:"11434,11435 or empty",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Limit this combo to specific Ollama ports. Empty means all enabled instances."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Selection policy"}),(0,a.jsx)("select",{value:y.selectionPolicy,onChange:e=>j({...y,selectionPolicy: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:n.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,a.jsx)(f,{children:"Best fit filters by memory and scores loaded status, model priority, GPU scope, free VRAM/RAM, latency and errors."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Fallback combo"}),(0,a.jsx)("input",{value:y.fallbackCombo,onChange:e=>j({...y,fallbackCombo:e.target.value}),placeholder:"empty = local only",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Optional combo/model to call if no local target is eligible. Empty means fail local-only."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Max wake VRAM MB"}),(0,a.jsx)("input",{value:y.maxWakeVramMb,onChange:e=>j({...y,maxWakeVramMb:e.target.value}),placeholder:"0 = no cap",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Cap for sleeping model wake cost. Loaded models use loaded overhead instead."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Max wake RAM MB"}),(0,a.jsx)("input",{value:y.maxWakeRamMb,onChange:e=>j({...y,maxWakeRamMb:e.target.value}),placeholder:"0 = no cap",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),(0,a.jsx)(f,{children:"Cap host RAM cost when waking sleeping models."})]})]}),(0,a.jsxs)("div",{className:"mt-4 grid gap-3 md:grid-cols-2",children:[(0,a.jsx)(g,{label:"Prefer loaded models",checked:y.preferLoaded,onChange:e=>j({...y,preferLoaded:e}),description:"Prefer /api/ps loaded models to avoid wake latency and OOM risk."}),(0,a.jsx)(g,{label:"Allow wake sleeping models",checked:y.allowWakeSleeping,onChange:e=>j({...y,allowWakeSleeping:e}),description:"When off, only already-loaded local models are eligible."}),(0,a.jsx)(g,{label:"Require GPU",checked:y.requireGpu,onChange:e=>j({...y,requireGpu:e}),description:"Reject CPU-only or no-GPU-scope targets."}),(0,a.jsx)(g,{label:"Allow CPU fallback",checked:y.allowCpuFallback,onChange:e=>j({...y,allowCpuFallback:e}),description:"Allow CPU route if GPU is unavailable. Usually off for large coding/vision models."}),(0,a.jsx)(g,{label:"Allow multi-GPU split",checked:y.allowMultiGpuSplit,onChange:e=>j({...y,allowMultiGpuSplit:e}),description:"Only enable when the instance/model can split VRAM across GPUs."})]})]})}):(0,a.jsxs)("div",{className:"mt-5 grid gap-4 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Strategy"}),(0,a.jsx)("select",{value:y.strategy,onChange:e=>j({...y,strategy: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:s.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Required tags"}),(0,a.jsx)("input",{value:y.requiredTagsText,onChange:e=>j({...y,requiredTagsText:e.target.value}),placeholder:"gpu, vram:8gb",className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"})]}),(0,a.jsxs)("label",{className:"block md:col-span-2",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Model tag rules"}),(0,a.jsx)("textarea",{value:y.modelRulesText,onChange:e=>j({...y,modelRulesText:e.target.value}),rows:3,placeholder:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b",className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary"})]}),(0,a.jsxs)("label",{className:"block md:col-span-2",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Targets"}),(0,a.jsx)("textarea",{value:y.targetsText,onChange:e=>j({...y,targetsText:e.target.value}),rows:8,placeholder:"oc/qwen3:8b | connection=abc123 | tags=gpu,vram:8gb\noc/qwen3:8b | tags=cpu",className:"w-full rounded-xl border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary"})]})]}),(0,a.jsxs)("label",{className:"mt-4 block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold text-text-muted",children:"Description"}),(0,a.jsx)("input",{value:y.description,onChange:e=>j({...y,description: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"})]}),(0,a.jsxs)("div",{className:"mt-5 flex flex-wrap gap-2",children:[(0,a.jsx)("button",{type:"button",onClick:W,disabled:v,className:"rounded-xl bg-primary px-5 py-2 text-sm font-medium text-white hover:opacity-90 disabled:opacity-50",children:v?"Saving...":x?"Save":"Create"}),"ollama-local"===y.type?(0,a.jsx)("button",{type:"button",onClick:G,disabled:P,className:"rounded-xl border border-border px-5 py-2 text-sm font-medium text-text-main hover:bg-surface",children:P?"Previewing...":"Preview routing"}):null,(0,a.jsx)("button",{type:"button",onClick:()=>{u(null),j(p),M(null),w("")},className:"rounded-xl border border-border px-5 py-2 text-sm font-medium text-text-main hover:bg-surface",children:"Clear"})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Field meanings"}),(0,a.jsxs)("dl",{className:"mt-3 space-y-2 text-xs text-text-muted",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Model patterns"}),(0,a.jsx)("dd",{children:"Allowed local model names or wildcards. Priority decides model preference after hardware filtering."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Allowed nodes / ports"}),(0,a.jsx)("dd",{children:"Optional constraints. Empty means all enabled Ollama nodes and instances."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Prefer loaded"}),(0,a.jsx)("dd",{children:"Boosts models already in /api/ps to avoid waking large models."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Allow wake"}),(0,a.jsx)("dd",{children:"If disabled, sleeping models are rejected even if RAM/VRAM is enough."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Require GPU / CPU fallback"}),(0,a.jsx)("dd",{children:"Controls whether CPU-only/no-GPU-scope targets are eligible."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Multi-GPU split"}),(0,a.jsx)("dd",{children:"Allows aggregate VRAM only when you know that instance can split across GPUs."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("dt",{className:"font-semibold text-text-main",children:"Fallback combo"}),(0,a.jsx)("dd",{children:"Optional cloud/provider fallback. Empty keeps the combo local-only."})]})]})]}),(0,a.jsx)(h,{preview:C})]})]}):null]})}},67711:(e,l,t)=>{Promise.resolve().then(t.bind(t,53677))}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=67711)),_N_E=e.O()}]);