@jheavenknows/bluerouter 4.0.16 → 4.0.17
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 +4 -4
- package/app/.next-cli-build/build-manifest.json +2 -2
- 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_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/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/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/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/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/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/skills/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/_global-error.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_index.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 +3 -3
- package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +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/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/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/analytics/route.js +32 -32
- 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/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/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/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/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/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/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/route.js +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 +3 -3
- package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/analytics.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/analytics.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk/dashboard/analytics/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk/dashboard/analytics.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/analytics.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/api-keys.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/api-keys.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard/api-keys/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard/api-keys.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/api-keys.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- 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 +5 -5
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/app/.next-cli-build/server/app/dashboard.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/index.html +1 -1
- package/app/.next-cli-build/server/app/index.rsc +3 -3
- package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +3 -3
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
- 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 +4 -4
- package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app-paths-manifest.json +4 -4
- package/app/.next-cli-build/server/chunks/2338.js +1 -1
- package/app/.next-cli-build/server/chunks/3110.js +1 -1
- package/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/app/.next-cli-build/server/chunks/7130.js +1 -1
- package/app/.next-cli-build/server/chunks/7153.js +1 -1
- package/app/.next-cli-build/server/middleware-build-manifest.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/{620-5b73dcd9a18f97b5.js → 620-8597abc6e0f1c879.js} +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/{-N6CoJVeyOe8T3ur4ATip → uCqnwJgxwtQxxz3tTkWO4}/_buildManifest.js +0 -0
- /package/app/.next-cli-build/static/{-N6CoJVeyOe8T3ur4ATip → uCqnwJgxwtQxxz3tTkWO4}/_ssgManifest.js +0 -0
- /package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/{upgrade-4.0.2-to-4.0.3-4.0.3-20260618-171158 → upgrade-4.0.16-to-4.0.17-4.0.17-20260619-143652}/data.sqlite +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";(()=>{var a={};a.id=451,a.ids=[451],a.modules={261:a=>{a.exports=require("next/dist/shared/lib/router/utils/app-paths")},1932:a=>{a.exports=require("url")},3295:a=>{a.exports=require("next/dist/server/app-render/after-task-async-storage.external.js")},4573:a=>{a.exports=require("node:buffer")},9588:(a,b,c)=>{c.d(b,{I8:()=>j,Tv:()=>t,aV:()=>n,bz:()=>p,hH:()=>s,oW:()=>r,s0:()=>l,ub:()=>m,vZ:()=>o});var d=c(65573),e=c(23211),f=c(89718),g=c(33792),h=c(90389);function i(a){return String(a||"").trim().toLowerCase()}function j(a){return i(a)}function k(a={}){return[a.ldapUsername,a.ldapEmail,a.ldapName,a.oidcEmail,a.oidcName,a.localUsername,a.username,a.email].map(i).filter(Boolean)}function l(a={}){let b=k(a),c=b[0]||"local",d=a.ldapName||a.ldapEmail||a.oidcName||a.oidcEmail||a.localUsername||c;return{userId:c,displayName:d,loginMethod:a.oidc?"OIDC":a.ldap?"LDAP":"Local",candidates:b}}function m(a={},b={}){var c;if(!b?.authenticated)return!1;if(b.local||!b.ldap&&!b.oidc||b.role===h.hS.ADMIN||!0===b.ldapIsAdmin)return!0;let d=Array.isArray(c=a.ldapAllowedUsers)?c.map(i).filter(Boolean):String(c||"").split(/[,\n]/).map(i).filter(Boolean);return 0!==d.length&&k(b).some(a=>d.includes(a))}function n(a={},b={}){return!(!b?.authenticated||m(a,b))&&(b.role===h.hS.MONITOR_ADMIN||!0===b.ldapIsMonitorAdmin)}function o(a={},b={}){return b?.authenticated?m(a,b)?h.hS.ADMIN:n(a,b)?h.hS.MONITOR_ADMIN:h.hS.USER:h.hS.GUEST}function p(a={}){return!0===a.isAdmin||!0===a.isMonitorAdmin}async function q(){let a=await (0,f.mt)(),b=await (0,d.UL)(),c=await (0,g.dY)(b.get("auth_token")?.value);if(!c?.authenticated)return{authenticated:!1,isAdmin:!1,isMonitorAdmin:!1,role:h.hS.GUEST,userId:"",displayName:"Guest",loginMethod:"None",settings:{...a,requireLogin:!0},session:null};let e=l(c||{}),i=o(a,c||{}),j=i===h.hS.ADMIN,k=i===h.hS.MONITOR_ADMIN;return{authenticated:!0,isAdmin:j,isMonitorAdmin:k,role:i,canManageApiKeys:j||k,canUseMonitorAdminTabs:j||k,...e,settings:{...a,requireLogin:!0},session:c}}async function r(){let a=await q();return a.authenticated?{access:a,response:null}:{access:a,response:e.NextResponse.json({error:"Authentication required"},{status:401})}}async function s(a={}){let{allowMonitorAdmin:b=!1}=a||{},{access:c,response:d}=await r();return d?{access:c,response:d}:c.isAdmin||b&&c.isMonitorAdmin?{access:c,response:null}:{access:c,response:e.NextResponse.json({error:"Admin access required"},{status:403})}}function t(a,b){if(!a?.authenticated||!b)return!1;if(p(a))return!0;let c=i(a.userId),d=i(b.ownerUser),e=i(b.createdByUser);return!!c&&(d===c||e===c)}},10846:a=>{a.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},19771:a=>{a.exports=require("process")},21820:a=>{a.exports=require("os")},27910:a=>{a.exports=require("stream")},28354:a=>{a.exports=require("util")},29294:a=>{a.exports=require("next/dist/server/app-render/work-async-storage.external.js")},33792:(a,b,c)=>{c.d(b,{Dc:()=>p,OZ:()=>s,YK:()=>n,dY:()=>q,tm:()=>r});var d=c(86935),e=c(69614),f=c(73024),g=c.n(f),h=c(76760),i=c.n(h),j=c(77598),k=c.n(j),l=c(49120);let m=new TextEncoder().encode(function(){if(process.env.JWT_SECRET)return process.env.JWT_SECRET;let a=i().join(l.DATA_DIR,"jwt-secret");try{return g().readFileSync(a,"utf8").trim()}catch{}g().mkdirSync(l.DATA_DIR,{recursive:!0});let b=k().randomBytes(32).toString("hex");return g().writeFileSync(a,b,{mode:384}),b}());function n(a){let b="true"===process.env.AUTH_COOKIE_SECURE,c=a?.headers?.get?.("x-forwarded-proto");return b||"https"===c}async function o(a={}){return new d.P({authenticated:!0,...a}).setProtectedHeader({alg:"HS256"}).setIssuedAt().setExpirationTime("24h").sign(m)}async function p(a){if(!a)return!1;try{return await (0,e.V)(a,m),!0}catch{return!1}}async function q(a){if(!a)return null;try{let{payload:b}=await (0,e.V)(a,m);return b}catch{return null}}async function r(a,b,c={}){let d=await o(c);a.set("auth_token",d,{httpOnly:!0,secure:n(b),sameSite:"lax",path:"/"})}function s(a){a.delete("auth_token")}},33873:a=>{a.exports=require("path")},34631:a=>{a.exports=require("tls")},41204:a=>{a.exports=require("string_decoder")},44870:a=>{a.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},46293:a=>{a.exports=require("sql.js")},50122:(a,b,c)=>{c.d(b,{k:()=>e});let d=[];for(let a=0;a<256;++a)d.push((a+256).toString(16).slice(1));function e(a,b=0){return(d[a[b+0]]+d[a[b+1]]+d[a[b+2]]+d[a[b+3]]+"-"+d[a[b+4]]+d[a[b+5]]+"-"+d[a[b+6]]+d[a[b+7]]+"-"+d[a[b+8]]+d[a[b+9]]+"-"+d[a[b+10]]+d[a[b+11]]+d[a[b+12]]+d[a[b+13]]+d[a[b+14]]+d[a[b+15]]).toLowerCase()}},53053:a=>{a.exports=require("node:diagnostics_channel")},55511:a=>{a.exports=require("crypto")},61066:(a,b,c)=>{c.r(b),c.d(b,{handler:()=>
|
|
1
|
+
"use strict";(()=>{var a={};a.id=451,a.ids=[451],a.modules={261:a=>{a.exports=require("next/dist/shared/lib/router/utils/app-paths")},1932:a=>{a.exports=require("url")},3295:a=>{a.exports=require("next/dist/server/app-render/after-task-async-storage.external.js")},4573:a=>{a.exports=require("node:buffer")},9588:(a,b,c)=>{c.d(b,{I8:()=>j,Tv:()=>t,aV:()=>n,bz:()=>p,hH:()=>s,oW:()=>r,s0:()=>l,ub:()=>m,vZ:()=>o});var d=c(65573),e=c(23211),f=c(89718),g=c(33792),h=c(90389);function i(a){return String(a||"").trim().toLowerCase()}function j(a){return i(a)}function k(a={}){return[a.ldapUsername,a.ldapEmail,a.ldapName,a.oidcEmail,a.oidcName,a.localUsername,a.username,a.email].map(i).filter(Boolean)}function l(a={}){let b=k(a),c=b[0]||"local",d=a.ldapName||a.ldapEmail||a.oidcName||a.oidcEmail||a.localUsername||c;return{userId:c,displayName:d,loginMethod:a.oidc?"OIDC":a.ldap?"LDAP":"Local",candidates:b}}function m(a={},b={}){var c;if(!b?.authenticated)return!1;if(b.local||!b.ldap&&!b.oidc||b.role===h.hS.ADMIN||!0===b.ldapIsAdmin)return!0;let d=Array.isArray(c=a.ldapAllowedUsers)?c.map(i).filter(Boolean):String(c||"").split(/[,\n]/).map(i).filter(Boolean);return 0!==d.length&&k(b).some(a=>d.includes(a))}function n(a={},b={}){return!(!b?.authenticated||m(a,b))&&(b.role===h.hS.MONITOR_ADMIN||!0===b.ldapIsMonitorAdmin)}function o(a={},b={}){return b?.authenticated?m(a,b)?h.hS.ADMIN:n(a,b)?h.hS.MONITOR_ADMIN:h.hS.USER:h.hS.GUEST}function p(a={}){return!0===a.isAdmin||!0===a.isMonitorAdmin}async function q(){let a=await (0,f.mt)(),b=await (0,d.UL)(),c=await (0,g.dY)(b.get("auth_token")?.value);if(!c?.authenticated)return{authenticated:!1,isAdmin:!1,isMonitorAdmin:!1,role:h.hS.GUEST,userId:"",displayName:"Guest",loginMethod:"None",settings:{...a,requireLogin:!0},session:null};let e=l(c||{}),i=o(a,c||{}),j=i===h.hS.ADMIN,k=i===h.hS.MONITOR_ADMIN;return{authenticated:!0,isAdmin:j,isMonitorAdmin:k,role:i,canManageApiKeys:j||k,canUseMonitorAdminTabs:j||k,...e,settings:{...a,requireLogin:!0},session:c}}async function r(){let a=await q();return a.authenticated?{access:a,response:null}:{access:a,response:e.NextResponse.json({error:"Authentication required"},{status:401})}}async function s(a={}){let{allowMonitorAdmin:b=!1}=a||{},{access:c,response:d}=await r();return d?{access:c,response:d}:c.isAdmin||b&&c.isMonitorAdmin?{access:c,response:null}:{access:c,response:e.NextResponse.json({error:"Admin access required"},{status:403})}}function t(a,b){if(!a?.authenticated||!b)return!1;if(p(a))return!0;let c=i(a.userId),d=i(b.ownerUser),e=i(b.createdByUser);return!!c&&(d===c||e===c)}},10846:a=>{a.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},19771:a=>{a.exports=require("process")},21820:a=>{a.exports=require("os")},27910:a=>{a.exports=require("stream")},28354:a=>{a.exports=require("util")},29294:a=>{a.exports=require("next/dist/server/app-render/work-async-storage.external.js")},33792:(a,b,c)=>{c.d(b,{Dc:()=>p,OZ:()=>s,YK:()=>n,dY:()=>q,tm:()=>r});var d=c(86935),e=c(69614),f=c(73024),g=c.n(f),h=c(76760),i=c.n(h),j=c(77598),k=c.n(j),l=c(49120);let m=new TextEncoder().encode(function(){if(process.env.JWT_SECRET)return process.env.JWT_SECRET;let a=i().join(l.DATA_DIR,"jwt-secret");try{return g().readFileSync(a,"utf8").trim()}catch{}g().mkdirSync(l.DATA_DIR,{recursive:!0});let b=k().randomBytes(32).toString("hex");return g().writeFileSync(a,b,{mode:384}),b}());function n(a){let b="true"===process.env.AUTH_COOKIE_SECURE,c=a?.headers?.get?.("x-forwarded-proto");return b||"https"===c}async function o(a={}){return new d.P({authenticated:!0,...a}).setProtectedHeader({alg:"HS256"}).setIssuedAt().setExpirationTime("24h").sign(m)}async function p(a){if(!a)return!1;try{return await (0,e.V)(a,m),!0}catch{return!1}}async function q(a){if(!a)return null;try{let{payload:b}=await (0,e.V)(a,m);return b}catch{return null}}async function r(a,b,c={}){let d=await o(c);a.set("auth_token",d,{httpOnly:!0,secure:n(b),sameSite:"lax",path:"/"})}function s(a){a.delete("auth_token")}},33873:a=>{a.exports=require("path")},34631:a=>{a.exports=require("tls")},41204:a=>{a.exports=require("string_decoder")},44870:a=>{a.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},46293:a=>{a.exports=require("sql.js")},50122:(a,b,c)=>{c.d(b,{k:()=>e});let d=[];for(let a=0;a<256;++a)d.push((a+256).toString(16).slice(1));function e(a,b=0){return(d[a[b+0]]+d[a[b+1]]+d[a[b+2]]+d[a[b+3]]+"-"+d[a[b+4]]+d[a[b+5]]+"-"+d[a[b+6]]+d[a[b+7]]+"-"+d[a[b+8]]+d[a[b+9]]+"-"+d[a[b+10]]+d[a[b+11]]+d[a[b+12]]+d[a[b+13]]+d[a[b+14]]+d[a[b+15]]).toLowerCase()}},53053:a=>{a.exports=require("node:diagnostics_channel")},55511:a=>{a.exports=require("crypto")},61066:(a,b,c)=>{c.r(b),c.d(b,{handler:()=>bd,patchFetch:()=>bc,routeModule:()=>a8,serverHooks:()=>bb,workAsyncStorage:()=>a9,workUnitAsyncStorage:()=>ba});var d={};c.r(d),c.d(d,{GET:()=>a7,dynamic:()=>a5});var e=c(19225),f=c(84006),g=c(8317),h=c(99373),i=c(34775),j=c(24235),k=c(261),l=c(54365),m=c(90771),n=c(73461),o=c(67798),p=c(92280),q=c(62018),r=c(45696),s=c(47929),t=c(86439),u=c(37527),v=c(23211),w=c(36366),x=c(644),y=c(45903),z=c(97242);let A=new Set;function B(a){return String(a||"").trim()}function C(a,b=0){let c=Number(a);return Number.isFinite(c)?c:b}async function D(){return(0,y.I6)(await (0,y.L7)())}async function E(a){let b=new(await Promise.resolve().then(c.bind(c,64939))).Client({host:a.host,port:Number(a.port||5432),database:a.database,user:a.username,password:a.password,ssl:!!a.ssl&&{rejectUnauthorized:!1}});return await b.connect(),{type:"postgres",query:async(a,c=[])=>(await b.query(a,c)).rows,queryOne:async(a,c=[])=>(await b.query(a,c)).rows[0]||null,async exec(a,c=[]){await b.query(a,c)},async close(){await b.end()}}}async function F(a){let b=await c.e(8491).then(c.t.bind(c,38491,19)),d=await b.createConnection({host:a.host,port:Number(a.port||3306),database:a.database,user:a.username,password:a.password,ssl:a.ssl?{}:void 0,dateStrings:!0,connectTimeout:3e3});return{type:"mysql",async query(a,b=[]){let[c]=await d.query(a,b);return c},async queryOne(a,b=[]){let[c]=await d.query(a,b);return c[0]||null},async exec(a,b=[]){await d.query(a,b)},async close(){await d.end()}}}async function G(a){if("postgres"===a.type)return E(a);if("mysql"===a.type)return F(a);throw Error(`Unsupported prompt log database type: ${a.type}`)}async function H(){await (0,z.DU)().catch(()=>null)}async function I(a){if(!a.enabled)return;let b=`${a.type}:${a.host||""}:${a.port||""}:${a.database||""}`;if(!A.has(b))try{await H(a),A.add(b)}catch(a){console.warn("[prompt-log-analytics] Unable to ensure indexes:",a?.message||a)}}async function J(a,b,c,d,e=50){let f=Math.max(1,Math.min(500,Number(e)||50));return await a.query(`SELECT ${c},
|
|
2
2
|
COUNT(*) AS requests,
|
|
3
3
|
SUM(CASE WHEN error_text IS NOT NULL AND error_text <> '' THEN 1
|
|
4
4
|
WHEN status_code IS NOT NULL AND CONCAT('', status_code) NOT LIKE '2%' THEN 1
|
|
@@ -45,21 +45,21 @@
|
|
|
45
45
|
COALESCE(SUM(CASE WHEN ${U} THEN COALESCE(promptTokens, 0) + COALESCE(completionTokens, 0) ELSE 0 END), 0) AS totalTokens,
|
|
46
46
|
COALESCE(SUM(CASE WHEN ${U} THEN COALESCE(cost, 0) ELSE 0 END), 0) AS cost,
|
|
47
47
|
MAX(timestamp) AS lastSeen
|
|
48
|
-
`;function W(a){return String(a||"").trim()}function X(a){return W(a).toLowerCase()}function Y(a,b=0){let c=Number(a);return Number.isFinite(c)?c:b}function Z(a){let b=W(a);if(!b)return"";let c=new Date(b);return Number.isNaN(c.getTime())?"":c.toISOString()}let
|
|
48
|
+
`;function W(a){return String(a||"").trim()}function X(a){return W(a).toLowerCase()}function Y(a,b=0){let c=Number(a);return Number.isFinite(c)?c:b}function Z(a){let b=W(a);if(!b)return"";let c=new Date(b);return Number.isNaN(c.getTime())?"":c.toISOString()}function $(a){return a?function a(b){let c=b instanceof Date?b:new Date(b||Date.now());if(Number.isNaN(c.getTime()))return a(new Date);let d=(a,b=2)=>String(a).padStart(b,"0");return`${c.getUTCFullYear()}-${d(c.getUTCMonth()+1)}-${d(c.getUTCDate())} ${d(c.getUTCHours())}:${d(c.getUTCMinutes())}:${d(c.getUTCSeconds())}.${d(c.getUTCMilliseconds(),3)}`}(a):a}let _=process.env.DASHBOARD_TIME_ZONE||process.env.APP_TIMEZONE||process.env.TZ||"Asia/Ho_Chi_Minh";function aa(a=new Date,b=_){return new Intl.DateTimeFormat("en-CA",{timeZone:b,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}).formatToParts(a).reduce((a,b)=>("literal"!==b.type&&(a[b.type]=Number(b.value)),a),{})}function ab(a=new Date,b=_){let c=aa(a,b);return Date.UTC(c.year,c.month-1,c.day,c.hour,c.minute,c.second||0)-a.getTime()}function ac({year:a,month:b,day:c,hour:d=0,minute:e=0,second:f=0,millisecond:g=0},h=_){let i=new Date(Date.UTC(a,b-1,c,d,e,f,g)),j=new Date(i.getTime()-ab(i,h));return new Date(i.getTime()-ab(j,h))}function ad(a=new Date){let b=aa(a);return ac({year:b.year,month:b.month,day:b.day})}function ae(a,b){let c=new Date(a);return c.setUTCDate(c.getUTCDate()+b),c}function af(a=new Date){let b={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6}[new Intl.DateTimeFormat("en-US",{timeZone:_,weekday:"short"}).format(a)]??1;return ae(ad(a),0===b?-6:1-b)}function ag(a=new Date){let b=aa(a);return ac({year:b.year,month:b.month,day:1})}function ah(a={}){var b;return{...function(a={}){let b=P.has(a.period)?a.period:"24h",c=new Date,d=null,e=c;if("custom"===b){let b=Z(a.dateFrom),f=Z(a.dateTo);d=new Date(b||c.getTime()-864e5),e=f?new Date(f):c}else if("today"===b)d=ad(c);else if("yesterday"===b){let a=ad(c);d=ae(a,-1),e=a}else if("24h"===b)d=new Date(c.getTime()-864e5);else if("thisWeek"===b)d=af(c);else if("lastWeek"===b){let a=af(c);d=ae(a,-7),e=a}else if("7d"===b)d=new Date(c.getTime()-6048e5);else if("thisMonth"===b)d=ag(c);else if("lastMonth"===b){let a,b=ag(c);d=ac({year:(a=aa(b)).year,month:a.month+-1,day:a.day}),e=b}else d="30d"===b?new Date(c.getTime()-2592e6):"60d"===b?new Date(c.getTime()-5184e6):null;if(d&&e&&d>e){let a=d;d=e,e=a}return{period:b,start:d,end:e,startIso:d?d.toISOString():"",endIso:e?e.toISOString():""}}(a),provider:W(a.provider),model:W(a.model),connectionId:W(a.connectionId),status:W(a.status),endpoint:W(a.endpoint),apiKey:W(a.apiKey),clientIp:W(a.clientIp||a.sourceIp),sourceTool:W(a.sourceTool),sessionId:W(a.sessionId),keyword:W(a.keyword),maxPromptLogRows:Math.max(200,Math.min(1500,Math.floor(Y(a.maxPromptLogRows,1500)))),userOwnedOnly:!0===a.userOwnedOnly||"1"===a.userOwnedOnly||"true"===a.userOwnedOnly,ownerCandidates:Array.isArray(b=a.ownerCandidates)?[...new Set(b.map(a=>X(a)).filter(Boolean))]:[...new Set(String(b||"").split(/[,\s]+/).map(a=>X(a)).filter(Boolean))]}}function ai(a){let b,c=W(a);return c?(b=W(c))?b.length<=12?b:`${b.slice(0,8)}...${b.slice(-4)}`:"local-no-key":"local-no-key"}async function aj(a){try{let b=await a.all("SELECT * FROM apiKeys ORDER BY createdAt DESC")||[],c=new Map,d=new Map,e=[];for(let a of b){let b=function(a={}){let b=W(a.key),c=ai(b);return{id:W(a.id),key:b,fingerprint:c,masked:c,name:W(a.name)||c,ownerUser:W(a.ownerUser||a.owner_user),createdByUser:W(a.createdByUser||a.created_by_user),machineId:W(a.machineId||a.machine_id),isActive:void 0===a.isActive||1===a.isActive||!0===a.isActive,createdAt:W(a.createdAt||a.created_at)}}(a);e.push(b),b.key&&c.set(b.key,b),d.set(b.fingerprint,b)}return{rows:b,all:e,byKey:c,byFingerprint:d}}catch{return{rows:[],all:[],byKey:new Map,byFingerprint:new Map}}}async function ak(a){let b=new Map;try{for(let c of await a.all("SELECT id, provider, name, email, isActive FROM providerConnections")||[])b.set(c.id,{id:c.id,provider:c.provider||"",name:c.name||c.email||c.id,email:c.email||"",isActive:1===c.isActive||!0===c.isActive})}catch{}try{for(let c of await a.all("SELECT id, type, name FROM providerNodes")||[]){let a=W(c.id);if(!a)continue;let d=W(c.name)||a;b.set(a,{id:a,provider:a,type:W(c.type),name:d,isProviderNode:!0})}}catch{}return b}function al(a,b=new Map){let c=W(a);if(!c)return"unknown";let d=b.get(c);if(d?.name)return d.name;let e=[...b.values()].filter(a=>a.provider===c&&a.name&&a.name!==c);return 1===e.length?e[0].name:c}function am(a){let b=Y(a.errors,0),c=Y(a.success,0),d=Y(a.pending,0),e=Y(a.requests,c+b),f=Y(a.promptTokens,0),g=Y(a.completionTokens,0),h=Y(a.totalTokens,f+g),i=c+b||e;return{...a,requests:e,success:c,errors:b,pending:d,totalTokens:h,errorRate:i?b/i:0,avgPromptTokens:e?f/e:0,avgCompletionTokens:e?g/e:0,avgTokens:e?h/e:0}}function an(a,b=null,c={}){let d=[],e=[];if(a.startIso&&(d.push("timestamp >= ?"),e.push($(a.startIso))),a.endIso&&(d.push("timestamp < ?"),e.push($(a.endIso))),a.provider&&"provider"!==c.skip&&(d.push("provider = ?"),e.push(a.provider)),a.model&&"model"!==c.skip&&(d.push("model = ?"),e.push(a.model)),a.connectionId&&"connectionId"!==c.skip&&(d.push("connectionId = ?"),e.push(a.connectionId)),a.status&&"status"!==c.skip&&(d.push("status = ?"),e.push(a.status)),a.endpoint&&"endpoint"!==c.skip&&(d.push("endpoint = ?"),e.push(a.endpoint)),b&&"apiKey"!==c.skip)if(b.noMatch)d.push("1 = 0");else{let a=[];if((b.keys||[]).length>0){let c=b.keys.map(()=>"?").join(", ");a.push(`(apiKey IN (${c}) OR apiKeyFingerprint IN (${c}) OR apiKeyId IN (${c}))`),e.push(...b.keys,...b.keys,...b.keys)}if(b.filter){a.push("(apiKeyFingerprint LIKE ? OR apiKeyName LIKE ? OR apiKeyOwner LIKE ? OR apiKeyId LIKE ?)");let c=`%${b.filter}%`;e.push(c,c,c,c)}b.includeLocal&&a.push("(apiKey IS NULL OR apiKey = '' OR apiKeyFingerprint = 'local-no-key')"),a.length&&d.push(`(${a.join(" OR ")})`)}let f=a.ownerScope;if(f?.enabled&&"apiKey"!==c.skip)if(f.noMatch)d.push("1 = 0");else{let a=[];if((f.identifiers||[]).length>0){let b=f.identifiers.map(()=>"?").join(", ");a.push(`(apiKey IN (${b}) OR apiKeyFingerprint IN (${b}) OR apiKeyId IN (${b}))`),e.push(...f.identifiers,...f.identifiers,...f.identifiers)}if((f.owners||[]).length>0){let b=f.owners.map(()=>"?").join(", ");a.push(`lower(COALESCE(apiKeyOwner, '')) IN (${b})`),e.push(...f.owners)}d.push(a.length?`(${a.join(" OR ")})`:"1 = 0")}if(a.clientIp&&"clientIp"!==c.skip&&(d.push("clientIpNormalized LIKE ?"),e.push(`%${a.clientIp}%`)),a.sourceTool&&"sourceTool"!==c.skip){d.push("(sourceTool LIKE ? OR sourceToolLabel LIKE ? OR sourceHost LIKE ?)");let b=`%${a.sourceTool}%`;e.push(b,b,b)}return a.sessionId&&"sessionId"!==c.skip&&(d.push("sessionId = ?"),e.push(a.sessionId)),{clause:d.length?`WHERE ${d.join(" AND ")}`:"",params:e}}function ao(a,b){return Math.floor(a/b)*b}async function ap(a,b,c){let d=an(b,c);return await a.get(`SELECT MIN(timestamp) AS minTs, MAX(timestamp) AS maxTs FROM usageHistory ${d.clause}`,d.params)||{}}async function aq(a,b,c){let d=an(b,c),e=await a.get(`SELECT
|
|
49
49
|
${V},
|
|
50
50
|
COUNT(DISTINCT COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''))) AS activeApiKeys,
|
|
51
51
|
COUNT(DISTINCT NULLIF(provider, '')) AS activeProviders,
|
|
52
52
|
COUNT(DISTINCT NULLIF(model, '')) AS activeModels,
|
|
53
53
|
COUNT(DISTINCT NULLIF(endpoint, '')) AS activeEndpoints
|
|
54
54
|
FROM usageHistory
|
|
55
|
-
${d.clause}`,d.params)||{},f=function(a={}){return
|
|
55
|
+
${d.clause}`,d.params)||{},f=function(a={}){return am({requests:Y(a.requests,0),success:Y(a.success,0),errors:Y(a.errors,0),pending:Y(a.pending,0),promptTokens:Y(a.promptTokens,0),completionTokens:Y(a.completionTokens,0),totalTokens:Y(a.totalTokens,0),cachedTokens:Y(a.cachedTokens,0),reasoningTokens:Y(a.reasoningTokens,0),cost:Y(a.cost,0),lastSeen:a.lastSeen||""})}(e),g=b.start&&b.end?Math.max(1,(b.end.getTime()-b.start.getTime())/6e4):1;return{...f,activeApiKeys:Y(e.activeApiKeys,0),activeProviders:Y(e.activeProviders,0),activeModels:Y(e.activeModels,0),activeEndpoints:Y(e.activeEndpoints,0),requestsPerMinute:f.requests/g,tokensPerMinute:f.totalTokens/g,inputOutputRatio:f.completionTokens?f.promptTokens/f.completionTokens:f.promptTokens?null:0}}function ar(a,b={}){return am({key:W(a.key)||"unknown",label:W(a.label||a.key)||"unknown",requests:Y(a.requests,0),success:Y(a.success,0),errors:Y(a.errors,0),pending:Y(a.pending,0),promptTokens:Y(a.promptTokens,0),completionTokens:Y(a.completionTokens,0),totalTokens:Y(a.totalTokens,0),cachedTokens:0,reasoningTokens:0,cost:Y(a.cost,0),lastSeen:a.lastSeen||"",...b})}async function as(a,b,c,d,e,f=[],g=50,h="requests DESC, totalTokens DESC"){let i=an(b,c);return await a.all(`SELECT
|
|
56
56
|
${d},
|
|
57
57
|
${V}
|
|
58
58
|
FROM usageHistory
|
|
59
59
|
${i.clause}
|
|
60
60
|
GROUP BY ${e}
|
|
61
61
|
ORDER BY ${h}
|
|
62
|
-
LIMIT ?`,[...f,...i.params,g])||[]}async function
|
|
62
|
+
LIMIT ?`,[...f,...i.params,g])||[]}async function at(a,b,c,d,e=new Map){let f=an(b,c),g=f.clause?`${f.clause} AND ${U}`:`WHERE ${U}`,h=`COALESCE(NULLIF(${d}, ''), 'unknown')`,i=await a.all(`SELECT
|
|
63
63
|
COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key') AS apiKeyGroupKey,
|
|
64
64
|
${h} AS itemKey,
|
|
65
65
|
COUNT(*) AS requests,
|
|
@@ -68,17 +68,17 @@
|
|
|
68
68
|
FROM usageHistory
|
|
69
69
|
${g}
|
|
70
70
|
GROUP BY COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key'), ${h}
|
|
71
|
-
ORDER BY apiKeyGroupKey ASC, requests DESC, totalTokens DESC`,f.params)||[],j=new Map;for(let a of i){let b=W(a.itemKey)||"unknown",c="provider"===d?
|
|
71
|
+
ORDER BY apiKeyGroupKey ASC, requests DESC, totalTokens DESC`,f.params)||[],j=new Map;for(let a of i){let b=W(a.itemKey)||"unknown",c="provider"===d?al(b,e):b;!function(a,b,c,d=3){if(!b||!c?.key)return;let e=a.get(b)||[];e.push(c),e.sort((a,b)=>b.requests-a.requests||b.totalTokens-a.totalTokens||String(a.label).localeCompare(String(b.label))),a.set(b,e.slice(0,d))}(j,a.apiKeyGroupKey,{key:b,label:c,requests:Y(a.requests,0),totalTokens:Y(a.totalTokens,0),lastSeen:a.lastSeen||""})}return j}async function au(a,b,c,d,e){let f=await as(a,b,e,"COALESCE(NULLIF(provider, ''), 'unknown') AS key, COALESCE(NULLIF(provider, ''), 'unknown') AS label","COALESCE(NULLIF(provider, ''), 'unknown')"),g=await as(a,b,e,`
|
|
72
72
|
COALESCE(NULLIF(provider, ''), 'unknown') || '|' || COALESCE(NULLIF(model, ''), 'unknown') AS key,
|
|
73
73
|
COALESCE(NULLIF(provider, ''), 'unknown') AS provider,
|
|
74
74
|
COALESCE(NULLIF(model, ''), 'unknown') AS model,
|
|
75
75
|
COALESCE(NULLIF(model, ''), 'unknown') || ' (' || COALESCE(NULLIF(provider, ''), 'unknown') || ')' AS label
|
|
76
|
-
`,"COALESCE(NULLIF(provider, ''), 'unknown'), COALESCE(NULLIF(model, ''), 'unknown')"),h=await
|
|
76
|
+
`,"COALESCE(NULLIF(provider, ''), 'unknown'), COALESCE(NULLIF(model, ''), 'unknown')"),h=await as(a,b,e,`
|
|
77
77
|
COALESCE(NULLIF(connectionId, ''), 'unknown') AS key,
|
|
78
78
|
COALESCE(NULLIF(connectionId, ''), 'unknown') AS connectionId,
|
|
79
79
|
COALESCE(NULLIF(provider, ''), 'unknown') AS provider,
|
|
80
80
|
COALESCE(NULLIF(connectionId, ''), 'unknown') AS label
|
|
81
|
-
`,"COALESCE(NULLIF(connectionId, ''), 'unknown')"),i=await
|
|
81
|
+
`,"COALESCE(NULLIF(connectionId, ''), 'unknown')"),i=await as(a,b,e,"COALESCE(NULLIF(endpoint, ''), 'unknown') AS key, COALESCE(NULLIF(endpoint, ''), 'unknown') AS label","COALESCE(NULLIF(endpoint, ''), 'unknown')"),j=await as(a,b,e,"COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key') AS key, COALESCE(NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key') AS rawApiKey, COALESCE(NULLIF(apiKeyName, ''), '') AS apiKeyName, COALESCE(NULLIF(apiKeyOwner, ''), '') AS apiKeyOwner, COALESCE(NULLIF(apiKeyId, ''), '') AS apiKeyId","COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key')"),k=await at(a,b,e,"model",d),l=await at(a,b,e,"provider",d),m=await at(a,b,e,"endpoint",d),n=await as(a,b,e,"COALESCE(NULLIF(status, ''), 'ok') AS key, COALESCE(NULLIF(status, ''), 'ok') AS label","COALESCE(NULLIF(status, ''), 'ok')"),o=an(b,e),p=await a.all(`SELECT
|
|
82
82
|
COALESCE(NULLIF(status, ''), 'error') AS status,
|
|
83
83
|
COALESCE(NULLIF(provider, ''), 'unknown') AS provider,
|
|
84
84
|
COALESCE(NULLIF(model, ''), 'unknown') AS model,
|
|
@@ -90,24 +90,24 @@
|
|
|
90
90
|
${o.clause?`${o.clause} AND NOT ${S} AND NOT ${T}`:`WHERE NOT ${S} AND NOT ${T}`}
|
|
91
91
|
GROUP BY COALESCE(NULLIF(status, ''), 'error'), COALESCE(NULLIF(provider, ''), 'unknown'), COALESCE(NULLIF(model, ''), 'unknown'), COALESCE(NULLIF(endpoint, ''), 'unknown'), COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key')
|
|
92
92
|
ORDER BY errors DESC, requests DESC, lastSeen DESC
|
|
93
|
-
LIMIT ?`,[...o.params,100])||[],q=f.map(a=>
|
|
93
|
+
LIMIT ?`,[...o.params,100])||[],q=f.map(a=>ar(a,{label:al(a.key||a.label,d),provider:a.key||a.label||"unknown",topModels:[],topApiKeys:[]})),r=g.map(a=>ar(a,{provider:a.provider||"",providerLabel:al(a.provider,d),model:a.model||"",label:`${a.model||"unknown"} (${al(a.provider,d)})`,topApiKeys:[]})),s=h.map(a=>{let b=d.get(a.connectionId);return ar(a,{label:b?.name||a.connectionId||"unknown",provider:b?.provider||a.provider||"",providerLabel:al(b?.provider||a.provider,d),connectionId:a.connectionId||"",topModels:[]})}),t=i.map(a=>ar(a)),u=j.map(a=>{let b="local-no-key"===a.rawApiKey?"":a.rawApiKey,d=c.byKey.get(b)||c.byFingerprint.get(b)||c.all.find(b=>b.id===a.apiKeyId||b.id===a.key),e=d?.fingerprint||ai(b),f=a.apiKeyName||d?.name||(b?e:"Local / kh\xf4ng d\xf9ng API key");return ar(a,{key:a.apiKeyId||e,label:f,name:f,fingerprint:e,apiKeyId:a.apiKeyId||d?.id||"",ownerUser:a.apiKeyOwner||d?.ownerUser||"",createdByUser:d?.createdByUser||"",isActive:d?.isActive??null,topModels:k.get(a.key)||[],topProviders:l.get(a.key)||[],topEndpoints:m.get(a.key)||[]})});return{providers:q,models:r,providerAccounts:s,endpoints:t,apiKeys:u,statuses:n.map(a=>ar(a)),errors:p.map(a=>{let b="local-no-key"===a.rawApiKey?"":a.rawApiKey,e=c.byKey.get(b)||c.byFingerprint.get(b)||c.all.find(a=>a.id===b);return ar(a,{label:a.status||"error",status:a.status||"error",provider:a.provider||"unknown",providerLabel:al(a.provider,d),model:a.model||"unknown",endpoint:a.endpoint||"unknown",apiKey:e?.fingerprint||ai(b)})})}}async function av(a,b,c,d={}){let e=function(a,b,c){let d=a.start?a.start.getTime():NaN,e=a.end?a.end.getTime():Date.now();if(!Number.isFinite(d)){let a=b?new Date(b).getTime():NaN,f=c?new Date(c).getTime():NaN;Number.isFinite(a)&&(d=a),Number.isFinite(f)&&(e=f)}Number.isFinite(d)||(d=e-864e5);let f=Math.max(1,e-d);return f<=216e5?3e5:f<=1296e5?36e5:f<=6912e5?216e5:f<=648e7?864e5:6048e5}(b,d.minTs,d.maxTs),f=Math.max(60,Math.floor(e/1e3)),g=b.start?b.start.getTime():new Date(d.minTs||Date.now()-864e5).getTime(),h=b.end?b.end.getTime():new Date(d.maxTs||Date.now()).getTime();Number.isFinite(g)||(g=Date.now()-864e5),Number.isFinite(h)||(h=Date.now());let i=Math.floor(((h=Math.max(g=ao(g,e),h))-g)/e)+1,j=f*(i>240?Math.ceil(i/240):1),k=1e3*j,l=an(b,c),m=await a.all(`SELECT
|
|
94
94
|
((CAST(strftime('%s', timestamp) AS INTEGER) / ?) * ?) AS bucketSec,
|
|
95
95
|
${V}
|
|
96
96
|
FROM usageHistory
|
|
97
97
|
${l.clause}
|
|
98
98
|
GROUP BY bucketSec
|
|
99
99
|
HAVING bucketSec IS NOT NULL
|
|
100
|
-
ORDER BY bucketSec ASC`,[j,j,...l.params])||[],n=new Map;for(let a=
|
|
100
|
+
ORDER BY bucketSec ASC`,[j,j,...l.params])||[],n=new Map;for(let a=ao(g,k);a<=h;a+=k)n.set(a,{ts:a,label:new Date(a).toISOString(),requests:0,success:0,errors:0,pending:0,promptTokens:0,completionTokens:0,totalTokens:0,cost:0});for(let a of m){let b=1e3*Y(a.bucketSec,0);b&&n.set(b,{ts:b,label:new Date(b).toISOString(),requests:Y(a.requests,0),success:Y(a.success,0),errors:Y(a.errors,0),pending:Y(a.pending,0),promptTokens:Y(a.promptTokens,0),completionTokens:Y(a.completionTokens,0),totalTokens:Y(a.totalTokens,0),cost:Y(a.cost,0)})}return[...n.values()].sort((a,b)=>a.ts-b.ts)}function aw(a,b){if(!a.length)return null;let c=[...a].sort((a,b)=>a-b),d=Math.min(c.length-1,Math.max(0,Math.ceil(b/100*c.length)-1));return c[d]}async function ax(a,b,c){try{let d=an(b,c),e=d.clause?`${d.clause} AND`:"WHERE",f=[...d.params],g=await a.get(`SELECT COUNT(*) AS samples, AVG(latencyMs) AS avgMs
|
|
101
101
|
FROM usageHistory
|
|
102
102
|
${e} latencyMs IS NOT NULL AND latencyMs > 0`,f)||{},h=Y(g.samples,0),i=async b=>{if(!h)return null;let c=Math.max(0,Math.min(h-1,Math.ceil(b/100*h)-1)),d=await a.get(`SELECT latencyMs
|
|
103
103
|
FROM usageHistory
|
|
104
104
|
${e} latencyMs IS NOT NULL AND latencyMs > 0
|
|
105
105
|
ORDER BY latencyMs ASC
|
|
106
|
-
LIMIT 1 OFFSET ?`,[...f,c]);return d?Y(d.latencyMs,null):null};if(h>0)return{samples:h,avgMs:Y(g.avgMs,null),p50Ms:await i(50),p95Ms:await i(95),p99Ms:await i(99)}}catch{}let d=[];try{let c,e,f=(c=[],e=[],b.startIso&&(c.push("timestamp >= ?"),e.push(b.startIso)),b.endIso&&(c.push("timestamp
|
|
106
|
+
LIMIT 1 OFFSET ?`,[...f,c]);return d?Y(d.latencyMs,null):null};if(h>0)return{samples:h,avgMs:Y(g.avgMs,null),p50Ms:await i(50),p95Ms:await i(95),p99Ms:await i(99)}}catch{}let d=[];try{let c,e,f=(c=[],e=[],b.startIso&&(c.push("timestamp >= ?"),e.push($(b.startIso))),b.endIso&&(c.push("timestamp < ?"),e.push($(b.endIso))),b.provider&&(c.push("provider = ?"),e.push(b.provider)),b.model&&(c.push("model = ?"),e.push(b.model)),b.connectionId&&(c.push("connectionId = ?"),e.push(b.connectionId)),b.status&&(c.push("status = ?"),e.push(b.status)),{clause:c.length?`WHERE ${c.join(" AND ")}`:"",params:e});d=await a.all(`SELECT data FROM requestDetails ${f.clause} ORDER BY timestamp DESC LIMIT ?`,[...f.params,3e3])||[]}catch{d=[]}let e=[];for(let a of d){let b=function(a){let b=a?.latency||{};for(let c of[b.totalMs,b.total_ms,b.durationMs,b.duration_ms,b.elapsedMs,b.elapsed_ms,b.responseMs,b.response_ms,b.ms,b.total,a?.durationMs,a?.latencyMs]){let a=Number(c);if(Number.isFinite(a)&&a>=0)return a}return null}((0,x.q)(a.data,{})||{});Number.isFinite(b)&&e.push(b)}let f=e.reduce((a,b)=>a+b,0);return{samples:e.length,avgMs:e.length?f/e.length:null,p50Ms:aw(e,50),p95Ms:aw(e,95),p99Ms:aw(e,99)}}function ay(a,b,c={}){let d=an(a,b,c),e=[U,S,"(COALESCE(promptTokens, 0) + COALESCE(completionTokens, 0)) > 0"];c.latencyOnly&&e.push("latencyMs IS NOT NULL AND latencyMs > 0"),c.ttftOnly&&e.push("ttftMs IS NOT NULL AND ttftMs > 0");let f=e.join(" AND ");return{clause:d.clause?`${d.clause} AND ${f}`:`WHERE ${f}`,params:d.params}}async function az(a,b,c){try{let d=await a.get(`SELECT COUNT(*) AS samples FROM usageHistory ${b.clause} AND ${c}`,b.params)||{};return Y(d.samples,0)}catch{return 0}}async function aA(a,b,c,d,e,f){if(!f||!new Set(["latencyMs","ttftMs","promptTokens","completionTokens","totalTokens"]).has(c))return null;let g=Math.max(0,Math.min(f-1,Math.ceil(e/100*f)-1));try{let e=await a.get(`SELECT ${c} AS value
|
|
107
107
|
FROM usageHistory
|
|
108
108
|
${b.clause} AND ${d}
|
|
109
109
|
ORDER BY ${c} ASC
|
|
110
|
-
LIMIT 1 OFFSET ?`,[...b.params,g]);return e?Y(e.value,null):null}catch{return null}}function
|
|
110
|
+
LIMIT 1 OFFSET ?`,[...b.params,g]);return e?Y(e.value,null):null}catch{return null}}function aB({samples:a=0,p95LatencyMs:b=0,p95TtftMs:c=0,slowRequestRate:d=0,errorRate:e=0}={}){if(!a)return{level:"none",label:"Chưa c\xf3 mẫu",tone:"slate",score:null};if(a<10)return{level:"low_sample",label:"\xcdt mẫu",tone:"amber",score:null};let f=100;return(b>0&&(b>9e4?f-=35:b>45e3?f-=20:b>15e3&&(f-=8)),c>0&&(c>45e3?f-=30:c>2e4?f-=16:c>8e3&&(f-=6)),f-=Math.min(30,Math.round(100*d)),f-=Math.min(25,Math.round(100*e)),(f=Math.max(0,Math.min(100,f)))>=85)?{level:"fast",label:"Nhanh",tone:"green",score:f}:f>=70?{level:"ok",label:"Ổn",tone:"blue",score:f}:f>=50?{level:"slow",label:"Chậm",tone:"amber",score:f}:{level:"very_slow",label:"Rất chậm",tone:"red",score:f}}async function aC(a,b,c,d={}){let e=ay(b,c,{latencyOnly:!0}),f={};try{f=await a.get(`SELECT
|
|
111
111
|
COUNT(*) AS samples,
|
|
112
112
|
AVG(latencyMs) AS avgLatencyMs,
|
|
113
113
|
MIN(latencyMs) AS minLatencyMs,
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
SUM(CASE WHEN promptTokens >= ? THEN 1 ELSE 0 END) AS hugeInputRequests,
|
|
135
135
|
SUM(CASE WHEN promptTokens >= ? THEN 1 ELSE 0 END) AS extremeInputRequests
|
|
136
136
|
FROM usageHistory
|
|
137
|
-
${e.clause}`,[45e3,9e4,2e4,3e4,5e4,7e4,...e.params])||{}}catch{f={}}let g=Y(f.samples,0),h=await
|
|
137
|
+
${e.clause}`,[45e3,9e4,2e4,3e4,5e4,7e4,...e.params])||{}}catch{f={}}let g=Y(f.samples,0),h=await az(a,e,"ttftMs IS NOT NULL AND ttftMs > 0"),i=await az(a,e,"promptTokens IS NOT NULL AND promptTokens > 0"),j=await az(a,e,"completionTokens IS NOT NULL AND completionTokens > 0"),k=await aA(a,e,"latencyMs","latencyMs IS NOT NULL AND latencyMs > 0",50,g),l=await aA(a,e,"latencyMs","latencyMs IS NOT NULL AND latencyMs > 0",95,g),m=await aA(a,e,"latencyMs","latencyMs IS NOT NULL AND latencyMs > 0",99,g),n=await aA(a,e,"ttftMs","ttftMs IS NOT NULL AND ttftMs > 0",50,h),o=await aA(a,e,"ttftMs","ttftMs IS NOT NULL AND ttftMs > 0",95,h),p=await aA(a,e,"ttftMs","ttftMs IS NOT NULL AND ttftMs > 0",99,h),q=await aA(a,e,"promptTokens","promptTokens IS NOT NULL AND promptTokens > 0",50,i),r=await aA(a,e,"promptTokens","promptTokens IS NOT NULL AND promptTokens > 0",95,i),s=await aA(a,e,"promptTokens","promptTokens IS NOT NULL AND promptTokens > 0",99,i),t=await aA(a,e,"completionTokens","completionTokens IS NOT NULL AND completionTokens > 0",95,j),u=Y(f.slowRequests,0),v=Y(f.verySlowRequests,0),w=Y(f.slowTtftRequests,0),x=Y(f.longInputRequests,0),y=Y(f.hugeInputRequests,0),z=Y(f.extremeInputRequests,0),A=Y(f.totalPromptTokens,0),B=Y(f.totalLatencyMs,0),C=Y(f.totalTtftMs,0),D=Y(f.promptTokensWithTtft,0),E=Y(f.completionTokensWithLatency,0),F=Y(f.latencyMsWithOutput,0),G=Y(f.completionTokensAfterTtft,0),H=Y(f.decodeMs,0),I=g?u/g:0,J=g?v/g:0,K=h?w/h:0,L=g?x/g:0,M=g?y/g:0,N=g?z/g:0,O=aB({samples:g,p95LatencyMs:Y(l,0),p95TtftMs:Y(o,0),slowRequestRate:I,errorRate:Y(d.errorRate,0)});return{samples:g,ttftSamples:h,inputSamples:i,outputSamples:j,label:O.label,level:O.level,tone:O.tone,score:O.score,thresholds:{slowLatencyMs:45e3,verySlowLatencyMs:9e4,slowTtftMs:2e4,longInputTokens:3e4,hugeInputTokens:5e4,extremeInputTokens:7e4},avgLatencyMs:Y(f.avgLatencyMs,null),minLatencyMs:Y(f.minLatencyMs,null),maxLatencyMs:Y(f.maxLatencyMs,null),p50LatencyMs:k,p95LatencyMs:l,p99LatencyMs:m,avgTtftMs:Y(f.avgTtftMs,null),maxTtftMs:Y(f.maxTtftMs,null),p50TtftMs:n,p95TtftMs:o,p99TtftMs:p,avgPromptTokens:Y(f.avgPromptTokens,0),maxPromptTokens:Y(f.maxPromptTokens,0),p50PromptTokens:q,p95PromptTokens:r,p99PromptTokens:s,avgCompletionTokens:Y(f.avgCompletionTokens,0),maxCompletionTokens:Y(f.maxCompletionTokens,0),p95CompletionTokens:t,slowRequests:u,verySlowRequests:v,slowTtftRequests:w,longInputRequests:x,hugeInputRequests:y,extremeInputRequests:z,slowRequestRate:I,verySlowRequestRate:J,slowTtftRate:K,longInputRate:L,hugeInputRate:M,extremeInputRate:N,approxInputTokensPerSecond:C>0?D/(C/1e3):null,outputTokensPerSecond:F>0?E/(F/1e3):null,decodeTokensPerSecond:H>0?G/(H/1e3):null,latencyMsPer10kInputTokens:A>0?B/(A/1e4):null}}async function aD(a,b,c,d=new Map){let e=ay(b,c,{latencyOnly:!0});try{return(await a.all(`WITH base AS (
|
|
138
138
|
SELECT
|
|
139
139
|
COALESCE(NULLIF(provider, ''), 'unknown') AS provider,
|
|
140
140
|
COALESCE(NULLIF(model, ''), 'unknown') AS model,
|
|
@@ -182,38 +182,38 @@
|
|
|
182
182
|
FROM ranked
|
|
183
183
|
GROUP BY provider, model
|
|
184
184
|
ORDER BY samples DESC, p95LatencyMs DESC
|
|
185
|
-
LIMIT ?`,[...e.params,45e3,2e4,3e4,5e4,30])||[]).map(a=>{let b=Y(a.samples,0),c=b?Y(a.slowRequests,0)/b:0,e=b?Y(a.slowTtftRequests,0)/b:0,f=b?Y(a.longInputRequests,0)/b:0,g=b?Y(a.hugeInputRequests,0)/b:0,h=
|
|
185
|
+
LIMIT ?`,[...e.params,45e3,2e4,3e4,5e4,30])||[]).map(a=>{let b=Y(a.samples,0),c=b?Y(a.slowRequests,0)/b:0,e=b?Y(a.slowTtftRequests,0)/b:0,f=b?Y(a.longInputRequests,0)/b:0,g=b?Y(a.hugeInputRequests,0)/b:0,h=aB({samples:b,p95LatencyMs:Y(a.p95LatencyMs,0),p95TtftMs:Y(a.p95TtftMs,0),slowRequestRate:c});return{key:a.key,provider:a.provider,providerLabel:al(a.provider,d),model:a.model,label:`${a.model} (${al(a.provider,d)})`,samples:b,level:h.level,labelQuality:h.label,tone:h.tone,score:h.score,avgLatencyMs:Y(a.avgLatencyMs,null),p50LatencyMs:Y(a.p50LatencyMs,null),p95LatencyMs:Y(a.p95LatencyMs,null),maxLatencyMs:Y(a.maxLatencyMs,null),avgTtftMs:Y(a.avgTtftMs,null),p95TtftMs:Y(a.p95TtftMs,null),maxTtftMs:Y(a.maxTtftMs,null),avgPromptTokens:Y(a.avgPromptTokens,0),p95PromptTokens:Y(a.p95PromptTokensApprox,0),maxPromptTokens:Y(a.maxPromptTokens,0),avgCompletionTokens:Y(a.avgCompletionTokens,0),slowRequests:Y(a.slowRequests,0),slowRequestRate:c,slowTtftRate:e,longInputRate:f,hugeInputRate:g,outputTokensPerSecond:Y(a.totalLatencyMs,0)>0?Y(a.totalCompletionTokens,0)/(Y(a.totalLatencyMs,0)/1e3):null}})}catch(a){return console.error("[analytics] Failed to build model experience stats:",a?.message||a),[]}}async function aE(a,b,c,d,e){try{let f=ay(b,c,{latencyOnly:!0});return(await a.all(`SELECT id, timestamp, provider, model, connectionId, apiKey, apiKeyId, apiKeyFingerprint, apiKeyName, endpoint, clientIp, clientIpNormalized, sourceTool, sourceToolLabel, sessionId, latencyMs, ttftMs, statusCode, errorCode, errorType, promptTokens, completionTokens, cost, status, tokens
|
|
186
186
|
FROM usageHistory
|
|
187
187
|
${f.clause}
|
|
188
188
|
ORDER BY latencyMs DESC
|
|
189
|
-
LIMIT ?`,[...f.params,20])||[]).map(a=>
|
|
189
|
+
LIMIT ?`,[...f.params,20])||[]).map(a=>aF(a,d,e))}catch{return[]}}function aF(a,b,c){let d=function(a={}){let b=(0,x.q)(a.tokens,{})||{},c=Y(a.promptTokens,0)||Y(b.prompt_tokens,0)||Y(b.input_tokens,0),d=Y(a.completionTokens,0)||Y(b.completion_tokens,0)||Y(b.output_tokens,0);return{promptTokens:c,completionTokens:d,totalTokens:c+d,cachedTokens:Y(b.cached_tokens,0)||Y(b.cache_read_input_tokens,0)||Y(b.prompt_tokens_details?.cached_tokens,0),reasoningTokens:Y(b.reasoning_tokens,0)||Y(b.completion_tokens_details?.reasoning_tokens,0)||Y(b.output_tokens_details?.reasoning_tokens,0)}}(a),e=b.get(a.apiKey)||b.get(a.apiKeyFingerprint)||null,f=c.get(a.connectionId)||null;return{id:a.id,timestamp:a.timestamp,provider:a.provider||"",providerLabel:al(a.provider,c),model:a.model||"",connectionId:a.connectionId||"",accountName:f?.name||a.connectionId||"",apiKeyName:a.apiKeyName||e?.name||(a.apiKeyFingerprint||a.apiKey?ai(a.apiKeyFingerprint||a.apiKey):"Local"),apiKeyFingerprint:a.apiKeyFingerprint||e?.fingerprint||ai(a.apiKey),apiKeyId:a.apiKeyId||e?.id||"",clientIp:a.clientIpNormalized||a.clientIp||"",sourceTool:a.sourceTool||a.sourceToolLabel||"",sessionId:a.sessionId||"",latencyMs:Y(a.latencyMs,0),ttftMs:Y(a.ttftMs,0),statusCode:a.statusCode||null,errorCode:a.errorCode||"",errorType:a.errorType||"",endpoint:a.endpoint||"",status:a.status||"ok",promptTokens:d.promptTokens,completionTokens:d.completionTokens,totalTokens:d.totalTokens,cachedTokens:d.cachedTokens,reasoningTokens:d.reasoningTokens,cost:Y(a.cost,0)}}async function aG(a,b,c,d,e){let f=an(b,c);return(await a.all(`SELECT id, timestamp, provider, model, connectionId, apiKey, apiKeyId, apiKeyFingerprint, apiKeyName, endpoint, clientIp, clientIpNormalized, sourceTool, sourceToolLabel, sessionId, latencyMs, ttftMs, statusCode, errorCode, errorType, promptTokens, completionTokens, cost, status, tokens
|
|
190
190
|
FROM usageHistory
|
|
191
191
|
${f.clause}
|
|
192
192
|
ORDER BY timestamp DESC
|
|
193
|
-
LIMIT ?`,[...f.params,50])||[]).map(a=>
|
|
193
|
+
LIMIT ?`,[...f.params,50])||[]).map(a=>aF(a,d,e))}async function aH(a,b,c,d,e){let f=an(b,c);return(await a.all(`SELECT id, timestamp, provider, model, connectionId, apiKey, apiKeyId, apiKeyFingerprint, apiKeyName, endpoint, clientIp, clientIpNormalized, sourceTool, sourceToolLabel, sessionId, latencyMs, ttftMs, statusCode, errorCode, errorType, promptTokens, completionTokens, cost, status, tokens
|
|
194
194
|
FROM usageHistory
|
|
195
195
|
${f.clause}
|
|
196
196
|
ORDER BY (COALESCE(promptTokens, 0) + COALESCE(completionTokens, 0)) DESC, timestamp DESC
|
|
197
|
-
LIMIT ?`,[...f.params,20])||[]).map(a=>
|
|
197
|
+
LIMIT ?`,[...f.params,20])||[]).map(a=>aF(a,d,e))}function aI(a,b,c=b){let d=function(a,b=a){let c=W(a);return c?{value:c,label:W(b)||c}:null}(b,c);return d&&(a.some(a=>a.value===d.value)||a.unshift(d)),a}function aJ(a){return{...a,provider:"",model:"",connectionId:"",status:"",endpoint:"",apiKey:""}}async function aK(a,b,c,d=500){let e=an(aJ(b),null),f=e.clause?`${e.clause} AND`:"WHERE";return(await a.all(`SELECT DISTINCT ${c} AS value
|
|
198
198
|
FROM usageHistory
|
|
199
199
|
${f} ${c} IS NOT NULL AND ${c} <> ''
|
|
200
200
|
ORDER BY ${c} ASC
|
|
201
|
-
LIMIT ?`,[...e.params,d])||[]).map(a=>W(a.value)).filter(Boolean)}async function
|
|
201
|
+
LIMIT ?`,[...e.params,d])||[]).map(a=>W(a.value)).filter(Boolean)}async function aL(a,b){let c=an(aJ(b),null),d=c.clause?`${c.clause} AND`:"WHERE";try{let b=await a.get(`SELECT 1 AS hasLocal
|
|
202
202
|
FROM usageHistory
|
|
203
203
|
${d} (apiKey IS NULL OR apiKey = '')
|
|
204
|
-
LIMIT 1`,c.params);return!!b?.hasLocal}catch{return!1}}async function
|
|
205
|
-
${
|
|
204
|
+
LIMIT 1`,c.params);return!!b?.hasLocal}catch{return!1}}async function aM(a,b,c,d){let e=await aK(a,b,"provider",500),f=await aK(a,b,"model",1e3),g=await aK(a,b,"endpoint",500),h=await aK(a,b,"status",200),i=(await aK(a,b,"connectionId",1e3)).map(a=>{let b=c.get(a),d=al(b?.provider||a,c),e=b?.name?`${b.name}${d&&d!==b.name?` \xb7 ${d}`:""}`:d||a;return{value:a,label:e}}),j=[];for(let c of(await aL(a,b)&&j.push({value:"local-no-key",label:"Local / kh\xf4ng d\xf9ng API key"}),(function(a={},b={}){let c=a.all||[],d=b.ownerScope;if(!d?.enabled)return c;if(d.noMatch)return[];let e=new Set((d.identifiers||[]).map(a=>W(a)).filter(Boolean)),f=new Set((d.ids||[]).map(a=>W(a)).filter(Boolean)),g=new Set((d.fingerprints||[]).map(a=>W(a)).filter(Boolean)),h=new Set((d.owners||[]).map(a=>X(a)).filter(Boolean));return c.filter(a=>!!a&&(a.key&&e.has(a.key)||a.id&&(e.has(a.id)||f.has(a.id))||a.fingerprint&&(e.has(a.fingerprint)||g.has(a.fingerprint))||a.ownerUser&&h.has(X(a.ownerUser))))})(d,b).slice(0,500)))j.push({value:c.fingerprint,label:`${c.name||c.fingerprint}${c.ownerUser?` \xb7 ${c.ownerUser}`:""}`});aI(i,b.connectionId,b.connectionId),aI(j,b.apiKey,b.apiKey);let k=e.map(a=>({value:a,label:al(a,c)})),l=f.map(a=>({value:a,label:a})),m=g.map(a=>({value:a,label:a})),n=h.map(a=>({value:a,label:a}));return aI(k,b.provider,b.provider),aI(l,b.model,b.model),aI(m,b.endpoint,b.endpoint),aI(n,b.status,b.status),{providers:k,models:l.map(a=>a.value),endpoints:m.map(a=>a.value),statuses:n.map(a=>a.value),connections:i,apiKeys:j,clientIps:[],sourceTools:[]}}async function aN(a,b,c,d,e,f,g=new Map){let h=await aM(a,b,g,e);return h.clientIps=(d.topClientIps||[]).map(a=>a.key).filter(Boolean),h.sourceTools=(d.topSourceTools||[]).map(a=>a.key).filter(Boolean),h}let aO="COALESCE(NULLIF(apiKeyOwner, ''), NULLIF(apiKeyName, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKeyId, ''), NULLIF(clientIpNormalized, ''), 'local-no-key')",aP="COALESCE(NULLIF(apiKeyOwner, ''), NULLIF(apiKeyName, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(clientIpNormalized, ''), 'Local / kh\xf4ng API key')",aQ="COALESCE(NULLIF(clientIpNormalized, ''), NULLIF(clientIp, ''), 'unknown')";async function aR(a,b,c,d,e=new Map){if(!new Set(["model","provider","endpoint","clientIpNormalized","sourceTool"]).has(d))return new Map;let f=ay(b,c),g=`COALESCE(NULLIF(${d}, ''), 'unknown')`;try{let b=await a.all(`SELECT
|
|
205
|
+
${aO} AS clientKey,
|
|
206
206
|
${g} AS itemKey,
|
|
207
207
|
COUNT(*) AS requests,
|
|
208
208
|
COALESCE(SUM(COALESCE(promptTokens, 0) + COALESCE(completionTokens, 0)), 0) AS totalTokens,
|
|
209
209
|
MAX(timestamp) AS lastSeen
|
|
210
210
|
FROM usageHistory
|
|
211
211
|
${f.clause}
|
|
212
|
-
GROUP BY ${
|
|
213
|
-
ORDER BY clientKey ASC, requests DESC, totalTokens DESC`,f.params)||[],c=new Map;for(let a of b){let b=W(a.itemKey)||"unknown",f="provider"===d?
|
|
212
|
+
GROUP BY ${aO}, ${g}
|
|
213
|
+
ORDER BY clientKey ASC, requests DESC, totalTokens DESC`,f.params)||[],c=new Map;for(let a of b){let b=W(a.itemKey)||"unknown",f="provider"===d?al(b,e):b;!function(a,b,c,d=3){if(!b||!c?.key)return;let e=a.get(b)||[];e.push(c),e.sort((a,b)=>b.requests-a.requests||b.totalTokens-a.totalTokens||String(a.label).localeCompare(String(b.label))),a.set(b,e.slice(0,d))}(c,a.clientKey,{key:b,label:f,requests:Y(a.requests,0),totalTokens:Y(a.totalTokens,0),lastSeen:a.lastSeen||""})}return c}catch(a){return console.error("[analytics] Failed to build client top usage map:",a?.message||a),new Map}}function aS(a={},b={}){let c=Y(a.requests,0),d=Y(a.success,c),e=Y(a.errors,0),f=Y(a.promptTokens,0),g=Y(a.completionTokens,0),h=Y(a.totalTokens,f+g),i=Y(a.p95PromptTokens,0),j=Y(a.p95LatencyMs,null),k=c?e/c:0,l=c?Y(a.longInputRequests,0)/c:0,m=c?Y(a.hugeInputRequests,0)/c:0,n=c?Y(a.extremeInputRequests,0)/c:0,o=c?Y(a.slowRequests,0)/c:0,p=function({requests:a=0,p95PromptTokens:b=0,p95LatencyMs:c=0,longInputRate:d=0,errorRate:e=0}={}){return a?b>=7e4||d>=.5||c>=9e4?{level:"critical",label:"Rất nặng",tone:"red"}:b>=5e4||d>=.3||c>=45e3||e>=.2?{level:"high",label:"Nặng",tone:"amber"}:b>=3e4||d>=.1||e>=.05?{level:"medium",label:"Cần theo d\xf5i",tone:"blue"}:{level:"normal",label:"Ổn",tone:"green"}:{level:"none",label:"Chưa c\xf3 mẫu",tone:"slate"}}({requests:c,p95PromptTokens:i,p95LatencyMs:Y(j,0),longInputRate:l,errorRate:k});return{key:W(a.clientKey)||"unknown",label:W(a.clientLabel||a.clientKey)||"unknown",ownerUser:W(a.ownerUser),apiKeyName:W(a.apiKeyName),apiKeyFingerprint:W(a.apiKeyFingerprint),primaryClientIp:W(a.primaryClientIp),primarySourceTool:W(a.primarySourceTool),apiKeyCount:Y(a.apiKeyCount,0),sourceIpCount:Y(a.sourceIpCount,0),sourceToolCount:Y(a.sourceToolCount,0),sessionCount:Y(a.sessionCount,0),requests:c,success:d,errors:e,errorRate:k,promptTokens:f,completionTokens:g,totalTokens:h,cost:Y(a.cost,0),avgPromptTokens:c?f/c:0,avgCompletionTokens:c?g/c:0,avgTokens:c?h/c:0,p50PromptTokens:Y(a.p50PromptTokens,0),p95PromptTokens:i,maxPromptTokens:Y(a.maxPromptTokens,0),avgLatencyMs:Y(a.avgLatencyMs,null),p95LatencyMs:j,maxLatencyMs:Y(a.maxLatencyMs,null),avgTtftMs:Y(a.avgTtftMs,null),p95TtftMs:Y(a.p95TtftMs,null),longInputRequests:Y(a.longInputRequests,0),hugeInputRequests:Y(a.hugeInputRequests,0),extremeInputRequests:Y(a.extremeInputRequests,0),slowRequests:Y(a.slowRequests,0),slowTtftRequests:Y(a.slowTtftRequests,0),longInputRate:l,hugeInputRate:m,extremeInputRate:n,slowRequestRate:o,slowTtftRate:c?Y(a.slowTtftRequests,0)/c:0,outputTokensPerSecond:Y(a.totalLatencyMs,0)>0?g/(Y(a.totalLatencyMs,0)/1e3):null,level:p.level,pressureLabel:p.label,tone:p.tone,lastSeen:a.lastSeen||"",...b}}async function aT(a,b,c,{dimension:d="apiKey",order:e="tokens",limit:f=25}={}){let g=ay(b,c),h="sourceIp"===d;try{return(await a.all(`WITH base AS (
|
|
214
214
|
SELECT
|
|
215
|
-
${h?
|
|
216
|
-
${h?
|
|
215
|
+
${h?aQ:"COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key')"} AS groupKey,
|
|
216
|
+
${h?aQ:"COALESCE(NULLIF(apiKeyName, ''), NULLIF(apiKeyOwner, ''), NULLIF(apiKeyFingerprint, ''), 'Local / kh\xf4ng API key')"} AS groupLabel,
|
|
217
217
|
COALESCE(NULLIF(apiKeyId, ''), NULLIF(apiKeyFingerprint, ''), NULLIF(apiKey, ''), 'local-no-key') AS apiKeyStable,
|
|
218
218
|
COALESCE(NULLIF(apiKeyName, ''), '') AS apiKeyName,
|
|
219
219
|
COALESCE(NULLIF(apiKeyOwner, ''), '') AS apiKeyOwner,
|
|
@@ -270,10 +270,10 @@
|
|
|
270
270
|
GROUP BY groupKey
|
|
271
271
|
HAVING groupKey <> 'unknown'
|
|
272
272
|
ORDER BY ${"heavy"===e?"heavyRequests DESC, maxPromptTokens DESC, promptTokens DESC, totalTokens DESC, requests DESC":"totalTokens DESC, promptTokens DESC, requests DESC, maxPromptTokens DESC"}
|
|
273
|
-
LIMIT ?`,[...g.params,3e4,5e4,7e4,3e4,3e4,f])||[]).map(a=>(function(a={},b={}){let c=Y(a.requests,0),d=Y(a.promptTokens,0),e=Y(a.completionTokens,0),f=Y(a.totalTokens,d+e);return{key:W(a.key||a.groupKey)||"unknown",label:W(a.label||a.groupLabel||a.key||a.groupKey)||"unknown",requests:c,promptTokens:d,completionTokens:e,totalTokens:f,cost:Y(a.cost,0),avgPromptTokens:c?d/c:0,avgCompletionTokens:c?e/c:0,avgTokens:c?f/c:0,p95PromptTokens:Y(a.p95PromptTokens,0),maxPromptTokens:Y(a.maxPromptTokens,0),p95TotalTokens:Y(a.p95TotalTokens,0),maxTotalTokens:Y(a.maxTotalTokens,0),longInputRequests:Y(a.longInputRequests,0),hugeInputRequests:Y(a.hugeInputRequests,0),extremeInputRequests:Y(a.extremeInputRequests,0),heavyRequests:Y(a.heavyRequests,0),longInputRate:c?Y(a.longInputRequests,0)/c:0,hugeInputRate:c?Y(a.hugeInputRequests,0)/c:0,extremeInputRate:c?Y(a.extremeInputRequests,0)/c:0,heavyRequestRate:c?Y(a.heavyRequests,0)/c:0,apiKeyCount:Y(a.apiKeyCount,0),sourceIpCount:Y(a.sourceIpCount,0),sourceToolCount:Y(a.sourceToolCount,0),modelCount:Y(a.modelCount,0),providerCount:Y(a.providerCount,0),lastSeen:a.lastSeen||"",...b}})(a,{apiKeyName:W(a.apiKeyName),apiKeyOwner:W(a.apiKeyOwner),apiKeyFingerprint:W(a.apiKeyFingerprint),primaryClientIp:W(a.primaryClientIp),primarySourceTool:W(a.primarySourceTool)}))}catch(a){return console.error(`[analytics] Failed to build top ${d} ${e} consumers:`,a?.message||a),[]}}async function
|
|
273
|
+
LIMIT ?`,[...g.params,3e4,5e4,7e4,3e4,3e4,f])||[]).map(a=>(function(a={},b={}){let c=Y(a.requests,0),d=Y(a.promptTokens,0),e=Y(a.completionTokens,0),f=Y(a.totalTokens,d+e);return{key:W(a.key||a.groupKey)||"unknown",label:W(a.label||a.groupLabel||a.key||a.groupKey)||"unknown",requests:c,promptTokens:d,completionTokens:e,totalTokens:f,cost:Y(a.cost,0),avgPromptTokens:c?d/c:0,avgCompletionTokens:c?e/c:0,avgTokens:c?f/c:0,p95PromptTokens:Y(a.p95PromptTokens,0),maxPromptTokens:Y(a.maxPromptTokens,0),p95TotalTokens:Y(a.p95TotalTokens,0),maxTotalTokens:Y(a.maxTotalTokens,0),longInputRequests:Y(a.longInputRequests,0),hugeInputRequests:Y(a.hugeInputRequests,0),extremeInputRequests:Y(a.extremeInputRequests,0),heavyRequests:Y(a.heavyRequests,0),longInputRate:c?Y(a.longInputRequests,0)/c:0,hugeInputRate:c?Y(a.hugeInputRequests,0)/c:0,extremeInputRate:c?Y(a.extremeInputRequests,0)/c:0,heavyRequestRate:c?Y(a.heavyRequests,0)/c:0,apiKeyCount:Y(a.apiKeyCount,0),sourceIpCount:Y(a.sourceIpCount,0),sourceToolCount:Y(a.sourceToolCount,0),modelCount:Y(a.modelCount,0),providerCount:Y(a.providerCount,0),lastSeen:a.lastSeen||"",...b}})(a,{apiKeyName:W(a.apiKeyName),apiKeyOwner:W(a.apiKeyOwner),apiKeyFingerprint:W(a.apiKeyFingerprint),primaryClientIp:W(a.primaryClientIp),primarySourceTool:W(a.primarySourceTool)}))}catch(a){return console.error(`[analytics] Failed to build top ${d} ${e} consumers:`,a?.message||a),[]}}async function aU(a,b,c){return await aT(a,b,c,{dimension:"apiKey",order:"tokens",limit:25})}async function aV(a,b,c){return await aT(a,b,c,{dimension:"sourceIp",order:"tokens",limit:25})}async function aW(a,b,c){return await aT(a,b,c,{dimension:"sourceIp",order:"heavy",limit:25})}async function aX(a,b,c,d=new Map){let e=ay(b,c),f=await aR(a,b,c,"model",d),g=await aR(a,b,c,"provider",d),h=await aR(a,b,c,"endpoint",d),i=await aR(a,b,c,"clientIpNormalized",d),j=await aR(a,b,c,"sourceTool",d);try{return(await a.all(`WITH base AS (
|
|
274
274
|
SELECT
|
|
275
|
-
${
|
|
276
|
-
${
|
|
275
|
+
${aO} AS clientKey,
|
|
276
|
+
${aP} AS clientLabel,
|
|
277
277
|
COALESCE(NULLIF(apiKeyOwner, ''), '') AS ownerUser,
|
|
278
278
|
COALESCE(NULLIF(apiKeyName, ''), '') AS apiKeyName,
|
|
279
279
|
COALESCE(NULLIF(apiKeyFingerprint, ''), '') AS apiKeyFingerprint,
|
|
@@ -337,9 +337,9 @@
|
|
|
337
337
|
FROM ranked
|
|
338
338
|
GROUP BY clientKey
|
|
339
339
|
ORDER BY promptTokens DESC, totalTokens DESC, requests DESC
|
|
340
|
-
LIMIT ?`,[...e.params,3e4,5e4,7e4,45e3,2e4,25])||[]).map(a=>
|
|
341
|
-
${
|
|
342
|
-
${
|
|
340
|
+
LIMIT ?`,[...e.params,3e4,5e4,7e4,45e3,2e4,25])||[]).map(a=>aS(a,{topModels:f.get(a.clientKey)||[],topProviders:g.get(a.clientKey)||[],topEndpoints:h.get(a.clientKey)||[],topIps:i.get(a.clientKey)||[],topTools:j.get(a.clientKey)||[]}))}catch(a){return console.error("[analytics] Failed to build top heavy users:",a?.message||a),[]}}async function aY(a,b,c){let d=an(b,c);try{return(await a.all(`SELECT
|
|
341
|
+
${aO} AS clientKey,
|
|
342
|
+
${aP} AS clientLabel,
|
|
343
343
|
COALESCE(NULLIF(apiKeyOwner, ''), '') AS ownerUser,
|
|
344
344
|
COALESCE(NULLIF(apiKeyName, ''), '') AS apiKeyName,
|
|
345
345
|
COALESCE(NULLIF(apiKeyFingerprint, ''), '') AS apiKeyFingerprint,
|
|
@@ -354,10 +354,10 @@
|
|
|
354
354
|
MAX(timestamp) AS lastSeen
|
|
355
355
|
FROM usageHistory
|
|
356
356
|
${d.clause}
|
|
357
|
-
GROUP BY ${
|
|
357
|
+
GROUP BY ${aO}
|
|
358
358
|
HAVING errors > 0
|
|
359
359
|
ORDER BY errors DESC, requests DESC
|
|
360
|
-
LIMIT ?`,[...d.params,25])||[]).map(a=>
|
|
360
|
+
LIMIT ?`,[...d.params,25])||[]).map(a=>aS(a))}catch(a){return console.error("[analytics] Failed to build problem clients:",a?.message||a),[]}}async function aZ(a,b,c){let d=ay(b,c);try{let b=await a.all(`WITH base AS (
|
|
361
361
|
SELECT
|
|
362
362
|
CASE
|
|
363
363
|
WHEN promptTokens < 2000 THEN 'lt2k'
|
|
@@ -415,7 +415,7 @@
|
|
|
415
415
|
MIN(CASE WHEN ttftMs > 0 AND ttftRank >= ((cnt * 95 + 99) / 100) THEN ttftMs END) AS p95TtftMs
|
|
416
416
|
FROM ranked
|
|
417
417
|
GROUP BY bucketKey, label, sortOrder
|
|
418
|
-
ORDER BY sortOrder ASC`,d.params)||[],c=b.reduce((a,b)=>a+Y(b.requests,0),0);return b.map(a=>({key:a.key,label:a.label,requests:Y(a.requests,0),share:c?Y(a.requests,0)/c:0,promptTokens:Y(a.promptTokens,0),completionTokens:Y(a.completionTokens,0),totalTokens:Y(a.totalTokens,0),avgPromptTokens:Y(a.avgPromptTokens,0),maxPromptTokens:Y(a.maxPromptTokens,0),avgLatencyMs:Y(a.avgLatencyMs,null),p95LatencyMs:Y(a.p95LatencyMs,null),maxLatencyMs:Y(a.maxLatencyMs,null),avgTtftMs:Y(a.avgTtftMs,null),p95TtftMs:Y(a.p95TtftMs,null)}))}catch(a){return console.error("[analytics] Failed to build input size buckets:",a?.message||a),[]}}async function aZ(a,b,c,d={},e=new Map){let f=await aW(a,b,c,e),g=await aX(a,b,c),h=await aT(a,b,c),i=await aU(a,b,c),j=await aV(a,b,c),k=await aY(a,b,c),l=f[0]||null,m=h[0]||null,n=i[0]||null,o=j[0]||null,p=f.reduce((a,b)=>a+Y(b.totalTokens,0),0),q=Y(d.totalTokens,0),r=l&&q?Y(l.totalTokens,0)/q:0,s=m&&q?Y(m.totalTokens,0)/q:0,t=n&&q?Y(n.totalTokens,0)/q:0,u=k.filter(a=>["30k-50k","50k-70k",">=70k"].includes(a.label)).reduce((a,b)=>a+Y(b.share,0),0),v=k.find(a=>">=70k"===a.label)||null;return{summary:{trackedUsers:f.length,topUserLabel:l?.label||"-",topUserTokens:l?.totalTokens||0,topUserTokenShare:r,topUsersTokenShare:q?p/q:0,topApiKeyLabel:m?.label||"-",topApiKeyTokens:m?.totalTokens||0,topApiKeyTokenShare:s,topSourceIpLabel:n?.label||"-",topSourceIpTokens:n?.totalTokens||0,topSourceIpTokenShare:t,topSourceIpHeavyLabel:o?.label||"-",topSourceIpHeavyRequests:o?.heavyRequests||0,longInputBucketShare:u,extremeInputShare:v?.share||0,problemClients:g.length},topHeavyUsers:f,topProblemClients:g,topApiKeysByTokens:h,topSourceIpsByTokens:i,topSourceIpsByHeavyRequests:j,inputBuckets:k}}function a$(a){let b=String(a??"");return/[",\n\r]/.test(b)?`"${b.replace(/"/g,'""')}"`:b}async function a_(a,b=4){let c=[a].filter(Boolean),d=Math.max(0,Math.max(1,Math.min(6,Number(b)||4))-c.length);if(d<=0)return c;for(let a of(await Promise.all(Array.from({length:d},async()=>{try{return await (0,O.d9)()}catch(a){return console.warn("[dashboardAnalytics] Extra MySQL analytics connection unavailable:",a?.message||a),null}}))))a&&c.push(a);return c}function a0(a,b=0){return Array.isArray(a)&&0!==a.length?a[Math.abs(b)%a.length]||a[0]:null}async function a1(a=[]){let b=[...new Set((a||[]).filter(Boolean))];await Promise.all(b.map(a=>a?.close?.().catch(()=>{})))}async function a2(a={}){let b=JSON.stringify(ag(a)),c=(global._dashboardAnalyticsV2Cache||(global._dashboardAnalyticsV2Cache=new Map),global._dashboardAnalyticsV2Cache),d=c.get(b);if(d&&Date.now()-d.createdAt<15e3)return d.data;let e=ag(a),f=await (0,w.c)(),g=await (0,O.d9)().catch(a=>(console.error("[dashboardAnalytics] MySQL observability query adapter unavailable; SQLite fallback is disabled:",a?.message||a),null));if(!g)throw Error("MySQL observability is not configured or unavailable; SQLite analytics fallback is disabled.");let h=[g];try{h=await a_(g,3);let a=a0(h,0),[d,i]=await Promise.all([ai(f),aj(f)]),j=e.userOwnedOnly?function(a=[],b={}){let c=[...new Set((a||[]).map(a=>X(a)).filter(Boolean))];if(0===c.length)return{enabled:!0,noMatch:!0,owners:[],identifiers:[],ids:[],fingerprints:[]};let d=new Set(c),e=new Set,f=new Set,g=new Set;for(let a of b.all||[]){let b=X(a.ownerUser);b&&d.has(b)&&(a.key&&e.add(a.key),a.id&&(e.add(a.id),f.add(a.id)),a.fingerprint&&(e.add(a.fingerprint),g.add(a.fingerprint)))}return{enabled:!0,noMatch:0===e.size,owners:c,identifiers:[...e],ids:[...f],fingerprints:[...g]}}(e.ownerCandidates,d):null,k=j?{...e,ownerScope:j}:e,l=function(a,b){let c=X(a);if(!c)return null;let d=[],e=!1;for(let a of(["local","local-no-key","no-key","khong-key","kh\xf4ng-key","kh\xf4ng d\xf9ng api key"].some(a=>a.includes(c)||c.includes(a))&&(e=!0),b.all||[]))[a.key,a.id,a.name,a.ownerUser,a.createdByUser,a.machineId,a.fingerprint,a.masked].some(a=>X(a).includes(c))&&a.key&&d.push(a.key);return a.length>=16&&!d.includes(a)&&d.push(a),{keys:[...new Set(d)],includeLocal:e,noMatch:0===d.length&&!e,filter:c}}(k.apiKey,d),m=k.userOwnedOnly?Promise.resolve(function(a="disabled"){return{disabled:!0,reason:a,missing:!1,total:0,sampled:0,dbInfo:{},models:[],stages:[],topClientIps:[],topSourceTools:[],topSessions:[],topStages:[],topModels:[],topAccounts:[],topStatuses:[]}}("user_owned_scope_no_api_key_columns")):M({keyword:k.keyword,model:k.model,sourceTool:k.sourceTool,clientIp:k.clientIp,sessionId:k.sessionId,dateFrom:k.startIso,dateTo:k.endIso}),n=(0,N.Wl)({keyword:k.keyword,provider:k.provider,model:k.model,connectionId:k.connectionId,endpoint:k.endpoint,apiKey:k.apiKey,apiKeyScope:j,status:k.status,sourceTool:k.sourceTool,clientIp:k.clientIp,sessionId:k.sessionId,dateFrom:k.startIso,dateTo:k.endIso}),[o,p,q,r,s,t]=await Promise.all([ao(a0(h,0),k,l),ap(a0(h,1),k,l),at(a0(h,2),k,d,i,l),aw(a0(h,3),k,l),m,n]),u=t?.summary||{};p.rawErrorEvents=Y(t?.total,0),p.serverErrorEvents=Y(u.serverImpacting,0),p.gatewayErrorEvents=Y(u.gateway,0),p.upstreamErrorEvents=Y(u.upstream,0),p.clientErrorEvents=Y(u.client,0),p.rateLimitErrorEvents=Y(u.rateLimit,0),p.unknownErrorEvents=Y(u.unknown,0),p.serverErrorRate=p.requests?p.serverErrorEvents/p.requests:0,p.clientErrorRate=p.requests?p.clientErrorEvents/p.requests:0,p.rateLimitErrorRate=p.requests?p.rateLimitErrorEvents/p.requests:0,t?.topErrors?.length&&(q.errors=t.topErrors);let v=new Map([...d.byKey.entries(),...d.byFingerprint.entries()]),[w,x,y,z,A]=await Promise.all([aB(a0(h,0),k,l,p),aZ(a0(h,1),k,l,p,i),au(a0(h,2),k,l,o),aF(a0(h,3),k,l,v,i),aG(a0(h,0),k,l,v,i)]),[B,C]=await Promise.all([aC(a0(h,1),k,l,i),aD(a0(h,2),k,l,v,i)]);w.byModel=B,w.slowestRequests=C,p.userExperienceScore=w.score,p.userExperienceLabel=w.label,p.slowRequestRate=w.slowRequestRate,p.longInputRate=w.longInputRate,p.topHeavyUser=x.summary?.topUserLabel||"",p.topHeavyUserTokenShare=x.summary?.topUserTokenShare||0,p.extremeInputShare=x.summary?.extremeInputShare||0;let D=await aM(a,k,q,s,d,l,i),E=function({overview:a,groups:b,promptLogStats:c,requestErrorStats:d,experience:e,clientRequests:f}){let g=[],h=d?.summary||{},i=Y(h.serverImpacting,0),j=Y(h.client,0),k=Y(h.rateLimit,0),l=Y(a.serverErrorRate,a.requests?i/a.requests:0),m=Y(a.clientErrorRate,a.requests?j/a.requests:0);a.requests>=10&&i>=3&&l>=.05?g.push({level:l>=.15?"danger":"warning",title:"Tỷ lệ lỗi server/provider cao",detail:`${i.toLocaleString("vi-VN")} lỗi server-impacting (${(100*l).toFixed(1)}% request) trong khoảng thời gian đang lọc. Ưu ti\xean kiểm tra upstream/provider, gateway, timeout v\xe0 5xx.`}):a.requests>=10&&a.errorRate>=.2&&m>=.1?g.push({level:"warning",title:"Nhiều lỗi do client/request",detail:`${j.toLocaleString("vi-VN")} lỗi được ph\xe2n loại l\xe0 client-side (${(100*m).toFixed(1)}% request): sai endpoint/model/auth/body/context. Kh\xf4ng n\xean t\xednh nh\xf3m n\xe0y như lỗi server.`}):a.requests>=10&&a.errorRate>=.2&&g.push({level:"warning",title:"Tỷ lệ lỗi tổng cao",detail:`Tổng lỗi usage l\xe0 ${(100*a.errorRate).toFixed(1)}%, nhưng lỗi server-impacting chỉ ${(100*l).toFixed(1)}%. Xem ph\xe2n loại client/server b\xean dưới trước khi kết luận provider hỏng.`}),k>=5&&a.requests>0&&k/a.requests>=.05&&g.push({level:"warning",title:"Rate limit / quota đ\xe1ng ch\xfa \xfd",detail:`${k.toLocaleString("vi-VN")} lỗi rate-limit/quota trong khoảng lọc. Kiểm tra policy API key, quota provider hoặc ph\xe2n tải model.`});let n=b.apiKeys?.[0];n&&a.totalTokens>0&&n.totalTokens/a.totalTokens>=.5&&g.push({level:"warning",title:"Một API key d\xf9ng phần lớn token",detail:`${n.name||n.fingerprint} đang d\xf9ng ${(n.totalTokens/a.totalTokens*100).toFixed(1)}% tổng token.`});let o=c?.topClientIps?.[0];o&&c.total>0&&o.requests/c.total>=.5&&o.requests>=20&&g.push({level:"warning",title:"Một IP chiếm phần lớn request prompt log",detail:`${o.label} chiếm ${(o.requests/c.total*100).toFixed(1)}% prompt logs trong to\xe0n bộ dữ liệu khớp bộ lọc.`});let p=d?.topServerErrors?.[0];return p&&p.requests>=5&&g.push({level:p.requests>=20?"danger":"warning",title:"Provider/Gateway c\xf3 lỗi cần xử l\xfd",detail:`${p.provider||p.errorSource||"unknown"}/${p.model||"unknown"} c\xf3 ${p.requests.toLocaleString("vi-VN")} lỗi ${p.errorType||p.status||"server-impacting"}.`}),e?.samples>=10&&Y(e.slowRequestRate,0)>=.2&&g.push({level:e.slowRequestRate>=.4?"danger":"warning",title:"Nhiều request phản hồi chậm",detail:`${(100*e.slowRequestRate).toFixed(1)}% request th\xe0nh c\xf4ng c\xf3 latency >= 45s. Kiểm tra request input d\xe0i, chờ slot/upstream queue v\xe0 tải model server.`}),e?.samples>=10&&Y(e.longInputRate,0)>=.3&&g.push({level:"warning",title:"Tỷ lệ request input d\xe0i cao",detail:`${(100*e.longInputRate).toFixed(1)}% request c\xf3 input >= 30k token. Với VS Code/agent, P95/P99 latency cao c\xf3 thể chủ yếu do prompt eval v\xe0 chờ slot, kh\xf4ng phải do output chậm.`}),f?.summary?.topUserTokenShare>=.35&&g.push({level:f.summary.topUserTokenShare>=.6?"danger":"warning",title:"Token usage tập trung v\xe0o một user/API key",detail:`${f.summary.topUserLabel||"Một client"} đang chiếm ${(100*f.summary.topUserTokenShare).toFixed(1)}% tổng token trong khoảng lọc. N\xean kiểm tra quota, workflow VS Code/agent v\xe0 request input d\xe0i của client n\xe0y.`}),f?.summary?.extremeInputShare>=.1&&g.push({level:f.summary.extremeInputShare>=.25?"danger":"warning",title:"Nhiều request cực d\xe0i >=70k token",detail:`${(100*f.summary.extremeInputShare).toFixed(1)}% request th\xe0nh c\xf4ng c\xf3 input >=70k token. Đ\xe2y l\xe0 nh\xf3m dễ k\xe9o TTFT/P95/P99 l\xean cao v\xe0 l\xe0m request nhỏ phải chờ slot.`}),g}({overview:p,groups:q,promptLogStats:s,requestErrorStats:t,experience:w,clientRequests:x}),F={generatedAt:new Date().toISOString(),analyticsVersion:"v3.5-token-consumer-monitor",filters:{period:k.period,startIso:k.startIso,endIso:k.endIso,provider:k.provider,model:k.model,connectionId:k.connectionId,status:k.status,endpoint:k.endpoint,apiKey:k.apiKey,clientIp:k.clientIp,sourceTool:k.sourceTool,sessionId:k.sessionId,keyword:k.keyword,userOwnedOnly:k.userOwnedOnly},overview:p,latency:r,experience:w,clientRequests:x,timeSeries:y,groups:q,promptLogs:s,requestErrors:t,anomalies:E,recentUsage:z,heavyRequests:A,options:D,qualityNotes:[]};if(await a1(h),c.set(b,{createdAt:Date.now(),data:F}),c.size>100){for(let[a,b]of c)if(Date.now()-b.createdAt>15e3&&c.delete(a),c.size<=100)break}return F}catch(a){throw await a1(h),console.error("[dashboardAnalytics] MySQL observability query failed; SQLite fallback is disabled:",a?.message||a),a}}var a3=c(9588);let a4="force-dynamic",a5=["period","dateFrom","dateTo","provider","model","connectionId","status","endpoint","apiKey","clientIp","sourceIp","sourceTool","sessionId","keyword","maxPromptLogRows"];async function a6(a){try{let{access:b,response:c}=await (0,a3.oW)();if(c)return c;let{searchParams:d}=new URL(a.url),e=function(a){let b={};for(let c of a5){let d=a.get(c);null!==d&&""!==String(d).trim()&&(b[c]=d)}return b}(d),f=b.isAdmin||b.isMonitorAdmin?e:{...e,userOwnedOnly:!0,ownerCandidates:[...new Set([...b.candidates||[],b.userId].map(a3.I8).filter(Boolean))]},g=await a2(f);if("csv"===d.get("format")){let a=(function(a){let b=[];for(let[c,d]of(b.push(["section","key","label","requests","success","errors","errorRate","inputTokens","outputTokens","totalTokens","cost","lastSeen"]),[["providers",a.groups.providers],["models",a.groups.models],["providerAccounts",a.groups.providerAccounts],["apiKeys",a.groups.apiKeys],["endpoints",a.groups.endpoints],["clientIps",a.promptLogs.topClientIps],["sourceTools",a.promptLogs.topSourceTools],["requestErrors",a.requestErrors?.topErrors||a.groups.errors],["modelExperience",a.experience?.byModel||[]],["clientHeavyUsers",a.clientRequests?.topHeavyUsers||[]],["clientTopApiKeysByTokens",a.clientRequests?.topApiKeysByTokens||[]],["clientTopSourceIpsByTokens",a.clientRequests?.topSourceIpsByTokens||[]],["clientTopSourceIpsByHeavyRequests",a.clientRequests?.topSourceIpsByHeavyRequests||[]],["clientProblemClients",a.clientRequests?.topProblemClients||[]],["inputBuckets",a.clientRequests?.inputBuckets||[]]]))for(let a of d||[])b.push([c,a.key||"",a.label||a.name||"",a.requests||0,a.success||0,a.errors||0,a.errorRate||0,a.promptTokens||0,a.completionTokens||0,a.totalTokens||0,a.cost||0,a.lastSeen||""]);return b})(g).map(a=>a.map(a$).join(",")).join("\n");return new Response(a,{status:200,headers:{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="bluerouter-analytics-${new Date().toISOString().slice(0,10)}.csv"`,"Cache-Control":"no-store"}})}return v.NextResponse.json(g,{headers:{"Cache-Control":"no-store"}})}catch(a){return console.error("[analytics] Failed to build dashboard analytics:",a),v.NextResponse.json({error:a?.message||"Failed to build dashboard analytics"},{status:500})}}let a7=new e.AppRouteRouteModule({definition:{kind:f.RouteKind.APP_ROUTE,page:"/api/dashboard/analytics/route",pathname:"/api/dashboard/analytics",filename:"route",bundlePath:"app/api/dashboard/analytics/route"},distDir:".next-cli-build",relativeProjectDir:"",resolvedPagePath:"D:\\bluerouter\\src\\app\\api\\dashboard\\analytics\\route.js",nextConfigOutput:"standalone",userland:d,...{}}),{workAsyncStorage:a8,workUnitAsyncStorage:a9,serverHooks:ba}=a7;function bb(){return(0,g.patchFetch)({workAsyncStorage:a8,workUnitAsyncStorage:a9})}async function bc(a,b,c){c.requestMeta&&(0,h.setRequestMeta)(a,c.requestMeta),a7.isDev&&(0,h.addRequestMeta)(a,"devRequestTimingInternalsEnd",process.hrtime.bigint());let d="/api/dashboard/analytics/route";"/index"===d&&(d="/");let e=await a7.prepare(a,b,{srcPage:d,multiZoneDraftMode:!1});if(!e)return b.statusCode=400,b.end("Bad Request"),null==c.waitUntil||c.waitUntil.call(c,Promise.resolve()),null;let{buildId:g,deploymentId:v,params:w,nextConfig:x,parsedUrl:y,isDraftMode:z,prerenderManifest:A,routerServerContext:B,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,resolvedPathname:E,clientReferenceManifest:F,serverActionsManifest:G}=e,H=(0,k.normalizeAppPath)(d),I=!!(A.dynamicRoutes[H]||A.routes[E]),J=async()=>((null==B?void 0:B.render404)?await B.render404(a,b,y,!1):b.end("This page could not be found"),null);if(I&&!z){let a=!!A.routes[E],b=A.dynamicRoutes[H];if(b&&!1===b.fallback&&!a){if(x.adapterPath)return await J();throw new t.NoFallbackError}}let K=null;!I||a7.isDev||z||(K="/index"===(K=E)?"/":K);let L=!0===a7.isDev||!I,M=I&&!L;G&&F&&(0,j.setManifestsSingleton)({page:d,clientReferenceManifest:F,serverActionsManifest:G});let N=a.method||"GET",O=(0,i.getTracer)(),P=O.getActiveScopeSpan(),Q=!!(null==B?void 0:B.isWrappedByNextServer),R=!!(0,h.getRequestMeta)(a,"minimalMode"),S=(0,h.getRequestMeta)(a,"incrementalCache")||await a7.getIncrementalCache(a,x,A,R);null==S||S.resetRequestCache(),globalThis.__incrementalCache=S;let T={params:w,previewProps:A.preview,renderOpts:{experimental:{authInterrupts:!!x.experimental.authInterrupts},cacheComponents:!!x.cacheComponents,supportsDynamicResponse:L,incrementalCache:S,cacheLifeProfiles:x.cacheLife,waitUntil:c.waitUntil,onClose:a=>{b.on("close",a)},onAfterTaskError:void 0,onInstrumentationRequestError:(b,c,d,e)=>a7.onRequestError(a,b,d,e,B)},sharedContext:{buildId:g,deploymentId:v}},U=new l.NodeNextRequest(a),V=new l.NodeNextResponse(b),W=m.NextRequestAdapter.fromNodeNextRequest(U,(0,m.signalFromNodeResponse)(b));try{let e,g=async a=>a7.handle(W,T).finally(()=>{if(!a)return;a.setAttributes({"http.status_code":b.statusCode,"next.rsc":!1});let c=O.getRootSpanAttributes();if(!c)return;if(c.get("next.span_type")!==n.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${c.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let f=c.get("next.route");if(f){let b=`${N} ${f}`;a.setAttributes({"next.route":f,"http.route":f,"next.span_name":b}),a.updateName(b),e&&e!==a&&(e.setAttribute("http.route",f),e.updateName(b))}else a.updateName(`${N} ${d}`)}),h=async e=>{var h,i;let j=async({previousCacheEntry:f})=>{try{if(!R&&C&&D&&!f)return b.statusCode=404,b.setHeader("x-nextjs-cache","REVALIDATED"),b.end("This page could not be found"),null;let d=await g(e);a.fetchMetrics=T.renderOpts.fetchMetrics;let h=T.renderOpts.pendingWaitUntil;h&&c.waitUntil&&(c.waitUntil(h),h=void 0);let i=T.renderOpts.collectedTags;if(!I)return await (0,p.I)(U,V,d,T.renderOpts.pendingWaitUntil),null;{let a=await d.blob(),b=(0,q.toNodeOutgoingHttpHeaders)(d.headers);i&&(b[s.NEXT_CACHE_TAGS_HEADER]=i),!b["content-type"]&&a.type&&(b["content-type"]=a.type);let c=void 0!==T.renderOpts.collectedRevalidate&&!(T.renderOpts.collectedRevalidate>=s.INFINITE_CACHE)&&T.renderOpts.collectedRevalidate,e=void 0===T.renderOpts.collectedExpire||T.renderOpts.collectedExpire>=s.INFINITE_CACHE?void 0:T.renderOpts.collectedExpire;return{value:{kind:u.CachedRouteKind.APP_ROUTE,status:d.status,body:Buffer.from(await a.arrayBuffer()),headers:b},cacheControl:{revalidate:c,expire:e}}}}catch(b){throw(null==f?void 0:f.isStale)&&await a7.onRequestError(a,b,{routerKind:"App Router",routePath:d,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),b}},k=await a7.handleResponse({req:a,nextConfig:x,cacheKey:K,routeKind:f.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:A,isRoutePPREnabled:!1,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,responseGenerator:j,waitUntil:c.waitUntil,isMinimalMode:R});if(!I)return null;if((null==k||null==(h=k.value)?void 0:h.kind)!==u.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==k||null==(i=k.value)?void 0:i.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});R||b.setHeader("x-nextjs-cache",C?"REVALIDATED":k.isMiss?"MISS":k.isStale?"STALE":"HIT"),z&&b.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let l=(0,q.fromNodeOutgoingHttpHeaders)(k.value.headers);return R&&I||l.delete(s.NEXT_CACHE_TAGS_HEADER),!k.cacheControl||b.getHeader("Cache-Control")||l.get("Cache-Control")||l.set("Cache-Control",(0,r.getCacheControlHeader)(k.cacheControl)),await (0,p.I)(U,V,new Response(k.value.body,{headers:l,status:k.value.status||200})),null};Q&&P?await h(P):(e=O.getActiveScopeSpan(),await O.withPropagatedContext(a.headers,()=>O.trace(n.BaseServerSpan.handleRequest,{spanName:`${N} ${d}`,kind:i.SpanKind.SERVER,attributes:{"http.method":N,"http.target":a.url}},h),void 0,!Q))}catch(b){if(b instanceof t.NoFallbackError||await a7.onRequestError(a,b,{routerKind:"App Router",routePath:H,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),I)throw b;return await (0,p.I)(U,V,new Response(null,{status:500})),null}}},63033:a=>{a.exports=require("next/dist/server/app-render/work-unit-async-storage.external.js")},64939:a=>{a.exports=import("pg")},66136:a=>{a.exports=require("timers")},69614:(a,b,c)=>{c.d(b,{V:()=>p});var d=c(88888),e=c(91356),f=c(99129),g=c(73575),h=c(41570),i=c(19035),j=c(24762),k=c(80308),l=c(11980);async function m(a,b,c){if(!(0,i.Gv)(a))throw new f.Ye("Flattened JWS must be an object");if(void 0===a.protected&&void 0===a.header)throw new f.Ye('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==a.protected&&"string"!=typeof a.protected)throw new f.Ye("JWS Protected Header incorrect type");if(void 0===a.payload)throw new f.Ye("JWS Payload missing");if("string"!=typeof a.signature)throw new f.Ye("JWS Signature missing or incorrect type");if(void 0!==a.header&&!(0,i.Gv)(a.header))throw new f.Ye("JWS Unprotected Header incorrect type");let m={};if(a.protected)try{let b=(0,d.D)(a.protected);m=JSON.parse(g.D0.decode(b))}catch{throw new f.Ye("JWS Protected Header is invalid")}if(!(0,i.fz)(m,a.header))throw new f.Ye("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");let n={...m,...a.header},o=(0,k.n)(f.Ye,new Map([["b64",!0]]),c?.crit,m,n),p=!0;if(o.has("b64")&&"boolean"!=typeof(p=m.b64))throw new f.Ye('The "b64" (base64url-encode payload) Header Parameter must be a boolean');let{alg:q}=n;if("string"!=typeof q||!q)throw new f.Ye('JWS "alg" (Algorithm) Header Parameter missing or invalid');let r=c&&function(a,b){if(void 0!==b&&(!Array.isArray(b)||b.some(a=>"string"!=typeof a)))throw TypeError(`"${a}" option must be an array of strings`);if(b)return new Set(b)}("algorithms",c.algorithms);if(r&&!r.has(q))throw new f.Rb('"alg" (Algorithm) Header Parameter value not allowed');if(p){if("string"!=typeof a.payload)throw new f.Ye("JWS Payload must be a string")}else if("string"!=typeof a.payload&&!(a.payload instanceof Uint8Array))throw new f.Ye("JWS Payload must be a string or an Uint8Array instance");let s=!1;"function"==typeof b&&(b=await b(m,a),s=!0),(0,j.y)(q,b,"verify");let t=(0,g.xW)(void 0!==a.protected?(0,g.lF)(a.protected):new Uint8Array,(0,g.lF)("."),"string"==typeof a.payload?p?(0,g.lF)(a.payload):g.Rd.encode(a.payload):a.payload),u=(0,h.h2)(a.signature,"signature",f.Ye),v=await (0,l.l)(b,q);if(!await (0,e.MX)(q,v,u,t))throw new f.h2;let w={payload:p?(0,h.h2)(a.payload,"payload",f.Ye):"string"==typeof a.payload?g.Rd.encode(a.payload):a.payload};return(void 0!==a.protected&&(w.protectedHeader=m),void 0!==a.header&&(w.unprotectedHeader=a.header),s)?{...w,key:v}:w}async function n(a,b,c){if(a instanceof Uint8Array&&(a=g.D0.decode(a)),"string"!=typeof a)throw new f.Ye("Compact JWS must be a string or Uint8Array");let{0:d,1:e,2:h,length:i}=a.split(".");if(3!==i)throw new f.Ye("Invalid Compact JWS");let j=await m({payload:e,protected:d,signature:h},b,c),k={payload:j.payload,protectedHeader:j.protectedHeader};return"function"==typeof b?{...k,key:j.key}:k}var o=c(17347);async function p(a,b,c){let d=await n(a,b,c);if(d.protectedHeader.crit?.includes("b64")&&!1===d.protectedHeader.b64)throw new f.Dp("JWTs MUST NOT use unencoded payload");let e={payload:(0,o.k6)(d.protectedHeader,d.payload,c),protectedHeader:d.protectedHeader};return"function"==typeof b?{...e,key:d.key}:e}},73024:a=>{a.exports=require("node:fs")},74075:a=>{a.exports=require("zlib")},76760:a=>{a.exports=require("node:path")},77598:a=>{a.exports=require("node:crypto")},79428:a=>{a.exports=require("buffer")},79868:a=>{a.exports=require("node:sqlite")},81787:a=>{a.exports=require("bun:sqlite")},86439:a=>{a.exports=require("next/dist/shared/lib/no-fallback-error.external")},87550:a=>{a.exports=require("better-sqlite3")},90389:(a,b,c)=>{c.d(b,{hS:()=>d});let d=Object.freeze({ADMIN:"admin",MONITOR_ADMIN:"monitor_admin",USER:"user",GUEST:"guest"});Object.freeze([{href:"/dashboard/endpoint",label:"Endpoint",icon:"api"},{href:"/dashboard/api-keys",label:"API Keys",icon:"vpn_key"},{href:"/dashboard/usage",label:"Usage",icon:"bar_chart"},{href:"/dashboard/analytics",label:"Analytics",icon:"monitoring"},{href:"/dashboard/quota",label:"Quota Tracker",icon:"data_usage"},{href:"/dashboard/prompt-logs",label:"Prompt Logs",icon:"manage_search"}]),Object.freeze(["/dashboard","/dashboard/endpoint","/dashboard/api-keys","/dashboard/usage","/dashboard/analytics","/dashboard/quota","/dashboard/prompt-logs"])},91645:a=>{a.exports=require("net")},94735:a=>{a.exports=require("events")},94755:(a,b,c)=>{c.d(b,{A:()=>i});var d=c(77598);let e={randomUUID:d.randomUUID},f=new Uint8Array(256),g=f.length;var h=c(50122);let i=function(a,b,c){if(e.randomUUID&&!b&&!a)return e.randomUUID();var i=a,j=c;let k=(i=i||{}).random??i.rng?.()??(g>f.length-16&&((0,d.randomFillSync)(f),g=0),f.slice(g,g+=16));if(k.length<16)throw Error("Random bytes length must be >= 16");if(k[6]=15&k[6]|64,k[8]=63&k[8]|128,b){if((j=j||0)<0||j+16>b.length)throw RangeError(`UUID byte range ${j}:${j+15} is out of buffer bounds`);for(let a=0;a<16;++a)b[j+a]=k[a];return b}return(0,h.k)(k)}},97242:(a,b,c)=>{c.d(b,{DU:()=>s,Ws:()=>t,_3:()=>v,nv:()=>u});var d=c(45903);let e=new Set;function f(a,b,c=null){let d=Number(a);if(!Number.isFinite(d)||d<0)return b;let e=Math.floor(d);return c?Math.min(e,c):e}function g(a){return String(a||"").trim()}async function h(){return(0,d.I6)(await (0,d.L7)())}async function i(a){let b=new(await Promise.resolve().then(c.bind(c,64939))).Client({host:a.host,port:Number(a.port||5432),database:a.database,user:a.username,password:a.password,ssl:!!a.ssl&&{rejectUnauthorized:!1}});return await b.connect(),{type:"postgres",query:async(a,c=[])=>(await b.query(a,c)).rows,queryOne:async(a,c=[])=>(await b.query(a,c)).rows[0]||null,async exec(a,c=[]){await b.query(a,c)},async close(){await b.end()}}}async function j(a){let b=await c.e(8491).then(c.t.bind(c,38491,19)),d=await b.createConnection({host:a.host,port:Number(a.port||3306),database:a.database,user:a.username,password:a.password,ssl:a.ssl?{}:void 0,dateStrings:!0,connectTimeout:3e3});return{type:"mysql",async query(a,b=[]){let[c]=await d.query(a,b);return c},async queryOne(a,b=[]){let[c]=await d.query(a,b);return c[0]||null},async exec(a,b=[]){await d.query(a,b)},async close(){await d.end()}}}async function k(a){if("postgres"===a.type)return i(a);if("mysql"===a.type)return j(a);throw Error(`Unsupported prompt log database type: ${a.type}`)}async function l(a,b){if(!b||b.full_request_json)return b;let c=function(a={}){return String(a.payload_hash||function(a){if(!a)return{};if("object"==typeof a)return a;try{return JSON.parse(a)}catch{return{}}}(a.meta_json).payloadHash||"").trim()}(b);if(!c)return b;try{let d=await a.queryOne("SELECT COUNT(1) AS count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'prompt_log_payloads'");if(0===Number(d?.count||0))return b;let e=await a.queryOne("SELECT payload_json FROM prompt_log_payloads WHERE payload_hash = ?",[c]);if(!e)return b;let f=e.payload_json;return{...b,full_request_json:"string"==typeof f?f:JSON.stringify(f)}}catch{return b}}async function m(a){let b=await i(a);try{for(let a of["CREATE INDEX IF NOT EXISTS idx_prompt_logs_created_id ON prompt_logs (created_at DESC, id)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_stage_created_at ON prompt_logs (stage, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_model_created_at ON prompt_logs (model, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_display_model_created_at ON prompt_logs (display_model, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_session_created_at ON prompt_logs (session_id, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_client_ip_created_at ON prompt_logs (client_ip, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_source_tool_created_at ON prompt_logs (source_tool, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_connection_created_at ON prompt_logs (connection_id, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_account_created_at ON prompt_logs (account_name, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_provider_created_at ON prompt_logs (provider, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_status_created_at ON prompt_logs (status_code, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_payload_hash ON prompt_logs (payload_hash)"])await b.exec(a)}finally{await b.close()}}async function n(a,b,c){let d=await a.queryOne("SELECT COUNT(1) AS count FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'prompt_logs' AND INDEX_NAME = ?",[b]);0===Number(d?.count||0)&&await a.exec(c)}async function o(a){let b=await j(a);try{let a=await b.queryOne("SELECT COUNT(1) AS count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'prompt_logs'");if(0===Number(a?.count||0))return;for(let[a,c]of[["idx_prompt_logs_created_id","CREATE INDEX idx_prompt_logs_created_id ON prompt_logs (created_at DESC, id)"],["idx_prompt_logs_stage_created_at","CREATE INDEX idx_prompt_logs_stage_created_at ON prompt_logs (stage, created_at DESC)"],["idx_prompt_logs_model_created_at","CREATE INDEX idx_prompt_logs_model_created_at ON prompt_logs (model, created_at DESC)"],["idx_prompt_logs_display_model_created_at","CREATE INDEX idx_prompt_logs_display_model_created_at ON prompt_logs (display_model, created_at DESC)"],["idx_prompt_logs_session_created_at","CREATE INDEX idx_prompt_logs_session_created_at ON prompt_logs (session_id, created_at DESC)"],["idx_prompt_logs_client_ip_created_at","CREATE INDEX idx_prompt_logs_client_ip_created_at ON prompt_logs (client_ip, created_at DESC)"],["idx_prompt_logs_source_tool_created_at","CREATE INDEX idx_prompt_logs_source_tool_created_at ON prompt_logs (source_tool, created_at DESC)"],["idx_prompt_logs_connection_created_at","CREATE INDEX idx_prompt_logs_connection_created_at ON prompt_logs (connection_id, created_at DESC)"],["idx_prompt_logs_account_created_at","CREATE INDEX idx_prompt_logs_account_created_at ON prompt_logs (account_name, created_at DESC)"],["idx_prompt_logs_provider_created_at","CREATE INDEX idx_prompt_logs_provider_created_at ON prompt_logs (provider, created_at DESC)"],["idx_prompt_logs_status_created_at","CREATE INDEX idx_prompt_logs_status_created_at ON prompt_logs (status_code, created_at DESC)"],["idx_prompt_logs_payload_hash","CREATE INDEX idx_prompt_logs_payload_hash ON prompt_logs (payload_hash)"]])await n(b,a,c)}finally{await b.close()}}async function p(a){if(!a.enabled)return;let b=`${a.type}:${a.host||""}:${a.port||""}:${a.database||""}`;if(!e.has(b))try{if("postgres"===a.type)await m(a);else if("mysql"===a.type)await o(a);else throw Error(`Unsupported prompt log database type: ${a.type}`);e.add(b)}catch(a){console.warn("[prompt-logs] Unable to ensure query indexes:",a.message)}}async function q(a){let b=await k(a);try{let c=(await b.query("SELECT DISTINCT COALESCE(NULLIF(display_model, ''), model) AS model FROM prompt_logs WHERE model IS NOT NULL AND model <> '' ORDER BY model LIMIT 300")).map(a=>a.model),d=(await b.query("SELECT DISTINCT stage FROM prompt_logs WHERE stage IS NOT NULL AND stage <> '' ORDER BY stage LIMIT 100")).map(a=>a.stage);return{models:c,stages:d,dbInfo:{type:a.type,host:a.host,database:a.database}}}finally{await b.close()}}async function r(a,b){let c=a.type,d=await k(a);try{let e=function(a,b){let c=[],d=[],e=a=>(d.push(a),"postgres"===b)?`$${d.length}`:"?",f="postgres"===b?"ILIKE":"LIKE";if(a.keyword){let b=`%${a.keyword}%`;c.push(`(${["prompt_text","response_text","error_text","model","endpoint","provider_url","provider","account_name","connection_id","display_model","session_id","client_ip","client_host","client_user_agent","source_tool","source_tool_label","source_host"].map(a=>`${a} ${f} ${e(b)}`).join(" OR ")})`)}if(a.model&&c.push(`(model = ${e(a.model)} OR display_model = ${e(a.model)})`),a.stage&&c.push(`stage = ${e(a.stage)}`),a.sessionId&&c.push(`session_id = ${e(a.sessionId)}`),a.clientIp&&c.push(`client_ip ${f} ${e(`%${a.clientIp}%`)}`),a.sourceTool){let b=`%${a.sourceTool}%`;c.push(`(source_tool ${f} ${e(b)} OR source_tool_label ${f} ${e(b)} OR source_host ${f} ${e(b)})`)}return a.dateFrom&&c.push(`created_at >= ${e(a.dateFrom)}`),a.dateTo&&c.push(`created_at <= ${e(a.dateTo)}`),{clause:c.length?`WHERE ${c.join(" AND ")}`:"",params:d,add:e}}(b,c),f=[...e.params],g=await d.queryOne(`SELECT COUNT(*) AS count FROM prompt_logs ${e.clause}`,f),h=e.add(b.limit),i=e.add(b.offset),j="postgres"===c?"LEFT(coalesce(prompt_text,''), 900)":"SUBSTRING(coalesce(prompt_text,''), 1, 900)",k="postgres"===c?"char_length(coalesce(prompt_text,''))":"CHAR_LENGTH(coalesce(prompt_text,''))",l="postgres"===c?"LEFT(coalesce(response_text,''), 400)":"SUBSTRING(coalesce(response_text,''), 1, 400)",m=await d.query(`
|
|
418
|
+
ORDER BY sortOrder ASC`,d.params)||[],c=b.reduce((a,b)=>a+Y(b.requests,0),0);return b.map(a=>({key:a.key,label:a.label,requests:Y(a.requests,0),share:c?Y(a.requests,0)/c:0,promptTokens:Y(a.promptTokens,0),completionTokens:Y(a.completionTokens,0),totalTokens:Y(a.totalTokens,0),avgPromptTokens:Y(a.avgPromptTokens,0),maxPromptTokens:Y(a.maxPromptTokens,0),avgLatencyMs:Y(a.avgLatencyMs,null),p95LatencyMs:Y(a.p95LatencyMs,null),maxLatencyMs:Y(a.maxLatencyMs,null),avgTtftMs:Y(a.avgTtftMs,null),p95TtftMs:Y(a.p95TtftMs,null)}))}catch(a){return console.error("[analytics] Failed to build input size buckets:",a?.message||a),[]}}async function a$(a,b,c,d={},e=new Map){let f=await aX(a,b,c,e),g=await aY(a,b,c),h=await aU(a,b,c),i=await aV(a,b,c),j=await aW(a,b,c),k=await aZ(a,b,c),l=f[0]||null,m=h[0]||null,n=i[0]||null,o=j[0]||null,p=f.reduce((a,b)=>a+Y(b.totalTokens,0),0),q=Y(d.totalTokens,0),r=l&&q?Y(l.totalTokens,0)/q:0,s=m&&q?Y(m.totalTokens,0)/q:0,t=n&&q?Y(n.totalTokens,0)/q:0,u=k.filter(a=>["30k-50k","50k-70k",">=70k"].includes(a.label)).reduce((a,b)=>a+Y(b.share,0),0),v=k.find(a=>">=70k"===a.label)||null;return{summary:{trackedUsers:f.length,topUserLabel:l?.label||"-",topUserTokens:l?.totalTokens||0,topUserTokenShare:r,topUsersTokenShare:q?p/q:0,topApiKeyLabel:m?.label||"-",topApiKeyTokens:m?.totalTokens||0,topApiKeyTokenShare:s,topSourceIpLabel:n?.label||"-",topSourceIpTokens:n?.totalTokens||0,topSourceIpTokenShare:t,topSourceIpHeavyLabel:o?.label||"-",topSourceIpHeavyRequests:o?.heavyRequests||0,longInputBucketShare:u,extremeInputShare:v?.share||0,problemClients:g.length},topHeavyUsers:f,topProblemClients:g,topApiKeysByTokens:h,topSourceIpsByTokens:i,topSourceIpsByHeavyRequests:j,inputBuckets:k}}function a_(a){let b=String(a??"");return/[",\n\r]/.test(b)?`"${b.replace(/"/g,'""')}"`:b}async function a0(a,b=4){let c=[a].filter(Boolean),d=Math.max(0,Math.max(1,Math.min(6,Number(b)||4))-c.length);if(d<=0)return c;for(let a of(await Promise.all(Array.from({length:d},async()=>{try{return await (0,O.d9)()}catch(a){return console.warn("[dashboardAnalytics] Extra MySQL analytics connection unavailable:",a?.message||a),null}}))))a&&c.push(a);return c}function a1(a,b=0){return Array.isArray(a)&&0!==a.length?a[Math.abs(b)%a.length]||a[0]:null}async function a2(a=[]){let b=[...new Set((a||[]).filter(Boolean))];await Promise.all(b.map(a=>a?.close?.().catch(()=>{})))}async function a3(a={}){let b=JSON.stringify(ah(a)),c=(global._dashboardAnalyticsV2Cache||(global._dashboardAnalyticsV2Cache=new Map),global._dashboardAnalyticsV2Cache),d=c.get(b);if(d&&Date.now()-d.createdAt<15e3)return d.data;let e=ah(a),f=await (0,w.c)(),g=await (0,O.d9)().catch(a=>(console.error("[dashboardAnalytics] MySQL observability query adapter unavailable; SQLite fallback is disabled:",a?.message||a),null));if(!g)throw Error("MySQL observability is not configured or unavailable; SQLite analytics fallback is disabled.");let h=[g];try{h=await a0(g,3);let a=a1(h,0),[d,i]=await Promise.all([aj(f),ak(f)]),j=e.userOwnedOnly?function(a=[],b={}){let c=[...new Set((a||[]).map(a=>X(a)).filter(Boolean))];if(0===c.length)return{enabled:!0,noMatch:!0,owners:[],identifiers:[],ids:[],fingerprints:[]};let d=new Set(c),e=new Set,f=new Set,g=new Set;for(let a of b.all||[]){let b=X(a.ownerUser);b&&d.has(b)&&(a.key&&e.add(a.key),a.id&&(e.add(a.id),f.add(a.id)),a.fingerprint&&(e.add(a.fingerprint),g.add(a.fingerprint)))}return{enabled:!0,noMatch:0===e.size,owners:c,identifiers:[...e],ids:[...f],fingerprints:[...g]}}(e.ownerCandidates,d):null,k=j?{...e,ownerScope:j}:e,l=function(a,b){let c=X(a);if(!c)return null;let d=[],e=!1;for(let a of(["local","local-no-key","no-key","khong-key","kh\xf4ng-key","kh\xf4ng d\xf9ng api key"].some(a=>a.includes(c)||c.includes(a))&&(e=!0),b.all||[]))[a.key,a.id,a.name,a.ownerUser,a.createdByUser,a.machineId,a.fingerprint,a.masked].some(a=>X(a).includes(c))&&a.key&&d.push(a.key);return a.length>=16&&!d.includes(a)&&d.push(a),{keys:[...new Set(d)],includeLocal:e,noMatch:0===d.length&&!e,filter:c}}(k.apiKey,d),m=k.userOwnedOnly?Promise.resolve(function(a="disabled"){return{disabled:!0,reason:a,missing:!1,total:0,sampled:0,dbInfo:{},models:[],stages:[],topClientIps:[],topSourceTools:[],topSessions:[],topStages:[],topModels:[],topAccounts:[],topStatuses:[]}}("user_owned_scope_no_api_key_columns")):M({keyword:k.keyword,model:k.model,sourceTool:k.sourceTool,clientIp:k.clientIp,sessionId:k.sessionId,dateFrom:k.startIso,dateTo:k.endIso}),n=(0,N.Wl)({keyword:k.keyword,provider:k.provider,model:k.model,connectionId:k.connectionId,endpoint:k.endpoint,apiKey:k.apiKey,apiKeyScope:j,status:k.status,sourceTool:k.sourceTool,clientIp:k.clientIp,sessionId:k.sessionId,dateFrom:k.startIso,dateTo:k.endIso}),[o,p,q,r,s,t]=await Promise.all([ap(a1(h,0),k,l),aq(a1(h,1),k,l),au(a1(h,2),k,d,i,l),ax(a1(h,3),k,l),m,n]),u=t?.summary||{};p.rawErrorEvents=Y(t?.total,0),p.serverErrorEvents=Y(u.serverImpacting,0),p.gatewayErrorEvents=Y(u.gateway,0),p.upstreamErrorEvents=Y(u.upstream,0),p.clientErrorEvents=Y(u.client,0),p.rateLimitErrorEvents=Y(u.rateLimit,0),p.unknownErrorEvents=Y(u.unknown,0),p.serverErrorRate=p.requests?p.serverErrorEvents/p.requests:0,p.clientErrorRate=p.requests?p.clientErrorEvents/p.requests:0,p.rateLimitErrorRate=p.requests?p.rateLimitErrorEvents/p.requests:0,t?.topErrors?.length&&(q.errors=t.topErrors);let v=new Map([...d.byKey.entries(),...d.byFingerprint.entries()]),[w,x,y,z,A]=await Promise.all([aC(a1(h,0),k,l,p),a$(a1(h,1),k,l,p,i),av(a1(h,2),k,l,o),aG(a1(h,3),k,l,v,i),aH(a1(h,0),k,l,v,i)]),[B,C]=await Promise.all([aD(a1(h,1),k,l,i),aE(a1(h,2),k,l,v,i)]);w.byModel=B,w.slowestRequests=C,p.userExperienceScore=w.score,p.userExperienceLabel=w.label,p.slowRequestRate=w.slowRequestRate,p.longInputRate=w.longInputRate,p.topHeavyUser=x.summary?.topUserLabel||"",p.topHeavyUserTokenShare=x.summary?.topUserTokenShare||0,p.extremeInputShare=x.summary?.extremeInputShare||0;let D=await aN(a,k,q,s,d,l,i),E=function({overview:a,groups:b,promptLogStats:c,requestErrorStats:d,experience:e,clientRequests:f}){let g=[],h=d?.summary||{},i=Y(h.serverImpacting,0),j=Y(h.client,0),k=Y(h.rateLimit,0),l=Y(a.serverErrorRate,a.requests?i/a.requests:0),m=Y(a.clientErrorRate,a.requests?j/a.requests:0);a.requests>=10&&i>=3&&l>=.05?g.push({level:l>=.15?"danger":"warning",title:"Tỷ lệ lỗi server/provider cao",detail:`${i.toLocaleString("vi-VN")} lỗi server-impacting (${(100*l).toFixed(1)}% request) trong khoảng thời gian đang lọc. Ưu ti\xean kiểm tra upstream/provider, gateway, timeout v\xe0 5xx.`}):a.requests>=10&&a.errorRate>=.2&&m>=.1?g.push({level:"warning",title:"Nhiều lỗi do client/request",detail:`${j.toLocaleString("vi-VN")} lỗi được ph\xe2n loại l\xe0 client-side (${(100*m).toFixed(1)}% request): sai endpoint/model/auth/body/context. Kh\xf4ng n\xean t\xednh nh\xf3m n\xe0y như lỗi server.`}):a.requests>=10&&a.errorRate>=.2&&g.push({level:"warning",title:"Tỷ lệ lỗi tổng cao",detail:`Tổng lỗi usage l\xe0 ${(100*a.errorRate).toFixed(1)}%, nhưng lỗi server-impacting chỉ ${(100*l).toFixed(1)}%. Xem ph\xe2n loại client/server b\xean dưới trước khi kết luận provider hỏng.`}),k>=5&&a.requests>0&&k/a.requests>=.05&&g.push({level:"warning",title:"Rate limit / quota đ\xe1ng ch\xfa \xfd",detail:`${k.toLocaleString("vi-VN")} lỗi rate-limit/quota trong khoảng lọc. Kiểm tra policy API key, quota provider hoặc ph\xe2n tải model.`});let n=b.apiKeys?.[0];n&&a.totalTokens>0&&n.totalTokens/a.totalTokens>=.5&&g.push({level:"warning",title:"Một API key d\xf9ng phần lớn token",detail:`${n.name||n.fingerprint} đang d\xf9ng ${(n.totalTokens/a.totalTokens*100).toFixed(1)}% tổng token.`});let o=c?.topClientIps?.[0];o&&c.total>0&&o.requests/c.total>=.5&&o.requests>=20&&g.push({level:"warning",title:"Một IP chiếm phần lớn request prompt log",detail:`${o.label} chiếm ${(o.requests/c.total*100).toFixed(1)}% prompt logs trong to\xe0n bộ dữ liệu khớp bộ lọc.`});let p=d?.topServerErrors?.[0];return p&&p.requests>=5&&g.push({level:p.requests>=20?"danger":"warning",title:"Provider/Gateway c\xf3 lỗi cần xử l\xfd",detail:`${p.provider||p.errorSource||"unknown"}/${p.model||"unknown"} c\xf3 ${p.requests.toLocaleString("vi-VN")} lỗi ${p.errorType||p.status||"server-impacting"}.`}),e?.samples>=10&&Y(e.slowRequestRate,0)>=.2&&g.push({level:e.slowRequestRate>=.4?"danger":"warning",title:"Nhiều request phản hồi chậm",detail:`${(100*e.slowRequestRate).toFixed(1)}% request th\xe0nh c\xf4ng c\xf3 latency >= 45s. Kiểm tra request input d\xe0i, chờ slot/upstream queue v\xe0 tải model server.`}),e?.samples>=10&&Y(e.longInputRate,0)>=.3&&g.push({level:"warning",title:"Tỷ lệ request input d\xe0i cao",detail:`${(100*e.longInputRate).toFixed(1)}% request c\xf3 input >= 30k token. Với VS Code/agent, P95/P99 latency cao c\xf3 thể chủ yếu do prompt eval v\xe0 chờ slot, kh\xf4ng phải do output chậm.`}),f?.summary?.topUserTokenShare>=.35&&g.push({level:f.summary.topUserTokenShare>=.6?"danger":"warning",title:"Token usage tập trung v\xe0o một user/API key",detail:`${f.summary.topUserLabel||"Một client"} đang chiếm ${(100*f.summary.topUserTokenShare).toFixed(1)}% tổng token trong khoảng lọc. N\xean kiểm tra quota, workflow VS Code/agent v\xe0 request input d\xe0i của client n\xe0y.`}),f?.summary?.extremeInputShare>=.1&&g.push({level:f.summary.extremeInputShare>=.25?"danger":"warning",title:"Nhiều request cực d\xe0i >=70k token",detail:`${(100*f.summary.extremeInputShare).toFixed(1)}% request th\xe0nh c\xf4ng c\xf3 input >=70k token. Đ\xe2y l\xe0 nh\xf3m dễ k\xe9o TTFT/P95/P99 l\xean cao v\xe0 l\xe0m request nhỏ phải chờ slot.`}),g}({overview:p,groups:q,promptLogStats:s,requestErrorStats:t,experience:w,clientRequests:x}),F={generatedAt:new Date().toISOString(),analyticsVersion:"v3.5-token-consumer-monitor",filters:{period:k.period,startIso:k.startIso,endIso:k.endIso,provider:k.provider,model:k.model,connectionId:k.connectionId,status:k.status,endpoint:k.endpoint,apiKey:k.apiKey,clientIp:k.clientIp,sourceTool:k.sourceTool,sessionId:k.sessionId,keyword:k.keyword,userOwnedOnly:k.userOwnedOnly},overview:p,latency:r,experience:w,clientRequests:x,timeSeries:y,groups:q,promptLogs:s,requestErrors:t,anomalies:E,recentUsage:z,heavyRequests:A,options:D,qualityNotes:[]};if(await a2(h),c.set(b,{createdAt:Date.now(),data:F}),c.size>100){for(let[a,b]of c)if(Date.now()-b.createdAt>15e3&&c.delete(a),c.size<=100)break}return F}catch(a){throw await a2(h),console.error("[dashboardAnalytics] MySQL observability query failed; SQLite fallback is disabled:",a?.message||a),a}}var a4=c(9588);let a5="force-dynamic",a6=["period","dateFrom","dateTo","provider","model","connectionId","status","endpoint","apiKey","clientIp","sourceIp","sourceTool","sessionId","keyword","maxPromptLogRows"];async function a7(a){try{let{access:b,response:c}=await (0,a4.oW)();if(c)return c;let{searchParams:d}=new URL(a.url),e=function(a){let b={};for(let c of a6){let d=a.get(c);null!==d&&""!==String(d).trim()&&(b[c]=d)}return b}(d),f=b.isAdmin||b.isMonitorAdmin?e:{...e,userOwnedOnly:!0,ownerCandidates:[...new Set([...b.candidates||[],b.userId].map(a4.I8).filter(Boolean))]},g=await a3(f);if("csv"===d.get("format")){let a=(function(a){let b=[];for(let[c,d]of(b.push(["section","key","label","requests","success","errors","errorRate","inputTokens","outputTokens","totalTokens","cost","lastSeen"]),[["providers",a.groups.providers],["models",a.groups.models],["providerAccounts",a.groups.providerAccounts],["apiKeys",a.groups.apiKeys],["endpoints",a.groups.endpoints],["clientIps",a.promptLogs.topClientIps],["sourceTools",a.promptLogs.topSourceTools],["requestErrors",a.requestErrors?.topErrors||a.groups.errors],["modelExperience",a.experience?.byModel||[]],["clientHeavyUsers",a.clientRequests?.topHeavyUsers||[]],["clientTopApiKeysByTokens",a.clientRequests?.topApiKeysByTokens||[]],["clientTopSourceIpsByTokens",a.clientRequests?.topSourceIpsByTokens||[]],["clientTopSourceIpsByHeavyRequests",a.clientRequests?.topSourceIpsByHeavyRequests||[]],["clientProblemClients",a.clientRequests?.topProblemClients||[]],["inputBuckets",a.clientRequests?.inputBuckets||[]]]))for(let a of d||[])b.push([c,a.key||"",a.label||a.name||"",a.requests||0,a.success||0,a.errors||0,a.errorRate||0,a.promptTokens||0,a.completionTokens||0,a.totalTokens||0,a.cost||0,a.lastSeen||""]);return b})(g).map(a=>a.map(a_).join(",")).join("\n");return new Response(a,{status:200,headers:{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="bluerouter-analytics-${new Date().toISOString().slice(0,10)}.csv"`,"Cache-Control":"no-store"}})}return v.NextResponse.json(g,{headers:{"Cache-Control":"no-store"}})}catch(a){return console.error("[analytics] Failed to build dashboard analytics:",a),v.NextResponse.json({error:a?.message||"Failed to build dashboard analytics"},{status:500})}}let a8=new e.AppRouteRouteModule({definition:{kind:f.RouteKind.APP_ROUTE,page:"/api/dashboard/analytics/route",pathname:"/api/dashboard/analytics",filename:"route",bundlePath:"app/api/dashboard/analytics/route"},distDir:".next-cli-build",relativeProjectDir:"",resolvedPagePath:"D:\\bluerouter\\src\\app\\api\\dashboard\\analytics\\route.js",nextConfigOutput:"standalone",userland:d,...{}}),{workAsyncStorage:a9,workUnitAsyncStorage:ba,serverHooks:bb}=a8;function bc(){return(0,g.patchFetch)({workAsyncStorage:a9,workUnitAsyncStorage:ba})}async function bd(a,b,c){c.requestMeta&&(0,h.setRequestMeta)(a,c.requestMeta),a8.isDev&&(0,h.addRequestMeta)(a,"devRequestTimingInternalsEnd",process.hrtime.bigint());let d="/api/dashboard/analytics/route";"/index"===d&&(d="/");let e=await a8.prepare(a,b,{srcPage:d,multiZoneDraftMode:!1});if(!e)return b.statusCode=400,b.end("Bad Request"),null==c.waitUntil||c.waitUntil.call(c,Promise.resolve()),null;let{buildId:g,deploymentId:v,params:w,nextConfig:x,parsedUrl:y,isDraftMode:z,prerenderManifest:A,routerServerContext:B,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,resolvedPathname:E,clientReferenceManifest:F,serverActionsManifest:G}=e,H=(0,k.normalizeAppPath)(d),I=!!(A.dynamicRoutes[H]||A.routes[E]),J=async()=>((null==B?void 0:B.render404)?await B.render404(a,b,y,!1):b.end("This page could not be found"),null);if(I&&!z){let a=!!A.routes[E],b=A.dynamicRoutes[H];if(b&&!1===b.fallback&&!a){if(x.adapterPath)return await J();throw new t.NoFallbackError}}let K=null;!I||a8.isDev||z||(K="/index"===(K=E)?"/":K);let L=!0===a8.isDev||!I,M=I&&!L;G&&F&&(0,j.setManifestsSingleton)({page:d,clientReferenceManifest:F,serverActionsManifest:G});let N=a.method||"GET",O=(0,i.getTracer)(),P=O.getActiveScopeSpan(),Q=!!(null==B?void 0:B.isWrappedByNextServer),R=!!(0,h.getRequestMeta)(a,"minimalMode"),S=(0,h.getRequestMeta)(a,"incrementalCache")||await a8.getIncrementalCache(a,x,A,R);null==S||S.resetRequestCache(),globalThis.__incrementalCache=S;let T={params:w,previewProps:A.preview,renderOpts:{experimental:{authInterrupts:!!x.experimental.authInterrupts},cacheComponents:!!x.cacheComponents,supportsDynamicResponse:L,incrementalCache:S,cacheLifeProfiles:x.cacheLife,waitUntil:c.waitUntil,onClose:a=>{b.on("close",a)},onAfterTaskError:void 0,onInstrumentationRequestError:(b,c,d,e)=>a8.onRequestError(a,b,d,e,B)},sharedContext:{buildId:g,deploymentId:v}},U=new l.NodeNextRequest(a),V=new l.NodeNextResponse(b),W=m.NextRequestAdapter.fromNodeNextRequest(U,(0,m.signalFromNodeResponse)(b));try{let e,g=async a=>a8.handle(W,T).finally(()=>{if(!a)return;a.setAttributes({"http.status_code":b.statusCode,"next.rsc":!1});let c=O.getRootSpanAttributes();if(!c)return;if(c.get("next.span_type")!==n.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${c.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let f=c.get("next.route");if(f){let b=`${N} ${f}`;a.setAttributes({"next.route":f,"http.route":f,"next.span_name":b}),a.updateName(b),e&&e!==a&&(e.setAttribute("http.route",f),e.updateName(b))}else a.updateName(`${N} ${d}`)}),h=async e=>{var h,i;let j=async({previousCacheEntry:f})=>{try{if(!R&&C&&D&&!f)return b.statusCode=404,b.setHeader("x-nextjs-cache","REVALIDATED"),b.end("This page could not be found"),null;let d=await g(e);a.fetchMetrics=T.renderOpts.fetchMetrics;let h=T.renderOpts.pendingWaitUntil;h&&c.waitUntil&&(c.waitUntil(h),h=void 0);let i=T.renderOpts.collectedTags;if(!I)return await (0,p.I)(U,V,d,T.renderOpts.pendingWaitUntil),null;{let a=await d.blob(),b=(0,q.toNodeOutgoingHttpHeaders)(d.headers);i&&(b[s.NEXT_CACHE_TAGS_HEADER]=i),!b["content-type"]&&a.type&&(b["content-type"]=a.type);let c=void 0!==T.renderOpts.collectedRevalidate&&!(T.renderOpts.collectedRevalidate>=s.INFINITE_CACHE)&&T.renderOpts.collectedRevalidate,e=void 0===T.renderOpts.collectedExpire||T.renderOpts.collectedExpire>=s.INFINITE_CACHE?void 0:T.renderOpts.collectedExpire;return{value:{kind:u.CachedRouteKind.APP_ROUTE,status:d.status,body:Buffer.from(await a.arrayBuffer()),headers:b},cacheControl:{revalidate:c,expire:e}}}}catch(b){throw(null==f?void 0:f.isStale)&&await a8.onRequestError(a,b,{routerKind:"App Router",routePath:d,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),b}},k=await a8.handleResponse({req:a,nextConfig:x,cacheKey:K,routeKind:f.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:A,isRoutePPREnabled:!1,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,responseGenerator:j,waitUntil:c.waitUntil,isMinimalMode:R});if(!I)return null;if((null==k||null==(h=k.value)?void 0:h.kind)!==u.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==k||null==(i=k.value)?void 0:i.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});R||b.setHeader("x-nextjs-cache",C?"REVALIDATED":k.isMiss?"MISS":k.isStale?"STALE":"HIT"),z&&b.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let l=(0,q.fromNodeOutgoingHttpHeaders)(k.value.headers);return R&&I||l.delete(s.NEXT_CACHE_TAGS_HEADER),!k.cacheControl||b.getHeader("Cache-Control")||l.get("Cache-Control")||l.set("Cache-Control",(0,r.getCacheControlHeader)(k.cacheControl)),await (0,p.I)(U,V,new Response(k.value.body,{headers:l,status:k.value.status||200})),null};Q&&P?await h(P):(e=O.getActiveScopeSpan(),await O.withPropagatedContext(a.headers,()=>O.trace(n.BaseServerSpan.handleRequest,{spanName:`${N} ${d}`,kind:i.SpanKind.SERVER,attributes:{"http.method":N,"http.target":a.url}},h),void 0,!Q))}catch(b){if(b instanceof t.NoFallbackError||await a8.onRequestError(a,b,{routerKind:"App Router",routePath:H,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),I)throw b;return await (0,p.I)(U,V,new Response(null,{status:500})),null}}},63033:a=>{a.exports=require("next/dist/server/app-render/work-unit-async-storage.external.js")},64939:a=>{a.exports=import("pg")},66136:a=>{a.exports=require("timers")},69614:(a,b,c)=>{c.d(b,{V:()=>p});var d=c(88888),e=c(91356),f=c(99129),g=c(73575),h=c(41570),i=c(19035),j=c(24762),k=c(80308),l=c(11980);async function m(a,b,c){if(!(0,i.Gv)(a))throw new f.Ye("Flattened JWS must be an object");if(void 0===a.protected&&void 0===a.header)throw new f.Ye('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==a.protected&&"string"!=typeof a.protected)throw new f.Ye("JWS Protected Header incorrect type");if(void 0===a.payload)throw new f.Ye("JWS Payload missing");if("string"!=typeof a.signature)throw new f.Ye("JWS Signature missing or incorrect type");if(void 0!==a.header&&!(0,i.Gv)(a.header))throw new f.Ye("JWS Unprotected Header incorrect type");let m={};if(a.protected)try{let b=(0,d.D)(a.protected);m=JSON.parse(g.D0.decode(b))}catch{throw new f.Ye("JWS Protected Header is invalid")}if(!(0,i.fz)(m,a.header))throw new f.Ye("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");let n={...m,...a.header},o=(0,k.n)(f.Ye,new Map([["b64",!0]]),c?.crit,m,n),p=!0;if(o.has("b64")&&"boolean"!=typeof(p=m.b64))throw new f.Ye('The "b64" (base64url-encode payload) Header Parameter must be a boolean');let{alg:q}=n;if("string"!=typeof q||!q)throw new f.Ye('JWS "alg" (Algorithm) Header Parameter missing or invalid');let r=c&&function(a,b){if(void 0!==b&&(!Array.isArray(b)||b.some(a=>"string"!=typeof a)))throw TypeError(`"${a}" option must be an array of strings`);if(b)return new Set(b)}("algorithms",c.algorithms);if(r&&!r.has(q))throw new f.Rb('"alg" (Algorithm) Header Parameter value not allowed');if(p){if("string"!=typeof a.payload)throw new f.Ye("JWS Payload must be a string")}else if("string"!=typeof a.payload&&!(a.payload instanceof Uint8Array))throw new f.Ye("JWS Payload must be a string or an Uint8Array instance");let s=!1;"function"==typeof b&&(b=await b(m,a),s=!0),(0,j.y)(q,b,"verify");let t=(0,g.xW)(void 0!==a.protected?(0,g.lF)(a.protected):new Uint8Array,(0,g.lF)("."),"string"==typeof a.payload?p?(0,g.lF)(a.payload):g.Rd.encode(a.payload):a.payload),u=(0,h.h2)(a.signature,"signature",f.Ye),v=await (0,l.l)(b,q);if(!await (0,e.MX)(q,v,u,t))throw new f.h2;let w={payload:p?(0,h.h2)(a.payload,"payload",f.Ye):"string"==typeof a.payload?g.Rd.encode(a.payload):a.payload};return(void 0!==a.protected&&(w.protectedHeader=m),void 0!==a.header&&(w.unprotectedHeader=a.header),s)?{...w,key:v}:w}async function n(a,b,c){if(a instanceof Uint8Array&&(a=g.D0.decode(a)),"string"!=typeof a)throw new f.Ye("Compact JWS must be a string or Uint8Array");let{0:d,1:e,2:h,length:i}=a.split(".");if(3!==i)throw new f.Ye("Invalid Compact JWS");let j=await m({payload:e,protected:d,signature:h},b,c),k={payload:j.payload,protectedHeader:j.protectedHeader};return"function"==typeof b?{...k,key:j.key}:k}var o=c(17347);async function p(a,b,c){let d=await n(a,b,c);if(d.protectedHeader.crit?.includes("b64")&&!1===d.protectedHeader.b64)throw new f.Dp("JWTs MUST NOT use unencoded payload");let e={payload:(0,o.k6)(d.protectedHeader,d.payload,c),protectedHeader:d.protectedHeader};return"function"==typeof b?{...e,key:d.key}:e}},73024:a=>{a.exports=require("node:fs")},74075:a=>{a.exports=require("zlib")},76760:a=>{a.exports=require("node:path")},77598:a=>{a.exports=require("node:crypto")},79428:a=>{a.exports=require("buffer")},79868:a=>{a.exports=require("node:sqlite")},81787:a=>{a.exports=require("bun:sqlite")},86439:a=>{a.exports=require("next/dist/shared/lib/no-fallback-error.external")},87550:a=>{a.exports=require("better-sqlite3")},90389:(a,b,c)=>{c.d(b,{hS:()=>d});let d=Object.freeze({ADMIN:"admin",MONITOR_ADMIN:"monitor_admin",USER:"user",GUEST:"guest"});Object.freeze([{href:"/dashboard/endpoint",label:"Endpoint",icon:"api"},{href:"/dashboard/api-keys",label:"API Keys",icon:"vpn_key"},{href:"/dashboard/usage",label:"Usage",icon:"bar_chart"},{href:"/dashboard/analytics",label:"Analytics",icon:"monitoring"},{href:"/dashboard/quota",label:"Quota Tracker",icon:"data_usage"},{href:"/dashboard/prompt-logs",label:"Prompt Logs",icon:"manage_search"}]),Object.freeze(["/dashboard","/dashboard/endpoint","/dashboard/api-keys","/dashboard/usage","/dashboard/analytics","/dashboard/quota","/dashboard/prompt-logs"])},91645:a=>{a.exports=require("net")},94735:a=>{a.exports=require("events")},94755:(a,b,c)=>{c.d(b,{A:()=>i});var d=c(77598);let e={randomUUID:d.randomUUID},f=new Uint8Array(256),g=f.length;var h=c(50122);let i=function(a,b,c){if(e.randomUUID&&!b&&!a)return e.randomUUID();var i=a,j=c;let k=(i=i||{}).random??i.rng?.()??(g>f.length-16&&((0,d.randomFillSync)(f),g=0),f.slice(g,g+=16));if(k.length<16)throw Error("Random bytes length must be >= 16");if(k[6]=15&k[6]|64,k[8]=63&k[8]|128,b){if((j=j||0)<0||j+16>b.length)throw RangeError(`UUID byte range ${j}:${j+15} is out of buffer bounds`);for(let a=0;a<16;++a)b[j+a]=k[a];return b}return(0,h.k)(k)}},97242:(a,b,c)=>{c.d(b,{DU:()=>s,Ws:()=>t,_3:()=>v,nv:()=>u});var d=c(45903);let e=new Set;function f(a,b,c=null){let d=Number(a);if(!Number.isFinite(d)||d<0)return b;let e=Math.floor(d);return c?Math.min(e,c):e}function g(a){return String(a||"").trim()}async function h(){return(0,d.I6)(await (0,d.L7)())}async function i(a){let b=new(await Promise.resolve().then(c.bind(c,64939))).Client({host:a.host,port:Number(a.port||5432),database:a.database,user:a.username,password:a.password,ssl:!!a.ssl&&{rejectUnauthorized:!1}});return await b.connect(),{type:"postgres",query:async(a,c=[])=>(await b.query(a,c)).rows,queryOne:async(a,c=[])=>(await b.query(a,c)).rows[0]||null,async exec(a,c=[]){await b.query(a,c)},async close(){await b.end()}}}async function j(a){let b=await c.e(8491).then(c.t.bind(c,38491,19)),d=await b.createConnection({host:a.host,port:Number(a.port||3306),database:a.database,user:a.username,password:a.password,ssl:a.ssl?{}:void 0,dateStrings:!0,connectTimeout:3e3});return{type:"mysql",async query(a,b=[]){let[c]=await d.query(a,b);return c},async queryOne(a,b=[]){let[c]=await d.query(a,b);return c[0]||null},async exec(a,b=[]){await d.query(a,b)},async close(){await d.end()}}}async function k(a){if("postgres"===a.type)return i(a);if("mysql"===a.type)return j(a);throw Error(`Unsupported prompt log database type: ${a.type}`)}async function l(a,b){if(!b||b.full_request_json)return b;let c=function(a={}){return String(a.payload_hash||function(a){if(!a)return{};if("object"==typeof a)return a;try{return JSON.parse(a)}catch{return{}}}(a.meta_json).payloadHash||"").trim()}(b);if(!c)return b;try{let d=await a.queryOne("SELECT COUNT(1) AS count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'prompt_log_payloads'");if(0===Number(d?.count||0))return b;let e=await a.queryOne("SELECT payload_json FROM prompt_log_payloads WHERE payload_hash = ?",[c]);if(!e)return b;let f=e.payload_json;return{...b,full_request_json:"string"==typeof f?f:JSON.stringify(f)}}catch{return b}}async function m(a){let b=await i(a);try{for(let a of["CREATE INDEX IF NOT EXISTS idx_prompt_logs_created_id ON prompt_logs (created_at DESC, id)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_stage_created_at ON prompt_logs (stage, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_model_created_at ON prompt_logs (model, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_display_model_created_at ON prompt_logs (display_model, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_session_created_at ON prompt_logs (session_id, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_client_ip_created_at ON prompt_logs (client_ip, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_source_tool_created_at ON prompt_logs (source_tool, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_connection_created_at ON prompt_logs (connection_id, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_account_created_at ON prompt_logs (account_name, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_provider_created_at ON prompt_logs (provider, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_status_created_at ON prompt_logs (status_code, created_at DESC)","CREATE INDEX IF NOT EXISTS idx_prompt_logs_payload_hash ON prompt_logs (payload_hash)"])await b.exec(a)}finally{await b.close()}}async function n(a,b,c){let d=await a.queryOne("SELECT COUNT(1) AS count FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'prompt_logs' AND INDEX_NAME = ?",[b]);0===Number(d?.count||0)&&await a.exec(c)}async function o(a){let b=await j(a);try{let a=await b.queryOne("SELECT COUNT(1) AS count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'prompt_logs'");if(0===Number(a?.count||0))return;for(let[a,c]of[["idx_prompt_logs_created_id","CREATE INDEX idx_prompt_logs_created_id ON prompt_logs (created_at DESC, id)"],["idx_prompt_logs_stage_created_at","CREATE INDEX idx_prompt_logs_stage_created_at ON prompt_logs (stage, created_at DESC)"],["idx_prompt_logs_model_created_at","CREATE INDEX idx_prompt_logs_model_created_at ON prompt_logs (model, created_at DESC)"],["idx_prompt_logs_display_model_created_at","CREATE INDEX idx_prompt_logs_display_model_created_at ON prompt_logs (display_model, created_at DESC)"],["idx_prompt_logs_session_created_at","CREATE INDEX idx_prompt_logs_session_created_at ON prompt_logs (session_id, created_at DESC)"],["idx_prompt_logs_client_ip_created_at","CREATE INDEX idx_prompt_logs_client_ip_created_at ON prompt_logs (client_ip, created_at DESC)"],["idx_prompt_logs_source_tool_created_at","CREATE INDEX idx_prompt_logs_source_tool_created_at ON prompt_logs (source_tool, created_at DESC)"],["idx_prompt_logs_connection_created_at","CREATE INDEX idx_prompt_logs_connection_created_at ON prompt_logs (connection_id, created_at DESC)"],["idx_prompt_logs_account_created_at","CREATE INDEX idx_prompt_logs_account_created_at ON prompt_logs (account_name, created_at DESC)"],["idx_prompt_logs_provider_created_at","CREATE INDEX idx_prompt_logs_provider_created_at ON prompt_logs (provider, created_at DESC)"],["idx_prompt_logs_status_created_at","CREATE INDEX idx_prompt_logs_status_created_at ON prompt_logs (status_code, created_at DESC)"],["idx_prompt_logs_payload_hash","CREATE INDEX idx_prompt_logs_payload_hash ON prompt_logs (payload_hash)"]])await n(b,a,c)}finally{await b.close()}}async function p(a){if(!a.enabled)return;let b=`${a.type}:${a.host||""}:${a.port||""}:${a.database||""}`;if(!e.has(b))try{if("postgres"===a.type)await m(a);else if("mysql"===a.type)await o(a);else throw Error(`Unsupported prompt log database type: ${a.type}`);e.add(b)}catch(a){console.warn("[prompt-logs] Unable to ensure query indexes:",a.message)}}async function q(a){let b=await k(a);try{let c=(await b.query("SELECT DISTINCT COALESCE(NULLIF(display_model, ''), model) AS model FROM prompt_logs WHERE model IS NOT NULL AND model <> '' ORDER BY model LIMIT 300")).map(a=>a.model),d=(await b.query("SELECT DISTINCT stage FROM prompt_logs WHERE stage IS NOT NULL AND stage <> '' ORDER BY stage LIMIT 100")).map(a=>a.stage);return{models:c,stages:d,dbInfo:{type:a.type,host:a.host,database:a.database}}}finally{await b.close()}}async function r(a,b){let c=a.type,d=await k(a);try{let e=function(a,b){let c=[],d=[],e=a=>(d.push(a),"postgres"===b)?`$${d.length}`:"?",f="postgres"===b?"ILIKE":"LIKE";if(a.keyword){let b=`%${a.keyword}%`;c.push(`(${["prompt_text","response_text","error_text","model","endpoint","provider_url","provider","account_name","connection_id","display_model","session_id","client_ip","client_host","client_user_agent","source_tool","source_tool_label","source_host"].map(a=>`${a} ${f} ${e(b)}`).join(" OR ")})`)}if(a.model&&c.push(`(model = ${e(a.model)} OR display_model = ${e(a.model)})`),a.stage&&c.push(`stage = ${e(a.stage)}`),a.sessionId&&c.push(`session_id = ${e(a.sessionId)}`),a.clientIp&&c.push(`client_ip ${f} ${e(`%${a.clientIp}%`)}`),a.sourceTool){let b=`%${a.sourceTool}%`;c.push(`(source_tool ${f} ${e(b)} OR source_tool_label ${f} ${e(b)} OR source_host ${f} ${e(b)})`)}return a.dateFrom&&c.push(`created_at >= ${e(a.dateFrom)}`),a.dateTo&&c.push(`created_at <= ${e(a.dateTo)}`),{clause:c.length?`WHERE ${c.join(" AND ")}`:"",params:d,add:e}}(b,c),f=[...e.params],g=await d.queryOne(`SELECT COUNT(*) AS count FROM prompt_logs ${e.clause}`,f),h=e.add(b.limit),i=e.add(b.offset),j="postgres"===c?"LEFT(coalesce(prompt_text,''), 900)":"SUBSTRING(coalesce(prompt_text,''), 1, 900)",k="postgres"===c?"char_length(coalesce(prompt_text,''))":"CHAR_LENGTH(coalesce(prompt_text,''))",l="postgres"===c?"LEFT(coalesce(response_text,''), 400)":"SUBSTRING(coalesce(response_text,''), 1, 400)",m=await d.query(`
|
|
419
419
|
SELECT
|
|
420
420
|
id,
|
|
421
421
|
created_at,
|