@jheavenknows/bluerouter 5.4.28 → 5.4.29
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.
- package/app/.next-cli-build/BUILD_ID +1 -1
- package/app/.next-cli-build/app-path-routes-manifest.json +5 -5
- package/app/.next-cli-build/build-manifest.json +2 -2
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/ai-power-index/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/analytics/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/analytics/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/api-keys/page.js +2 -2
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/api-keys/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/audit-proxy/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/audit-proxy/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/model-profiles/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cluster/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/logs/console/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/logs/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/personal/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/personalcloudprovider/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/personalcloudprovidermonitor/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/personalquota/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/stt/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/tts/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/resource-monitor/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/app/.next-cli-build/server/app/_not-found.rsc +6 -6
- package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/api/audit-proxy/ca/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/audit-proxy/me/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/audit-proxy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/audit-proxy/users/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/ldap/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/ldap/users/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/view-mode/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/branding/[asset]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/branding/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/branding/upload/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-model-profiles/cloud-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-model-profiles/model-catalog/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-model-profiles/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/autostart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/prompt-log-db/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/root-ca/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/config/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/heartbeat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/peers/[id]/command/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/peers/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/peers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/snapshot/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/sync/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cluster/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/codex-catalog/download/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/codex-catalog/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/codex-catalog/upload/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/ai-power-index/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/analytics/ai-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/analytics/analyze/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/analytics/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/combos/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/endpoint/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/options/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/token-saver/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/caveman-test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/rotate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/grok-cli/device-code/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/grok-cli/poll/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/[id]/api-key-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/[id]/import-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/[id]/models/[...routeModel]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/[id]/move/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/[id]/usage/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/client/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/monitor/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/permissions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/routing/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/shares/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/personal-cloud-providers/visibility/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pricing/catalog/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pricing/recalculate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-health/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/openai-compatible/manage/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/resource-monitor/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/resource-monitor/ai-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/resource-monitor/analyze/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/resource-monitor/history/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/resource-monitor/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/database/export/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-start-daemon/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/callback.html +1 -1
- package/app/.next-cli-build/server/app/callback.rsc +6 -6
- package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/ai-power-index.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/ai-power-index.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/ai-power-index.segments/!KGRhc2hib2FyZCk/dashboard/ai-power-index/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/ai-power-index.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/ai-power-index.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/api-keys.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/api-keys.rsc +10 -10
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard/api-keys/__PAGE__.segment.rsc +10 -10
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_full.segment.rsc +10 -10
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools/model-profiles.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools/model-profiles.rsc +9 -9
- package/app/.next-cli-build/server/app/dashboard/cli-tools/model-profiles.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/model-profiles/__PAGE__.segment.rsc +9 -9
- package/app/.next-cli-build/server/app/dashboard/cli-tools/model-profiles.segments/_full.segment.rsc +9 -9
- package/app/.next-cli-build/server/app/dashboard/cli-tools/model-profiles.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cluster.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cluster.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/cluster.segments/!KGRhc2hib2FyZCk/dashboard/cluster/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/cluster.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/cluster.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/logs.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/logs.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/logs.segments/!KGRhc2hib2FyZCk/dashboard/logs/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/logs.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/logs.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/personal.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/personal.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/personal.segments/!KGRhc2hib2FyZCk/dashboard/personal/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/personal.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/personal.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/provider-health.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/stt.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/stt.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/stt.segments/!KGRhc2hib2FyZCk/dashboard/providers/stt/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/stt.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/stt.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/tts.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/tts.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/tts.segments/!KGRhc2hib2FyZCk/dashboard/providers/tts/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/tts.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers/tts.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.rsc +9 -9
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +9 -9
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +9 -9
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/resource-monitor.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/resource-monitor.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/resource-monitor.segments/!KGRhc2hib2FyZCk/dashboard/resource-monitor/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/resource-monitor.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/resource-monitor.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/app/.next-cli-build/server/app/dashboard.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/index.html +1 -1
- package/app/.next-cli-build/server/app/index.rsc +6 -6
- package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/landing.html +1 -1
- package/app/.next-cli-build/server/app/landing.rsc +6 -6
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/login.html +1 -1
- package/app/.next-cli-build/server/app/login.rsc +7 -7
- package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app-paths-manifest.json +5 -5
- package/app/.next-cli-build/server/chunks/1470.js +8 -22
- package/app/.next-cli-build/server/chunks/2428.js +1 -1
- package/app/.next-cli-build/server/chunks/2731.js +8 -22
- package/app/.next-cli-build/server/chunks/3399.js +1 -1
- package/app/.next-cli-build/server/chunks/402.js +1 -1
- package/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/app/.next-cli-build/server/chunks/6811.js +1 -1
- package/app/.next-cli-build/server/chunks/689.js +1 -1
- package/app/.next-cli-build/server/chunks/6992.js +1 -1
- package/app/.next-cli-build/server/chunks/9489.js +1 -1
- package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/app/.next-cli-build/server/middleware.js +1 -1
- package/app/.next-cli-build/server/pages/404.html +1 -1
- package/app/.next-cli-build/server/pages/500.html +1 -1
- package/app/.next-cli-build/static/chunks/{5263-6856971b5c7c38ac.js → 5263-675098c923e1ee6b.js} +1 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/analytics/page-1fa5bfb048882df9.js +1 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/api-keys/{page-02881fb8f9782fd0.js → page-1f046119676ebee9.js} +2 -2
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/combos/page-786d94f8dd164774.js +1 -0
- package/app/.next-cli-build/static/css/{b1d9e34c2c3debb5.css → 3ee2c86da45c8465.css} +1 -1
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-shm +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-wal +0 -0
- package/app/package.json +1 -1
- package/package.json +1 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/analytics/page-a490ee99c12ec139.js +0 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/combos/page-e6712886cd01ffe3.js +0 -1
- /package/app/.next-cli-build/static/{x-Qb8zBG_LMJpbcg7V5kZ → RLHlm_VhJtUy0g062tWk9}/_buildManifest.js +0 -0
- /package/app/.next-cli-build/static/{x-Qb8zBG_LMJpbcg7V5kZ → RLHlm_VhJtUy0g062tWk9}/_ssgManifest.js +0 -0
- /package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/{upgrade-5.4.18-to-5.4.19-5.4.19-20260825-075641 → upgrade-5.4.26-to-5.4.27-5.4.27-20260827-201818}/data.sqlite +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7593],{9385:(e,t,n)=>{"use strict";n.d(t,{Ek:()=>h,FY:()=>f,H1:()=>p,O0:()=>o,Zn:()=>j,cL:()=>b,j5:()=>u,pA:()=>s,u1:()=>g});let s=["coder","fast","thinking"],r=["claude","codex"],l={claude:"claude/",codex:"codex/"},a={coder:{model:"",contextWindow:0},fast:{model:"",contextWindow:0},thinking:{model:"",contextWindow:0}},o={version:2,local:{enabled:!0,providerName:"Local AI",autoCompactPct:75,models:{coder:{model:"programmer",contextWindow:12e4},fast:{model:"programmer-fast",contextWindow:12e4},thinking:{model:"programmer",contextWindow:12e4}}},cloud:{claude:{enabled:!1,providerName:"Claude Code Cloud",models:a},codex:{enabled:!1,providerName:"Codex Cloud",models:a}}};function i(e,t=300){return String(e??"").trim().slice(0,t)}function d(e,t){let n=Number(e);return!Number.isFinite(n)||n<=0?t:Math.floor(n)}function c(e,t=75){let n=Number(e);return Number.isFinite(n)?Math.min(100,Math.max(1,Math.floor(n))):t}function x(e,t,{local:n}){let r=e&&"object"==typeof e&&!Array.isArray(e)?e:{},l=r.models&&"object"==typeof r.models&&!Array.isArray(r.models)?r.models:{},a={};for(let e of s)a[e]=function(e,t,{local:n}){let s=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return{model:i(Object.prototype.hasOwnProperty.call(s,"model")?s.model:t.model),contextWindow:n?d(s.contextWindow,t.contextWindow||12e4):0}}(l[e],t.models[e],{local:n});let o={enabled:Object.prototype.hasOwnProperty.call(r,"enabled")?!0===r.enabled:t.enabled,providerName:i(Object.prototype.hasOwnProperty.call(r,"providerName")?r.providerName:t.providerName,80)||t.providerName,models:a};return n&&(o.autoCompactPct=c(r.autoCompactPct,t.autoCompactPct)),o}function m(e,t){if(!e||"object"!=typeof e||Array.isArray(e)||e.claude||e.codex)return null;let n=e.models&&"object"==typeof e.models&&!Array.isArray(e.models)?e.models:{},r=s.map(e=>i(n?.[e]?.model)).filter(Boolean),a=l[t];return a&&0!==r.length&&r.every(e=>e.startsWith(a))?e:null}function u(e={}){let t=e&&"object"==typeof e&&!Array.isArray(e)?e:{},n=t.cloud&&"object"==typeof t.cloud&&!Array.isArray(t.cloud)?t.cloud:{};return{version:2,local:x(t.local,o.local,{local:!0}),cloud:{claude:x(n.claude||m(n,"claude"),o.cloud.claude,{local:!1}),codex:x(n.codex||m(n,"codex"),o.cloud.codex,{local:!1})}}}function h(e,t){return r.includes(t)&&e?.cloud?.[t]||null}function p(e){return l[e]||""}function b(e,t,n=""){return i(e?.models?.[t]?.model)||n}function g(e,t,n=12e4){return d(e?.models?.[t]?.contextWindow,n)}function f(e){return[...new Set(s.map(t=>b(e,t)).filter(Boolean))]}function j(e){return Math.max(1,Math.floor(g(e,"coder")*c(e?.autoCompactPct)/100))}},56484:(e,t,n)=>{"use strict";n.d(t,{default:()=>R});var s=n(95155),r=n(12115),l=n(35497),a=n(94027),o=n(11059);let i=Object.freeze({enabled:!0,requestsPerMinute:20,promptCharsMax:12e4,maxOutputTokens:0,forceThinkingOff:!0,allowedIpCidrs:[],expiresAt:""});function d(e){return String(e||"").trim().toLowerCase()}function c(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function x(e,t){let n=c(e?.allowedModels),s=n[0]||String(t||"programmer").trim()||"programmer",r=n.find(e=>/fast|small|haiku/i.test(e))||n.find(e=>e!==s)||s;return{codingModel:s,fastModel:r}}let m="model_catalog.json";function u({icon:e,materialIcon:t,image:n,children:r,className:l=""}){return(0,s.jsxs)("span",{className:`inline-flex items-center gap-1.5 ${l}`,children:[n?(0,s.jsx)("img",{src:n,alt:"","aria-hidden":"true",className:"size-4 rounded-sm object-contain"}):t?(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[17px] leading-none",children:t}):e?(0,s.jsx)("span",{"aria-hidden":"true",className:"text-base leading-none",children:e}):null,(0,s.jsx)("span",{children:r})]})}function h(e,t=0){let n=Number(e);return Number.isFinite(n)?Math.max(0,Math.floor(n)):t}function p(e,t=!0){return null==e||""===e?t:!0===e||"true"===e||1===e||"1"===e}function b(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function g(e){return e&&"object"==typeof e&&!Array.isArray(e)&&Object.keys(e).length>0}function f(e={},t={}){let n={...t},s=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return{enabled:p(s.enabled??n.enabled,!0),requestsPerMinute:h(s.requestsPerMinute??n.requestsPerMinute,0),promptCharsMax:h(s.promptCharsMax??n.promptCharsMax,0),maxOutputTokens:h(s.maxOutputTokens??s.outputTokensMax??s.maxTokens??s.max_tokens??s.max_completion_tokens??n.maxOutputTokens,0),forceThinkingOff:p(s.forceThinkingOff??n.forceThinkingOff,!0),allowedIpCidrs:b(s.allowedIpCidrs??n.allowedIpCidrs),expiresAt:String(s.expiresAt??n.expiresAt??"").trim()}}function j({models:e,emptyLabel:t="Chưa g\xe1n model"}){let n=c(e);return 0===n.length?(0,s.jsx)("span",{className:"text-xs text-text-muted",children:t}):(0,s.jsxs)("div",{className:"mt-2 flex flex-wrap gap-1.5",children:[n.slice(0,8).map(e=>(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 font-mono text-xs",children:e},e)),n.length>8?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 text-xs",children:["+",n.length-8," model kh\xe1c"]}):null]})}function y({limits:e,showThinking:t=!1,showOutputLimit:n=!1}){if(!g(e))return(0,s.jsx)("div",{className:"mt-2 flex flex-wrap gap-2 text-xs text-text-muted",children:(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"policy: chưa set, kh\xf4ng giới hạn"})});let r=f(e);return(0,s.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2 text-xs text-text-muted",children:[(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:["policy: ",r.enabled?"bật":"tắt"]}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[r.requestsPerMinute||"∞"," req/ph\xfat"]}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[r.promptCharsMax||"∞"," chars prompt"]}),n?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[r.maxOutputTokens||"∞"," output tokens"]}):null,t?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:["thinking: ",r.forceThinkingOff?"force off":"client tự quyết"]}):null,r.allowedIpCidrs.length>0?(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"IP locked"}):null]})}function v({label:e,value:t,onChange:n,hint:r}){return(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:e}),(0,s.jsx)("input",{type:"number",min:"0",value:t,onChange:e=>n(h(e.target.value,0)),className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),r?(0,s.jsx)("span",{className:"mt-1 block text-xs text-text-muted",children:r}):null]})}function N({isOpen:e,keyName:t,policy:n,setPolicy:r,onClose:a,onSave:o,onClear:d,saving:c,clearLabel:x="X\xf3a policy / kh\xf4ng limit"}){let m=f(n,i),u=(e,t)=>r(n=>f({...n,[e]:t},i));return(0,s.jsx)(l.aF,{isOpen:e,onClose:a,title:`Policy API key: ${t||"API Key"}`,size:"xl",children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"rounded-xl border border-border bg-surface/60 p-3 text-sm text-text-muted",children:["Key mới tự c\xf3 ",(0,s.jsx)("b",{children:"default policy"}),". Chỉ admin được sửa policy. Request/ph\xfat = 0 nghĩa l\xe0 kh\xf4ng giới hạn tần suất. Max output tokens = 0 nghĩa l\xe0 kh\xf4ng \xe9p giới hạn output."]}),(0,s.jsxs)("label",{className:"flex items-center justify-between gap-3 rounded-xl border border-border p-3 text-sm",children:[(0,s.jsxs)("span",{children:[(0,s.jsx)("b",{children:"Bật policy"}),(0,s.jsx)("br",{}),(0,s.jsx)("span",{className:"text-xs text-text-muted",children:"Tắt mục n\xe0y th\xec policy được lưu nhưng kh\xf4ng \xe1p limit."})]}),(0,s.jsx)("input",{type:"checkbox",checked:m.enabled,onChange:e=>u("enabled",e.target.checked)})]}),(0,s.jsxs)("div",{className:"grid gap-3 md:grid-cols-2",children:[(0,s.jsx)(v,{label:"Request / ph\xfat",value:m.requestsPerMinute,onChange:e=>u("requestsPerMinute",e),hint:"0 = kh\xf4ng giới hạn tần suất. Khuyến nghị user thường: 10–20 req/ph\xfat."}),(0,s.jsx)(v,{label:"Max output tokens",value:m.maxOutputTokens,onChange:e=>u("maxOutputTokens",e),hint:"0 = kh\xf4ng giới hạn. VS Code khuyến nghị 2048–3072; chat d\xe0i 4096–8192."})]}),(0,s.jsx)(v,{label:"Prompt chars tối đa",value:m.promptCharsMax,onChange:e=>u("promptCharsMax",e),hint:"0 = kh\xf4ng giới hạn input/prompt."}),(0,s.jsxs)("label",{className:"flex items-center justify-between gap-3 rounded-xl border border-border p-3 text-sm",children:[(0,s.jsxs)("span",{children:[(0,s.jsx)("b",{children:"Force Thinking Off"}),(0,s.jsx)("br",{}),(0,s.jsx)("span",{className:"text-xs text-text-muted",children:"Khi bật, gateway \xe9p request c\xf3 chat_template_kwargs.enable_thinking=false theo chuẩn llama.cpp."})]}),(0,s.jsx)("input",{type:"checkbox",checked:m.forceThinkingOff,onChange:e=>u("forceThinkingOff",e.target.checked)})]}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"IP/CIDR được ph\xe9p"}),(0,s.jsx)("textarea",{value:b(m.allowedIpCidrs).join("\n"),onChange:e=>u("allowedIpCidrs",[...new Set(String(e.target.value||"").split(/[\n,]+/).map(e=>e.trim()).filter(Boolean))]),rows:3,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",placeholder:"10.0.0.0/8\n192.168.0.0/16"}),(0,s.jsx)("span",{className:"mt-1 block text-xs text-text-muted",children:"Để trống = mọi IP. Hỗ trợ IPv4 exact hoặc CIDR."})]}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Hết hạn l\xfac"}),(0,s.jsx)("input",{value:m.expiresAt,onChange:e=>u("expiresAt",e.target.value),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",placeholder:"2026-12-31T23:59:59+07:00 hoặc để trống"})]}),(0,s.jsxs)("div",{className:"flex flex-wrap justify-end gap-2",children:[(0,s.jsx)(l.$n,{variant:"ghost",onClick:a,children:"Hủy"}),d?(0,s.jsx)(l.$n,{variant:"outline",onClick:d,disabled:c,children:x}):null,(0,s.jsx)(l.$n,{onClick:()=>o(m),disabled:c,children:c?"Đang lưu...":"Lưu policy"})]})]})})}function k({open:e,keyName:t,models:n,setModels:a,activeProviders:o,modelAliases:i,onClose:d,onSave:x,saving:m,personalOnly:u,extraModels:h}){let[p,b]=(0,r.useState)(!1),g=c(n),f=e=>{let t=e?.value||e?.name||e;a(e=>c(e).filter(e=>e!==t))};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(l.aF,{isOpen:e,onClose:d,title:`Model access: ${t||"API Key"}`,size:"xl",children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsx)("p",{className:"text-sm text-text-muted",children:"Chọn một hoặc nhiều model m\xe0 API key n\xe0y được ph\xe9p sử dụng. Trang n\xe0y kh\xf4ng cho lưu danh s\xe1ch model rỗng."}),(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"text-sm font-medium",children:"Model được ph\xe9p d\xf9ng"}),(0,s.jsx)(l.$n,{size:"sm",variant:"outline",onClick:()=>b(!0),children:"Th\xeam model"})]}),0===g.length?(0,s.jsx)("div",{className:"rounded-xl border border-dashed border-border p-4 text-sm text-text-muted",children:"Chưa chọn model n\xe0o. H\xe3y th\xeam \xedt nhất một model trước khi lưu."}):(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:g.map(e=>(0,s.jsxs)("button",{type:"button",onClick:()=>f(e),className:"rounded-full border border-primary/30 bg-primary/10 px-2 py-1 font-mono text-xs text-primary transition hover:bg-red-500/10 hover:text-red-600",title:"Bấm để gỡ model n\xe0y",children:[e," \xd7"]},e))}),(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(l.$n,{variant:"ghost",onClick:d,children:"Hủy"}),(0,s.jsx)(l.$n,{onClick:x,disabled:m||0===g.length,children:m?"Đang lưu...":"Lưu danh s\xe1ch model"})]})]})}),(0,s.jsx)(l.rq,{isOpen:p,onClose:()=>b(!1),onSelect:e=>{let t=e?.value||e?.name||e;t&&a(e=>c([...e,t]))},onDeselect:f,activeProviders:o,modelAliases:i,title:"Chọn model được ph\xe9p d\xf9ng",addedModelValues:g,closeOnSelect:!1,personalOnly:u,extraModels:h})]})}function w({label:e,value:t,hint:n}){return(0,s.jsxs)("div",{className:"rounded-2xl border border-border bg-surface/70 p-4",children:[(0,s.jsx)("div",{className:"text-xs font-medium uppercase tracking-wide text-text-muted",children:e}),(0,s.jsx)("div",{className:"mt-2 text-2xl font-semibold text-text-main",children:t}),n?(0,s.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:n}):null]})}function C({pagination:e,pageSize:t,onPageChange:n,onPageSizeChange:r,loading:a}){let o=Number(e?.page||1),i=Number(e?.totalPages||1),d=Number(e?.total||0),c=0===d?0:(o-1)*t+1,x=Math.min(d,o*t);return(0,s.jsxs)("div",{className:"flex flex-col gap-3 border-t border-border px-4 py-3 md:flex-row md:items-center md:justify-between",children:[(0,s.jsxs)("div",{className:"text-sm text-text-muted",children:["Hiển thị ",(0,s.jsx)("b",{children:c}),"–",(0,s.jsx)("b",{children:x})," / ",(0,s.jsx)("b",{children:d})," API keys"]}),(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,s.jsxs)("select",{value:t,onChange:e=>r(Number(e.target.value)),className:"rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary",disabled:a,children:[(0,s.jsx)("option",{value:25,children:"25 / trang"}),(0,s.jsx)("option",{value:50,children:"50 / trang"}),(0,s.jsx)("option",{value:100,children:"100 / trang"})]}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(1),disabled:a||o<=1,children:"Đầu"}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(Math.max(1,o-1)),disabled:a||o<=1,children:"Trước"}),(0,s.jsxs)("span",{className:"rounded-xl border border-border bg-surface px-3 py-2 text-sm",children:["Trang ",o,"/",i]}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(Math.min(i,o+1)),disabled:a||o>=i,children:"Sau"}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(i),disabled:a||o>=i,children:"Cuối"})]})]})}function A({image:e,label:t,onClick:n}){return(0,s.jsx)("button",{type:"button",onClick:n,title:t,"aria-label":t,className:"flex h-9 w-9 items-center justify-center rounded-xl border border-border bg-background transition hover:border-primary/50 hover:bg-surface focus:outline-none focus:ring-2 focus:ring-primary/20",children:(0,s.jsx)("img",{src:e,alt:"","aria-hidden":"true",className:"size-5 rounded-sm object-contain"})})}function S({apiKey:e,onClaudeSettings:t,onOpenCodeSettings:n,onCodexSettings:r,onQwenSettings:l}){return(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,s.jsx)(A,{image:"/providers/claude.png",label:"Claude Code Settings",onClick:()=>t(e)}),(0,s.jsx)(A,{image:"/providers/opencode.png",label:"OpenCode Settings",onClick:()=>n(e)}),(0,s.jsx)(A,{image:"/providers/codex.png",label:"Codex Settings",onClick:()=>r(e)}),(0,s.jsx)(A,{image:"/providers/qwen.png",label:"Qwen Code Settings",onClick:()=>l(e)})]})}function P({apiKey:e,globalEnabled:t,globalLevel:n,onClose:a,onSave:o,saving:i,infoOnly:d=!1}){let[c,x]=(0,r.useState)(e?.cavemanMode||"inherit"),[m,u]=(0,r.useState)(e?.cavemanLevel||"lite"),[h,p]=(0,r.useState)(d?"info":"edit"),[b,g]=(0,r.useState)("");if((0,r.useEffect)(()=>{e&&(x(e.cavemanMode||"inherit"),u(e.cavemanLevel||"lite"),p(d?"info":"edit"),g(""))},[e,d]),!e)return null;let f="on"===c||"off"!==c&&t,j="on"===c?m:n,y=String(n||"full").toUpperCase(),v="info"===h,N=()=>{if(!i){if(v&&!d)return void p("edit");a()}},k=async()=>{if(!i){g("");try{let e=await o({cavemanMode:c,cavemanLevel:m});!1===e&&g("Kh\xf4ng lưu được cấu h\xecnh Caveman. Vui l\xf2ng kiểm tra lại v\xe0 thử lần nữa.")}catch(e){g(e?.message||"Kh\xf4ng lưu được cấu h\xecnh Caveman.")}}};return(0,s.jsx)(l.aF,{isOpen:!!e,onClose:N,title:v?"Caveman output compression l\xe0 g\xec?":`Caveman: ${e.name||"API Key"}`,size:v?"xl":"lg",footer:v?(0,s.jsx)(l.$n,{onClick:N,disabled:i,children:d?"Đ\xe3 hiểu":"Quay lại cấu h\xecnh"}):void 0,children:v?(0,s.jsxs)("div",{className:"space-y-5 text-sm text-text-main",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-surface px-3 py-2",children:[(0,s.jsx)("span",{className:"text-xs text-text-muted",children:"Global Caveman hiện đang:"}),(0,s.jsx)(l.Ex,{variant:t?"success":"default",size:"sm",children:t?"ON":"OFF"}),t?(0,s.jsx)(l.Ex,{variant:"default",size:"sm",children:y}):null,(0,s.jsx)("span",{className:"text-xs text-text-muted",children:'— \xe1p dụng cho API key chọn "Kế thừa Global"'})]}),(0,s.jsxs)("p",{className:"text-text-muted",children:["Caveman ch\xe8n một instruction về phong c\xe1ch trả lời v\xe0o ",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:"provider request"})," ngay trước khi gửi tới model, nhằm giảm lời dẫn, lặp \xfd v\xe0 diễn giải kh\xf4ng cần thiết để output ngắn gọn hơn. T\xednh năng n\xe0y d\xf9ng được cho mọi request qua API key, kh\xf4ng chỉ CLI tool."]}),(0,s.jsxs)("div",{className:"rounded-xl border border-amber-500/30 bg-amber-500/10 p-3 text-amber-800 dark:text-amber-200",children:["Caveman kh\xf4ng n\xe9n input hoặc tool output như RTK. Hiệu quả phụ thuộc model v\xe0 nội dung request. D\xf9ng n\xfat ",(0,s.jsx)("b",{children:"Test"})," ngay cuối block Caveman của API key để gọi c\xf9ng prompt khi Caveman OFF v\xe0 ON, sau đ\xf3 so s\xe1nh output token thực tế."]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"Caveman được \xe1p dụng ở đ\xe2u?"}),(0,s.jsxs)("div",{className:"rounded-xl border border-border bg-surface/60 p-3 font-mono text-xs text-text-muted",children:["Client request → x\xe1c thực / quota → routing → translate provider → RTK → ",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:"Caveman"})," → gửi provider"]}),(0,s.jsxs)("ul",{className:"mt-2 list-disc space-y-1 pl-5 text-text-muted",children:[(0,s.jsx)("li",{children:"Kh\xf4ng thay đổi model, provider, account, combo routing, fallback hoặc retry."}),(0,s.jsx)("li",{children:"Client Request v\xe0 Source Request vẫn giữ nội dung gốc."}),(0,s.jsx)("li",{children:"Provider Request JSON trong log sẽ chứa instruction Caveman v\xec đ\xf3 l\xe0 body thực tế gửi upstream."})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"C\xe1c mức độ"}),(0,s.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,s.jsxs)("table",{className:"min-w-full text-xs",children:[(0,s.jsx)("thead",{className:"bg-surface/80 text-left uppercase tracking-wide text-text-muted",children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"Mức"}),(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"T\xe1c dụng"}),(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"Khuyến nghị"})]})}),(0,s.jsxs)("tbody",{className:"divide-y divide-border text-text-muted",children:[(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Lite"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Bỏ lời dẫn v\xe0 lặp \xfd, vẫn ưu ti\xean giữ giải th\xedch cần thiết."}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Coding CLI, chat kỹ thuật, agent th\xf4ng thường."})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Full"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"\xc9p c\xe2u trả lời s\xfac t\xedch hơn, ưu ti\xean lệnh, code v\xe0 kết luận."}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Automation, t\xe1c vụ lặp lại, người d\xf9ng đ\xe3 quen ngữ cảnh."})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Ultra"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Output cực ngắn, giảm mạnh phần giải th\xedch."}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Chỉ d\xf9ng cho workflow kiểm so\xe1t chặt v\xe0 đ\xe3 kiểm thử."})]})]})]})})]}),(0,s.jsxs)("div",{className:"grid gap-4 md:grid-cols-2",children:[(0,s.jsxs)("div",{className:"rounded-xl border border-green-500/30 bg-green-500/10 p-4",children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-green-800 dark:text-green-200",children:"N\xean bật"}),(0,s.jsxs)("ul",{className:"list-disc space-y-1 pl-5 text-green-800/90 dark:text-green-200/90",children:[(0,s.jsx)("li",{children:"Claude Code, Codex CLI, OpenCode v\xe0 coding agent."}),(0,s.jsx)("li",{children:"Chat hỗ trợ kỹ thuật cần c\xe2u trả lời đi thẳng v\xe0o thao t\xe1c."}),(0,s.jsx)("li",{children:"Automation hoặc agent gọi model nhiều lần với ngữ cảnh r\xf5 r\xe0ng."}),(0,s.jsx)("li",{children:"API key chuy\xean d\xf9ng cho output ngắn: lệnh, checklist, kết luận, đoạn code."})]})]}),(0,s.jsxs)("div",{className:"rounded-xl border border-red-500/30 bg-red-500/10 p-4",children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-red-800 dark:text-red-200",children:"Kh\xf4ng n\xean bật"}),(0,s.jsxs)("ul",{className:"list-disc space-y-1 pl-5 text-red-800/90 dark:text-red-200/90",children:[(0,s.jsx)("li",{children:"Dịch thuật, viết t\xe0i liệu, b\xe1o c\xe1o, proposal hoặc tạo presentation."}),(0,s.jsx)("li",{children:"Nội dung ph\xe1p l\xfd, hợp đồng, bi\xean bản, incident report cần đầy đủ chi tiết."}),(0,s.jsx)("li",{children:"Hướng dẫn đ\xe0o tạo, giải th\xedch chuy\xean s\xe2u, brainstorming hoặc s\xe1ng tạo nội dung."}),(0,s.jsx)("li",{children:"Workflow y\xeau cầu đ\xfang cấu tr\xfac, đủ trường hoặc wording ch\xednh x\xe1c tuyệt đối."})]})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"Caveman kh\xe1c RTK thế n\xe0o?"}),(0,s.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,s.jsxs)("table",{className:"min-w-full text-xs",children:[(0,s.jsx)("thead",{className:"bg-surface/80 text-left uppercase tracking-wide text-text-muted",children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"T\xednh năng"}),(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"T\xe1c động"})]})}),(0,s.jsxs)("tbody",{className:"divide-y divide-border text-text-muted",children:[(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"RTK"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"R\xfat gọn tool output trước khi gửi model."})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Caveman"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Điều khiển model trả lời ngắn hơn."})]})]})]})})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"Global vs từng API key"}),(0,s.jsxs)("p",{className:"text-text-muted",children:[(0,s.jsx)("span",{className:"font-semibold text-text-main",children:"Kế thừa Global"})," d\xf9ng đ\xfang trạng th\xe1i v\xe0 level tại ",(0,s.jsx)("span",{className:"font-mono text-text-main",children:"/dashboard/endpoint"}),";",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:" Force ON"})," bật ri\xeang cho key v\xe0 d\xf9ng level đ\xe3 chọn;",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:" Force OFF"})," lu\xf4n tắt cho key. Override của API key lu\xf4n thắng Global theo cả hai chiều."]})]})]}):(0,s.jsxs)("div",{className:"space-y-5",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-surface p-3 text-sm",children:[(0,s.jsx)("span",{className:"text-text-muted",children:"Global Caveman hiện đang:"}),(0,s.jsx)(l.Ex,{variant:t?"success":"default",size:"sm",children:t?"ON":"OFF"}),t?(0,s.jsx)(l.Ex,{variant:"default",size:"sm",children:y}):null,(0,s.jsx)("span",{className:"text-xs text-text-muted",children:'— \xe1p dụng cho API key chọn "Kế thừa Global"'}),(0,s.jsx)("button",{type:"button",onClick:()=>p("info"),disabled:i,title:"Caveman l\xe0 g\xec? Bấm để xem giải th\xedch","aria-label":"Xem giải th\xedch về Caveman",className:"inline-flex size-5 shrink-0 items-center justify-center rounded-full border border-border text-[11px] font-bold text-text-muted transition-colors hover:border-brand-500 hover:text-brand-600 disabled:cursor-not-allowed disabled:opacity-50",children:"?"})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"block text-sm font-medium",children:"Chế độ override"}),(0,s.jsxs)("select",{value:c,onChange:e=>{x(e.target.value),g("")},disabled:i,className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-60",children:[(0,s.jsxs)("option",{value:"inherit",children:["Kế thừa Global (",t?`ON \xb7 ${y}`:"OFF",")"]}),(0,s.jsx)("option",{value:"on",children:"Force ON"}),(0,s.jsx)("option",{value:"off",children:"Force OFF"})]})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"block text-sm font-medium",children:"Mức n\xe9n"}),"on"===c?(0,s.jsxs)("select",{value:m,onChange:e=>{u(e.target.value),g("")},disabled:i,className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-60",children:[(0,s.jsx)("option",{value:"lite",children:"Lite — an to\xe0n cho coding CLI"}),(0,s.jsx)("option",{value:"full",children:"Full — s\xfac t\xedch hơn"}),(0,s.jsx)("option",{value:"ultra",children:"Ultra — cực ngắn"})]}):(0,s.jsx)("div",{className:"rounded-xl border border-border bg-surface/60 px-3 py-2.5 text-sm text-text-muted",children:"inherit"===c?t?(0,s.jsxs)(s.Fragment,{children:["Đang d\xf9ng mức Global: ",(0,s.jsx)("b",{className:"text-text-main",children:y})]}):(0,s.jsxs)(s.Fragment,{children:["Global đang ",(0,s.jsx)("b",{className:"text-text-main",children:"OFF"}),", n\xean kh\xf4ng c\xf3 mức n\xe9n hiệu lực."]}):(0,s.jsx)(s.Fragment,{children:"Force OFF — mức n\xe9n kh\xf4ng được \xe1p dụng."})})]}),(0,s.jsxs)("div",{className:"rounded-xl border border-border p-3 text-sm text-text-muted",children:["Hiệu lực: ",(0,s.jsx)("b",{className:"text-text-main",children:f?`ON \xb7 ${String(j||"lite").toUpperCase()}`:"OFF"})]}),b?(0,s.jsxs)("div",{className:"flex items-start gap-2 rounded-xl border border-red-500/30 bg-red-500/10 p-3 text-sm text-red-700 dark:text-red-300",children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[19px]",children:"error"}),(0,s.jsx)("span",{children:b})]}):null,(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(l.$n,{variant:"outline",onClick:N,disabled:i,children:"Hủy"}),(0,s.jsx)(l.$n,{onClick:k,disabled:i,children:i?"Đang lưu...":"Lưu"})]})]})})}let O=Object.freeze([{value:"lite",label:"Lite",description:"Giữ giải th\xedch cần thiết"},{value:"full",label:"Full",description:"Ưu ti\xean code v\xe0 kết luận"},{value:"ultra",label:"Ultra",description:"Output cực ngắn"}]),$=`Ph\xe2n t\xedch đoạn code sau, chỉ ra lỗi, nguy\xean nh\xe2n v\xe0 đưa bản sửa ho\xe0n chỉnh. Giữ đầy đủ lệnh v\xe0 code cần thiết:
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7593],{9385:(e,t,n)=>{"use strict";n.d(t,{Ek:()=>h,FY:()=>f,H1:()=>p,O0:()=>o,Zn:()=>j,cL:()=>b,j5:()=>u,pA:()=>s,u1:()=>g});let s=["coder","fast","thinking"],r=["claude","codex"],l={claude:"claude/",codex:"codex/"},a={coder:{model:"",contextWindow:0},fast:{model:"",contextWindow:0},thinking:{model:"",contextWindow:0}},o={version:2,local:{enabled:!0,providerName:"Local AI",autoCompactPct:75,models:{coder:{model:"programmer",contextWindow:12e4},fast:{model:"programmer-fast",contextWindow:12e4},thinking:{model:"programmer",contextWindow:12e4}}},cloud:{claude:{enabled:!1,providerName:"Claude Code Cloud",models:a},codex:{enabled:!1,providerName:"Codex Cloud",models:a}}};function i(e,t=300){return String(e??"").trim().slice(0,t)}function d(e,t){let n=Number(e);return!Number.isFinite(n)||n<=0?t:Math.floor(n)}function c(e,t=75){let n=Number(e);return Number.isFinite(n)?Math.min(100,Math.max(1,Math.floor(n))):t}function x(e,t,{local:n}){let r=e&&"object"==typeof e&&!Array.isArray(e)?e:{},l=r.models&&"object"==typeof r.models&&!Array.isArray(r.models)?r.models:{},a={};for(let e of s)a[e]=function(e,t,{local:n}){let s=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return{model:i(Object.prototype.hasOwnProperty.call(s,"model")?s.model:t.model),contextWindow:n?d(s.contextWindow,t.contextWindow||12e4):0}}(l[e],t.models[e],{local:n});let o={enabled:Object.prototype.hasOwnProperty.call(r,"enabled")?!0===r.enabled:t.enabled,providerName:i(Object.prototype.hasOwnProperty.call(r,"providerName")?r.providerName:t.providerName,80)||t.providerName,models:a};return n&&(o.autoCompactPct=c(r.autoCompactPct,t.autoCompactPct)),o}function m(e,t){if(!e||"object"!=typeof e||Array.isArray(e)||e.claude||e.codex)return null;let n=e.models&&"object"==typeof e.models&&!Array.isArray(e.models)?e.models:{},r=s.map(e=>i(n?.[e]?.model)).filter(Boolean),a=l[t];return a&&0!==r.length&&r.every(e=>e.startsWith(a))?e:null}function u(e={}){let t=e&&"object"==typeof e&&!Array.isArray(e)?e:{},n=t.cloud&&"object"==typeof t.cloud&&!Array.isArray(t.cloud)?t.cloud:{};return{version:2,local:x(t.local,o.local,{local:!0}),cloud:{claude:x(n.claude||m(n,"claude"),o.cloud.claude,{local:!1}),codex:x(n.codex||m(n,"codex"),o.cloud.codex,{local:!1})}}}function h(e,t){return r.includes(t)&&e?.cloud?.[t]||null}function p(e){return l[e]||""}function b(e,t,n=""){return i(e?.models?.[t]?.model)||n}function g(e,t,n=12e4){return d(e?.models?.[t]?.contextWindow,n)}function f(e){return[...new Set(s.map(t=>b(e,t)).filter(Boolean))]}function j(e){return Math.max(1,Math.floor(g(e,"coder")*c(e?.autoCompactPct)/100))}},56484:(e,t,n)=>{"use strict";n.d(t,{default:()=>R});var s=n(95155),r=n(12115),l=n(35497),a=n(94027),o=n(11059);let i=Object.freeze({enabled:!0,requestsPerMinute:20,maxOutputTokens:0,forceThinkingOff:!0,allowedIpCidrs:[],expiresAt:""});function d(e){return String(e||"").trim().toLowerCase()}function c(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function x(e,t){let n=c(e?.allowedModels),s=n[0]||String(t||"programmer").trim()||"programmer",r=n.find(e=>/fast|small|haiku/i.test(e))||n.find(e=>e!==s)||s;return{codingModel:s,fastModel:r}}let m="model_catalog.json";function u({icon:e,materialIcon:t,image:n,children:r,className:l=""}){return(0,s.jsxs)("span",{className:`inline-flex items-center gap-1.5 ${l}`,children:[n?(0,s.jsx)("img",{src:n,alt:"","aria-hidden":"true",className:"size-4 rounded-sm object-contain"}):t?(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[17px] leading-none",children:t}):e?(0,s.jsx)("span",{"aria-hidden":"true",className:"text-base leading-none",children:e}):null,(0,s.jsx)("span",{children:r})]})}function h(e,t=0){let n=Number(e);return Number.isFinite(n)?Math.max(0,Math.floor(n)):t}function p(e,t=!0){return null==e||""===e?t:!0===e||"true"===e||1===e||"1"===e}function b(e){return Array.isArray(e)?[...new Set(e.map(e=>String(e||"").trim()).filter(Boolean))]:[]}function g(e){return e&&"object"==typeof e&&!Array.isArray(e)&&Object.keys(e).length>0}function f(e={},t={}){let n={...t},s=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return{enabled:p(s.enabled??n.enabled,!0),requestsPerMinute:h(s.requestsPerMinute??n.requestsPerMinute,0),maxOutputTokens:h(s.maxOutputTokens??s.outputTokensMax??s.maxTokens??s.max_tokens??s.max_completion_tokens??n.maxOutputTokens,0),forceThinkingOff:p(s.forceThinkingOff??n.forceThinkingOff,!0),allowedIpCidrs:b(s.allowedIpCidrs??n.allowedIpCidrs),expiresAt:String(s.expiresAt??n.expiresAt??"").trim()}}function j({models:e,emptyLabel:t="Chưa g\xe1n model"}){let n=c(e);return 0===n.length?(0,s.jsx)("span",{className:"text-xs text-text-muted",children:t}):(0,s.jsxs)("div",{className:"mt-2 flex flex-wrap gap-1.5",children:[n.slice(0,8).map(e=>(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 font-mono text-xs",children:e},e)),n.length>8?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 text-xs",children:["+",n.length-8," model kh\xe1c"]}):null]})}function y({limits:e,showThinking:t=!1,showOutputLimit:n=!1}){if(!g(e))return(0,s.jsx)("div",{className:"mt-2 flex flex-wrap gap-2 text-xs text-text-muted",children:(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"policy: chưa set, kh\xf4ng giới hạn"})});let r=f(e);return(0,s.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2 text-xs text-text-muted",children:[(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:["policy: ",r.enabled?"bật":"tắt"]}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[r.requestsPerMinute||"∞"," req/ph\xfat"]}),n?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[r.maxOutputTokens||"∞"," output tokens"]}):null,t?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:["thinking: ",r.forceThinkingOff?"force off":"client tự quyết"]}):null,r.allowedIpCidrs.length>0?(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"IP locked"}):null]})}function v({label:e,value:t,onChange:n,hint:r}){return(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:e}),(0,s.jsx)("input",{type:"number",min:"0",value:t,onChange:e=>n(h(e.target.value,0)),className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary"}),r?(0,s.jsx)("span",{className:"mt-1 block text-xs text-text-muted",children:r}):null]})}function N({isOpen:e,keyName:t,policy:n,setPolicy:r,onClose:a,onSave:o,onClear:d,saving:c,clearLabel:x="X\xf3a policy / kh\xf4ng limit"}){let m=f(n,i),u=(e,t)=>r(n=>f({...n,[e]:t},i));return(0,s.jsx)(l.aF,{isOpen:e,onClose:a,title:`Policy API key: ${t||"API Key"}`,size:"xl",children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"rounded-xl border border-border bg-surface/60 p-3 text-sm text-text-muted",children:["Key mới tự c\xf3 ",(0,s.jsx)("b",{children:"default policy"}),". Chỉ admin được sửa policy. Request/ph\xfat = 0 nghĩa l\xe0 kh\xf4ng giới hạn tần suất. Max output tokens = 0 nghĩa l\xe0 kh\xf4ng \xe9p giới hạn output."]}),(0,s.jsxs)("label",{className:"flex items-center justify-between gap-3 rounded-xl border border-border p-3 text-sm",children:[(0,s.jsxs)("span",{children:[(0,s.jsx)("b",{children:"Bật policy"}),(0,s.jsx)("br",{}),(0,s.jsx)("span",{className:"text-xs text-text-muted",children:"Tắt mục n\xe0y th\xec policy được lưu nhưng kh\xf4ng \xe1p limit."})]}),(0,s.jsx)("input",{type:"checkbox",checked:m.enabled,onChange:e=>u("enabled",e.target.checked)})]}),(0,s.jsxs)("div",{className:"grid gap-3 md:grid-cols-2",children:[(0,s.jsx)(v,{label:"Request / ph\xfat",value:m.requestsPerMinute,onChange:e=>u("requestsPerMinute",e),hint:"0 = kh\xf4ng giới hạn tần suất. Khuyến nghị user thường: 10–20 req/ph\xfat."}),(0,s.jsx)(v,{label:"Max output tokens",value:m.maxOutputTokens,onChange:e=>u("maxOutputTokens",e),hint:"0 = kh\xf4ng giới hạn. VS Code khuyến nghị 2048–3072; chat d\xe0i 4096–8192."})]}),(0,s.jsxs)("label",{className:"flex items-center justify-between gap-3 rounded-xl border border-border p-3 text-sm",children:[(0,s.jsxs)("span",{children:[(0,s.jsx)("b",{children:"Force Thinking Off"}),(0,s.jsx)("br",{}),(0,s.jsx)("span",{className:"text-xs text-text-muted",children:"Khi bật, gateway \xe9p request c\xf3 chat_template_kwargs.enable_thinking=false theo chuẩn llama.cpp."})]}),(0,s.jsx)("input",{type:"checkbox",checked:m.forceThinkingOff,onChange:e=>u("forceThinkingOff",e.target.checked)})]}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"IP/CIDR được ph\xe9p"}),(0,s.jsx)("textarea",{value:b(m.allowedIpCidrs).join("\n"),onChange:e=>u("allowedIpCidrs",[...new Set(String(e.target.value||"").split(/[\n,]+/).map(e=>e.trim()).filter(Boolean))]),rows:3,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",placeholder:"10.0.0.0/8\n192.168.0.0/16"}),(0,s.jsx)("span",{className:"mt-1 block text-xs text-text-muted",children:"Để trống = mọi IP. Hỗ trợ IPv4 exact hoặc CIDR."})]}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Hết hạn l\xfac"}),(0,s.jsx)("input",{value:m.expiresAt,onChange:e=>u("expiresAt",e.target.value),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",placeholder:"2026-12-31T23:59:59+07:00 hoặc để trống"})]}),(0,s.jsxs)("div",{className:"flex flex-wrap justify-end gap-2",children:[(0,s.jsx)(l.$n,{variant:"ghost",onClick:a,children:"Hủy"}),d?(0,s.jsx)(l.$n,{variant:"outline",onClick:d,disabled:c,children:x}):null,(0,s.jsx)(l.$n,{onClick:()=>o(m),disabled:c,children:c?"Đang lưu...":"Lưu policy"})]})]})})}function k({open:e,keyName:t,models:n,setModels:a,activeProviders:o,modelAliases:i,onClose:d,onSave:x,saving:m,personalOnly:u,extraModels:h}){let[p,b]=(0,r.useState)(!1),g=c(n),f=e=>{let t=e?.value||e?.name||e;a(e=>c(e).filter(e=>e!==t))};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(l.aF,{isOpen:e,onClose:d,title:`Model access: ${t||"API Key"}`,size:"xl",children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsx)("p",{className:"text-sm text-text-muted",children:"Chọn một hoặc nhiều model m\xe0 API key n\xe0y được ph\xe9p sử dụng. Trang n\xe0y kh\xf4ng cho lưu danh s\xe1ch model rỗng."}),(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"text-sm font-medium",children:"Model được ph\xe9p d\xf9ng"}),(0,s.jsx)(l.$n,{size:"sm",variant:"outline",onClick:()=>b(!0),children:"Th\xeam model"})]}),0===g.length?(0,s.jsx)("div",{className:"rounded-xl border border-dashed border-border p-4 text-sm text-text-muted",children:"Chưa chọn model n\xe0o. H\xe3y th\xeam \xedt nhất một model trước khi lưu."}):(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:g.map(e=>(0,s.jsxs)("button",{type:"button",onClick:()=>f(e),className:"rounded-full border border-primary/30 bg-primary/10 px-2 py-1 font-mono text-xs text-primary transition hover:bg-red-500/10 hover:text-red-600",title:"Bấm để gỡ model n\xe0y",children:[e," \xd7"]},e))}),(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(l.$n,{variant:"ghost",onClick:d,children:"Hủy"}),(0,s.jsx)(l.$n,{onClick:x,disabled:m||0===g.length,children:m?"Đang lưu...":"Lưu danh s\xe1ch model"})]})]})}),(0,s.jsx)(l.rq,{isOpen:p,onClose:()=>b(!1),onSelect:e=>{let t=e?.value||e?.name||e;t&&a(e=>c([...e,t]))},onDeselect:f,activeProviders:o,modelAliases:i,title:"Chọn model được ph\xe9p d\xf9ng",addedModelValues:g,closeOnSelect:!1,personalOnly:u,extraModels:h})]})}function w({label:e,value:t,hint:n}){return(0,s.jsxs)("div",{className:"rounded-2xl border border-border bg-surface/70 p-4",children:[(0,s.jsx)("div",{className:"text-xs font-medium uppercase tracking-wide text-text-muted",children:e}),(0,s.jsx)("div",{className:"mt-2 text-2xl font-semibold text-text-main",children:t}),n?(0,s.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:n}):null]})}function C({pagination:e,pageSize:t,onPageChange:n,onPageSizeChange:r,loading:a}){let o=Number(e?.page||1),i=Number(e?.totalPages||1),d=Number(e?.total||0),c=0===d?0:(o-1)*t+1,x=Math.min(d,o*t);return(0,s.jsxs)("div",{className:"flex flex-col gap-3 border-t border-border px-4 py-3 md:flex-row md:items-center md:justify-between",children:[(0,s.jsxs)("div",{className:"text-sm text-text-muted",children:["Hiển thị ",(0,s.jsx)("b",{children:c}),"–",(0,s.jsx)("b",{children:x})," / ",(0,s.jsx)("b",{children:d})," API keys"]}),(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,s.jsxs)("select",{value:t,onChange:e=>r(Number(e.target.value)),className:"rounded-xl border border-border bg-background px-3 py-2 text-sm text-text-main outline-none focus:border-primary",disabled:a,children:[(0,s.jsx)("option",{value:25,children:"25 / trang"}),(0,s.jsx)("option",{value:50,children:"50 / trang"}),(0,s.jsx)("option",{value:100,children:"100 / trang"})]}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(1),disabled:a||o<=1,children:"Đầu"}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(Math.max(1,o-1)),disabled:a||o<=1,children:"Trước"}),(0,s.jsxs)("span",{className:"rounded-xl border border-border bg-surface px-3 py-2 text-sm",children:["Trang ",o,"/",i]}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(Math.min(i,o+1)),disabled:a||o>=i,children:"Sau"}),(0,s.jsx)(l.$n,{variant:"outline",size:"sm",onClick:()=>n(i),disabled:a||o>=i,children:"Cuối"})]})]})}function A({image:e,label:t,onClick:n}){return(0,s.jsx)("button",{type:"button",onClick:n,title:t,"aria-label":t,className:"flex h-9 w-9 items-center justify-center rounded-xl border border-border bg-background transition hover:border-primary/50 hover:bg-surface focus:outline-none focus:ring-2 focus:ring-primary/20",children:(0,s.jsx)("img",{src:e,alt:"","aria-hidden":"true",className:"size-5 rounded-sm object-contain"})})}function S({apiKey:e,onClaudeSettings:t,onOpenCodeSettings:n,onCodexSettings:r,onQwenSettings:l}){return(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,s.jsx)(A,{image:"/providers/claude.png",label:"Claude Code Settings",onClick:()=>t(e)}),(0,s.jsx)(A,{image:"/providers/opencode.png",label:"OpenCode Settings",onClick:()=>n(e)}),(0,s.jsx)(A,{image:"/providers/codex.png",label:"Codex Settings",onClick:()=>r(e)}),(0,s.jsx)(A,{image:"/providers/qwen.png",label:"Qwen Code Settings",onClick:()=>l(e)})]})}function P({apiKey:e,globalEnabled:t,globalLevel:n,onClose:a,onSave:o,saving:i,infoOnly:d=!1}){let[c,x]=(0,r.useState)(e?.cavemanMode||"inherit"),[m,u]=(0,r.useState)(e?.cavemanLevel||"lite"),[h,p]=(0,r.useState)(d?"info":"edit"),[b,g]=(0,r.useState)("");if((0,r.useEffect)(()=>{e&&(x(e.cavemanMode||"inherit"),u(e.cavemanLevel||"lite"),p(d?"info":"edit"),g(""))},[e,d]),!e)return null;let f="on"===c||"off"!==c&&t,j="on"===c?m:n,y=String(n||"full").toUpperCase(),v="info"===h,N=()=>{if(!i){if(v&&!d)return void p("edit");a()}},k=async()=>{if(!i){g("");try{let e=await o({cavemanMode:c,cavemanLevel:m});!1===e&&g("Kh\xf4ng lưu được cấu h\xecnh Caveman. Vui l\xf2ng kiểm tra lại v\xe0 thử lần nữa.")}catch(e){g(e?.message||"Kh\xf4ng lưu được cấu h\xecnh Caveman.")}}};return(0,s.jsx)(l.aF,{isOpen:!!e,onClose:N,title:v?"Caveman output compression l\xe0 g\xec?":`Caveman: ${e.name||"API Key"}`,size:v?"xl":"lg",footer:v?(0,s.jsx)(l.$n,{onClick:N,disabled:i,children:d?"Đ\xe3 hiểu":"Quay lại cấu h\xecnh"}):void 0,children:v?(0,s.jsxs)("div",{className:"space-y-5 text-sm text-text-main",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-surface px-3 py-2",children:[(0,s.jsx)("span",{className:"text-xs text-text-muted",children:"Global Caveman hiện đang:"}),(0,s.jsx)(l.Ex,{variant:t?"success":"default",size:"sm",children:t?"ON":"OFF"}),t?(0,s.jsx)(l.Ex,{variant:"default",size:"sm",children:y}):null,(0,s.jsx)("span",{className:"text-xs text-text-muted",children:'— \xe1p dụng cho API key chọn "Kế thừa Global"'})]}),(0,s.jsxs)("p",{className:"text-text-muted",children:["Caveman ch\xe8n một instruction về phong c\xe1ch trả lời v\xe0o ",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:"provider request"})," ngay trước khi gửi tới model, nhằm giảm lời dẫn, lặp \xfd v\xe0 diễn giải kh\xf4ng cần thiết để output ngắn gọn hơn. T\xednh năng n\xe0y d\xf9ng được cho mọi request qua API key, kh\xf4ng chỉ CLI tool."]}),(0,s.jsxs)("div",{className:"rounded-xl border border-amber-500/30 bg-amber-500/10 p-3 text-amber-800 dark:text-amber-200",children:["Caveman kh\xf4ng n\xe9n input hoặc tool output như RTK. Hiệu quả phụ thuộc model v\xe0 nội dung request. D\xf9ng n\xfat ",(0,s.jsx)("b",{children:"Test"})," ngay cuối block Caveman của API key để gọi c\xf9ng prompt khi Caveman OFF v\xe0 ON, sau đ\xf3 so s\xe1nh output token thực tế."]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"Caveman được \xe1p dụng ở đ\xe2u?"}),(0,s.jsxs)("div",{className:"rounded-xl border border-border bg-surface/60 p-3 font-mono text-xs text-text-muted",children:["Client request → x\xe1c thực / quota → routing → translate provider → RTK → ",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:"Caveman"})," → gửi provider"]}),(0,s.jsxs)("ul",{className:"mt-2 list-disc space-y-1 pl-5 text-text-muted",children:[(0,s.jsx)("li",{children:"Kh\xf4ng thay đổi model, provider, account, combo routing, fallback hoặc retry."}),(0,s.jsx)("li",{children:"Client Request v\xe0 Source Request vẫn giữ nội dung gốc."}),(0,s.jsx)("li",{children:"Provider Request JSON trong log sẽ chứa instruction Caveman v\xec đ\xf3 l\xe0 body thực tế gửi upstream."})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"C\xe1c mức độ"}),(0,s.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,s.jsxs)("table",{className:"min-w-full text-xs",children:[(0,s.jsx)("thead",{className:"bg-surface/80 text-left uppercase tracking-wide text-text-muted",children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"Mức"}),(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"T\xe1c dụng"}),(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"Khuyến nghị"})]})}),(0,s.jsxs)("tbody",{className:"divide-y divide-border text-text-muted",children:[(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Lite"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Bỏ lời dẫn v\xe0 lặp \xfd, vẫn ưu ti\xean giữ giải th\xedch cần thiết."}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Coding CLI, chat kỹ thuật, agent th\xf4ng thường."})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Full"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"\xc9p c\xe2u trả lời s\xfac t\xedch hơn, ưu ti\xean lệnh, code v\xe0 kết luận."}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Automation, t\xe1c vụ lặp lại, người d\xf9ng đ\xe3 quen ngữ cảnh."})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Ultra"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Output cực ngắn, giảm mạnh phần giải th\xedch."}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Chỉ d\xf9ng cho workflow kiểm so\xe1t chặt v\xe0 đ\xe3 kiểm thử."})]})]})]})})]}),(0,s.jsxs)("div",{className:"grid gap-4 md:grid-cols-2",children:[(0,s.jsxs)("div",{className:"rounded-xl border border-green-500/30 bg-green-500/10 p-4",children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-green-800 dark:text-green-200",children:"N\xean bật"}),(0,s.jsxs)("ul",{className:"list-disc space-y-1 pl-5 text-green-800/90 dark:text-green-200/90",children:[(0,s.jsx)("li",{children:"Claude Code, Codex CLI, OpenCode v\xe0 coding agent."}),(0,s.jsx)("li",{children:"Chat hỗ trợ kỹ thuật cần c\xe2u trả lời đi thẳng v\xe0o thao t\xe1c."}),(0,s.jsx)("li",{children:"Automation hoặc agent gọi model nhiều lần với ngữ cảnh r\xf5 r\xe0ng."}),(0,s.jsx)("li",{children:"API key chuy\xean d\xf9ng cho output ngắn: lệnh, checklist, kết luận, đoạn code."})]})]}),(0,s.jsxs)("div",{className:"rounded-xl border border-red-500/30 bg-red-500/10 p-4",children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-red-800 dark:text-red-200",children:"Kh\xf4ng n\xean bật"}),(0,s.jsxs)("ul",{className:"list-disc space-y-1 pl-5 text-red-800/90 dark:text-red-200/90",children:[(0,s.jsx)("li",{children:"Dịch thuật, viết t\xe0i liệu, b\xe1o c\xe1o, proposal hoặc tạo presentation."}),(0,s.jsx)("li",{children:"Nội dung ph\xe1p l\xfd, hợp đồng, bi\xean bản, incident report cần đầy đủ chi tiết."}),(0,s.jsx)("li",{children:"Hướng dẫn đ\xe0o tạo, giải th\xedch chuy\xean s\xe2u, brainstorming hoặc s\xe1ng tạo nội dung."}),(0,s.jsx)("li",{children:"Workflow y\xeau cầu đ\xfang cấu tr\xfac, đủ trường hoặc wording ch\xednh x\xe1c tuyệt đối."})]})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"Caveman kh\xe1c RTK thế n\xe0o?"}),(0,s.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,s.jsxs)("table",{className:"min-w-full text-xs",children:[(0,s.jsx)("thead",{className:"bg-surface/80 text-left uppercase tracking-wide text-text-muted",children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"T\xednh năng"}),(0,s.jsx)("th",{className:"px-3 py-2 font-medium",children:"T\xe1c động"})]})}),(0,s.jsxs)("tbody",{className:"divide-y divide-border text-text-muted",children:[(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"RTK"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"R\xfat gọn tool output trước khi gửi model."})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{className:"px-3 py-2 font-semibold text-text-main",children:"Caveman"}),(0,s.jsx)("td",{className:"px-3 py-2",children:"Điều khiển model trả lời ngắn hơn."})]})]})]})})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"mb-2 font-semibold text-text-main",children:"Global vs từng API key"}),(0,s.jsxs)("p",{className:"text-text-muted",children:[(0,s.jsx)("span",{className:"font-semibold text-text-main",children:"Kế thừa Global"})," d\xf9ng đ\xfang trạng th\xe1i v\xe0 level tại ",(0,s.jsx)("span",{className:"font-mono text-text-main",children:"/dashboard/endpoint"}),";",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:" Force ON"})," bật ri\xeang cho key v\xe0 d\xf9ng level đ\xe3 chọn;",(0,s.jsx)("span",{className:"font-semibold text-text-main",children:" Force OFF"})," lu\xf4n tắt cho key. Override của API key lu\xf4n thắng Global theo cả hai chiều."]})]})]}):(0,s.jsxs)("div",{className:"space-y-5",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-surface p-3 text-sm",children:[(0,s.jsx)("span",{className:"text-text-muted",children:"Global Caveman hiện đang:"}),(0,s.jsx)(l.Ex,{variant:t?"success":"default",size:"sm",children:t?"ON":"OFF"}),t?(0,s.jsx)(l.Ex,{variant:"default",size:"sm",children:y}):null,(0,s.jsx)("span",{className:"text-xs text-text-muted",children:'— \xe1p dụng cho API key chọn "Kế thừa Global"'}),(0,s.jsx)("button",{type:"button",onClick:()=>p("info"),disabled:i,title:"Caveman l\xe0 g\xec? Bấm để xem giải th\xedch","aria-label":"Xem giải th\xedch về Caveman",className:"inline-flex size-5 shrink-0 items-center justify-center rounded-full border border-border text-[11px] font-bold text-text-muted transition-colors hover:border-brand-500 hover:text-brand-600 disabled:cursor-not-allowed disabled:opacity-50",children:"?"})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"block text-sm font-medium",children:"Chế độ override"}),(0,s.jsxs)("select",{value:c,onChange:e=>{x(e.target.value),g("")},disabled:i,className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-60",children:[(0,s.jsxs)("option",{value:"inherit",children:["Kế thừa Global (",t?`ON \xb7 ${y}`:"OFF",")"]}),(0,s.jsx)("option",{value:"on",children:"Force ON"}),(0,s.jsx)("option",{value:"off",children:"Force OFF"})]})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"block text-sm font-medium",children:"Mức n\xe9n"}),"on"===c?(0,s.jsxs)("select",{value:m,onChange:e=>{u(e.target.value),g("")},disabled:i,className:"w-full rounded-xl border border-border bg-background px-3 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-60",children:[(0,s.jsx)("option",{value:"lite",children:"Lite — an to\xe0n cho coding CLI"}),(0,s.jsx)("option",{value:"full",children:"Full — s\xfac t\xedch hơn"}),(0,s.jsx)("option",{value:"ultra",children:"Ultra — cực ngắn"})]}):(0,s.jsx)("div",{className:"rounded-xl border border-border bg-surface/60 px-3 py-2.5 text-sm text-text-muted",children:"inherit"===c?t?(0,s.jsxs)(s.Fragment,{children:["Đang d\xf9ng mức Global: ",(0,s.jsx)("b",{className:"text-text-main",children:y})]}):(0,s.jsxs)(s.Fragment,{children:["Global đang ",(0,s.jsx)("b",{className:"text-text-main",children:"OFF"}),", n\xean kh\xf4ng c\xf3 mức n\xe9n hiệu lực."]}):(0,s.jsx)(s.Fragment,{children:"Force OFF — mức n\xe9n kh\xf4ng được \xe1p dụng."})})]}),(0,s.jsxs)("div",{className:"rounded-xl border border-border p-3 text-sm text-text-muted",children:["Hiệu lực: ",(0,s.jsx)("b",{className:"text-text-main",children:f?`ON \xb7 ${String(j||"lite").toUpperCase()}`:"OFF"})]}),b?(0,s.jsxs)("div",{className:"flex items-start gap-2 rounded-xl border border-red-500/30 bg-red-500/10 p-3 text-sm text-red-700 dark:text-red-300",children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[19px]",children:"error"}),(0,s.jsx)("span",{children:b})]}):null,(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(l.$n,{variant:"outline",onClick:N,disabled:i,children:"Hủy"}),(0,s.jsx)(l.$n,{onClick:k,disabled:i,children:i?"Đang lưu...":"Lưu"})]})]})})}let O=Object.freeze([{value:"lite",label:"Lite",description:"Giữ giải th\xedch cần thiết"},{value:"full",label:"Full",description:"Ưu ti\xean code v\xe0 kết luận"},{value:"ultra",label:"Ultra",description:"Output cực ngắn"}]),$=`Ph\xe2n t\xedch đoạn code sau, chỉ ra lỗi, nguy\xean nh\xe2n v\xe0 đưa bản sửa ho\xe0n chỉnh. Giữ đầy đủ lệnh v\xe0 code cần thiết:
|
|
2
2
|
|
|
3
3
|
function getUserName(user) {
|
|
4
4
|
return user.profile.name.trim();
|
|
5
|
-
}`;function I(e){if(null==e||""===e)return"—";let t=Number(e);return Number.isFinite(t)?t.toLocaleString("vi-VN"):"—"}function E(e){if(null==e||""===e)return"—";let t=Number(e);if(!Number.isFinite(t))return"—";let n=t>0?"+":"";return`${n}${t.toFixed(1)}%`}function L(e){if(null==e||""===e)return"—";let t=Number(e);if(!Number.isFinite(t))return"—";let n=t>0?"+":"";return`${n}${t.toLocaleString("vi-VN")}`}function T({label:e,value:t,hint:n,tone:r="default"}){return(0,s.jsxs)("div",{className:`rounded-xl border p-3 ${"good"===r?"border-emerald-500/25 bg-emerald-500/10 text-emerald-800 dark:text-emerald-200":"bad"===r?"border-red-500/25 bg-red-500/10 text-red-700 dark:text-red-300":"border-border bg-surface/70 text-text-main"}`,children:[(0,s.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wide opacity-70",children:e}),(0,s.jsx)("div",{className:"mt-1 text-lg font-semibold",children:t}),n?(0,s.jsx)("div",{className:"mt-1 text-[11px] opacity-70",children:n}):null]})}function _({apiKey:e,fallbackModels:t,onClose:n}){let a=(0,r.useMemo)(()=>{let n=c(e?.allowedModels);return n.length>0?n:c(t)},[e,t]),[o,i]=(0,r.useState)(""),[d,x]=(0,r.useState)($),[m,h]=(0,r.useState)("lite"),[p,b]=(0,r.useState)(!1),[g,f]=(0,r.useState)(""),[j,y]=(0,r.useState)(null);if((0,r.useEffect)(()=>{if(!e)return;let n=c(e.allowedModels),s=c(t);i(n[0]||s[0]||""),h(["lite","full","ultra"].includes(e.cavemanLevel)?e.cavemanLevel:"lite"),x($),b(!1),f(""),y(null)},[e?.id]),!e)return null;let v=!!o&&!!d.trim()&&!p,N=async()=>{if(v){b(!0),f(""),y(null);try{let t=await fetch(`/api/keys/${e.id}/caveman-test`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:o,prompt:d.trim(),level:m})}),n=await t.json().catch(()=>({}));if(!t.ok){let e=n?.error?.message||n?.error||n?.message||"Kh\xf4ng chạy được Caveman A/B test";throw Error(e)}y(n)}catch(e){f(e?.message||"Kh\xf4ng chạy được Caveman A/B test")}finally{b(!1)}}},k=j?.baseline||null;return(0,s.jsx)(l.aF,{isOpen:!!e,onClose:()=>!p&&n(),title:"Test Caveman A/B",size:"xl",children:(0,s.jsxs)("div",{className:"space-y-5",children:[(0,s.jsx)("div",{className:"overflow-hidden rounded-2xl border border-indigo-500/25 bg-gradient-to-r from-indigo-500/10 via-primary/5 to-cyan-500/10",children:(0,s.jsxs)("div",{className:"flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,s.jsx)("span",{className:"inline-flex size-11 shrink-0 items-center justify-center rounded-2xl bg-indigo-500/15 text-indigo-700 dark:text-indigo-300",children:(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[25px]",children:"experiment"})}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsx)("div",{className:"truncate font-semibold text-text-main",children:e.name||"API Key"}),(0,s.jsx)("div",{className:"mt-0.5 text-xs text-text-muted",children:"So s\xe1nh c\xf9ng prompt: Caveman OFF với mức ON đ\xe3 chọn"})]})]}),(0,s.jsxs)("div",{className:"flex shrink-0 items-center gap-2 text-xs",children:[(0,s.jsx)("span",{className:"rounded-full border border-border bg-background/80 px-2.5 py-1",children:"A/B thực tế"}),(0,s.jsxs)("span",{className:"rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-amber-700 dark:text-amber-300",children:[2," lượt gọi"]})]})]})}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1.5 block text-xs font-medium text-text-muted",children:"Model được ph\xe9p d\xf9ng"}),(0,s.jsxs)("select",{value:o,onChange:e=>i(e.target.value),disabled:p||0===a.length,className:"w-full rounded-xl border border-border bg-background px-3 py-2.5 font-mono text-sm text-text-main outline-none transition focus:border-primary disabled:opacity-60",children:[0===a.length?(0,s.jsx)("option",{value:"",children:"Kh\xf4ng c\xf3 model để test"}):null,a.map(e=>(0,s.jsx)("option",{value:e,children:e},e))]})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"mb-2 flex items-center justify-between gap-3",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-text-muted",children:"Mức Caveman"}),(0,s.jsx)("span",{className:"text-[11px] text-text-muted",children:"Tối đa 2.048 output tokens"})]}),(0,s.jsx)("div",{className:"grid gap-2 sm:grid-cols-3",children:O.map(e=>{let t=m===e.value;return(0,s.jsxs)("button",{type:"button",onClick:()=>h(e.value),disabled:p,className:`rounded-xl border p-3 text-left transition ${t?"border-primary bg-primary/10 ring-1 ring-primary/20":"border-border bg-background hover:border-primary/40 hover:bg-surface"} disabled:cursor-default disabled:opacity-80`,children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"font-semibold text-text-main",children:e.label}),t?(0,s.jsx)("span",{className:"material-symbols-outlined text-[17px] text-primary",children:"check_circle"}):null]}),(0,s.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:e.description})]},e.value)})})]}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsxs)("div",{className:"mb-1.5 flex items-center justify-between gap-3",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-text-muted",children:"Prompt test"}),(0,s.jsxs)("span",{className:`text-[11px] ${d.length>12e3?"text-red-600":"text-text-muted"}`,children:[d.length.toLocaleString("vi-VN"),"/12.000 k\xfd tự"]})]}),(0,s.jsx)("textarea",{value:d,onChange:e=>x(e.target.value.slice(0,12e3)),disabled:p,rows:7,className:"w-full resize-y rounded-xl border border-border bg-background px-3 py-3 font-mono text-sm leading-6 text-text-main outline-none transition focus:border-primary disabled:opacity-70",placeholder:"Nhập c\xf9ng một prompt để so s\xe1nh Caveman OFF v\xe0 ON..."})]}),(0,s.jsxs)("div",{className:"rounded-xl border border-amber-500/30 bg-amber-500/10 p-3 text-xs leading-5 text-amber-800 dark:text-amber-200",children:[(0,s.jsx)("b",{children:"Lưu \xfd chi ph\xed:"})," ph\xe9p thử gọi provider thật v\xe0 tạo usage/log như request b\xecnh thường. Mỗi lần test d\xf9ng đ\xfang 2 lượt gọi: một baseline OFF v\xe0 một lượt ON ở mức đ\xe3 chọn. Kết quả vẫn c\xf3 thể dao động nhẹ theo model."]}),g?(0,s.jsxs)("div",{className:"flex items-start gap-2 rounded-xl border border-red-500/30 bg-red-500/10 p-3 text-sm text-red-700 dark:text-red-300",children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[19px]",children:"error"}),(0,s.jsx)("span",{children:g})]}):null,p?(0,s.jsxs)("div",{className:"rounded-2xl border border-primary/25 bg-primary/5 p-6 text-center",children:[(0,s.jsx)("span",{className:"material-symbols-outlined animate-spin text-3xl text-primary",children:"progress_activity"}),(0,s.jsxs)("div",{className:"mt-2 font-medium text-text-main",children:["Đang chạy ",2," lượt A/B..."]}),(0,s.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:"Giữ modal mở cho tới khi model trả đủ kết quả. Mỗi lượt c\xf3 timeout tối đa 5 ph\xfat."})]}):null,j&&k?(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"font-semibold text-text-main",children:"Kết quả A/B"}),(0,s.jsxs)("p",{className:"text-xs text-text-muted",children:[j.model," \xb7 ",j.callsMade," lượt gọi \xb7 output cap ",I(j.maxOutputTokens)]})]}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-3 py-1 text-xs text-text-muted",children:["Baseline OFF: ",I(k.usage?.outputTokens)," output tokens"]})]}),(0,s.jsx)("div",{className:"grid gap-3 lg:grid-cols-1",children:(j.results||[]).map(e=>{if(e.error)return(0,s.jsxs)("div",{className:"rounded-2xl border border-red-500/30 bg-red-500/10 p-4",children:[(0,s.jsx)("div",{className:"font-semibold uppercase text-red-700 dark:text-red-300",children:e.level}),(0,s.jsx)("div",{className:"mt-2 text-sm text-red-700 dark:text-red-300",children:e.error})]},e.level);let t=e.savings?.outputSaved,n=e.savings?.outputSavedPercent,r=k.usage?.outputTokens!==null&&e.usage?.outputTokens!==null,l=Number(t)>0,a=0>Number(t),o=Number.isFinite(Number(n))?Math.max(0,Math.min(100,Number(n))):0;return(0,s.jsxs)("div",{className:"overflow-hidden rounded-2xl border border-border bg-background shadow-sm",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2 border-b border-border bg-surface/60 px-4 py-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"inline-flex size-8 items-center justify-center rounded-xl bg-primary/10 text-primary",children:(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[19px]",children:"compress"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"font-semibold uppercase text-text-main",children:e.level}),(0,s.jsxs)("div",{className:"text-[11px] text-text-muted",children:[I(e.latencyMs)," ms"]})]})]}),(0,s.jsx)("span",{className:`rounded-full px-2.5 py-1 text-xs font-semibold ${l?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":a?"bg-red-500/15 text-red-700 dark:text-red-300":"bg-surface text-text-muted"}`,children:r?`${L(t)} tokens`:"No usage"})]}),(0,s.jsxs)("div",{className:"space-y-3 p-4",children:[(0,s.jsxs)("div",{className:"grid grid-cols-2 gap-2",children:[(0,s.jsx)(T,{label:"OFF output",value:I(k.usage?.outputTokens)}),(0,s.jsx)(T,{label:"ON output",value:I(e.usage?.outputTokens),tone:l?"good":a?"bad":"default"}),(0,s.jsx)(T,{label:"Output giảm",value:r?E(n):"—",hint:r?`${L(t)} token`:"Provider kh\xf4ng trả usage",tone:l?"good":a?"bad":"default"}),(0,s.jsx)(T,{label:"Input overhead",value:L(e.savings?.inputOverhead),hint:"instruction Caveman"})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"mb-1 flex justify-between text-[11px] text-text-muted",children:[(0,s.jsx)("span",{children:"Hiệu quả output"}),(0,s.jsx)("span",{children:r?E(n):"—"})]}),(0,s.jsx)("div",{className:"h-2 overflow-hidden rounded-full bg-surface",children:(0,s.jsx)("div",{className:`h-full rounded-full transition-all ${l?"bg-emerald-500":"bg-red-500"}`,style:{width:`${o}%`}})})]}),(0,s.jsxs)("div",{className:"flex items-center justify-between rounded-xl border border-border bg-surface/50 px-3 py-2 text-xs",children:[(0,s.jsx)("span",{className:"text-text-muted",children:"Net total token"}),(0,s.jsxs)("span",{className:`font-semibold ${Number(e.savings?.totalSaved)>0?"text-emerald-700 dark:text-emerald-300":0>Number(e.savings?.totalSaved)?"text-red-600":"text-text-main"}`,children:[L(e.savings?.totalSaved)," (",E(e.savings?.totalSavedPercent),")"]})]})]})]},e.level)})}),(0,s.jsxs)("div",{className:"grid gap-3 lg:grid-cols-2",children:[(0,s.jsxs)("details",{className:"overflow-hidden rounded-xl border border-border bg-background",open:!0,children:[(0,s.jsx)("summary",{className:"cursor-pointer bg-surface/60 px-4 py-3 text-sm font-medium text-text-main",children:"Output baseline \xb7 Caveman OFF"}),(0,s.jsx)("pre",{className:"max-h-80 overflow-auto whitespace-pre-wrap p-4 text-xs leading-5 text-text-muted",children:k.output||"Model kh\xf4ng trả content text."})]}),(j.results||[]).map(e=>(0,s.jsxs)("details",{className:"overflow-hidden rounded-xl border border-border bg-background",open:!0,children:[(0,s.jsxs)("summary",{className:"cursor-pointer bg-surface/60 px-4 py-3 text-sm font-medium text-text-main",children:["Output Caveman \xb7 ",String(e.level||"").toUpperCase()]}),(0,s.jsx)("pre",{className:"max-h-80 overflow-auto whitespace-pre-wrap p-4 text-xs leading-5 text-text-muted",children:e.error||e.output||"Model kh\xf4ng trả content text."})]},`output-${e.level}`))]}),(0,s.jsx)("p",{className:"text-[11px] leading-5 text-text-muted",children:j.note})]}):null,(0,s.jsxs)("div",{className:"flex flex-wrap justify-end gap-2 border-t border-border pt-4",children:[(0,s.jsx)(l.$n,{variant:"ghost",onClick:n,disabled:p,children:"Đ\xf3ng"}),(0,s.jsx)(l.$n,{onClick:N,disabled:!v||d.length>12e3,children:(0,s.jsx)(u,{materialIcon:p?"progress_activity":"experiment",children:p?"Đang test...":"Chạy A/B (2 calls)"})})]})]})})}function M({apiKey:e,owner:t,isAdmin:n,onRename:l,onRotate:a,onEditModels:o,onEditPolicy:i,onAssignOwner:d,onDelete:c}){let[x,m]=(0,r.useState)(!1),h=(0,r.useRef)(null);(0,r.useEffect)(()=>{if(!x)return;let e=e=>{!h.current||h.current.contains(e.target)||m(!1)},t=e=>{"Escape"===e.key&&m(!1)};return document.addEventListener("pointerdown",e,!0),document.addEventListener("keydown",t),()=>{document.removeEventListener("pointerdown",e,!0),document.removeEventListener("keydown",t)}},[h,x,m]);let p=e=>{m(!1),e()};return(0,s.jsxs)("details",{ref:h,className:"group",open:x,onToggle:e=>m(e.currentTarget.open),children:[(0,s.jsx)("summary",{title:"Thao t\xe1c kh\xe1c",className:"flex h-9 cursor-pointer list-none items-center rounded-xl border border-border bg-background px-3 text-sm font-medium text-text-main transition hover:border-primary/50 hover:bg-surface focus:outline-none focus:ring-2 focus:ring-primary/20 [&::-webkit-details-marker]:hidden",children:(0,s.jsx)("span",{"aria-hidden":"true",className:"text-lg leading-none",children:"⋯"})}),(0,s.jsxs)("div",{className:"ml-auto mt-2 w-48 overflow-hidden rounded-xl border border-border bg-background py-1 text-left shadow-xl shadow-black/10",children:[(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>l(e.id,e.name)),children:(0,s.jsx)(u,{icon:"✏️",children:"Đổi t\xean"})}),(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>a(e)),children:(0,s.jsx)(u,{materialIcon:"key",children:"Đổi key"})}),(0,s.jsx)("div",{className:"my-1 border-t border-border"}),(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>o(e)),children:(0,s.jsx)(u,{icon:"\uD83D\uDCE6",children:"Models"})}),n?(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>i(e)),children:(0,s.jsx)(u,{icon:"\uD83D\uDEE1️",children:"Policy"})}):null,n?(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>d(e.id,t)),children:(0,s.jsx)(u,{icon:"\uD83D\uDC64",children:"Owner"})}):null,(0,s.jsx)("div",{className:"my-1 border-t border-border"}),(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm font-medium text-red-600 transition hover:bg-red-500/10",onClick:()=>p(()=>c(e.id)),children:(0,s.jsx)(u,{icon:"\uD83D\uDDD1️",children:"X\xf3a"})})]})]})}function K({mode:e,effectiveEnabled:t,effectiveLevel:n,globalEnabled:r,onEdit:l,onInfo:a,onTest:o}){let i=String(n||"lite").toUpperCase();return(0,s.jsxs)("div",{className:`inline-flex max-w-full items-center gap-1.5 whitespace-nowrap rounded-xl border px-2 py-1.5 shadow-sm ${t?"border-emerald-500/30 bg-emerald-500/10 text-emerald-800 dark:text-emerald-200":"border-slate-300/80 bg-slate-500/5 text-slate-700 dark:border-slate-600 dark:text-slate-300"}`,title:`Caveman ${t?"ON":"OFF"} \xb7 ${"inherit"===e?"Kế thừa Global":"on"===e?"Force ON":"Force OFF"} \xb7 Global ${r?"ON":"OFF"} \xb7 Mức ${i}`,children:[(0,s.jsx)("span",{className:`inline-flex size-5 shrink-0 items-center justify-center rounded-md ${t?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-slate-500/10 text-slate-600 dark:text-slate-300"}`,children:(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[15px] leading-none",children:"compress"})}),(0,s.jsx)("button",{type:"button",onClick:a,className:"shrink-0 rounded-md font-semibold underline-offset-2 transition hover:text-primary hover:underline focus:outline-none focus:ring-2 focus:ring-primary/25",title:"Xem hướng dẫn Caveman","aria-label":"Mở hướng dẫn Caveman",children:"Caveman"}),(0,s.jsx)("button",{type:"button",onClick:l,className:`shrink-0 rounded-full border px-2 py-0.5 text-[10px] font-bold tracking-wide transition focus:outline-none focus:ring-2 focus:ring-primary/25 ${t?"border-emerald-500/40 bg-emerald-600 text-white hover:bg-emerald-700":"border-slate-300 bg-white text-slate-600 hover:border-primary/50 hover:text-primary dark:border-slate-600 dark:bg-slate-900/40 dark:text-slate-300"}`,"aria-label":`Mở cấu h\xecnh Caveman, hiện đang ${t?"bật":"tắt"}`,children:t?"ON":"OFF"}),(0,s.jsxs)("span",{className:`inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-semibold ${t?"border-emerald-500/25 bg-white/55 text-emerald-800 dark:bg-slate-950/20 dark:text-emerald-200":"border-slate-300/80 bg-white/55 text-slate-500 dark:border-slate-600 dark:bg-slate-950/20 dark:text-slate-400"}`,children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[12px] leading-none",children:"tune"}),i]}),(0,s.jsx)("span",{"aria-hidden":"true",className:"h-5 w-px shrink-0 bg-current opacity-15"}),(0,s.jsxs)("button",{type:"button",onClick:o,className:"inline-flex shrink-0 items-center gap-1 rounded-lg border border-indigo-500/30 bg-indigo-500/10 px-2 py-0.5 text-[10px] font-semibold text-indigo-700 transition hover:border-indigo-500/60 hover:bg-indigo-500/20 focus:outline-none focus:ring-2 focus:ring-indigo-500/25 dark:text-indigo-300",title:"Test A/B Caveman với một mức n\xe9n","aria-label":"Mở Caveman A/B test",children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[13px] leading-none",children:"experiment"}),"Test"]})]})}function F({keys:e,copied:t,copy:n,isAdmin:r,globalCavemanEnabled:a,globalCavemanLevel:o,onToggleActive:i,onApiTest:d,onClaudeSettings:x,onOpenCodeSettings:m,onCodexSettings:u,onQwenSettings:h,onRename:p,onRotate:b,onEditModels:j,onEditPolicy:y,onEditCaveman:v,onShowCavemanInfo:N,onCavemanTest:k,onAssignOwner:w,onDelete:C}){return(0,s.jsx)("div",{className:"overflow-hidden rounded-2xl border border-border",children:(0,s.jsx)("div",{className:"overflow-x-auto",children:(0,s.jsxs)("table",{className:"min-w-full divide-y divide-border text-sm",children:[(0,s.jsx)("thead",{className:"bg-surface/80 text-left text-xs uppercase tracking-wide text-text-muted",children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"T\xean / Key"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Trạng th\xe1i"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Owner"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Model"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Policy"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Ng\xe0y tạo"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 text-right font-medium",children:"Thao t\xe1c"})]})}),(0,s.jsx)("tbody",{className:"divide-y divide-border bg-background",children:e.map(e=>{var A;let P=e.ownerUser||e.createdByUser||"chưa g\xe1n",O=c(e.allowedModels),$=g(e.limits),I=f(e.limits||{}),E=e.cavemanMode||"inherit",L="on"===E||"off"!==E&&a,T="on"===E?e.cavemanLevel||"lite":o;return(0,s.jsxs)("tr",{className:"align-top transition hover:bg-surface/50",children:[(0,s.jsxs)("td",{className:"min-w-[280px] px-4 py-4",children:[(0,s.jsx)("div",{className:"font-medium text-text-main",children:e.name||"API Key"}),(0,s.jsxs)("div",{className:"group/key mt-2 flex max-w-[380px] items-center gap-2 rounded-xl border border-border bg-surface px-3 py-2 font-mono text-xs text-text-main",children:[(0,s.jsx)("span",{className:"min-w-0 flex-1 truncate",children:(A=e.key)?A.length>12?`${A.slice(0,8)}...${A.slice(-4)}`:A:""}),(0,s.jsxs)("div",{className:"relative shrink-0 group/btn",children:[(0,s.jsx)("button",{type:"button",onClick:()=>n(e.key,e.id),className:"rounded p-0.5 text-text-muted transition hover:bg-sidebar hover:text-primary","aria-label":t===e.id?"Đ\xe3 copy":"Copy API key",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-sm",children:t===e.id?"check":"content_copy"})}),(0,s.jsx)("span",{className:"pointer-events-none absolute left-1/2 top-5 mt-1 -translate-x-1/2 whitespace-nowrap text-[10px] text-text-muted opacity-0 transition-opacity group-hover/btn:opacity-100",children:t===e.id?"Copied!":"Copy"})]}),(0,s.jsxs)("div",{className:"relative shrink-0 group/btn",children:[(0,s.jsx)("button",{type:"button",onClick:()=>d(e),className:"rounded p-0.5 text-text-muted transition hover:bg-sidebar hover:text-primary","aria-label":"Test API key bằng curl",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-sm",children:"science"})}),(0,s.jsx)("span",{className:"pointer-events-none absolute left-1/2 top-5 mt-1 -translate-x-1/2 whitespace-nowrap text-[10px] text-text-muted opacity-0 transition-opacity group-hover/btn:opacity-100",children:"Test"})]})]}),e.createdByUser?(0,s.jsxs)("div",{className:"mt-2 text-xs text-text-muted",children:["Tạo bởi: ",e.createdByUser]}):null]}),(0,s.jsx)("td",{className:"whitespace-nowrap px-4 py-4",children:(0,s.jsx)(l.lM,{checked:!!e.isActive,onChange:t=>i(e.id,t)})}),(0,s.jsx)("td",{className:"min-w-[160px] px-4 py-4",children:(0,s.jsx)("div",{className:"break-all text-sm text-text-main",children:P})}),(0,s.jsx)("td",{className:"px-4 py-4 align-top",children:O.length>0?(0,s.jsxs)("div",{className:"flex flex-col items-start gap-1",children:[O.slice(0,3).map(e=>(0,s.jsx)("span",{className:"max-w-full truncate rounded-full border border-border bg-surface px-2 py-1 font-mono text-xs",children:e},e)),O.length>3?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 text-xs",children:["+",O.length-3]}):null]}):(0,s.jsx)("span",{className:"inline-block rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-1 text-xs text-amber-700 dark:text-amber-300",children:"Legacy full access"})}),(0,s.jsx)("td",{className:"px-4 py-4 align-top",children:(0,s.jsxs)("div",{className:"flex flex-col items-start gap-1 text-xs",children:[$?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:I.enabled?"bật":"tắt"}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[I.requestsPerMinute||"∞","/ph\xfat"]}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[I.promptCharsMax||"∞"," chars"]}),r&&I.maxOutputTokens>0?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[I.maxOutputTokens," out"]}):null,r&&I.forceThinkingOff?(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"thinking off"}):null,I.allowedIpCidrs.length>0?(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"IP locked"}):null]}):(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 text-text-muted",children:"Policy: chưa set"}),(0,s.jsx)(K,{mode:E,effectiveEnabled:L,effectiveLevel:T,globalEnabled:a,onEdit:()=>v(e),onInfo:()=>N(e),onTest:()=>k(e)})]})}),(0,s.jsx)("td",{className:"min-w-[150px] px-4 py-4 text-xs text-text-muted",children:function(e){if(!e)return"kh\xf4ng r\xf5";try{return new Date(e).toLocaleString()}catch{return String(e)}}(e.createdAt)}),(0,s.jsx)("td",{className:"min-w-[200px] px-4 py-4",children:(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2",children:[(0,s.jsx)(M,{apiKey:e,owner:P,isAdmin:r,onRename:p,onRotate:b,onEditModels:j,onEditPolicy:y,onAssignOwner:w,onDelete:C}),(0,s.jsx)(S,{apiKey:e,onClaudeSettings:x,onOpenCodeSettings:m,onCodexSettings:u,onQwenSettings:h})]})})]},e.id)})})]})})})}function R(){let e,t,n,u,[p,b]=(0,r.useState)([]),[v,A]=(0,r.useState)(!0),[S,O]=(0,r.useState)(""),[$,I]=(0,r.useState)(!1),[E,L]=(0,r.useState)(""),[T,M]=(0,r.useState)(""),[K,R]=(0,r.useState)(""),[U,D]=(0,r.useState)(""),[q,B]=(0,r.useState)(null),[z,W]=(0,r.useState)([]),[H,G]=(0,r.useState)(""),[Y,J]=(0,r.useState)(!1),[V,X]=(0,r.useState)(!1),[Z,Q]=(0,r.useState)([]),[ee,et]=(0,r.useState)([]),[en,es]=(0,r.useState)(!1),[er,el]=(0,r.useState)(i),[ea,eo]=(0,r.useState)(i),[ei,ed]=(0,r.useState)(!1),[ec,ex]=(0,r.useState)(!1),[em,eu]=(0,r.useState)(!1),[eh,ep]=(0,r.useState)([]),[eb,eg]=(0,r.useState)({}),[ef,ej]=(0,r.useState)(!1),[ey,ev]=(0,r.useState)(!1),[eN,ek]=(0,r.useState)(null),[ew,eC]=(0,r.useState)([]),[eA,eS]=(0,r.useState)(!1),[eP,eO]=(0,r.useState)(null),[e$,eI]=(0,r.useState)(i),[eE,eL]=(0,r.useState)(!1),[eT,e_]=(0,r.useState)(null),[eM,eK]=(0,r.useState)(null),[eF,eR]=(0,r.useState)(null),[eU,eD]=(0,r.useState)(!1),[eq,eB]=(0,r.useState)(!1),[ez,eW]=(0,r.useState)("full"),[eH,eG]=(0,r.useState)(5),[eY,eJ]=(0,r.useState)(0),[eV,eX]=(0,r.useState)(0),[eZ,eQ]=(0,r.useState)(5),[e0,e1]=(0,r.useState)(String(5)),[e2,e3]=(0,r.useState)(!1),[e5,e4]=(0,r.useState)({}),[e7,e8]=(0,r.useState)(""),[e6,e9]=(0,r.useState)(""),[te,tt]=(0,r.useState)(!1),[tn,ts]=(0,r.useState)(""),[tr,tl]=(0,r.useState)(null),[ta,to]=(0,r.useState)(null),[ti,td]=(0,r.useState)(null),[tc,tx]=(0,r.useState)(null),[tm,tu]=(0,r.useState)(null),[th,tp]=(0,r.useState)(!1),[tb,tg]=(0,r.useState)({type:"",message:""}),tf=(0,r.useRef)(null),[tj,ty]=(0,r.useState)(null),[tv,tN]=(0,r.useState)(""),[tk,tw]=(0,r.useState)(""),[tC,tA]=(0,r.useState)("all"),[tS,tP]=(0,r.useState)(1),[tO,t$]=(0,r.useState)(25),[tI,tE]=(0,r.useState)({page:1,pageSize:25,total:0,totalAll:0,totalPages:1,status:"all",search:""}),{copied:tL,copy:tT}=(0,o.C)(),{isAdmin:t_,isMonitorAdmin:tM,canManageApiKeys:tK,userId:tF}=(0,a.s)(),tR=t_||tM||tK,tU=Number.isFinite(Number(eH))?Number(eH):5,tD=Number.isFinite(Number(eY))?Number(eY):p.length,tq=Number.isFinite(Number(eV))?Number(eV):Number(tI.totalAll||tI.total||0),tB=Number(tI.total||0),tz=!tR&&tD>=tU,tW=tn?`${tn}/v1`:"/v1",tH=tn||"",tG=tn?`${tn}/v1/chat/completions`:"/v1/chat/completions",tY=c(Z)[0]||"",tJ=(e=c(tr?.allowedModels)[0],t=String(tY||"").trim(),e||t||"YOUR_MODEL"),tV=tr?f(tr.limits||{}):i,tX=tV.maxOutputTokens>0?tV.maxOutputTokens:0,tZ=tr?function({endpoint:e,apiKey:t,model:n,maxOutputTokens:s=0}){let r=String(e||"/v1/chat/completions").replace(/"/g,""),l=String(t||"YOUR_API_KEY").replace(/"/g,""),a=h(s,0),o={model:String(n||"YOUR_MODEL"),messages:[{role:"user",content:"Say hi.\nReply in one short sentence."}],temperature:.2,stream:!1};a>0&&(o.max_tokens=a);let i=JSON.stringify(o).replace(/"/g,'\\"');return`curl.exe -X POST "${r}" ^
|
|
5
|
+
}`;function I(e){if(null==e||""===e)return"—";let t=Number(e);return Number.isFinite(t)?t.toLocaleString("vi-VN"):"—"}function E(e){if(null==e||""===e)return"—";let t=Number(e);if(!Number.isFinite(t))return"—";let n=t>0?"+":"";return`${n}${t.toFixed(1)}%`}function L(e){if(null==e||""===e)return"—";let t=Number(e);if(!Number.isFinite(t))return"—";let n=t>0?"+":"";return`${n}${t.toLocaleString("vi-VN")}`}function T({label:e,value:t,hint:n,tone:r="default"}){return(0,s.jsxs)("div",{className:`rounded-xl border p-3 ${"good"===r?"border-emerald-500/25 bg-emerald-500/10 text-emerald-800 dark:text-emerald-200":"bad"===r?"border-red-500/25 bg-red-500/10 text-red-700 dark:text-red-300":"border-border bg-surface/70 text-text-main"}`,children:[(0,s.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wide opacity-70",children:e}),(0,s.jsx)("div",{className:"mt-1 text-lg font-semibold",children:t}),n?(0,s.jsx)("div",{className:"mt-1 text-[11px] opacity-70",children:n}):null]})}function _({apiKey:e,fallbackModels:t,onClose:n}){let a=(0,r.useMemo)(()=>{let n=c(e?.allowedModels);return n.length>0?n:c(t)},[e,t]),[o,i]=(0,r.useState)(""),[d,x]=(0,r.useState)($),[m,h]=(0,r.useState)("lite"),[p,b]=(0,r.useState)(!1),[g,f]=(0,r.useState)(""),[j,y]=(0,r.useState)(null);if((0,r.useEffect)(()=>{if(!e)return;let n=c(e.allowedModels),s=c(t);i(n[0]||s[0]||""),h(["lite","full","ultra"].includes(e.cavemanLevel)?e.cavemanLevel:"lite"),x($),b(!1),f(""),y(null)},[e?.id]),!e)return null;let v=!!o&&!!d.trim()&&!p,N=async()=>{if(v){b(!0),f(""),y(null);try{let t=await fetch(`/api/keys/${e.id}/caveman-test`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:o,prompt:d.trim(),level:m})}),n=await t.json().catch(()=>({}));if(!t.ok){let e=n?.error?.message||n?.error||n?.message||"Kh\xf4ng chạy được Caveman A/B test";throw Error(e)}y(n)}catch(e){f(e?.message||"Kh\xf4ng chạy được Caveman A/B test")}finally{b(!1)}}},k=j?.baseline||null;return(0,s.jsx)(l.aF,{isOpen:!!e,onClose:()=>!p&&n(),title:"Test Caveman A/B",size:"xl",children:(0,s.jsxs)("div",{className:"space-y-5",children:[(0,s.jsx)("div",{className:"overflow-hidden rounded-2xl border border-indigo-500/25 bg-gradient-to-r from-indigo-500/10 via-primary/5 to-cyan-500/10",children:(0,s.jsxs)("div",{className:"flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,s.jsx)("span",{className:"inline-flex size-11 shrink-0 items-center justify-center rounded-2xl bg-indigo-500/15 text-indigo-700 dark:text-indigo-300",children:(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[25px]",children:"experiment"})}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsx)("div",{className:"truncate font-semibold text-text-main",children:e.name||"API Key"}),(0,s.jsx)("div",{className:"mt-0.5 text-xs text-text-muted",children:"So s\xe1nh c\xf9ng prompt: Caveman OFF với mức ON đ\xe3 chọn"})]})]}),(0,s.jsxs)("div",{className:"flex shrink-0 items-center gap-2 text-xs",children:[(0,s.jsx)("span",{className:"rounded-full border border-border bg-background/80 px-2.5 py-1",children:"A/B thực tế"}),(0,s.jsxs)("span",{className:"rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-amber-700 dark:text-amber-300",children:[2," lượt gọi"]})]})]})}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"mb-1.5 block text-xs font-medium text-text-muted",children:"Model được ph\xe9p d\xf9ng"}),(0,s.jsxs)("select",{value:o,onChange:e=>i(e.target.value),disabled:p||0===a.length,className:"w-full rounded-xl border border-border bg-background px-3 py-2.5 font-mono text-sm text-text-main outline-none transition focus:border-primary disabled:opacity-60",children:[0===a.length?(0,s.jsx)("option",{value:"",children:"Kh\xf4ng c\xf3 model để test"}):null,a.map(e=>(0,s.jsx)("option",{value:e,children:e},e))]})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"mb-2 flex items-center justify-between gap-3",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-text-muted",children:"Mức Caveman"}),(0,s.jsx)("span",{className:"text-[11px] text-text-muted",children:"Tối đa 2.048 output tokens"})]}),(0,s.jsx)("div",{className:"grid gap-2 sm:grid-cols-3",children:O.map(e=>{let t=m===e.value;return(0,s.jsxs)("button",{type:"button",onClick:()=>h(e.value),disabled:p,className:`rounded-xl border p-3 text-left transition ${t?"border-primary bg-primary/10 ring-1 ring-primary/20":"border-border bg-background hover:border-primary/40 hover:bg-surface"} disabled:cursor-default disabled:opacity-80`,children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"font-semibold text-text-main",children:e.label}),t?(0,s.jsx)("span",{className:"material-symbols-outlined text-[17px] text-primary",children:"check_circle"}):null]}),(0,s.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:e.description})]},e.value)})})]}),(0,s.jsxs)("label",{className:"block",children:[(0,s.jsxs)("div",{className:"mb-1.5 flex items-center justify-between gap-3",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-text-muted",children:"Prompt test"}),(0,s.jsxs)("span",{className:`text-[11px] ${d.length>12e3?"text-red-600":"text-text-muted"}`,children:[d.length.toLocaleString("vi-VN"),"/12.000 k\xfd tự"]})]}),(0,s.jsx)("textarea",{value:d,onChange:e=>x(e.target.value.slice(0,12e3)),disabled:p,rows:7,className:"w-full resize-y rounded-xl border border-border bg-background px-3 py-3 font-mono text-sm leading-6 text-text-main outline-none transition focus:border-primary disabled:opacity-70",placeholder:"Nhập c\xf9ng một prompt để so s\xe1nh Caveman OFF v\xe0 ON..."})]}),(0,s.jsxs)("div",{className:"rounded-xl border border-amber-500/30 bg-amber-500/10 p-3 text-xs leading-5 text-amber-800 dark:text-amber-200",children:[(0,s.jsx)("b",{children:"Lưu \xfd chi ph\xed:"})," ph\xe9p thử gọi provider thật v\xe0 tạo usage/log như request b\xecnh thường. Mỗi lần test d\xf9ng đ\xfang 2 lượt gọi: một baseline OFF v\xe0 một lượt ON ở mức đ\xe3 chọn. Kết quả vẫn c\xf3 thể dao động nhẹ theo model."]}),g?(0,s.jsxs)("div",{className:"flex items-start gap-2 rounded-xl border border-red-500/30 bg-red-500/10 p-3 text-sm text-red-700 dark:text-red-300",children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[19px]",children:"error"}),(0,s.jsx)("span",{children:g})]}):null,p?(0,s.jsxs)("div",{className:"rounded-2xl border border-primary/25 bg-primary/5 p-6 text-center",children:[(0,s.jsx)("span",{className:"material-symbols-outlined animate-spin text-3xl text-primary",children:"progress_activity"}),(0,s.jsxs)("div",{className:"mt-2 font-medium text-text-main",children:["Đang chạy ",2," lượt A/B..."]}),(0,s.jsx)("div",{className:"mt-1 text-xs text-text-muted",children:"Giữ modal mở cho tới khi model trả đủ kết quả. Mỗi lượt c\xf3 timeout tối đa 5 ph\xfat."})]}):null,j&&k?(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"font-semibold text-text-main",children:"Kết quả A/B"}),(0,s.jsxs)("p",{className:"text-xs text-text-muted",children:[j.model," \xb7 ",j.callsMade," lượt gọi \xb7 output cap ",I(j.maxOutputTokens)]})]}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-3 py-1 text-xs text-text-muted",children:["Baseline OFF: ",I(k.usage?.outputTokens)," output tokens"]})]}),(0,s.jsx)("div",{className:"grid gap-3 lg:grid-cols-1",children:(j.results||[]).map(e=>{if(e.error)return(0,s.jsxs)("div",{className:"rounded-2xl border border-red-500/30 bg-red-500/10 p-4",children:[(0,s.jsx)("div",{className:"font-semibold uppercase text-red-700 dark:text-red-300",children:e.level}),(0,s.jsx)("div",{className:"mt-2 text-sm text-red-700 dark:text-red-300",children:e.error})]},e.level);let t=e.savings?.outputSaved,n=e.savings?.outputSavedPercent,r=k.usage?.outputTokens!==null&&e.usage?.outputTokens!==null,l=Number(t)>0,a=0>Number(t),o=Number.isFinite(Number(n))?Math.max(0,Math.min(100,Number(n))):0;return(0,s.jsxs)("div",{className:"overflow-hidden rounded-2xl border border-border bg-background shadow-sm",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2 border-b border-border bg-surface/60 px-4 py-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"inline-flex size-8 items-center justify-center rounded-xl bg-primary/10 text-primary",children:(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[19px]",children:"compress"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"font-semibold uppercase text-text-main",children:e.level}),(0,s.jsxs)("div",{className:"text-[11px] text-text-muted",children:[I(e.latencyMs)," ms"]})]})]}),(0,s.jsx)("span",{className:`rounded-full px-2.5 py-1 text-xs font-semibold ${l?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":a?"bg-red-500/15 text-red-700 dark:text-red-300":"bg-surface text-text-muted"}`,children:r?`${L(t)} tokens`:"No usage"})]}),(0,s.jsxs)("div",{className:"space-y-3 p-4",children:[(0,s.jsxs)("div",{className:"grid grid-cols-2 gap-2",children:[(0,s.jsx)(T,{label:"OFF output",value:I(k.usage?.outputTokens)}),(0,s.jsx)(T,{label:"ON output",value:I(e.usage?.outputTokens),tone:l?"good":a?"bad":"default"}),(0,s.jsx)(T,{label:"Output giảm",value:r?E(n):"—",hint:r?`${L(t)} token`:"Provider kh\xf4ng trả usage",tone:l?"good":a?"bad":"default"}),(0,s.jsx)(T,{label:"Input overhead",value:L(e.savings?.inputOverhead),hint:"instruction Caveman"})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"mb-1 flex justify-between text-[11px] text-text-muted",children:[(0,s.jsx)("span",{children:"Hiệu quả output"}),(0,s.jsx)("span",{children:r?E(n):"—"})]}),(0,s.jsx)("div",{className:"h-2 overflow-hidden rounded-full bg-surface",children:(0,s.jsx)("div",{className:`h-full rounded-full transition-all ${l?"bg-emerald-500":"bg-red-500"}`,style:{width:`${o}%`}})})]}),(0,s.jsxs)("div",{className:"flex items-center justify-between rounded-xl border border-border bg-surface/50 px-3 py-2 text-xs",children:[(0,s.jsx)("span",{className:"text-text-muted",children:"Net total token"}),(0,s.jsxs)("span",{className:`font-semibold ${Number(e.savings?.totalSaved)>0?"text-emerald-700 dark:text-emerald-300":0>Number(e.savings?.totalSaved)?"text-red-600":"text-text-main"}`,children:[L(e.savings?.totalSaved)," (",E(e.savings?.totalSavedPercent),")"]})]})]})]},e.level)})}),(0,s.jsxs)("div",{className:"grid gap-3 lg:grid-cols-2",children:[(0,s.jsxs)("details",{className:"overflow-hidden rounded-xl border border-border bg-background",open:!0,children:[(0,s.jsx)("summary",{className:"cursor-pointer bg-surface/60 px-4 py-3 text-sm font-medium text-text-main",children:"Output baseline \xb7 Caveman OFF"}),(0,s.jsx)("pre",{className:"max-h-80 overflow-auto whitespace-pre-wrap p-4 text-xs leading-5 text-text-muted",children:k.output||"Model kh\xf4ng trả content text."})]}),(j.results||[]).map(e=>(0,s.jsxs)("details",{className:"overflow-hidden rounded-xl border border-border bg-background",open:!0,children:[(0,s.jsxs)("summary",{className:"cursor-pointer bg-surface/60 px-4 py-3 text-sm font-medium text-text-main",children:["Output Caveman \xb7 ",String(e.level||"").toUpperCase()]}),(0,s.jsx)("pre",{className:"max-h-80 overflow-auto whitespace-pre-wrap p-4 text-xs leading-5 text-text-muted",children:e.error||e.output||"Model kh\xf4ng trả content text."})]},`output-${e.level}`))]}),(0,s.jsx)("p",{className:"text-[11px] leading-5 text-text-muted",children:j.note})]}):null,(0,s.jsxs)("div",{className:"flex flex-wrap justify-end gap-2 border-t border-border pt-4",children:[(0,s.jsx)(l.$n,{variant:"ghost",onClick:n,disabled:p,children:"Đ\xf3ng"}),(0,s.jsx)(l.$n,{onClick:N,disabled:!v||d.length>12e3,children:(0,s.jsx)(u,{materialIcon:p?"progress_activity":"experiment",children:p?"Đang test...":"Chạy A/B (2 calls)"})})]})]})})}function M({apiKey:e,owner:t,isAdmin:n,onRename:l,onRotate:a,onEditModels:o,onEditPolicy:i,onAssignOwner:d,onDelete:c}){let[x,m]=(0,r.useState)(!1),h=(0,r.useRef)(null);(0,r.useEffect)(()=>{if(!x)return;let e=e=>{!h.current||h.current.contains(e.target)||m(!1)},t=e=>{"Escape"===e.key&&m(!1)};return document.addEventListener("pointerdown",e,!0),document.addEventListener("keydown",t),()=>{document.removeEventListener("pointerdown",e,!0),document.removeEventListener("keydown",t)}},[h,x,m]);let p=e=>{m(!1),e()};return(0,s.jsxs)("details",{ref:h,className:"group",open:x,onToggle:e=>m(e.currentTarget.open),children:[(0,s.jsx)("summary",{title:"Thao t\xe1c kh\xe1c",className:"flex h-9 cursor-pointer list-none items-center rounded-xl border border-border bg-background px-3 text-sm font-medium text-text-main transition hover:border-primary/50 hover:bg-surface focus:outline-none focus:ring-2 focus:ring-primary/20 [&::-webkit-details-marker]:hidden",children:(0,s.jsx)("span",{"aria-hidden":"true",className:"text-lg leading-none",children:"⋯"})}),(0,s.jsxs)("div",{className:"ml-auto mt-2 w-48 overflow-hidden rounded-xl border border-border bg-background py-1 text-left shadow-xl shadow-black/10",children:[(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>l(e.id,e.name)),children:(0,s.jsx)(u,{icon:"✏️",children:"Đổi t\xean"})}),(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>a(e)),children:(0,s.jsx)(u,{materialIcon:"key",children:"Đổi key"})}),(0,s.jsx)("div",{className:"my-1 border-t border-border"}),(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>o(e)),children:(0,s.jsx)(u,{icon:"\uD83D\uDCE6",children:"Models"})}),n?(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>i(e)),children:(0,s.jsx)(u,{icon:"\uD83D\uDEE1️",children:"Policy"})}):null,n?(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm text-text-main transition hover:bg-surface",onClick:()=>p(()=>d(e.id,t)),children:(0,s.jsx)(u,{icon:"\uD83D\uDC64",children:"Owner"})}):null,(0,s.jsx)("div",{className:"my-1 border-t border-border"}),(0,s.jsx)("button",{type:"button",className:"block w-full px-3 py-2 text-left text-sm font-medium text-red-600 transition hover:bg-red-500/10",onClick:()=>p(()=>c(e.id)),children:(0,s.jsx)(u,{icon:"\uD83D\uDDD1️",children:"X\xf3a"})})]})]})}function K({mode:e,effectiveEnabled:t,effectiveLevel:n,globalEnabled:r,onEdit:l,onInfo:a,onTest:o}){let i=String(n||"lite").toUpperCase();return(0,s.jsxs)("div",{className:`inline-flex max-w-full items-center gap-1.5 whitespace-nowrap rounded-xl border px-2 py-1.5 shadow-sm ${t?"border-emerald-500/30 bg-emerald-500/10 text-emerald-800 dark:text-emerald-200":"border-slate-300/80 bg-slate-500/5 text-slate-700 dark:border-slate-600 dark:text-slate-300"}`,title:`Caveman ${t?"ON":"OFF"} \xb7 ${"inherit"===e?"Kế thừa Global":"on"===e?"Force ON":"Force OFF"} \xb7 Global ${r?"ON":"OFF"} \xb7 Mức ${i}`,children:[(0,s.jsx)("span",{className:`inline-flex size-5 shrink-0 items-center justify-center rounded-md ${t?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-slate-500/10 text-slate-600 dark:text-slate-300"}`,children:(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[15px] leading-none",children:"compress"})}),(0,s.jsx)("button",{type:"button",onClick:a,className:"shrink-0 rounded-md font-semibold underline-offset-2 transition hover:text-primary hover:underline focus:outline-none focus:ring-2 focus:ring-primary/25",title:"Xem hướng dẫn Caveman","aria-label":"Mở hướng dẫn Caveman",children:"Caveman"}),(0,s.jsx)("button",{type:"button",onClick:l,className:`shrink-0 rounded-full border px-2 py-0.5 text-[10px] font-bold tracking-wide transition focus:outline-none focus:ring-2 focus:ring-primary/25 ${t?"border-emerald-500/40 bg-emerald-600 text-white hover:bg-emerald-700":"border-slate-300 bg-white text-slate-600 hover:border-primary/50 hover:text-primary dark:border-slate-600 dark:bg-slate-900/40 dark:text-slate-300"}`,"aria-label":`Mở cấu h\xecnh Caveman, hiện đang ${t?"bật":"tắt"}`,children:t?"ON":"OFF"}),(0,s.jsxs)("span",{className:`inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-semibold ${t?"border-emerald-500/25 bg-white/55 text-emerald-800 dark:bg-slate-950/20 dark:text-emerald-200":"border-slate-300/80 bg-white/55 text-slate-500 dark:border-slate-600 dark:bg-slate-950/20 dark:text-slate-400"}`,children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[12px] leading-none",children:"tune"}),i]}),(0,s.jsx)("span",{"aria-hidden":"true",className:"h-5 w-px shrink-0 bg-current opacity-15"}),(0,s.jsxs)("button",{type:"button",onClick:o,className:"inline-flex shrink-0 items-center gap-1 rounded-lg border border-indigo-500/30 bg-indigo-500/10 px-2 py-0.5 text-[10px] font-semibold text-indigo-700 transition hover:border-indigo-500/60 hover:bg-indigo-500/20 focus:outline-none focus:ring-2 focus:ring-indigo-500/25 dark:text-indigo-300",title:"Test A/B Caveman với một mức n\xe9n","aria-label":"Mở Caveman A/B test",children:[(0,s.jsx)("span",{"aria-hidden":"true",className:"material-symbols-outlined text-[13px] leading-none",children:"experiment"}),"Test"]})]})}function F({keys:e,copied:t,copy:n,isAdmin:r,globalCavemanEnabled:a,globalCavemanLevel:o,onToggleActive:i,onApiTest:d,onClaudeSettings:x,onOpenCodeSettings:m,onCodexSettings:u,onQwenSettings:h,onRename:p,onRotate:b,onEditModels:j,onEditPolicy:y,onEditCaveman:v,onShowCavemanInfo:N,onCavemanTest:k,onAssignOwner:w,onDelete:C}){return(0,s.jsx)("div",{className:"overflow-hidden rounded-2xl border border-border",children:(0,s.jsx)("div",{className:"overflow-x-auto",children:(0,s.jsxs)("table",{className:"min-w-full divide-y divide-border text-sm",children:[(0,s.jsx)("thead",{className:"bg-surface/80 text-left text-xs uppercase tracking-wide text-text-muted",children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"T\xean / Key"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Trạng th\xe1i"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Owner"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Model"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Policy"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 font-medium",children:"Ng\xe0y tạo"}),(0,s.jsx)("th",{className:"whitespace-nowrap px-4 py-3 text-right font-medium",children:"Thao t\xe1c"})]})}),(0,s.jsx)("tbody",{className:"divide-y divide-border bg-background",children:e.map(e=>{var A;let P=e.ownerUser||e.createdByUser||"chưa g\xe1n",O=c(e.allowedModels),$=g(e.limits),I=f(e.limits||{}),E=e.cavemanMode||"inherit",L="on"===E||"off"!==E&&a,T="on"===E?e.cavemanLevel||"lite":o;return(0,s.jsxs)("tr",{className:"align-top transition hover:bg-surface/50",children:[(0,s.jsxs)("td",{className:"min-w-[280px] px-4 py-4",children:[(0,s.jsx)("div",{className:"font-medium text-text-main",children:e.name||"API Key"}),(0,s.jsxs)("div",{className:"group/key mt-2 flex max-w-[380px] items-center gap-2 rounded-xl border border-border bg-surface px-3 py-2 font-mono text-xs text-text-main",children:[(0,s.jsx)("span",{className:"min-w-0 flex-1 truncate",children:(A=e.key)?A.length>12?`${A.slice(0,8)}...${A.slice(-4)}`:A:""}),(0,s.jsxs)("div",{className:"relative shrink-0 group/btn",children:[(0,s.jsx)("button",{type:"button",onClick:()=>n(e.key,e.id),className:"rounded p-0.5 text-text-muted transition hover:bg-sidebar hover:text-primary","aria-label":t===e.id?"Đ\xe3 copy":"Copy API key",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-sm",children:t===e.id?"check":"content_copy"})}),(0,s.jsx)("span",{className:"pointer-events-none absolute left-1/2 top-5 mt-1 -translate-x-1/2 whitespace-nowrap text-[10px] text-text-muted opacity-0 transition-opacity group-hover/btn:opacity-100",children:t===e.id?"Copied!":"Copy"})]}),(0,s.jsxs)("div",{className:"relative shrink-0 group/btn",children:[(0,s.jsx)("button",{type:"button",onClick:()=>d(e),className:"rounded p-0.5 text-text-muted transition hover:bg-sidebar hover:text-primary","aria-label":"Test API key bằng curl",children:(0,s.jsx)("span",{className:"material-symbols-outlined text-sm",children:"science"})}),(0,s.jsx)("span",{className:"pointer-events-none absolute left-1/2 top-5 mt-1 -translate-x-1/2 whitespace-nowrap text-[10px] text-text-muted opacity-0 transition-opacity group-hover/btn:opacity-100",children:"Test"})]})]}),e.createdByUser?(0,s.jsxs)("div",{className:"mt-2 text-xs text-text-muted",children:["Tạo bởi: ",e.createdByUser]}):null]}),(0,s.jsx)("td",{className:"whitespace-nowrap px-4 py-4",children:(0,s.jsx)(l.lM,{checked:!!e.isActive,onChange:t=>i(e.id,t)})}),(0,s.jsx)("td",{className:"min-w-[160px] px-4 py-4",children:(0,s.jsx)("div",{className:"break-all text-sm text-text-main",children:P})}),(0,s.jsx)("td",{className:"px-4 py-4 align-top",children:O.length>0?(0,s.jsxs)("div",{className:"flex flex-col items-start gap-1",children:[O.slice(0,3).map(e=>(0,s.jsx)("span",{className:"max-w-full truncate rounded-full border border-border bg-surface px-2 py-1 font-mono text-xs",children:e},e)),O.length>3?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 text-xs",children:["+",O.length-3]}):null]}):(0,s.jsx)("span",{className:"inline-block rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-1 text-xs text-amber-700 dark:text-amber-300",children:"Legacy full access"})}),(0,s.jsx)("td",{className:"px-4 py-4 align-top",children:(0,s.jsxs)("div",{className:"flex flex-col items-start gap-1 text-xs",children:[$?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:I.enabled?"bật":"tắt"}),(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[I.requestsPerMinute||"∞","/ph\xfat"]}),r&&I.maxOutputTokens>0?(0,s.jsxs)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:[I.maxOutputTokens," out"]}):null,r&&I.forceThinkingOff?(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"thinking off"}):null,I.allowedIpCidrs.length>0?(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1",children:"IP locked"}):null]}):(0,s.jsx)("span",{className:"rounded-full border border-border bg-surface px-2 py-1 text-text-muted",children:"Policy: chưa set"}),(0,s.jsx)(K,{mode:E,effectiveEnabled:L,effectiveLevel:T,globalEnabled:a,onEdit:()=>v(e),onInfo:()=>N(e),onTest:()=>k(e)})]})}),(0,s.jsx)("td",{className:"min-w-[150px] px-4 py-4 text-xs text-text-muted",children:function(e){if(!e)return"kh\xf4ng r\xf5";try{return new Date(e).toLocaleString()}catch{return String(e)}}(e.createdAt)}),(0,s.jsx)("td",{className:"min-w-[200px] px-4 py-4",children:(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2",children:[(0,s.jsx)(M,{apiKey:e,owner:P,isAdmin:r,onRename:p,onRotate:b,onEditModels:j,onEditPolicy:y,onAssignOwner:w,onDelete:C}),(0,s.jsx)(S,{apiKey:e,onClaudeSettings:x,onOpenCodeSettings:m,onCodexSettings:u,onQwenSettings:h})]})})]},e.id)})})]})})})}function R(){let e,t,n,u,[p,b]=(0,r.useState)([]),[v,A]=(0,r.useState)(!0),[S,O]=(0,r.useState)(""),[$,I]=(0,r.useState)(!1),[E,L]=(0,r.useState)(""),[T,M]=(0,r.useState)(""),[K,R]=(0,r.useState)(""),[U,D]=(0,r.useState)(""),[q,B]=(0,r.useState)(null),[z,W]=(0,r.useState)([]),[H,G]=(0,r.useState)(""),[Y,J]=(0,r.useState)(!1),[V,X]=(0,r.useState)(!1),[Z,Q]=(0,r.useState)([]),[ee,et]=(0,r.useState)([]),[en,es]=(0,r.useState)(!1),[er,el]=(0,r.useState)(i),[ea,eo]=(0,r.useState)(i),[ei,ed]=(0,r.useState)(!1),[ec,ex]=(0,r.useState)(!1),[em,eu]=(0,r.useState)(!1),[eh,ep]=(0,r.useState)([]),[eb,eg]=(0,r.useState)({}),[ef,ej]=(0,r.useState)(!1),[ey,ev]=(0,r.useState)(!1),[eN,ek]=(0,r.useState)(null),[ew,eC]=(0,r.useState)([]),[eA,eS]=(0,r.useState)(!1),[eP,eO]=(0,r.useState)(null),[e$,eI]=(0,r.useState)(i),[eE,eL]=(0,r.useState)(!1),[eT,e_]=(0,r.useState)(null),[eM,eK]=(0,r.useState)(null),[eF,eR]=(0,r.useState)(null),[eU,eD]=(0,r.useState)(!1),[eq,eB]=(0,r.useState)(!1),[ez,eW]=(0,r.useState)("full"),[eH,eG]=(0,r.useState)(5),[eY,eJ]=(0,r.useState)(0),[eV,eX]=(0,r.useState)(0),[eZ,eQ]=(0,r.useState)(5),[e0,e1]=(0,r.useState)(String(5)),[e2,e3]=(0,r.useState)(!1),[e5,e4]=(0,r.useState)({}),[e7,e8]=(0,r.useState)(""),[e6,e9]=(0,r.useState)(""),[te,tt]=(0,r.useState)(!1),[tn,ts]=(0,r.useState)(""),[tr,tl]=(0,r.useState)(null),[ta,to]=(0,r.useState)(null),[ti,td]=(0,r.useState)(null),[tc,tx]=(0,r.useState)(null),[tm,tu]=(0,r.useState)(null),[th,tp]=(0,r.useState)(!1),[tb,tg]=(0,r.useState)({type:"",message:""}),tf=(0,r.useRef)(null),[tj,ty]=(0,r.useState)(null),[tv,tN]=(0,r.useState)(""),[tk,tw]=(0,r.useState)(""),[tC,tA]=(0,r.useState)("all"),[tS,tP]=(0,r.useState)(1),[tO,t$]=(0,r.useState)(25),[tI,tE]=(0,r.useState)({page:1,pageSize:25,total:0,totalAll:0,totalPages:1,status:"all",search:""}),{copied:tL,copy:tT}=(0,o.C)(),{isAdmin:t_,isMonitorAdmin:tM,canManageApiKeys:tK,userId:tF}=(0,a.s)(),tR=t_||tM||tK,tU=Number.isFinite(Number(eH))?Number(eH):5,tD=Number.isFinite(Number(eY))?Number(eY):p.length,tq=Number.isFinite(Number(eV))?Number(eV):Number(tI.totalAll||tI.total||0),tB=Number(tI.total||0),tz=!tR&&tD>=tU,tW=tn?`${tn}/v1`:"/v1",tH=tn||"",tG=tn?`${tn}/v1/chat/completions`:"/v1/chat/completions",tY=c(Z)[0]||"",tJ=(e=c(tr?.allowedModels)[0],t=String(tY||"").trim(),e||t||"YOUR_MODEL"),tV=tr?f(tr.limits||{}):i,tX=tV.maxOutputTokens>0?tV.maxOutputTokens:0,tZ=tr?function({endpoint:e,apiKey:t,model:n,maxOutputTokens:s=0}){let r=String(e||"/v1/chat/completions").replace(/"/g,""),l=String(t||"YOUR_API_KEY").replace(/"/g,""),a=h(s,0),o={model:String(n||"YOUR_MODEL"),messages:[{role:"user",content:"Say hi.\nReply in one short sentence."}],temperature:.2,stream:!1};a>0&&(o.max_tokens=a);let i=JSON.stringify(o).replace(/"/g,'\\"');return`curl.exe -X POST "${r}" ^
|
|
6
6
|
-H "Authorization: Bearer ${l}" ^
|
|
7
7
|
-H "Content-Type: application/json" ^
|
|
8
8
|
-d "${i}"`}({endpoint:tG,apiKey:tr.key,model:tJ,maxOutputTokens:tX}):"",tQ=ta?x(ta,tY):{codingModel:"programmer",fastModel:"programmer-fast"},t0=ta?function({baseUrl:e,apiKey:t,codingModel:n,fastModel:s}){let r=n||"programmer",l=s||r||"programmer-fast";return`{
|
package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/combos/page-786d94f8dd164774.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3649],{20061:(e,t,n)=>{Promise.resolve().then(n.bind(n,47295))},47295:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>Y});var a=n(95155),r=n(12115),l=n(44923),s=n(87256),i=n(39768),o=n(5020),d=n(35497),c=n(11059),m=n(28777),u=n(52679);let x=/^[a-zA-Z0-9_.\-]+$/,p=[{value:"global",label:"To\xe0n cục / h\xe0nh vi hiện tại",description:"Giữ h\xe0nh vi hiện tại: mọi request d\xf9ng chung v\xf2ng xoay combo to\xe0n cục."},{value:"client_ip",label:"IP client",description:"Giữ c\xf9ng model khởi đầu cho c\xf9ng IP client cho đến khi hết TTL."},{value:"client_session",label:"IP client + phi\xean chat",description:"Ph\xf9 hợp nhất cho c\xf4ng cụ chat. Giữ c\xf9ng model cho c\xf9ng m\xe1y v\xe0 c\xf9ng phi\xean chat."}],h=[{value:"fallback",label:"Ưu ti\xean fallback",description:"Thử model trong combo theo đ\xfang thứ tự hiển thị, lỗi th\xec fallback."},{value:"round-robin",label:"Round Robin",description:"Lu\xe2n phi\xean model đang bật được thử đầu ti\xean. C\xe1c t\xf9y chọn giữ d\xednh b\xean dưới vẫn được \xe1p dụng."},{value:"least-latency",label:"Độ trễ thấp nhất",description:"Ưu ti\xean target c\xf3 điểm health/độ trễ tốt nhất. Hữu \xedch cho LAN Ollama."},{value:"p2c",label:"P2C",description:"Power of Two Choices: lấy mẫu hai target khỏe rồi chọn target \xedt bận hơn."}],b=[{card:"border-sky-100 bg-sky-50/55 dark:border-sky-400/15 dark:bg-sky-950/10",panel:"border-sky-100/80 bg-white/80 dark:border-sky-400/15 dark:bg-zinc-950/60"},{card:"border-slate-200 bg-slate-50/80 dark:border-slate-500/15 dark:bg-slate-900/35",panel:"border-slate-200/80 bg-white/80 dark:border-slate-500/15 dark:bg-zinc-950/60"},{card:"border-emerald-100 bg-emerald-50/45 dark:border-emerald-400/15 dark:bg-emerald-950/10",panel:"border-emerald-100/80 bg-white/80 dark:border-emerald-400/15 dark:bg-zinc-950/60"},{card:"border-violet-100 bg-violet-50/45 dark:border-violet-400/15 dark:bg-violet-950/10",panel:"border-violet-100/80 bg-white/80 dark:border-violet-400/15 dark:bg-zinc-950/60"}],g=Object.freeze({temperature:.3,top_p:.95,presence_penalty:0,max_tokens:4096,reasoning_budget:0,thinkingMode:"off"}),f=Object.freeze({temperature:.6,top_p:.95,presence_penalty:0,max_tokens:4096}),y=Object.freeze({temperature:.7,top_p:.8,presence_penalty:0,max_tokens:4096}),v=Object.freeze({think:"inheritThinkRequestOverrides",nothink:"inheritNoThinkRequestOverrides"}),k=[{key:"temperature",label:"temp",min:0,max:2,step:.05},{key:"top_p",label:"top_p",min:.01,max:1,step:.01},{key:"presence_penalty",label:"presence_penalty",min:-2,max:2,step:.05},{key:"max_tokens",label:"max_tokens",min:1,max:262144,step:1}],j=[{value:"inherit",label:"Theo request gốc",description:"Giữ nguy\xean request gốc, kh\xf4ng inject thinking."},{value:"off",label:"Tắt thinking",description:"Gửi chat_template_kwargs.enable_thinking = false."},{value:"on",label:"Bật thinking",description:"Gửi chat_template_kwargs.enable_thinking = true."}],N=[{value:"inherit",label:"Theo cấu h\xecnh hệ thống",description:"Sử dụng ch\xednh s\xe1ch lưu Prompt Logs chung của hệ thống."},{value:"enabled",label:"Lưu đầy đủ nội dung",description:"Cho ph\xe9p quản trị vi\xean xem lại to\xe0n bộ prompt v\xe0 phản hồi của c\xe1c request thuộc combo n\xe0y."},{value:"disabled",label:"Chỉ lưu thống k\xea",description:"Kh\xf4ng lưu nội dung hội thoại. Chỉ lưu metadata, model, provider, token, thời gian xử l\xfd v\xe0 c\xe1c thống k\xea vận h\xe0nh."}];function _(e){return e&&"object"==typeof e&&!Array.isArray(e)}function w(e,t){return Object.prototype.hasOwnProperty.call(e||{},t)}function C(e,{min:t,max:n,precision:a=3}={}){if(null==e||""===e)return;let r=Number(e);if(Number.isFinite(r))return Number(Math.min(n,Math.max(t,r)).toFixed(a))}function T(e,{min:t,max:n}={}){let a=C(e,{min:t,max:n,precision:0});return void 0===a?void 0:Math.trunc(a)}function O(e){let t=R(e).toLowerCase();return"enabled"===t||"disabled"===t?t:"inherit"}let S=["temperature","top_p","presence_penalty","max_tokens"];function q(e={}){let t=_(e)?e:{},n={};if(w(t,"temperature")){let e=C(t.temperature,{min:0,max:2});void 0!==e&&(n.temperature=e)}if(w(t,"top_p")||w(t,"topP")){let e=C(t.top_p??t.topP,{min:.01,max:1});void 0!==e&&(n.top_p=e)}let a=t.presence_penalty??t.presencePenalty??t["presence-penalty"];if(w(t,"presence_penalty")||w(t,"presencePenalty")||w(t,"presence-penalty")){let e=C(a,{min:-2,max:2});void 0!==e&&(n.presence_penalty=e)}let r=t.max_tokens??t.maxTokens??t.max_token;if(w(t,"max_tokens")||w(t,"maxTokens")||w(t,"max_token")){let e=T(r,{min:1,max:262144});void 0!==e&&(n.max_tokens=e)}return n}function $(e={}){let t=_(e)?e:{},n={};if(w(t,"temperature")){let e=C(t.temperature,{min:0,max:2});void 0!==e&&(n.temperature=e)}if(w(t,"top_p")){let e=C(t.top_p,{min:.01,max:1});void 0!==e&&(n.top_p=e)}let a=t.presence_penalty??t.presencePenalty??t["presence-penalty"];if(w(t,"presence_penalty")||w(t,"presencePenalty")||w(t,"presence-penalty")){let e=C(a,{min:-2,max:2});void 0!==e&&(n.presence_penalty=e)}let r=t.max_tokens??t.maxTokens??t.max_token;if(w(t,"max_tokens")||w(t,"maxTokens")||w(t,"max_token")){let e=T(r,{min:1,max:262144});void 0!==e&&(n.max_tokens=e)}let l=t.reasoning_budget??t.reasoningBudget??t["reasoning-budget"];if(w(t,"reasoning_budget")||w(t,"reasoningBudget")||w(t,"reasoning-budget")){let e=T(l,{min:0,max:262144});void 0!==e&&(n.reasoning_budget=e)}let s=t.inheritThinkRequestOverrides??t.thinkRequestOverrides??t.thinkingOnRequestOverrides;if(w(t,"inheritThinkRequestOverrides")||w(t,"thinkRequestOverrides")||w(t,"thinkingOnRequestOverrides")){let e=q(s);Object.keys(e).length>0&&(n.inheritThinkRequestOverrides=e)}let i=t.inheritNoThinkRequestOverrides??t.noThinkRequestOverrides??t.thinkingOffRequestOverrides;if(w(t,"inheritNoThinkRequestOverrides")||w(t,"noThinkRequestOverrides")||w(t,"thinkingOffRequestOverrides")){let e=q(i);Object.keys(e).length>0&&(n.inheritNoThinkRequestOverrides=e)}let o=function(e){if(!0===e)return"on";if(!1===e)return"off";let t=R(e).toLowerCase();return["on","true","1","enable","enabled"].includes(t)?"on":["off","false","0","disable","disabled"].includes(t)?"off":void 0}(t.thinkingMode??t.thinking);if(o&&(n.thinkingMode=o),"off"===n.thinkingMode&&delete n.reasoning_budget,!n.thinkingMode){let e=q(n);if(Object.keys(e).length>0)for(let t of(n.inheritThinkRequestOverrides={...e,...n.inheritThinkRequestOverrides||{}},n.inheritNoThinkRequestOverrides={...e,...n.inheritNoThinkRequestOverrides||{}},S))delete n[t]}return n}function M(e={}){let t=q(e||{}),n=[];return void 0!==t.temperature&&n.push(`temp ${t.temperature}`),void 0!==t.top_p&&n.push(`top_p ${t.top_p}`),void 0!==t.presence_penalty&&n.push(`presence ${t.presence_penalty}`),void 0!==t.max_tokens&&n.push(`max ${t.max_tokens}`),n}function R(e){return String(e||"").trim()}function L(e={}){return Array.isArray(e.disabledModels)?[...new Set(e.disabledModels.map(e=>R(e)).filter(Boolean))]:[]}function E(e={}){let t=e.fallbackStrategy||"fallback";return{...e,fallbackStrategy:t,stickyScope:e.stickyScope||"global",stickyTtlMinutes:Number(e.stickyTtlMinutes||120),stickyFallbackToClientIp:!1!==e.stickyFallbackToClientIp,lanHealthEnabled:!1!==e.lanHealthEnabled,healthCheckPath:e.healthCheckPath||"/api/tags",healthCheckIntervalMs:Number(e.healthCheckIntervalMs||15e3),requiredTags:Array.isArray(e.requiredTags)?e.requiredTags:[],modelTagRules:e.modelTagRules||e.modelTags||e.tagRules||{},disabledModels:L(e),requestOverrides:$(e.requestOverrides||{}),contentLoggingMode:O(e.contentLoggingMode)}}function P(e={}){let t={...e};t.disabledModels=L(e),"fallback"===(t.fallbackStrategy||"fallback")&&delete t.fallbackStrategy,t.disabledModels.length||delete t.disabledModels;let n=O(t.contentLoggingMode);"inherit"===n?delete t.contentLoggingMode:t.contentLoggingMode=n,t.requiredTags?.length||delete t.requiredTags;let a=$(t.requestOverrides||{});return Object.keys(a).length?t.requestOverrides=a:delete t.requestOverrides,t.modelTagRules&&0!==Object.keys(t.modelTagRules).length||delete t.modelTagRules,"/api/tags"===t.healthCheckPath&&delete t.healthCheckPath,15e3===Number(t.healthCheckIntervalMs)&&delete t.healthCheckIntervalMs,!0===t.lanHealthEnabled&&delete t.lanHealthEnabled,Object.keys(t).length?t:null}function I(e){return Array.isArray(e)?`[${e.map(I).join(",")}]`:e&&"object"==typeof e?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${I(e[t])}`).join(",")}}`:JSON.stringify(void 0===e?null:e)}function A(e=[]){return Array.isArray(e)?e.join(", "):String(e||"")}function z(e=""){return String(e||"").split(/[\n,;]+/).map(e=>e.trim()).filter(Boolean)}function B(e={}){return e&&"object"==typeof e?Object.entries(e).map(([e,t])=>`${e}: ${Array.isArray(t)?t.join(", "):String(t||"")}`).join("\n"):""}function F(e){return"string"==typeof e?e:e&&"object"==typeof e&&(e.value||e.model||e.id)||""}function D(e={}){let t=R(e.provider);return R(e.providerSpecificData?.prefix)||R(e.prefix)||R((0,u.wG)(t))||t}function G(e={}){return R(e.email)||R(e.accountName)||R(e.displayName)||R(e.name)||R(e.providerSpecificData?.nodeName)||R(e.id)}function H(e){return e&&"object"==typeof e?R(e.connectionId||e.connection_id):""}function K(e){let t=F(e),n=H(e);return t?n?`${t}@@${n}`:t:""}function J(e){return"string"==typeof e?e:e&&"object"==typeof e?R(e.label)||R(e.displayName)||R(e.name)||F(e):""}function X(e){if(!e||"object"!=typeof e)return F(e);let t=F(e);return t?Object.fromEntries(Object.entries({model:t,connectionId:H(e)||void 0,label:J(e)||void 0,provider:R(e.provider)||void 0,accountName:R(e.accountName||e.account_name)||void 0,weight:Number(e.weight||0)>0?Number(e.weight):void 0}).filter(([,e])=>void 0!==e&&""!==e)):""}function U(e,t=!0){let n=X(e),a=K(n);return{value:a,enabled:t,target:n,label:J(n)||a,subtitle:function(e){if(!e||"object"!=typeof e)return"";let t=H(e),n=F(e);return t?`T\xe0i khoản cố định • ${t}${n?` • ${n}`:""}`:""}(n)}}function W(e={}){return R(e.defaultModel)||R(e.providerSpecificData?.defaultModel)||R(e.model)||""}function Q(e,t,n,a=""){let r=R(n);!r||t.has(r)||(t.add(r),e.push({value:r,label:R(a)||r}))}function V(e={},t={}){let n=[],a=new Set,r=R(e.provider),l=[...new Set([D(e),R((0,u.wG)(r)),r].filter(Boolean))];for(let e of(0,m.KC)(r)||[])e?.type&&"llm"!==e.type||Q(n,a,e.id,e.name||e.id);for(let[e,r]of Object.entries(t||{})){let t=R(r),s=l.find(e=>e&&t.startsWith(`${e}/`));if(!s)continue;let i=t.slice(s.length+1);Q(n,a,i,e||i)}return Q(n,a,W(e),"Model mặc định"),n}function Z(e={},{disabledModels:t=[],requestOverrides:n,contentLoggingMode:a}={}){let r={...e},l=[...new Set((t||[]).map(e=>R(e)).filter(Boolean))];if(l.length>0?r.disabledModels=l:delete r.disabledModels,void 0!==n){let e=$(n||{});Object.keys(e).length?r.requestOverrides=e:delete r.requestOverrides}if(void 0!==a){let e=O(a);"inherit"===e?delete r.contentLoggingMode:r.contentLoggingMode=e}return P(r)}function Y(){let[e,t]=(0,r.useState)([]),[n,l]=(0,r.useState)(!0),[s,i]=(0,r.useState)(!1),[o,m]=(0,r.useState)(null),[u,x]=(0,r.useState)([]),[p,h]=(0,r.useState)(!1),[b,g]=(0,r.useState)(!1),[f,y]=(0,r.useState)({}),[v,k]=(0,r.useState)(""),[j,N]=(0,r.useState)(null),{copied:_,copy:w}=(0,c.C)();(0,r.useEffect)(()=>{C()},[]),(0,r.useEffect)(()=>{if(0===e.length){v&&k("");return}let t=e.some(e=>e.name===v);v&&t||k(e[0].name)},[e,v]);let C=async()=>{try{let e=await fetch("/api/dashboard/combos",{cache:"no-store"}),n=await e.json();e.ok&&(t(n.combos||[]),y(n.comboStrategies||{}))}catch(e){console.log("Error fetching combo data:",e)}finally{l(!1)}},T=async()=>{if(!p&&!b){g(!0);try{let e=await fetch("/api/providers",{cache:"no-store"}),t=await e.json();e.ok&&(x(t.connections||[]),h(!0))}catch(e){console.log("Error loading provider accounts:",e)}finally{g(!1)}}},O=async()=>{i(!0),T()},S=async e=>{m(e),T()},q=async e=>{let t=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStrategies:e})});if(!t.ok)throw Error(`Save combo strategies failed: ${t.status}`);y(e)},$=async e=>{let{disabledModels:t=[],requestOverrides:n,contentLoggingMode:a,...r}=e;try{let e=await fetch("/api/combos",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(e.ok){let e=Z({},{disabledModels:t,requestOverrides:n,contentLoggingMode:a});e&&await q({...f,[r.name]:e}),await C(),k(r.name),i(!1)}else{let t=await e.json();alert(t.error||"Tạo combo thất bại")}}catch(e){console.log("Error creating combo:",e)}},M=async(e,t)=>{let{disabledModels:n=[],requestOverrides:a,contentLoggingMode:r,...l}=t,s=o?.name;try{let t=await fetch(`/api/combos/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(t.ok){let e={...f};s&&s!==l.name&&e[s]&&(e[l.name]=e[s],delete e[s]);let t=Z(e[l.name]||{},{disabledModels:n,requestOverrides:a,contentLoggingMode:r});t?e[l.name]=t:delete e[l.name],await q(e),await C(),k(l.name),m(null)}else{let e=await t.json();alert(e.error||"Cập nhật combo thất bại")}}catch(e){console.log("Error updating combo:",e)}},R=async n=>{let a=e.find(e=>e.id===n);N({title:"X\xf3a combo",message:"Bạn c\xf3 chắc muốn x\xf3a combo n\xe0y?",onConfirm:async()=>{N(null);try{if((await fetch(`/api/combos/${n}`,{method:"DELETE"})).ok){if(a?.name&&f[a.name]){let e={...f};delete e[a.name],await q(e)}t(e=>{let t=e.filter(e=>e.id!==n);return a?.name===v&&k(t[0]?.name||""),t})}}catch(e){console.log("Error deleting combo:",e)}}})},L=async(e,t)=>{try{let n={...f},a=P({...E(n[e]),...t});return a?n[e]=a:delete n[e],await q(n),!0}catch(e){return console.log("Error updating combo routing settings:",e),!1}},I=e.find(e=>e.name===v)||e[0]||null,A=I?Math.max(0,e.findIndex(e=>e.id===I.id)):0;return n?(0,a.jsx)("div",{className:"grid gap-4",children:[1,2,3].map(e=>(0,a.jsx)("div",{className:"h-36 animate-pulse rounded-2xl border border-border bg-surface"},e))}):(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"text-2xl font-bold text-text-main",children:"Combo model"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Tạo combo model với fallback, round-robin, độ trễ thấp nhất, P2C v\xe0 routing theo trạng th\xe1i health của LAN Ollama."})]}),(0,a.jsxs)("button",{type:"button",onClick:O,className:"inline-flex items-center justify-center gap-2 rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Tạo combo"]})]}),0===e.length?(0,a.jsxs)("div",{className:"rounded-2xl border border-dashed border-border bg-surface p-12 text-center",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-text-muted",children:"layers"}),(0,a.jsx)("h2",{className:"mt-3 text-lg font-semibold text-text-main",children:"Chưa c\xf3 combo n\xe0o"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Tạo combo model c\xf3 hỗ trợ fallback."}),(0,a.jsx)("button",{type:"button",onClick:O,className:"mt-4 rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90",children:"Tạo combo"})]}):(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("div",{className:"rounded-2xl border border-border bg-surface/80 p-4 shadow-sm dark:bg-zinc-950/70",children:(0,a.jsxs)("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between",children:[(0,a.jsxs)("label",{className:"block min-w-0 flex-1",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-semibold uppercase tracking-wide text-text-muted",children:"Combo đang xem"}),(0,a.jsx)("select",{value:I?.name||"",onChange:e=>k(e.target.value),className:"w-full rounded-xl border border-border bg-white px-4 py-2.5 text-sm font-semibold text-text-main outline-none transition focus:border-primary dark:bg-zinc-900",children:e.map(e=>(0,a.jsxs)("option",{value:e.name,children:[e.name," • ",(e.models||[]).length," model"]},e.id))})]}),(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-xs text-text-muted",children:[(0,a.jsxs)("span",{className:"rounded-full bg-background px-3 py-1 dark:bg-zinc-900",children:["Tổng ",e.length," combo"]}),I?(0,a.jsxs)("span",{className:"rounded-full bg-primary/10 px-3 py-1 font-medium text-primary",children:["Đang hiển thị: ",I.name]}):null]})]})}),I?(0,a.jsx)(ee,{combo:I,comboIndex:A,copied:_,onCopy:w,onEdit:()=>S(I),onDelete:()=>R(I.id),comboStrategy:f[I.name]||{},onUpdateComboStrategy:e=>L(I.name,e)},I.id):null]}),(0,a.jsx)(ei,{isOpen:s,comboStrategy:{},onClose:()=>i(!1),onSave:$,activeProviders:u,providersLoading:b}),(0,a.jsx)(ei,{isOpen:!!o,combo:o,comboStrategy:f[o?.name]||{},onClose:()=>m(null),onSave:e=>M(o.id,e),activeProviders:u,providersLoading:b}),(0,a.jsx)(d.uo,{isOpen:!!j,onClose:()=>N(null),onConfirm:j?.onConfirm,title:j?.title||"X\xe1c nhận",message:j?.message,variant:"danger"})]})}function ee({combo:e,comboIndex:t=0,copied:n,onCopy:l,onEdit:s,onDelete:i,comboStrategy:o={},onUpdateComboStrategy:d}){let[c,m]=(0,r.useState)({}),[u,x]=(0,r.useState)(!1),[g,f]=(0,r.useState)(""),y=E(o||{}),v=E({...o||{},...c}),k=!function(e={},t={}){return I(P(e)||{})===I(P(t)||{})}(v,y),j=v.fallbackStrategy||"fallback",N=h.find(e=>e.value===j)||h[0],_=v.stickyScope||"global",w=p.find(e=>e.value===_)||p[0],C=L(o),T=b[t%b.length],[O,S]=(0,r.useState)(A(v.requiredTags)),[q,R]=(0,r.useState)(B(v.modelTagRules)),F=e=>{f(""),m(t=>({...t,...e}))},D=async()=>{if(!k||u)return;x(!0);let e=await d(c);(x(!1),!1===e)?f("Lưu thất bại, thử lại."):m({})};return(0,r.useEffect)(()=>{m({}),f("")},[e.name]),(0,r.useEffect)(()=>{S(A(v.requiredTags)),R(B(v.modelTagRules))},[e.name,JSON.stringify(v.requiredTags||[]),JSON.stringify(v.modelTagRules||{})]),(0,a.jsxs)("div",{className:`rounded-2xl border p-5 shadow-sm transition-colors ${T.card}`,children:[(0,a.jsxs)("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between",children:[(0,a.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-primary",children:"layers"}),(0,a.jsx)("h3",{className:"truncate text-lg font-semibold text-text-main",children:e.name})]}),(0,a.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[(e.models||[]).length," model đang bật",C.length>0?` • ${C.length} đ\xe3 tắt`:""]})]}),(0,a.jsxs)("div",{className:"flex items-center gap-1",children:[(0,a.jsx)(et,{icon:n===`combo-${e.id}`?"check":"content_copy",title:"Copy t\xean combo",onClick:()=>l(e.name,`combo-${e.id}`)}),(0,a.jsx)(et,{icon:"edit",title:"Chỉnh sửa",onClick:s}),(0,a.jsx)(et,{icon:"delete",title:"X\xf3a",onClick:i,danger:!0})]})]}),(0,a.jsxs)("div",{className:"mt-4 flex flex-wrap gap-2",children:[0===(e.models||[]).length?(0,a.jsx)("span",{className:"rounded-lg bg-background px-2 py-1 text-xs text-text-muted",children:"Chưa c\xf3 model đang bật"}):(e.models||[]).slice(0,5).map((e,t)=>(0,a.jsx)("span",{className:"rounded-lg bg-background px-2 py-1 font-mono text-xs text-text-main",children:J(e)},`${K(e)}-${t}`)),(e.models||[]).length>5&&(0,a.jsxs)("span",{className:"rounded-lg bg-background px-2 py-1 text-xs text-text-muted",children:["+",e.models.length-5," model nữa"]}),C.length>0&&(0,a.jsxs)("span",{className:"rounded-lg bg-red-500/10 px-2 py-1 text-xs text-red-500",children:[C.length," đ\xe3 tắt"]}),(function(e={}){let t=$(e),n=[];if(void 0!==t.temperature&&n.push(`temp ${t.temperature}`),void 0!==t.top_p&&n.push(`top_p ${t.top_p}`),void 0!==t.presence_penalty&&n.push(`presence ${t.presence_penalty}`),void 0!==t.max_tokens&&n.push(`max ${t.max_tokens}`),void 0!==t.reasoning_budget&&n.push(`reasoning ${t.reasoning_budget}`),"off"===t.thinkingMode&&n.push("thinking off"),"on"===t.thinkingMode&&n.push("thinking on"),!t.thinkingMode){let e=M(t.inheritThinkRequestOverrides),a=M(t.inheritNoThinkRequestOverrides);e.length&&n.push(`think: ${e.join(", ")}`),a.length&&n.push(`nothink: ${a.join(", ")}`)}return n})(y.requestOverrides).map(e=>(0,a.jsx)("span",{className:"rounded-lg bg-primary/10 px-2 py-1 text-xs font-medium text-primary",children:e},e)),"inherit"!==y.contentLoggingMode?(0,a.jsxs)("span",{className:`rounded-lg px-2 py-1 text-xs font-medium ${"disabled"===y.contentLoggingMode?"bg-amber-500/10 text-amber-600":"bg-emerald-500/10 text-emerald-600"}`,children:["prompt logs ",y.contentLoggingMode]}):null]}),(0,a.jsxs)("div",{className:`mt-5 rounded-xl border p-4 ${T.panel}`,children:[(0,a.jsxs)("div",{className:"flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"font-semibold text-text-main",children:"Chiến lược routing"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:N.description})]}),(0,a.jsx)("select",{value:j,onChange:e=>F({fallbackStrategy:e.target.value}),className:"rounded-lg border border-border bg-surface px-3 py-2 text-sm text-text-main outline-none focus:border-primary",children:h.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))})]}),(0,a.jsx)(es,{value:v.requestOverrides||{},onChange:e=>F({requestOverrides:e}),compact:!0}),(0,a.jsx)(ea,{value:v.contentLoggingMode,onChange:e=>F({contentLoggingMode:e}),compact:!0}),("least-latency"===j||"p2c"===j)&&(0,a.jsxs)("div",{className:"mt-4 rounded-xl border border-primary/15 bg-surface p-3",children:[(0,a.jsxs)("label",{className:"flex items-start gap-2 text-sm text-text-muted",children:[(0,a.jsx)("input",{type:"checkbox",checked:!1!==v.lanHealthEnabled,onChange:e=>F({lanHealthEnabled:e.target.checked}),className:"mt-0.5 h-3.5 w-3.5 accent-primary"}),(0,a.jsxs)("span",{children:[(0,a.jsx)("span",{className:"font-medium text-text-main",children:"Routing theo trạng th\xe1i health LAN"}),(0,a.jsx)("span",{className:"mt-1 block text-xs",children:"D\xf9ng dữ liệu health v\xe0 circuit breaker khi xếp hạng target trong combo."})]})]}),(0,a.jsxs)("div",{className:"mt-3 grid gap-3 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Đường dẫn health"}),(0,a.jsx)("input",{value:v.healthCheckPath||"/api/tags",onChange:e=>F({healthCheckPath:e.target.value||"/api/tags"}),placeholder:"/api/tags",className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Chu kỳ kiểm tra (ms)"}),(0,a.jsx)("input",{type:"number",min:"1000",value:v.healthCheckIntervalMs||15e3,onChange:e=>F({healthCheckIntervalMs:Number(e.target.value)||15e3}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary"})]})]}),(0,a.jsxs)("div",{className:"mt-3 grid gap-3 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Tag endpoint bắt buộc"}),(0,a.jsx)("input",{value:O,onChange:e=>S(e.target.value),onBlur:()=>F({requiredTags:z(O)}),onKeyDown:e=>"Enter"===e.key&&e.currentTarget.blur(),placeholder:"gpu, vram:8gb",className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"}),(0,a.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:"Mọi endpoint được route đều phải c\xf3 c\xe1c tag n\xe0y."})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Quy tắc tag theo model"}),(0,a.jsx)("textarea",{value:q,onChange:e=>R(e.target.value),onBlur:()=>F({modelTagRules:function(e=""){let t={};for(let n of String(e||"").split(/\n+/)){let e=n.trim();if(!e)continue;let a=e.indexOf(":");if(-1===a)continue;let r=e.slice(0,a).trim(),l=z(e.slice(a+1));r&&l.length&&(t[r]=l)}return t}(q)}),placeholder:"qwen3:32b: gpu, vram:16gb\nqwen3:8b: model_support:qwen3:8b",rows:3,className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 font-mono text-xs text-text-main outline-none focus:border-primary"})]})]})]}),"round-robin"===j&&(0,a.jsxs)("div",{className:"mt-4 rounded-xl border border-primary/15 bg-surface p-3",children:[(0,a.jsxs)("div",{className:"mb-3 flex items-center justify-between gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 text-sm font-semibold text-primary",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"sticky_note_2"}),"Round Robin giữ d\xednh"]}),(0,a.jsxs)("label",{className:"flex items-center gap-2 text-xs text-text-muted",children:[(0,a.jsx)("input",{type:"checkbox",checked:"round-robin"===j,onChange:e=>F({fallbackStrategy:e.target.checked?"round-robin":"fallback"}),className:"h-3.5 w-3.5 accent-primary"}),"Bật"]})]}),(0,a.jsxs)("div",{className:"grid gap-3 md:grid-cols-2",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"Chế độ giữ d\xednh"}),(0,a.jsx)("select",{value:_,onChange:e=>F({stickyScope:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary",children:p.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,a.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:w.description})]}),(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-1 block text-xs font-medium text-text-muted",children:"TTL giữ d\xednh (ph\xfat)"}),(0,a.jsx)("input",{type:"number",min:"1",value:v.stickyTtlMinutes||120,onChange:e=>F({stickyTtlMinutes:Number(e.target.value)||120}),className:"w-full rounded-lg border border-border bg-background px-2 py-1.5 text-xs text-text-main outline-none focus:border-primary"})]})]}),(0,a.jsxs)("label",{className:"mt-3 flex items-start gap-2 text-xs text-text-muted",children:[(0,a.jsx)("input",{type:"checkbox",checked:!1!==v.stickyFallbackToClientIp,onChange:e=>F({stickyFallbackToClientIp:e.target.checked}),className:"mt-0.5 h-3.5 w-3.5 accent-primary"}),"Nếu thiếu chat session id, fallback về IP client thay v\xec xoay to\xe0n cục."]})]}),(0,a.jsxs)("div",{className:"mt-4 flex flex-col gap-2 border-t border-border pt-3 sm:flex-row sm:items-center sm:justify-between",children:[(0,a.jsx)("span",{className:`text-xs ${g?"text-red-500":k?"text-amber-600":"text-text-muted"}`,children:g||(k?"C\xf3 thay đổi chưa lưu — chỉ \xe1p dụng sau khi bấm Lưu.":"Đang \xe1p dụng cho request mới.")}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("button",{type:"button",onClick:()=>{f(""),m({})},disabled:!k||u,className:"rounded-lg border border-border px-3 py-1.5 text-sm font-medium text-text-muted transition hover:text-text-main disabled:opacity-40",children:"Ho\xe0n t\xe1c"}),(0,a.jsxs)("button",{type:"button",onClick:D,disabled:!k||u,className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-4 py-1.5 text-sm font-medium text-white transition hover:opacity-90 disabled:opacity-40",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"save"}),u?"Đang lưu…":"Lưu thay đổi"]})]})]})]})]})}function et({icon:e,title:t,onClick:n,danger:r=!1}){return(0,a.jsx)("button",{type:"button",onClick:e=>{e.stopPropagation(),n?.()},className:`rounded-lg p-2 transition ${r?"text-red-500 hover:bg-red-500/10":"text-text-muted hover:bg-background hover:text-primary"}`,title:t,"aria-label":t,children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:e})})}function en({id:e,index:t,model:n,subtitle:l="",enabled:o,isFirst:d,isLast:c,onEdit:m,onMoveUp:u,onMoveDown:x,onRemove:p,onToggleEnabled:h}){let{attributes:b,listeners:g,setNodeRef:f,transform:y,isDragging:v}=(0,s.gl)({id:e}),k={transform:i.Ks.Transform.toString(y),opacity:v?.4:1,zIndex:v?999:void 0},[j,N]=(0,r.useState)(!1),[_,w]=(0,r.useState)(n);(0,r.useEffect)(()=>{w(n)},[n]);let C=()=>{let e=_.trim();e&&e!==n?m(e):w(n),N(!1)};return(0,a.jsxs)("div",{ref:f,style:k,className:`flex items-center gap-3 rounded-xl border p-3 transition ${o?"border-border bg-background":"border-red-200 bg-red-50/70 opacity-75 dark:border-red-500/30 dark:bg-red-500/10"}`,children:[(0,a.jsx)("button",{type:"button",className:"cursor-grab text-text-muted active:cursor-grabbing",...b,...g,title:"K\xe9o để sắp xếp lại",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"drag_indicator"})}),(0,a.jsx)("span",{className:`flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-xs font-semibold ${o?"bg-primary/10 text-primary":"bg-red-100 text-red-600 dark:bg-red-500/20 dark:text-red-300"}`,children:t+1}),j?(0,a.jsx)("input",{autoFocus:!0,value:_,onChange:e=>w(e.target.value),onBlur:C,onKeyDown:e=>{"Enter"===e.key&&C(),"Escape"===e.key&&(w(n),N(!1))},className:"min-w-0 flex-1 rounded border border-primary/40 bg-background px-2 py-1 font-mono text-xs text-text-main outline-none"}):(0,a.jsxs)("button",{type:"button",onClick:()=>N(!0),className:"min-w-0 flex-1 text-left",title:"Bấm để sửa model",children:[(0,a.jsx)("span",{className:`block truncate font-mono text-xs ${o?"text-text-main":"text-text-muted line-through"}`,children:n}),l?(0,a.jsx)("span",{className:"mt-0.5 block truncate text-[11px] text-text-muted",children:l}):null]}),(0,a.jsx)("button",{type:"button",onClick:h,className:`rounded-lg p-1.5 transition ${o?"text-green-600 hover:bg-green-500/10":"text-red-500 hover:bg-red-500/10"}`,title:o?"Tắt model trong combo":"Bật model trong combo",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:o?"toggle_on":"toggle_off"})}),(0,a.jsx)("button",{type:"button",onClick:u,disabled:d,className:"rounded-lg p-1.5 text-text-muted transition hover:bg-surface disabled:opacity-30",title:"Di chuyển l\xean",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"arrow_upward"})}),(0,a.jsx)("button",{type:"button",onClick:x,disabled:c,className:"rounded-lg p-1.5 text-text-muted transition hover:bg-surface disabled:opacity-30",title:"Di chuyển xuống",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"arrow_downward"})}),(0,a.jsx)("button",{type:"button",onClick:p,className:"rounded-lg p-1.5 text-red-500 transition hover:bg-red-500/10",title:"X\xf3a",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"close"})})]})}function ea({value:e="inherit",onChange:t,compact:n=!1}){let r=O(e),l=N.find(e=>e.value===r)||N[0];return(0,a.jsx)("div",{className:n?"mt-4 rounded-xl border border-amber-500/15 bg-surface p-3":"rounded-xl border border-amber-500/15 bg-amber-500/5 p-4",children:(0,a.jsxs)("div",{className:"grid gap-3 md:grid-cols-[minmax(0,1fr)_280px] md:items-center",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 text-sm font-semibold text-text-main",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px] text-amber-500",children:"manage_search"}),"Prompt Logs cho combo n\xe0y"]}),(0,a.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:l.description}),"disabled"===r?(0,a.jsx)("p",{className:"mt-1 text-[11px] font-medium text-amber-600",children:"Khi chạy request, Prompt Logs sẽ chỉ ghi metadata v\xe0 hiển thị [promptlogs disabled on this combo]."}):null]}),(0,a.jsx)("select",{value:r,onChange:e=>t?.(O(e.target.value)),className:"w-full rounded-lg border border-border bg-surface 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))})]})})}function er({icon:e,label:t,children:n,active:r,muted:l=!1,className:s=""}){return(0,a.jsxs)("label",{className:`rounded-lg border p-3 transition ${r?"border-primary/30 bg-background shadow-sm":"border-border bg-background/60"} ${s}`,children:[(0,a.jsxs)("span",{className:"mb-2 flex items-center justify-between gap-2 text-xs font-medium text-text-main",children:[(0,a.jsxs)("span",{className:"flex min-w-0 items-center gap-1.5",children:[(0,a.jsx)("span",{className:`material-symbols-outlined text-[16px] ${r?"text-primary":"text-text-muted"}`,children:e}),(0,a.jsx)("span",{className:"truncate",children:t})]}),n?.toggle]}),n?.control,n?.hint?(0,a.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:n.hint}):null]})}function el({icon:e,title:t,values:n={},defaults:r={},onToggleField:l,onChangeField:s,inputClass:i}){let o=Object.keys(n||{}).length>0;return(0,a.jsxs)("div",{className:`rounded-lg border p-2 transition ${o?"border-primary/30 bg-background":"border-border bg-background/60"}`,children:[(0,a.jsxs)("div",{className:"mb-2 flex items-center gap-1.5 text-[11px] font-semibold text-text-main",children:[(0,a.jsx)("span",{className:`material-symbols-outlined text-[15px] ${o?"text-primary":"text-text-muted"}`,children:e}),(0,a.jsx)("span",{className:"truncate",children:t})]}),(0,a.jsx)("div",{className:"grid gap-2 sm:grid-cols-2",children:k.map(e=>{let t=n?.[e.key]!==void 0;return(0,a.jsxs)("label",{className:"space-y-1",children:[(0,a.jsxs)("span",{className:"flex items-center justify-between gap-1 text-[11px] font-medium text-text-main",children:[(0,a.jsx)("span",{className:"truncate",children:e.label}),(0,a.jsx)("input",{type:"checkbox",checked:t,onChange:t=>l?.(e.key,t.target.checked,r[e.key]),className:"h-3.5 w-3.5 accent-primary"})]}),(0,a.jsx)("input",{type:"number",min:e.min,max:e.max,step:e.step,disabled:!t,value:t?n[e.key]:r[e.key],onChange:t=>s?.(e.key,t.target.value),className:i})]},e.key)})})]})}function es({value:e={},onChange:t,compact:n=!1}){let r=$(e),l=void 0!==r.temperature,s=void 0!==r.top_p,i=void 0!==r.presence_penalty,o=void 0!==r.max_tokens,d=void 0!==r.reasoning_budget,c=r.thinkingMode||"inherit",m="inherit"!==c,u="off"===c,x=r.inheritThinkRequestOverrides||{},p=r.inheritNoThinkRequestOverrides||{},h=Object.keys(x).length>0||Object.keys(p).length>0,b=l||s||i||o||!m&&h,k=m||d,N=e=>{t?.($({...r,...e}))},_=(e,n,a)=>{if(!n){let n={...r};delete n[e],t?.($(n));return}N({[e]:a})},w=(e,t,n,a)=>{let l=v[e],s={...r[l]||{}};if(!n){delete s[t],N({[l]:s});return}s[t]=a,N({[l]:q(s)})},C=(e,t,n)=>{let a=v[e];N({[a]:q({...r[a]||{},[t]:n})})},T="w-full rounded-lg border border-border bg-surface px-2 py-1.5 text-sm text-text-main outline-none focus:border-primary disabled:opacity-50";return(0,a.jsxs)("div",{className:n?"mt-4 rounded-xl border border-sky-500/15 bg-surface p-3":"rounded-xl border border-sky-500/15 bg-sky-500/5 p-4",children:[(0,a.jsxs)("div",{className:"mb-3 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 text-sm font-semibold text-text-main",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px] text-sky-500",children:"tune"}),"Tham số request Local endpoint"]}),(0,a.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:["Chỉ inject khi combo route 100% tới local endpoint: ",(0,a.jsx)("span",{className:"font-mono",children:"llama.cpp"}),", ",(0,a.jsx)("span",{className:"font-mono",children:"vLLM"})," hoặc ",(0,a.jsx)("span",{className:"font-mono",children:"Ollama"}),". Nếu combo mix local + cloud/provider kh\xe1c, BlueRouter bỏ qua block n\xe0y v\xe0 giữ nguy\xean request gốc."]})]}),!function(e={}){return Object.keys($(e)).length>0}(r)?(0,a.jsx)("span",{className:"inline-flex shrink-0 items-center rounded-full bg-background px-2 py-1 text-[11px] font-semibold text-text-muted",children:"Kh\xf4ng override"}):(0,a.jsx)("span",{className:"inline-flex shrink-0 items-center rounded-full bg-primary/10 px-2 py-1 text-[11px] font-semibold text-primary",children:"C\xf3 override"})]}),(0,a.jsxs)("div",{className:"grid gap-3 xl:grid-cols-2",children:[(0,a.jsxs)("div",{className:`rounded-xl border p-3 ${b?"border-primary/20 bg-primary/5":"border-border bg-background/40"}`,children:[(0,a.jsxs)("div",{className:"mb-3 flex items-center gap-2 text-xs font-semibold text-primary",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"graphic_eq"}),"Sampling ",(0,a.jsx)("span",{className:"font-normal text-text-muted",children:"(điều khiển lựa chọn token)"})]}),m?(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2 2xl:grid-cols-3",children:[(0,a.jsx)(er,{icon:"thermostat",label:"Temperature",active:l,children:{toggle:(0,a.jsx)("input",{type:"checkbox",checked:l,onChange:e=>_("temperature",e.target.checked,g.temperature),className:"h-3.5 w-3.5 accent-primary"}),control:(0,a.jsx)("input",{type:"number",min:"0",max:"2",step:"0.05",disabled:!l,value:l?r.temperature:g.temperature,onChange:e=>N({temperature:e.target.value}),className:T}),hint:"0 = ổn định, 2 = s\xe1ng tạo."}}),(0,a.jsx)(er,{icon:"filter_alt",label:"top_p",active:s,children:{toggle:(0,a.jsx)("input",{type:"checkbox",checked:s,onChange:e=>_("top_p",e.target.checked,g.top_p),className:"h-3.5 w-3.5 accent-primary"}),control:(0,a.jsx)("input",{type:"number",min:"0.01",max:"1",step:"0.01",disabled:!s,value:s?r.top_p:g.top_p,onChange:e=>N({top_p:e.target.value}),className:T}),hint:"0.01–1.0; 0.9–0.95 thường hợp coder/chat."}}),(0,a.jsx)(er,{icon:"repeat",label:"presence_penalty",active:i,children:{toggle:(0,a.jsx)("input",{type:"checkbox",checked:i,onChange:e=>_("presence_penalty",e.target.checked,g.presence_penalty),className:"h-3.5 w-3.5 accent-primary"}),control:(0,a.jsx)("input",{type:"number",min:"-2",max:"2",step:"0.05",disabled:!i,value:i?r.presence_penalty:g.presence_penalty,onChange:e=>N({presence_penalty:e.target.value}),className:T}),hint:"-2–2; coder thường để 0, chỉ tăng nhẹ nếu hay lặp."}}),(0,a.jsx)(er,{icon:"output",label:"max_tokens",active:o,className:"sm:col-span-2 2xl:col-span-1",children:{toggle:(0,a.jsx)("input",{type:"checkbox",checked:o,onChange:e=>_("max_tokens",e.target.checked,g.max_tokens),className:"h-3.5 w-3.5 accent-primary"}),control:(0,a.jsx)("input",{type:"number",min:"1",max:"262144",step:"1",disabled:!o,value:o?r.max_tokens:g.max_tokens,onChange:e=>N({max_tokens:e.target.value}),className:T}),hint:"Giới hạn output cho request."}})]}):(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("div",{className:"grid gap-3 2xl:grid-cols-2",children:[(0,a.jsx)(el,{icon:"psychology",title:"Khi request bật thinking",values:x,defaults:f,onToggleField:(e,t,n)=>w("think",e,t,n),onChangeField:(e,t)=>C("think",e,t),inputClass:T}),(0,a.jsx)(el,{icon:"bolt",title:"Khi request tắt thinking",values:p,defaults:y,onToggleField:(e,t,n)=>w("nothink",e,t,n),onChangeField:(e,t)=>C("nothink",e,t),inputClass:T})]}),(0,a.jsx)("span",{className:"block text-[11px] text-text-muted",children:"Thinking đang theo request gốc n\xean mỗi nh\xe1nh c\xf3 bộ sampling ri\xeang, chọn theo đ\xfang cờ thinking client gửi l\xean. Request kh\xf4ng khai b\xe1o thinking t\xednh l\xe0 tắt. Field kh\xf4ng tick th\xec giữ nguy\xean gi\xe1 trị client gửi."})]})]}),(0,a.jsxs)("div",{className:`rounded-xl border p-3 ${k?"border-primary/20 bg-primary/5":"border-border bg-background/40"}`,children:[(0,a.jsxs)("div",{className:"mb-3 flex items-center gap-2 text-xs font-semibold text-primary",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"psychology"}),"Thinking ",(0,a.jsx)("span",{className:"font-normal text-text-muted",children:"(suy luận nội bộ)"})]}),(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2",children:[(0,a.jsxs)("label",{className:`rounded-lg border p-3 transition ${m?"border-primary/30 bg-background shadow-sm":"border-border bg-background/60"}`,children:[(0,a.jsxs)("span",{className:"mb-2 flex items-center gap-1.5 text-xs font-medium text-text-main",children:[(0,a.jsx)("span",{className:`material-symbols-outlined text-[16px] ${m?"text-primary":"text-text-muted"}`,children:"psychology_alt"}),"Thinking"]}),(0,a.jsx)("select",{value:c,onChange:e=>(e=>{if("inherit"===e)return void N({thinkingMode:void 0});let n="on"===e?x:p;t?.($({...r,...n,inheritThinkRequestOverrides:{},inheritNoThinkRequestOverrides:{},thinkingMode:e}))})(e.target.value),className:"w-full rounded-lg border border-border bg-surface px-2 py-1.5 text-sm text-text-main outline-none focus:border-primary",children:j.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,a.jsx)("span",{className:"mt-1 block text-[11px] text-text-muted",children:j.find(e=>e.value===c)?.description||j[0].description})]}),(0,a.jsx)(er,{icon:"account_balance_wallet",label:"reasoning_budget",active:d,className:u?"opacity-60":"",children:{toggle:(0,a.jsx)("input",{type:"checkbox",checked:d,disabled:u,onChange:e=>_("reasoning_budget",e.target.checked,g.reasoning_budget),className:"h-3.5 w-3.5 accent-primary disabled:opacity-50"}),control:(0,a.jsx)("input",{type:"number",min:"0",max:"262144",step:"1",disabled:u||!d,value:d?r.reasoning_budget:g.reasoning_budget,onChange:e=>N({reasoning_budget:e.target.value}),className:T}),hint:u?"Thinking đang tắt n\xean budget kh\xf4ng được gửi.":"Chỉ d\xf9ng cho llama.cpp/vLLM local; runtime sẽ map đ\xfang field."}})]})]})]})]})}function ei({isOpen:e,combo:t,comboStrategy:n={},onClose:i,onSave:c,activeProviders:m,providersLoading:p=!1,kindFilter:h=null}){let[b,f]=(0,r.useState)(t?.name||""),[y,v]=(0,r.useState)([]),[k,j]=(0,r.useState)(!1),[N,_]=(0,r.useState)(!1),[w,C]=(0,r.useState)(""),[T,S]=(0,r.useState)({}),[q,M]=(0,r.useState)(""),[E,P]=(0,r.useState)(""),[I,A]=(0,r.useState)(()=>t?$(n?.requestOverrides||{}):$(g)),[z,B]=(0,r.useState)(()=>O(n?.contentLoggingMode)),F=n||{},H=(0,l.FR)((0,l.MS)(l.AN,{activationConstraint:{distance:5}}),(0,l.MS)(l.uN,{coordinateGetter:s.JR}));(0,r.useEffect)(()=>{e&&(f(t?.name||""),v(function(e,t={}){let n=(e?.models||[]).map(e=>U(e,!0)).filter(e=>e.value),a=new Set(n.map(e=>e.value));return[...n,...L(t).filter(e=>!a.has(e)).map(e=>U(e,!1)).filter(e=>e.value)]}(t,F)),C(""),M(""),P(""),A(t?$(F.requestOverrides||{}):$(g)),B(O(F.contentLoggingMode)))},[e,t?.id,t?.name,F.contentLoggingMode]),(0,r.useEffect)(()=>{e&&J()},[e]);let J=async()=>{try{let e=await fetch("/api/models/alias",{cache:"no-store"});if(!e.ok)return;let t=await e.json();S(t.aliases||{})}catch(e){console.error("Error fetching modal data:",e)}},Q=y.map((e,t)=>({uid:`item-${t}-${e.value}`,row:e})),Z=y.map(e=>e.value),Y=y.filter(e=>e.enabled).length,ee=y.filter(e=>!e.enabled).length,et=(m||[]).filter(e=>e?.isActive!==!1),er=et.find(e=>e.id===q)||null,el=er?V(er,T):[],eo=el[0]?.value||(er?W(er):""),ed=e=>e.trim()?x.test(e)?(C(""),!0):(C("Chỉ cho ph\xe9p chữ, số, dấu -, _ v\xe0 ."),!1):(C("Bắt buộc nhập t\xean"),!1),ec=async()=>{if(!ed(b))return;let{models:e,disabledModels:t}=function(e=[]){let t=[],n=new Set;for(let a of e){let e=R(a?.value||K(a?.target));!e||n.has(e)||(n.add(e),t.push({...a,value:e,enabled:a?.enabled!==!1,target:X(a?.target||a?.value)}))}return{models:t.filter(e=>e.enabled).map(e=>e.target).filter(Boolean),disabledModels:t.filter(e=>!e.enabled).map(e=>e.value)}}(y);_(!0),await c({name:b.trim(),models:e,disabledModels:t,requestOverrides:$(I),contentLoggingMode:z}),_(!1)};if(!e)return null;let em=!!t;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 z-[100] flex items-center justify-center bg-black/45 p-3 backdrop-blur-[1px] sm:p-4",children:(0,a.jsxs)("div",{className:"flex max-h-[92vh] w-full max-w-7xl flex-col overflow-hidden rounded-2xl border border-border bg-white shadow-2xl dark:bg-zinc-950",children:[(0,a.jsxs)("div",{className:"flex items-start justify-between border-b border-border px-5 py-4 sm:px-6",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-xl font-semibold text-text-main",children:em?"Chỉnh sửa combo":"Tạo combo"}),(0,a.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Chọn model, tắt tạm thời khi cần v\xe0 sắp xếp thứ tự ưu ti\xean fallback đang bật."})]}),(0,a.jsx)("button",{type:"button",onClick:i,className:"rounded-lg p-1 text-text-muted transition hover:bg-surface hover:text-text-main",children:(0,a.jsx)("span",{className:"material-symbols-outlined",children:"close"})})]}),(0,a.jsxs)("div",{className:"min-h-0 flex-1 space-y-5 overflow-y-auto bg-white px-5 py-4 dark:bg-zinc-950 sm:px-6",children:[(0,a.jsxs)("label",{className:"block",children:[(0,a.jsx)("span",{className:"mb-2 block text-sm font-semibold text-text-main",children:"T\xean"}),(0,a.jsx)("input",{value:b,onChange:e=>{let t=e.target.value;f(t),t?ed(t):C("")},placeholder:"premium-coding",className:`w-full rounded-xl border bg-white px-4 py-2.5 text-text-main outline-none transition focus:border-primary dark:bg-zinc-900 ${w?"border-red-400":"border-border"}`}),(0,a.jsx)("span",{className:`mt-1 block text-xs ${w?"text-red-500":"text-text-muted"}`,children:w||"Chỉ cho ph\xe9p chữ, số, dấu -, _ v\xe0 ."})]}),(0,a.jsx)(es,{value:I,onChange:A,defaultEnabled:!em}),(0,a.jsx)(ea,{value:z,onChange:B}),(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"mb-3 flex items-center justify-between gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-sm font-semibold text-text-main",children:"Danh s\xe1ch model"}),(0,a.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:[Y," đang bật",ee>0?`, ${ee} đ\xe3 tắt`:"",". Model đ\xe3 tắt vẫn nằm trong combo nhưng kh\xf4ng được route."]})]}),(0,a.jsxs)("button",{type:"button",onClick:()=>j(!0),className:"inline-flex items-center gap-1 rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-primary hover:border-primary/50",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add"}),"Th\xeam model"]})]}),(0,a.jsxs)("div",{className:"mb-4 rounded-xl border border-primary/15 bg-primary/5 p-3",children:[(0,a.jsxs)("div",{className:"mb-2 flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-primary",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"account_tree"}),"Th\xeam target theo provider account"]}),(0,a.jsx)("p",{className:"mb-3 text-xs text-text-muted",children:"Cố định bước combo n\xe0y v\xe0o một provider account cụ thể. Danh s\xe1ch account chỉ được load khi mở modal để trang combo nhẹ hơn."}),(0,a.jsxs)("div",{className:"grid gap-2 md:grid-cols-[minmax(0,1.5fr)_minmax(0,1fr)_auto]",children:[(0,a.jsxs)("select",{value:q,onChange:e=>{let t=e.target.value,n=et.find(e=>e.id===t),a=n?V(n,T):[];M(t),P(a[0]?.value||W(n||{})||"")},className:"min-w-0 rounded-lg border border-border bg-background px-3 py-2 text-xs text-text-main outline-none focus:border-primary",children:[(0,a.jsx)("option",{value:"",children:p?"Đang tải provider account...":"Chọn provider account"}),et.map(e=>{let t=D(e),n=G(e),r=n&&n!==t?`${t} / ${n}`:t;return(0,a.jsx)("option",{value:e.id,children:r},e.id)})]}),(0,a.jsxs)("select",{value:E,onChange:e=>P(e.target.value),disabled:!q||0===el.length,className:"min-w-0 rounded-lg border border-border bg-background px-3 py-2 font-mono text-xs text-text-main outline-none focus:border-primary disabled:cursor-not-allowed disabled:opacity-60",children:[(0,a.jsx)("option",{value:"",children:q?el.length>0?"Chọn model":"Kh\xf4ng t\xecm thấy model của provider":"Chọn account trước"}),el.map(e=>(0,a.jsx)("option",{value:e.value,children:e.label},`${e.value}-${e.label}`))]}),(0,a.jsxs)("button",{type:"button",onClick:()=>{if(!er)return;let e=function(e,t){let n=D(e),a=function(e={}){let t=R(e.provider),n=D(e);return(0,u.mq)(t)||(0,u.gb)(t)?n||t:t||n}(e),r=G(e),l=R(t||W(e));if(!n||!e?.id||!l)return null;let s=l.includes("/"),i=s?l:`${n}/${l}`,o=s&&l.startsWith(`${n}/`)?l.slice(n.length+1):l,d=r&&r!==a?`${a}/${r}/${o}`:`${a}/${o}`;return{model:i,connectionId:e.id,provider:a||n,accountName:r||void 0,label:d}}(er,E||eo);if(!e)return void alert("H\xe3y chọn provider account v\xe0 model cho target cố định n\xe0y.");let t=U(e,!0);v(e=>{let n=e.findIndex(e=>e.value===t.value);if(-1!==n){let a=[...e];return a[n]={...a[n],...t,enabled:!0},a}return[...e,t]}),P("")},disabled:!q||!E,className:"inline-flex items-center justify-center gap-1 rounded-lg bg-primary px-3 py-2 text-xs font-semibold text-white disabled:opacity-50",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"add_link"}),"Th\xeam account"]})]})]}),0===y.length?(0,a.jsxs)("div",{className:"rounded-xl border border-dashed border-border p-8 text-center text-text-muted",children:[(0,a.jsx)("span",{className:"material-symbols-outlined",children:"layers"}),(0,a.jsx)("p",{className:"mt-2 text-sm",children:"Chưa th\xeam model n\xe0o"})]}):(0,a.jsx)(l.Mp,{sensors:H,collisionDetection:l.fp,modifiers:[o.FN,o.gj],onDragEnd:e=>{let{active:t,over:n}=e;if(n&&t.id!==n.id){let e=Q.findIndex(e=>e.uid===t.id),a=Q.findIndex(e=>e.uid===n.id);-1!==e&&-1!==a&&v(t=>(0,s.be)(t,e,a))}},children:(0,a.jsx)(s.gB,{items:Q.map(e=>e.uid),strategy:s._G,children:(0,a.jsx)("div",{className:"space-y-3",children:Q.map(({uid:e,row:t},n)=>(0,a.jsx)(en,{id:e,index:n,model:t.label||t.value,subtitle:t.subtitle,enabled:t.enabled,isFirst:0===n,isLast:n===y.length-1,onEdit:e=>{let t=e.trim();if(!t)return;let a=[...y],r=a[n];if(r?.target&&"object"==typeof r.target){let e=X({...r.target,model:t});a[n]=U(e,!1!==r.enabled)}else a[n]=U(t,r?.enabled!==!1);v(a)},onMoveUp:()=>{if(0===n)return;let e=[...y];[e[n-1],e[n]]=[e[n],e[n-1]],v(e)},onMoveDown:()=>{if(n===y.length-1)return;let e=[...y];[e[n],e[n+1]]=[e[n+1],e[n]],v(e)},onToggleEnabled:()=>{let e=[...y];e[n]={...e[n],enabled:!e[n].enabled},v(e)},onRemove:()=>v(y.filter((e,t)=>t!==n))},e))})})})]})]}),(0,a.jsxs)("div",{className:"flex justify-end gap-3 border-t border-border bg-white px-5 py-4 dark:bg-zinc-950 sm:px-6",children:[(0,a.jsx)("button",{type:"button",onClick:i,className:"rounded-xl border border-border px-4 py-2 text-sm font-medium text-text-main hover:bg-surface",children:"Hủy"}),(0,a.jsx)("button",{type:"button",onClick:ec,disabled:N,className:"rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white hover:opacity-90 disabled:opacity-50",children:N?"Đang lưu...":em?"Lưu":"Tạo"})]})]})}),(0,a.jsx)(d.rq,{isOpen:k,onClose:()=>j(!1),onSelect:e=>{let t=e.value;v(e=>{let n=e.findIndex(e=>e.value===t);if(-1!==n){let t=[...e];return t[n]={...t[n],enabled:!0},t}return[...e,U(t,!0)]})},onDeselect:e=>{v(t=>t.filter(t=>t.value!==e.value))},activeProviders:m,modelAliases:T,title:"Th\xeam model v\xe0o combo",kindFilter:h,addedModelValues:Z,closeOnSelect:!1})]})}}},e=>{e.O(0,[6373,3862,8500,9893,9959,7050,7055,5564,5263,7033,5497,8441,3794,7358],()=>e(e.s=20061)),_N_E=e.O()}]);
|