n9router 0.4.53 → 0.4.55
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/BUILD_ID +1 -1
- package/app/.next/app-path-routes-manifest.json +16 -12
- package/app/.next/build-manifest.json +2 -2
- package/app/.next/prerender-manifest.json +3 -3
- package/app/.next/routes-manifest.json +24 -0
- package/app/.next/server/app/(dashboard)/dashboard/basic-chat/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/web/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/proxy-pools/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/pxpipe/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/skills/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/token-saver/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page.js +3 -3
- package/app/.next/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_global-error/page.js +2 -2
- package/app/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_global-error.html +1 -1
- package/app/.next/server/app/_global-error.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/_not-found/page.js +2 -2
- package/app/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_not-found.html +1 -1
- package/app/.next/server/app/_not-found.rsc +4 -4
- package/app/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/api/antigravity-app/route.js +1 -1
- package/app/.next/server/app/api/antigravity-app-v2/route.js +1 -1
- package/app/.next/server/app/api/antigravity-ide/route.js +1 -1
- package/app/.next/server/app/api/antigravity-targets/route.js +1 -1
- package/app/.next/server/app/api/antigravity-tools/import/route.js +1 -1
- package/app/.next/server/app/api/antigravity-tools/import/route.js.nft.json +1 -1
- package/app/.next/server/app/api/antigravity-tools/import-refresh-tokens/route.js +1 -1
- package/app/.next/server/app/api/antigravity-tools/import-refresh-tokens/route.js.nft.json +1 -1
- package/app/.next/server/app/api/auth/login/route.js +3 -1
- package/app/.next/server/app/api/auth/login/route.js.nft.json +1 -1
- package/app/.next/server/app/api/auth/logout/route.js +1 -1
- package/app/.next/server/app/api/auth/oidc/callback/route.js +1 -1
- package/app/.next/server/app/api/auth/oidc/start/route.js +1 -1
- package/app/.next/server/app/api/auth/oidc/test/route.js +1 -1
- package/app/.next/server/app/api/auth/reset-password/route.js +1 -1
- package/app/.next/server/app/api/auth/saml/acs/route.js +3 -0
- package/app/.next/server/app/api/auth/saml/acs/route.js.nft.json +1 -0
- package/app/.next/server/app/api/auth/saml/acs/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/auth/saml/metadata/route.js +3 -0
- package/app/.next/server/app/api/auth/saml/metadata/route.js.nft.json +1 -0
- package/app/.next/server/app/api/auth/saml/metadata/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/auth/saml/start/route.js +3 -0
- package/app/.next/server/app/api/auth/saml/start/route.js.nft.json +1 -0
- package/app/.next/server/app/api/auth/saml/start/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/auth/saml/test/route.js +3 -0
- package/app/.next/server/app/api/auth/saml/test/route.js.nft.json +1 -0
- package/app/.next/server/app/api/auth/saml/test/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/auth/status/route.js +3 -1
- package/app/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/app/.next/server/app/api/cli-tools/all-statuses/route.js +7 -6
- package/app/.next/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/claude-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/cline-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/codex-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/copilot-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/cowork-mcp-registry/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cowork-mcp-tools/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/cowork-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
- package/app/.next/server/app/api/cli-tools/cursor-byok/jobs/[jobId]/events/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/cursor-byok/jobs/[jobId]/sudo/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cursor-byok/jobs/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cursor-byok/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/deepseek-tui-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/devin-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/droid-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/grok-build-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/hermes-settings/route.js +4 -3
- package/app/.next/server/app/api/cli-tools/jcode-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/kilo-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/openclaw-settings/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/opencode-settings/route.js +1 -1
- package/app/.next/server/app/api/combos/[id]/route.js +1 -1
- package/app/.next/server/app/api/combos/route.js +1 -1
- package/app/.next/server/app/api/donate/route.js +1 -1
- package/app/.next/server/app/api/headroom/extras/route.js +1 -1
- package/app/.next/server/app/api/headroom/proxy/[...path]/route.js +1 -1
- package/app/.next/server/app/api/headroom/restart/route.js +1 -1
- package/app/.next/server/app/api/headroom/start/route.js +1 -1
- package/app/.next/server/app/api/headroom/status/route.js +1 -1
- package/app/.next/server/app/api/headroom/stop/route.js +1 -1
- package/app/.next/server/app/api/health/route.js +1 -1
- package/app/.next/server/app/api/init/route.js +1 -1
- package/app/.next/server/app/api/internal/account-health/route.js +1 -1
- package/app/.next/server/app/api/internal/request-detail/route.js +1 -1
- package/app/.next/server/app/api/internal/usage/route.js +1 -1
- package/app/.next/server/app/api/keys/[id]/reset-usage/route.js +1 -1
- package/app/.next/server/app/api/keys/[id]/route.js +1 -1
- package/app/.next/server/app/api/keys/[id]/usage/route.js +1 -1
- package/app/.next/server/app/api/keys/route.js +1 -1
- package/app/.next/server/app/api/locale/route.js +1 -1
- package/app/.next/server/app/api/mcp/[plugin]/message/route.js +1 -1
- package/app/.next/server/app/api/mcp/[plugin]/sse/route.js +2 -2
- package/app/.next/server/app/api/media-providers/tts/deepgram/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
- package/app/.next/server/app/api/media-providers/tts/inworld/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/minimax/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
- package/app/.next/server/app/api/models/alias/route.js +1 -1
- package/app/.next/server/app/api/models/availability/route.js +1 -1
- package/app/.next/server/app/api/models/custom/route.js +1 -1
- package/app/.next/server/app/api/models/disabled/route.js +1 -1
- package/app/.next/server/app/api/models/route.js +1 -1
- package/app/.next/server/app/api/models/route.js.nft.json +1 -1
- package/app/.next/server/app/api/models/test/route.js +1 -1
- package/app/.next/server/app/api/models/test/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/[provider]/[action]/route.js +1 -1
- package/app/.next/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/codex/bulk-import/route.js +1 -1
- package/app/.next/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/codex/import-token/route.js +1 -1
- package/app/.next/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/cursor/auto-import/route.js +2 -2
- package/app/.next/server/app/api/oauth/cursor/import/route.js +1 -1
- package/app/.next/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/gitlab/pat/route.js +1 -1
- package/app/.next/server/app/api/oauth/iflow/cookie/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/api-key/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/kiro/auto-import/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/import/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/kiro/import-cli-proxy/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-authorize/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
- package/app/.next/server/app/api/pricing/route.js +1 -1
- package/app/.next/server/app/api/provider-nodes/[id]/route.js +1 -1
- package/app/.next/server/app/api/provider-nodes/route.js +1 -1
- package/app/.next/server/app/api/provider-nodes/route.js.nft.json +1 -1
- package/app/.next/server/app/api/provider-nodes/validate/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/models/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
- package/app/.next/server/app/api/providers/[id]/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
- package/app/.next/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
- package/app/.next/server/app/api/providers/client/route.js +1 -1
- package/app/.next/server/app/api/providers/client/route.js.nft.json +1 -1
- package/app/.next/server/app/api/providers/kilo/free-models/route.js +1 -1
- package/app/.next/server/app/api/providers/route.js +1 -1
- package/app/.next/server/app/api/providers/route.js.nft.json +1 -1
- package/app/.next/server/app/api/providers/suggested-models/route.js +1 -1
- package/app/.next/server/app/api/providers/test-batch/route.js +1 -1
- package/app/.next/server/app/api/providers/test-batch/route.js.nft.json +1 -1
- package/app/.next/server/app/api/providers/validate/route.js +1 -1
- package/app/.next/server/app/api/providers/validate/route.js.nft.json +1 -1
- package/app/.next/server/app/api/proxy-pools/[id]/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/[id]/test/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/cloudflare-deploy/route.js +2 -2
- package/app/.next/server/app/api/proxy-pools/deno-deploy/route.js +2 -2
- package/app/.next/server/app/api/proxy-pools/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/vercel-deploy/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/health/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/install/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/logs/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/restart/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/start/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/stats/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/status/route.js +2 -2
- package/app/.next/server/app/api/pxpipe/stop/route.js +2 -2
- package/app/.next/server/app/api/settings/database/route.js +1 -1
- package/app/.next/server/app/api/settings/database/selective/route.js +1 -1
- package/app/.next/server/app/api/settings/proxy-test/route.js +1 -1
- package/app/.next/server/app/api/settings/require-login/route.js +1 -1
- package/app/.next/server/app/api/settings/route.js +1 -1
- package/app/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/.next/server/app/api/shutdown/route.js +1 -1
- package/app/.next/server/app/api/tags/route.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/route.js.nft.json +1 -1
- package/app/.next/server/app/api/translator/console-logs/stream/route.js +2 -2
- package/app/.next/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
- package/app/.next/server/app/api/translator/load/route.js +1 -1
- package/app/.next/server/app/api/translator/save/route.js +1 -1
- package/app/.next/server/app/api/translator/send/route.js +1 -1
- package/app/.next/server/app/api/translator/send/route.js.nft.json +1 -1
- package/app/.next/server/app/api/translator/translate/route.js +1 -1
- package/app/.next/server/app/api/translator/translate/route.js.nft.json +1 -1
- package/app/.next/server/app/api/tunnel/disable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/disable/route.js.nft.json +1 -1
- package/app/.next/server/app/api/tunnel/enable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/enable/route.js.nft.json +1 -1
- package/app/.next/server/app/api/tunnel/status/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-check/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-disable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-enable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-install/route.js +2 -2
- package/app/.next/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
- package/app/.next/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
- package/app/.next/server/app/api/usage/[connectionId]/route.js +1 -1
- package/app/.next/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/usage/chart/route.js +1 -1
- package/app/.next/server/app/api/usage/history/route.js +1 -1
- package/app/.next/server/app/api/usage/logs/route.js +1 -1
- package/app/.next/server/app/api/usage/providers/route.js +1 -1
- package/app/.next/server/app/api/usage/providers/route.js.nft.json +1 -1
- package/app/.next/server/app/api/usage/report/route.js +1 -1
- package/app/.next/server/app/api/usage/request-details/route.js +1 -1
- package/app/.next/server/app/api/usage/request-logs/route.js +1 -1
- package/app/.next/server/app/api/usage/stats/route.js +1 -1
- package/app/.next/server/app/api/usage/stream/route.js +2 -2
- package/app/.next/server/app/api/v1/api/chat/route.js +1 -1
- package/app/.next/server/app/api/v1/api/chat/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/audio/speech/route.js +1 -1
- package/app/.next/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/audio/transcriptions/route.js +1 -1
- package/app/.next/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/audio/voices/route.js +1 -1
- package/app/.next/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/chat/completions/route.js +1 -1
- package/app/.next/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/embeddings/route.js +1 -1
- package/app/.next/server/app/api/v1/embeddings/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/images/generations/route.js +1 -1
- package/app/.next/server/app/api/v1/images/generations/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/messages/count_tokens/route.js +1 -1
- package/app/.next/server/app/api/v1/messages/route.js +1 -1
- package/app/.next/server/app/api/v1/messages/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/models/[kind]/route.js +1 -1
- package/app/.next/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/models/info/route.js +1 -1
- package/app/.next/server/app/api/v1/models/info/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/models/route.js +1 -1
- package/app/.next/server/app/api/v1/models/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/responses/compact/route.js +1 -1
- package/app/.next/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/responses/route.js +1 -1
- package/app/.next/server/app/api/v1/responses/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/route.js +1 -1
- package/app/.next/server/app/api/v1/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/search/route.js +1 -1
- package/app/.next/server/app/api/v1/search/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/videos/[id]/route.js +1 -1
- package/app/.next/server/app/api/v1/videos/[id]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/videos/edits/route.js +1 -1
- package/app/.next/server/app/api/v1/videos/edits/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/videos/extensions/route.js +1 -1
- package/app/.next/server/app/api/v1/videos/extensions/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/videos/generations/route.js +1 -1
- package/app/.next/server/app/api/v1/videos/generations/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1/web/fetch/route.js +1 -1
- package/app/.next/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1beta/models/[...path]/route.js +1 -1
- package/app/.next/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v1beta/models/route.js +1 -1
- package/app/.next/server/app/api/v1beta/models/route.js.nft.json +1 -1
- package/app/.next/server/app/api/version/route.js +1 -1
- package/app/.next/server/app/api/version/shutdown/route.js +1 -1
- package/app/.next/server/app/api/version/shutdown/route.js.nft.json +1 -1
- package/app/.next/server/app/api/version/update/route.js +1 -1
- package/app/.next/server/app/api/version/update/route.js.nft.json +1 -1
- package/app/.next/server/app/callback/page.js +2 -2
- package/app/.next/server/app/callback/page.js.nft.json +1 -1
- package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/callback.html +1 -1
- package/app/.next/server/app/callback.rsc +4 -4
- package/app/.next/server/app/callback.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/callback.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/callback.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/callback.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next/server/app/dashboard/basic-chat.rsc +6 -6
- package/app/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/basic-chat.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next/server/app/dashboard/cli-tools.rsc +6 -6
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/combos.html +1 -1
- package/app/.next/server/app/dashboard/combos.rsc +6 -6
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/combos.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/endpoint.html +1 -1
- package/app/.next/server/app/dashboard/endpoint.rsc +6 -6
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/endpoint.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/media-providers/web.html +1 -1
- package/app/.next/server/app/dashboard/media-providers/web.rsc +6 -6
- package/app/.next/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/mitm.html +1 -1
- package/app/.next/server/app/dashboard/mitm.rsc +6 -6
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/mitm.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/profile.html +1 -1
- package/app/.next/server/app/dashboard/profile.rsc +6 -6
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/profile.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers/new.html +1 -1
- package/app/.next/server/app/dashboard/providers/new.rsc +6 -6
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers.html +1 -1
- package/app/.next/server/app/dashboard/providers.rsc +6 -6
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next/server/app/dashboard/proxy-pools.rsc +6 -6
- package/app/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/pxpipe.html +1 -1
- package/app/.next/server/app/dashboard/pxpipe.rsc +6 -6
- package/app/.next/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/pxpipe.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/pxpipe.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/quota.html +2 -2
- package/app/.next/server/app/dashboard/quota.rsc +7 -7
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
- package/app/.next/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/quota.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/settings/pricing/page.js +2 -2
- package/app/.next/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
- package/app/.next/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.rsc +4 -4
- package/app/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/skills.html +1 -1
- package/app/.next/server/app/dashboard/skills.rsc +6 -6
- package/app/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/skills.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/token-saver.html +1 -1
- package/app/.next/server/app/dashboard/token-saver.rsc +6 -6
- package/app/.next/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/token-saver.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/token-saver.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/token-saver.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/translator.html +1 -1
- package/app/.next/server/app/dashboard/translator.rsc +6 -6
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/usage.html +1 -1
- package/app/.next/server/app/dashboard/usage.rsc +6 -6
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/usage.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard.html +1 -1
- package/app/.next/server/app/dashboard.rsc +6 -6
- package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/dashboard.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/favicon.ico/route.js +1 -1
- package/app/.next/server/app/index.html +1 -1
- package/app/.next/server/app/index.rsc +4 -4
- package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/landing/page.js +2 -2
- package/app/.next/server/app/landing/page.js.nft.json +1 -1
- package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/landing.html +1 -1
- package/app/.next/server/app/landing.rsc +4 -4
- package/app/.next/server/app/landing.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/landing.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/landing.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/landing.segment.rsc +1 -1
- package/app/.next/server/app/login/page.js +2 -2
- package/app/.next/server/app/login/page.js.nft.json +1 -1
- package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/login.html +1 -1
- package/app/.next/server/app/login.rsc +5 -5
- package/app/.next/server/app/login.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/login.segments/_index.segment.rsc +4 -4
- package/app/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/app/.next/server/app/manifest.webmanifest/route.js +2 -2
- package/app/.next/server/app/page.js +2 -2
- package/app/.next/server/app/page.js.nft.json +1 -1
- package/app/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app-paths-manifest.json +16 -12
- package/app/.next/server/chunks/112.js +1 -1
- package/app/.next/server/chunks/1470.js +1 -1
- package/app/.next/server/chunks/2251.js +1 -1
- package/app/.next/server/chunks/241.js +1 -1
- package/app/.next/server/chunks/318.js +26 -34
- package/app/.next/server/chunks/3481.js +1 -1
- package/app/.next/server/chunks/3913.js +1 -1
- package/app/.next/server/chunks/4037.js +1 -1
- package/app/.next/server/chunks/412.js +1 -1
- package/app/.next/server/chunks/4123.js +1 -1
- package/app/.next/server/chunks/4125.js +1 -1
- package/app/.next/server/chunks/4443.js +1 -1
- package/app/.next/server/chunks/4705.js +1 -1
- package/app/.next/server/chunks/4953.js +1 -0
- package/app/.next/server/chunks/4975.js +1 -1
- package/app/.next/server/chunks/5081.js +29 -0
- package/app/.next/server/chunks/5285.js +1 -0
- package/app/.next/server/chunks/5612.js +1 -1
- package/app/.next/server/chunks/5699.js +1 -1
- package/app/.next/server/chunks/6070.js +1 -1
- package/app/.next/server/chunks/615.js +1 -1
- package/app/.next/server/chunks/6630.js +1 -1
- package/app/.next/server/chunks/6671.js +1 -1
- package/app/.next/server/chunks/7137.js +1 -1
- package/app/.next/server/chunks/7211.js +1 -1
- package/app/.next/server/chunks/8145.js +1 -1
- package/app/.next/server/chunks/8301.js +3 -2
- package/app/.next/server/chunks/8499.js +7 -7
- package/app/.next/server/chunks/869.js +1 -1
- package/app/.next/server/chunks/8895.js +4 -4
- package/app/.next/server/chunks/8910.js +2 -2
- package/app/.next/server/chunks/9718.js +1 -1
- package/app/.next/server/instrumentation.js +1 -1
- package/app/.next/server/middleware-build-manifest.js +1 -1
- package/app/.next/server/middleware.js +2 -2
- package/app/.next/server/pages/404.html +1 -1
- package/app/.next/server/pages/500.html +1 -1
- package/app/.next/server/server-reference-manifest.js +1 -1
- package/app/.next/server/server-reference-manifest.json +1 -1
- package/app/.next/static/chunks/1321-99f0141dbac9848a.js +1 -0
- package/app/.next/static/chunks/{4028-f5a8d63d47b1b2cf.js → 4028-9d0d68c835868df5.js} +10 -9
- package/app/.next/static/chunks/{5497-91a1a5870e39d2d0.js → 5497-017258c3c16b719e.js} +2 -2
- package/app/.next/static/chunks/8198-bf66ab4ae1cda8e0.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-0d1269add49cb3e2.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/quota/page-c8a6e0e2bef2932e.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/token-saver/page-46e9c726ae1032e0.js +1 -0
- package/app/.next/static/chunks/app/_global-error/page-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/antigravity-app/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/antigravity-app-v2/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/antigravity-ide/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/antigravity-targets/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/antigravity-tools/import/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/antigravity-tools/import-refresh-tokens/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/login/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/logout/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/oidc/callback/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/oidc/start/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/oidc/test/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/reset-password/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/saml/acs/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/saml/metadata/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/saml/start/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/saml/test/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/auth/status/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/all-statuses/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cline-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/copilot-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cowork-mcp-registry/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cowork-mcp-tools/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cowork-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/jobs/[jobId]/events/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/jobs/[jobId]/sudo/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/jobs/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/deepseek-tui-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/devin-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/grok-build-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/hermes-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/jcode-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/kilo-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/opencode-settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/combos/[id]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/combos/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/donate/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/headroom/extras/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/headroom/proxy/[...path]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/headroom/restart/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/headroom/start/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/headroom/status/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/headroom/stop/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/health/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/init/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/internal/account-health/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/internal/request-detail/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/internal/usage/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/keys/[id]/reset-usage/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/keys/[id]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/keys/[id]/usage/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/keys/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/locale/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/mcp/[plugin]/message/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/mcp/[plugin]/sse/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/media-providers/tts/deepgram/voices/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/media-providers/tts/elevenlabs/voices/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/media-providers/tts/inworld/voices/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/media-providers/tts/minimax/voices/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/media-providers/tts/voices/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/models/alias/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/models/availability/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/models/custom/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/models/disabled/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/models/test/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/codex/bulk-import/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/codex/import-token/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/gitlab/pat/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/iflow/cookie/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/api-key/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/import-cli-proxy/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pricing/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/test-models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/client/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/kilo/free-models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/suggested-models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/test-batch/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/providers/validate/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/proxy-pools/[id]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/proxy-pools/[id]/test/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/proxy-pools/cloudflare-deploy/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/proxy-pools/deno-deploy/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/proxy-pools/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/proxy-pools/vercel-deploy/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/health/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/install/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/logs/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/restart/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/start/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/stats/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/status/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/pxpipe/stop/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/settings/database/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/settings/database/selective/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/settings/proxy-test/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/settings/require-login/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/settings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/shutdown/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tags/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/translator/console-logs/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/translator/console-logs/stream/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/translator/load/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/translator/save/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/translator/send/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/translator/translate/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/disable/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/enable/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/status/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/tailscale-check/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/tailscale-disable/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/tailscale-enable/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/tailscale-install/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/[connectionId]/codex-reset-credits/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/chart/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/history/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/logs/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/providers/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/report/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/request-details/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/request-logs/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/stats/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/usage/stream/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/api/chat/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/audio/speech/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/audio/transcriptions/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/audio/voices/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/embeddings/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/images/generations/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/messages/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/models/[kind]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/models/info/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/responses/compact/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/responses/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/search/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/videos/[id]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/videos/edits/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/videos/extensions/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/videos/generations/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1/web/fetch/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/v1beta/models/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/version/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/version/shutdown/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/api/version/update/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/login/page-e6ff5089ced15cea.js +1 -0
- package/app/.next/static/chunks/app/manifest.webmanifest/route-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/app/page-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-1a2fcb867d9ffccf.js +1 -0
- package/app/.next/static/css/c5181f678ef0b6e0.css +1 -0
- package/app/.next/static/flxITMsAmoXf-wWjPORMD/_buildManifest.js +1 -0
- package/app/custom-server.js +139 -0
- package/app/open-sse/config/providerModels.js +9 -1
- package/app/open-sse/executors/antigravity.js +12 -0
- package/app/open-sse/executors/index.js +0 -3
- package/app/open-sse/executors/kiro.js +1162 -530
- package/app/open-sse/executors/opencode.js +43 -5
- package/app/open-sse/executors/qoder.js +91 -5
- package/app/open-sse/handlers/chatCore/requestDetail.js +7 -6
- package/app/open-sse/handlers/chatCore.js +19 -5
- package/app/open-sse/handlers/search/callers.js +21 -0
- package/app/open-sse/handlers/ttsProviders/genericFormats.js +20 -0
- package/app/open-sse/providers/models/schema.js +8 -0
- package/app/open-sse/providers/registry/alitp-intl.js +35 -0
- package/app/open-sse/providers/registry/fish-audio.js +31 -0
- package/app/open-sse/providers/registry/glm-cn.js +1 -0
- package/app/open-sse/providers/registry/glm.js +1 -0
- package/app/open-sse/providers/registry/index.js +4 -0
- package/app/open-sse/providers/registry/kimchi.js +1 -1
- package/app/open-sse/providers/registry/opencode-go.js +22 -14
- package/app/open-sse/services/combo.js +39 -2
- package/app/open-sse/services/usage/claude.js +37 -1
- package/app/open-sse/services/usage.js +11 -3
- package/app/open-sse/translator/concerns/modality.js +13 -0
- package/app/open-sse/translator/formats/claude.js +93 -20
- package/app/open-sse/translator/request/claude-to-kiro.js +12 -0
- package/app/open-sse/translator/request/openai-responses.js +1 -0
- package/app/open-sse/translator/request/openai-to-kiro.js +12 -0
- package/app/open-sse/translator/response/kiro-to-claude.js +16 -0
- package/app/open-sse/translator/response/openai-responses.js +2 -2
- package/app/package.json +5 -4
- package/app/src/mitm/config.js +19 -1
- package/app/src/mitm/server.js +3 -4
- package/app/src/shared/constants/cliTools.js +6 -1
- package/bin/n9router.js +13 -1
- package/package.json +1 -1
- package/app/.next/server/chunks/4963.js +0 -1
- package/app/.next/server/chunks/5619.js +0 -1
- package/app/.next/static/__qB-b0EP9cu_2Y1YJiUT/_buildManifest.js +0 -1
- package/app/.next/static/chunks/1321-d151de24f85b1705.js +0 -1
- package/app/.next/static/chunks/8198-6ba877462e24c355.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-8aff85e95a62beda.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/quota/page-6916d780a2d54b89.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/token-saver/page-16a983d7f45461ec.js +0 -1
- package/app/.next/static/chunks/app/_global-error/page-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/antigravity-app/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/antigravity-app-v2/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/antigravity-ide/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/antigravity-targets/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/antigravity-tools/import/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/antigravity-tools/import-refresh-tokens/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/login/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/logout/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/oidc/callback/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/oidc/start/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/oidc/test/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/reset-password/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/auth/status/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/all-statuses/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cline-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/copilot-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cowork-mcp-registry/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cowork-mcp-tools/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cowork-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/jobs/[jobId]/events/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/jobs/[jobId]/sudo/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/jobs/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/cursor-byok/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/deepseek-tui-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/devin-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/grok-build-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/hermes-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/jcode-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/kilo-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/opencode-settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/combos/[id]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/combos/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/donate/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/headroom/extras/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/headroom/proxy/[...path]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/headroom/restart/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/headroom/start/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/headroom/status/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/headroom/stop/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/health/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/init/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/internal/account-health/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/internal/request-detail/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/internal/usage/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/keys/[id]/reset-usage/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/keys/[id]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/keys/[id]/usage/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/keys/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/locale/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/mcp/[plugin]/message/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/mcp/[plugin]/sse/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/media-providers/tts/deepgram/voices/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/media-providers/tts/elevenlabs/voices/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/media-providers/tts/inworld/voices/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/media-providers/tts/minimax/voices/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/media-providers/tts/voices/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/models/alias/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/models/availability/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/models/custom/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/models/disabled/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/models/test/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/codex/bulk-import/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/codex/import-token/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/gitlab/pat/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/iflow/cookie/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/api-key/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/import-cli-proxy/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pricing/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test-models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/client/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/kilo/free-models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/suggested-models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/test-batch/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/providers/validate/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/proxy-pools/[id]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/proxy-pools/[id]/test/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/proxy-pools/cloudflare-deploy/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/proxy-pools/deno-deploy/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/proxy-pools/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/proxy-pools/vercel-deploy/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/health/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/install/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/logs/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/restart/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/start/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/stats/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/status/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/pxpipe/stop/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/settings/database/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/settings/database/selective/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/settings/proxy-test/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/settings/require-login/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/settings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/shutdown/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tags/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/translator/console-logs/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/translator/console-logs/stream/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/translator/load/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/translator/save/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/translator/send/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/translator/translate/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/disable/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/enable/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/status/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/tailscale-check/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/tailscale-disable/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/tailscale-enable/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/tailscale-install/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/[connectionId]/codex-reset-credits/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/chart/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/history/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/logs/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/providers/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/report/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-details/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-logs/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/stats/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/usage/stream/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/api/chat/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/audio/speech/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/audio/transcriptions/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/audio/voices/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/embeddings/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/images/generations/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/models/[kind]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/models/info/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/responses/compact/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/responses/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/search/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/videos/[id]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/videos/edits/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/videos/extensions/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/videos/generations/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1/web/fetch/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/version/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/version/shutdown/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/api/version/update/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/login/page-7b85623bf9ba8d60.js +0 -1
- package/app/.next/static/chunks/app/manifest.webmanifest/route-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/app/page-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-c74ff3c527010d28.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c74ff3c527010d28.js +0 -1
- package/app/.next/static/css/d16761d8d90e43ab.css +0 -1
- package/app/open-sse/executors/opencode-go.js +0 -49
- /package/app/.next/static/{__qB-b0EP9cu_2Y1YJiUT → flxITMsAmoXf-wWjPORMD}/_ssgManifest.js +0 -0
|
@@ -1,29 +1,226 @@
|
|
|
1
1
|
import { BaseExecutor } from "./base.js";
|
|
2
2
|
import { PROVIDERS } from "../config/providers.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
KIRO_CODEWHISPERER_TARGET,
|
|
5
|
+
KIRO_ENDPOINT_FALLBACK_STATUSES,
|
|
6
|
+
resolveKiroModel,
|
|
7
|
+
} from "../config/kiroConstants.js";
|
|
4
8
|
import { v4 as uuidv4 } from "uuid";
|
|
5
9
|
import { refreshKiroToken } from "../services/tokenRefresh.js";
|
|
6
|
-
import { proxyAwareFetch } from "../utils/proxyFetch.js";
|
|
7
|
-
import { HTTP_STATUS, DEFAULT_KIRO_RETRY_COUNT, FETCH_CONNECT_TIMEOUT_MS } from "../config/runtimeConfig.js";
|
|
8
10
|
import { SSE_DONE, SSE_HEADERS } from "../utils/sseConstants.js";
|
|
9
11
|
import { getCapabilitiesForModel } from "../providers/capabilities.js";
|
|
12
|
+
import { STREAM_FIRST_CHUNK_TIMEOUT_MS, HTTP_STATUS, DEFAULT_KIRO_RETRY_COUNT } from "../config/runtimeConfig.js";
|
|
10
13
|
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
// Keeps the downstream stall watchdog (pipeWithDisconnect) aware of upstream
|
|
14
|
-
// activity so it doesn't false-abort. Comment lines are dropped by the translate
|
|
15
|
-
// parser and ignored by SSE clients in passthrough.
|
|
16
|
-
const KIRO_KEEPALIVE = new TextEncoder().encode(": ka\n\n");
|
|
17
|
-
|
|
18
|
-
// Exponential backoff config for Kiro retries (mirrors MITM approach)
|
|
14
|
+
// Transient 400 patterns that should be retried (Kiro-specific false positives)
|
|
15
|
+
const KIRO_RETRYABLE_400_PATTERNS = ["improperly formed request"];
|
|
19
16
|
const KIRO_BACKOFF_BASE_MS = 2000;
|
|
20
17
|
const KIRO_BACKOFF_CAP_MS = 15000;
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
const
|
|
19
|
+
const KIRO_REPAIR_BUFFER_MAX_BYTES = 8 * 1024 * 1024;
|
|
20
|
+
const KIRO_REPAIR_HEARTBEAT_MS = 10_000;
|
|
21
|
+
const KIRO_SHORT_FINAL_MAX_CHARS = 800;
|
|
22
|
+
const EVENTSTREAM_MAX_MESSAGE_BYTES = 24 * 1024 * 1024;
|
|
23
|
+
const EVENTSTREAM_MAX_HEADERS_BYTES = 128 * 1024;
|
|
24
|
+
const KIRO_EVENT_TYPES = new Set([
|
|
25
|
+
"assistantResponseEvent",
|
|
26
|
+
"reasoningContentEvent",
|
|
27
|
+
"codeEvent",
|
|
28
|
+
"toolUseEvent",
|
|
29
|
+
"messageStopEvent",
|
|
30
|
+
"metadataEvent",
|
|
31
|
+
"MetadataEvent",
|
|
32
|
+
"contextUsageEvent",
|
|
33
|
+
"meteringEvent",
|
|
34
|
+
"metricsEvent"
|
|
35
|
+
]);
|
|
36
|
+
const encoder = new TextEncoder();
|
|
37
|
+
const decoder = new TextDecoder();
|
|
38
|
+
const CRC32_TABLE = Uint32Array.from({ length: 256 }, (_, index) => {
|
|
39
|
+
let value = index;
|
|
40
|
+
for (let bit = 0; bit < 8; bit++) {
|
|
41
|
+
value = (value >>> 1) ^ ((value & 1) ? 0xedb88320 : 0);
|
|
42
|
+
}
|
|
43
|
+
return value >>> 0;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const REPAIR_INSTRUCTIONS = Object.freeze({
|
|
47
|
+
tool: "Retry the previous response because its Kiro tool_call wrapper was malformed. If you use the wrapper tool named tool_call, its input must contain a non-empty name and an arguments field.",
|
|
48
|
+
ellipsis: "Retry the previous response because it ended with only an ellipsis. Return the complete final answer, not only ... or ….",
|
|
49
|
+
short_final: "Retry the previous response because its final only announced a future action. Complete the check now and return the result or a concrete blocker."
|
|
50
|
+
});
|
|
51
|
+
const SHORT_FUTURE_ACTION = /^(?:(?:(?:現在|接著|接下來|下一步)[,,::\s]*(?:我(?:只)?(?:會|要|將|再)?\s*)?|我只再)(?:補|查|確認|驗證|追(?:查|蹤)?|繼續|檢查|測試)|我(?:會|要|將)(?:再|重新)?(?:補(?:齊|查)?|抓取|查(?:詢)?|確認|驗證|追(?:查|蹤)?|繼續|檢查|測試)|(?:(?:next|now|then)\b[\s,:-]*)?(?:i(?:'ll| will| am going to| need to)|let me)\s+(?:verify|check|confirm|validate|investigate|trace|continue|follow up|test)\b)/iu;
|
|
52
|
+
// Keep this tied to the observed whole-response signature. Broader Chinese
|
|
53
|
+
// result/progress heuristics create false positives for completed findings.
|
|
54
|
+
const OBSERVED_TRAILING_FUTURE_ACTION = /^目前證據顯示[\s\S]{1,700}[。.!?;;]\s*最後補查\s+504\s+access\s+log[,,]\s*確認\s+host[//]路徑與是否為集中流量[。.!]?$/iu;
|
|
55
|
+
const ENGLISH_FUTURE_ACTION = /^(?:(?:next|now|then)\b[\s,:-]*)?(?:i(?:'ll| will| am going to| need to)|let me)\s+(?:verify|check|confirm|validate|investigate|trace|continue|follow up|test)\b/iu;
|
|
56
|
+
const ENGLISH_RESULT_CLAUSE = /(?:[:;\n]|[.!?]\s+\S|\b(?:status|checksum|response|deployment)\s+(?:is|are|was|were|matches?|equals?|returned)\b)/iu;
|
|
57
|
+
const CHINESE_FUTURE_ACTION = /^(?:(?:現在|接著|接下來|下一步)[,,::\s]*(?:我(?:只)?(?:會|要|將|再)?\s*)?|我只再|我(?:會|要|將)(?:再|重新)?)(?:補|抓取|查|確認|驗證|追|繼續|檢查|測試)/u;
|
|
58
|
+
const CHINESE_RESULT_CLAUSE = /(?:[。!?]\s*\S|(?:版本|狀態|回應|結果|部署|校驗碼)(?:是|為|等於|顯示))/u;
|
|
59
|
+
const USER_WAIT = /(?:請(?:你|先)|你(?:先|需要|可以|提供|確認|批准|允許)|等待(?:你|使用者)|等你|核准|同意|授權|\b(?:after|when|once)\s+you\b|\byour\s+(?:approval|confirmation|permission|input)\b|\bwait(?:ing)?\s+for\s+you\b|\bplease\s+(?:approve|confirm|provide|send)\b)/iu;
|
|
60
|
+
const COMPLETED_FINAL = /(?:已(?:經)?完成|完成(?:了|驗證|確認)|修復完成|確認無誤|驗證(?:完成|通過)|測試(?:均)?通過|結論|總結|\b(?:done|completed|fixed|verified|confirmed|passed|in conclusion|summary)\b|\b(?:is|are) complete\b)/iu;
|
|
61
|
+
const RESULT_EVIDENCE = /(?:顯示|發現|因此|成功|失敗|正常|無錯誤|沒有錯誤|\b(?:found|shows?|showed|because|therefore|succeeded|failed|healthy|green|no errors?)\b)/iu;
|
|
62
|
+
|
|
63
|
+
function crc32(bytes) {
|
|
64
|
+
let crc = 0xffffffff;
|
|
65
|
+
for (const byte of bytes) crc = CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);
|
|
66
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function envPositiveInt(name, fallback) {
|
|
70
|
+
const parsed = Number.parseInt(process.env?.[name] || "", 10);
|
|
71
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function concatChunks(chunks, totalBytes) {
|
|
75
|
+
const output = new Uint8Array(totalBytes);
|
|
76
|
+
let offset = 0;
|
|
77
|
+
for (const chunk of chunks) {
|
|
78
|
+
output.set(chunk, offset);
|
|
79
|
+
offset += chunk.byteLength;
|
|
80
|
+
}
|
|
81
|
+
return output;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function makeAbortError(reason) {
|
|
85
|
+
const error = new Error(reason?.message || reason || "Request aborted");
|
|
86
|
+
error.name = "AbortError";
|
|
87
|
+
return error;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function readWithTimeout(reader, signal, timeoutMs, message) {
|
|
91
|
+
if (signal?.aborted) throw makeAbortError(signal.reason);
|
|
92
|
+
let timeout;
|
|
93
|
+
let abortHandler;
|
|
94
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
95
|
+
timeout = setTimeout(() => reject(new Error(message)), timeoutMs);
|
|
96
|
+
});
|
|
97
|
+
const abortPromise = new Promise((_, reject) => {
|
|
98
|
+
abortHandler = () => reject(makeAbortError(signal.reason));
|
|
99
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
100
|
+
});
|
|
101
|
+
try {
|
|
102
|
+
return await Promise.race([reader.read(), timeoutPromise, abortPromise]);
|
|
103
|
+
} finally {
|
|
104
|
+
clearTimeout(timeout);
|
|
105
|
+
signal?.removeEventListener?.("abort", abortHandler);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function readResponsePrefix(response, signal, maxBytes, timeoutMs) {
|
|
110
|
+
const reader = response?.body?.getReader?.();
|
|
111
|
+
if (!reader) return "";
|
|
112
|
+
const chunks = [];
|
|
113
|
+
let totalBytes = 0;
|
|
114
|
+
try {
|
|
115
|
+
while (totalBytes < maxBytes) {
|
|
116
|
+
const { done, value } = await readWithTimeout(
|
|
117
|
+
reader,
|
|
118
|
+
signal,
|
|
119
|
+
timeoutMs,
|
|
120
|
+
"Kiro retry error body stalled"
|
|
121
|
+
);
|
|
122
|
+
if (done) break;
|
|
123
|
+
const remaining = maxBytes - totalBytes;
|
|
124
|
+
const chunk = value.byteLength > remaining ? value.slice(0, remaining) : value;
|
|
125
|
+
chunks.push(chunk);
|
|
126
|
+
totalBytes += chunk.byteLength;
|
|
127
|
+
if (value.byteLength > remaining) break;
|
|
128
|
+
}
|
|
129
|
+
} finally {
|
|
130
|
+
await reader.cancel("bounded Kiro retry error body").catch(() => {});
|
|
131
|
+
}
|
|
132
|
+
return decoder.decode(concatChunks(chunks, totalBytes));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function appendRepairInstruction(body, kind) {
|
|
136
|
+
const repaired = structuredClone(body || {});
|
|
137
|
+
const instruction = REPAIR_INSTRUCTIONS[kind] || "Retry the previous incomplete Kiro response.";
|
|
138
|
+
repaired.systemPrompt = repaired.systemPrompt
|
|
139
|
+
? `${repaired.systemPrompt}\n\n${instruction}`
|
|
140
|
+
: instruction;
|
|
141
|
+
return repaired;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function normalizeStopReason(value) {
|
|
145
|
+
const reason = String(value || "").trim().replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase().replace(/[\s-]+/g, "_");
|
|
146
|
+
if (["endturn", "end_turn", "stop", "stop_sequence"].includes(reason)) return "end_turn";
|
|
147
|
+
if (["tooluse", "tool_use", "tool_calls"].includes(reason)) return "tool_use";
|
|
148
|
+
if (["maxtokens", "max_tokens", "max_output_tokens", "length"].includes(reason)) return "max_tokens";
|
|
149
|
+
return reason || null;
|
|
150
|
+
}
|
|
24
151
|
|
|
25
|
-
//
|
|
26
|
-
|
|
152
|
+
// Of the reasons stopDisposition() folds into "terminal_incomplete", only these
|
|
153
|
+
// mean "usable as far as it got, then the budget ran out" -- the case
|
|
154
|
+
// finish_reason "length" exists for. cancelled / pause_turn are abandoned turns
|
|
155
|
+
// whose partial content must stay private, so they are deliberately absent.
|
|
156
|
+
const KIRO_TRUNCATION_STOP_REASONS = new Set(["model_context_window_exceeded", "max_tokens"]);
|
|
157
|
+
|
|
158
|
+
function stopDisposition(stopReason, hasToolCalls) {
|
|
159
|
+
if (["malformed_model_output", "invalid_model_output"].includes(stopReason)) return "retryable_protocol_failure";
|
|
160
|
+
if (["cancelled", "pause_turn", "model_context_window_exceeded"].includes(stopReason)) return "terminal_incomplete";
|
|
161
|
+
if (stopReason === "refusal" || /(?:content.*filter|guardrail|safety|policy|blocked)/u.test(stopReason)) return "terminal_refusal";
|
|
162
|
+
if (stopReason === "max_tokens") return hasToolCalls ? "terminal_incomplete" : "length";
|
|
163
|
+
if (stopReason && !["end_turn", "tool_use"].includes(stopReason)) return "unknown_failure";
|
|
164
|
+
if (hasToolCalls || stopReason === "tool_use") return "tool_use";
|
|
165
|
+
if (!stopReason || stopReason === "end_turn") return "complete";
|
|
166
|
+
return "unknown_failure";
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function mergeStopReason(current, incoming) {
|
|
170
|
+
if (!incoming) return current;
|
|
171
|
+
if (!current) return incoming;
|
|
172
|
+
const severity = (reason) => {
|
|
173
|
+
const disposition = stopDisposition(reason, false);
|
|
174
|
+
if (disposition === "terminal_refusal") return 6;
|
|
175
|
+
if (disposition === "terminal_incomplete") return 5;
|
|
176
|
+
if (disposition === "unknown_failure") return 4;
|
|
177
|
+
if (disposition === "retryable_protocol_failure") return 3;
|
|
178
|
+
if (disposition === "length") return 2;
|
|
179
|
+
return 1;
|
|
180
|
+
};
|
|
181
|
+
return severity(incoming) > severity(current) ? incoming : current;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function isEllipsisOnly(value) {
|
|
185
|
+
return ["...", "…"].includes(String(value || "").trim());
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function isShortFutureAction(value) {
|
|
189
|
+
const text = String(value || "").trim().replaceAll("’", "'");
|
|
190
|
+
if (OBSERVED_TRAILING_FUTURE_ACTION.test(text)) return true;
|
|
191
|
+
if (ENGLISH_FUTURE_ACTION.test(text) && ENGLISH_RESULT_CLAUSE.test(text)) return false;
|
|
192
|
+
if (CHINESE_FUTURE_ACTION.test(text) && CHINESE_RESULT_CLAUSE.test(text)) return false;
|
|
193
|
+
return text.length > 0 && text.length <= KIRO_SHORT_FINAL_MAX_CHARS &&
|
|
194
|
+
SHORT_FUTURE_ACTION.test(text) && !USER_WAIT.test(text) &&
|
|
195
|
+
!COMPLETED_FINAL.test(text) && !RESULT_EVIDENCE.test(text);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function encodeSSEError(code, message, details) {
|
|
199
|
+
return encoder.encode(`data: ${JSON.stringify({ error: {
|
|
200
|
+
message,
|
|
201
|
+
type: "upstream_error",
|
|
202
|
+
code,
|
|
203
|
+
...(details ? { details } : {})
|
|
204
|
+
} })}\n\ndata: [DONE]\n\n`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function inspectSSEChunk(chunk, state) {
|
|
208
|
+
for (const line of decoder.decode(chunk).split("\n")) {
|
|
209
|
+
if (!line.startsWith("data: ")) continue;
|
|
210
|
+
const data = line.slice(6).trim();
|
|
211
|
+
if (!data || data === "[DONE]") continue;
|
|
212
|
+
try {
|
|
213
|
+
const event = JSON.parse(data);
|
|
214
|
+
if (event.error) state.error = event.error;
|
|
215
|
+
for (const choice of event.choices || []) {
|
|
216
|
+
const delta = choice.delta || {};
|
|
217
|
+
if (typeof delta.content === "string") state.content += delta.content;
|
|
218
|
+
if (typeof delta.reasoning_content === "string") state.reasoning += delta.reasoning_content;
|
|
219
|
+
if (delta.tool_calls?.length) state.hasToolCalls = true;
|
|
220
|
+
}
|
|
221
|
+
} catch { /* a malformed SSE line is diagnosed by the transformer */ }
|
|
222
|
+
}
|
|
223
|
+
}
|
|
27
224
|
|
|
28
225
|
/**
|
|
29
226
|
* KiroExecutor - Executor for Kiro AI (AWS CodeWhisperer)
|
|
@@ -34,12 +231,17 @@ export class KiroExecutor extends BaseExecutor {
|
|
|
34
231
|
super("kiro", PROVIDERS.kiro);
|
|
35
232
|
}
|
|
36
233
|
|
|
37
|
-
buildHeaders(credentials, stream = true) {
|
|
234
|
+
buildHeaders(credentials, stream = true, url = "") {
|
|
38
235
|
const headers = {
|
|
39
236
|
...this.config.headers,
|
|
40
237
|
"Amz-Sdk-Request": "attempt=1; max=3",
|
|
41
238
|
"Amz-Sdk-Invocation-Id": uuidv4()
|
|
42
239
|
};
|
|
240
|
+
if (url.includes("://codewhisperer.")) {
|
|
241
|
+
headers["X-Amz-Target"] = KIRO_CODEWHISPERER_TARGET;
|
|
242
|
+
} else {
|
|
243
|
+
delete headers["X-Amz-Target"];
|
|
244
|
+
}
|
|
43
245
|
|
|
44
246
|
// API-key auth: the key is stored as accessToken and sent as a bearer token
|
|
45
247
|
// exactly like an OAuth access token, but with an extra `tokentype: API_KEY`
|
|
@@ -54,8 +256,8 @@ export class KiroExecutor extends BaseExecutor {
|
|
|
54
256
|
const apiKey = credentials?.apiKey || (isApiKey ? credentials?.accessToken : null);
|
|
55
257
|
if (isApiKey && apiKey) {
|
|
56
258
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
57
|
-
headers["
|
|
58
|
-
} else if (credentials
|
|
259
|
+
headers["TokenType"] = "API_KEY";
|
|
260
|
+
} else if (credentials?.accessToken) {
|
|
59
261
|
headers["Authorization"] = `Bearer ${credentials.accessToken}`;
|
|
60
262
|
if (isExternalIdp) {
|
|
61
263
|
headers["TokenType"] = "EXTERNAL_IDP";
|
|
@@ -68,14 +270,14 @@ export class KiroExecutor extends BaseExecutor {
|
|
|
68
270
|
/**
|
|
69
271
|
* Auth-aware endpoint ordering.
|
|
70
272
|
*
|
|
71
|
-
* API-key Kiro connections
|
|
72
|
-
*
|
|
273
|
+
* API-key Kiro connections use the Amazon Q surface. The legacy
|
|
274
|
+
* codewhisperer.* GenerateAssistantResponse endpoint can authenticate the key
|
|
275
|
+
* but rejects the same valid payload with REQUEST_BODY_INVALID. Since a 400
|
|
276
|
+
* is terminal in BaseExecutor, putting CodeWhisperer first prevents the working
|
|
277
|
+
* q.* endpoint from ever being tried. Keep q.* first only for api_key accounts.
|
|
278
|
+
*
|
|
73
279
|
* The Kiro IDE gateway (runtime.*.kiro.dev) expects Kiro OIDC/social tokens
|
|
74
|
-
* and rejects
|
|
75
|
-
* BaseExecutor.execute() returns immediately (only 429 / network errors fall
|
|
76
|
-
* through to the next host). So for api-key auth we must try the *.amazonaws.com
|
|
77
|
-
* CodeWhisperer hosts FIRST, mirroring the Kiro-Go reference fork which never
|
|
78
|
-
* routes api-key traffic through kiro.dev. External IdP enterprise tokens also
|
|
280
|
+
* and rejects TokenType=API_KEY. External IdP enterprise tokens instead
|
|
79
281
|
* use the CodeWhisperer surface, with the `TokenType: EXTERNAL_IDP` header.
|
|
80
282
|
* Other OAuth methods keep the default order (kiro.dev first) since their
|
|
81
283
|
* tokens are what that gateway accepts.
|
|
@@ -100,6 +302,14 @@ export class KiroExecutor extends BaseExecutor {
|
|
|
100
302
|
|
|
101
303
|
const amazon = baseUrls.filter((u) => u.includes("amazonaws.com")).map(regionalize);
|
|
102
304
|
const others = baseUrls.filter((u) => !u.includes("amazonaws.com"));
|
|
305
|
+
if (authMethod === "api_key") {
|
|
306
|
+
const q = amazon.filter((u) => u.includes("://q."));
|
|
307
|
+
const remaining = amazon.filter((u) => !u.includes("://q."));
|
|
308
|
+
return q.length > 0
|
|
309
|
+
? [...q, ...remaining, ...others]
|
|
310
|
+
: [...amazon, ...others];
|
|
311
|
+
}
|
|
312
|
+
|
|
103
313
|
return amazon.length > 0 ? [...amazon, ...others] : baseUrls;
|
|
104
314
|
}
|
|
105
315
|
|
|
@@ -108,516 +318,913 @@ export class KiroExecutor extends BaseExecutor {
|
|
|
108
318
|
return baseUrls[urlIndex] || baseUrls[0] || this.config.baseUrl;
|
|
109
319
|
}
|
|
110
320
|
|
|
321
|
+
// Retry only endpoint/auth-surface failures. Payload-invalid HTTP 400 must be
|
|
322
|
+
// terminal: sending the same malformed body to every surface cannot repair it.
|
|
323
|
+
shouldRetry(status, urlIndex) {
|
|
324
|
+
const hasFallback = urlIndex + 1 < this.getFallbackCount();
|
|
325
|
+
return super.shouldRetry(status, urlIndex)
|
|
326
|
+
|| (hasFallback && KIRO_ENDPOINT_FALLBACK_STATUSES.has(status));
|
|
327
|
+
}
|
|
328
|
+
|
|
111
329
|
transformRequest(model, body, stream, credentials) {
|
|
112
330
|
return body;
|
|
113
331
|
}
|
|
114
332
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
333
|
+
// Resolve max retry count: per-account → global setting → default. Applied to
|
|
334
|
+
// every in-place-retryable status (429/500/502/503/504) plus 400, whose actual
|
|
335
|
+
// retry eligibility is decided per-body in computeRetryDelay (see below).
|
|
336
|
+
getRetryConfig(credentials) {
|
|
337
|
+
const attempts = credentials?.kiroRetryCount ?? DEFAULT_KIRO_RETRY_COUNT;
|
|
338
|
+
const delayMs = 2000;
|
|
339
|
+
return {
|
|
340
|
+
...this.config.retry,
|
|
341
|
+
[HTTP_STATUS.RATE_LIMITED]: { attempts, delayMs },
|
|
342
|
+
500: { attempts, delayMs },
|
|
343
|
+
502: { attempts, delayMs },
|
|
344
|
+
503: { attempts, delayMs },
|
|
345
|
+
504: { attempts, delayMs },
|
|
346
|
+
400: { attempts, delayMs },
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// 400 is normally a terminal validation error, but Kiro occasionally returns
|
|
351
|
+
// "improperly formed request" for what is actually a transient upstream hiccup.
|
|
352
|
+
// getRetryConfig() enables in-place retry for status 400 unconditionally; this
|
|
353
|
+
// hook vetoes it (no attempt consumed) unless the body matches a known transient
|
|
354
|
+
// pattern, so genuine validation errors still fail fast. Non-400 statuses get
|
|
355
|
+
// the same exponential-backoff-with-jitter curve as the pre-merge implementation.
|
|
356
|
+
async computeRetryDelay(response, attempt) {
|
|
357
|
+
if (response.status === HTTP_STATUS.BAD_REQUEST) {
|
|
358
|
+
let bodyText = "";
|
|
359
|
+
try { bodyText = await response.clone().text(); } catch { /* ignore */ }
|
|
360
|
+
if (!this._isRetryable400(bodyText)) return false;
|
|
361
|
+
}
|
|
362
|
+
return this._computeBackoff(attempt);
|
|
363
|
+
}
|
|
364
|
+
|
|
119
365
|
_isRetryable400(responseBody) {
|
|
120
366
|
if (!responseBody) return false;
|
|
121
367
|
const lower = responseBody.toLowerCase();
|
|
122
368
|
return KIRO_RETRYABLE_400_PATTERNS.some(pattern => lower.includes(pattern));
|
|
123
369
|
}
|
|
124
370
|
|
|
371
|
+
_computeBackoff(attempt) {
|
|
372
|
+
return Math.floor(Math.random() * Math.min(KIRO_BACKOFF_CAP_MS, KIRO_BACKOFF_BASE_MS * 2 ** (attempt - 1))) + KIRO_BACKOFF_BASE_MS / 2;
|
|
373
|
+
}
|
|
374
|
+
|
|
125
375
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
376
|
+
* Kiro execute — delegate to BaseExecutor for endpoint fallback + retry, then
|
|
377
|
+
* transform the binary AWS EventStream into OpenAI-shaped SSE on success.
|
|
378
|
+
*
|
|
379
|
+
* BaseExecutor.execute() walks config.baseUrls (runtime.us-east-1.kiro.dev →
|
|
380
|
+
* codewhisperer → q) advancing to the next host on 429 (shouldRetry) and on
|
|
381
|
+
* network/5xx errors, while tryRetry handles in-place retries per `retry: {429: 2}`.
|
|
382
|
+
* Note: api-key connections reorder these so the *.amazonaws.com hosts come
|
|
383
|
+
* first — see getOrderedBaseUrls/buildUrl above.
|
|
384
|
+
* Note: the baseUrls are alternate surfaces of one regional service, so rotation
|
|
385
|
+
* is edge-level failover — it does not grant fresh 429 quota. Per-account 429
|
|
386
|
+
* spreading is handled upstream by account rotation in sse/handlers/chat.js.
|
|
387
|
+
*
|
|
388
|
+
* Errors are returned untransformed so the upstream handler can read the body,
|
|
389
|
+
* classify the status, and trigger account fallback/cooldown.
|
|
128
390
|
*/
|
|
129
|
-
async execute(
|
|
130
|
-
const
|
|
131
|
-
|
|
391
|
+
async execute(args) {
|
|
392
|
+
const result = await super.execute(args);
|
|
393
|
+
// Retries in getRetryConfig()/computeRetryDelay() are exhausted by the time
|
|
394
|
+
// execute() returns. A still-400 transient response at this point means every
|
|
395
|
+
// attempt failed the same way — remap to 429 so callers (e.g. Claude Code CLI)
|
|
396
|
+
// that only auto-retry 429/503 treat it as retryable instead of terminal.
|
|
397
|
+
if (result?.response && !result.response.ok && result.response.status === HTTP_STATUS.BAD_REQUEST) {
|
|
398
|
+
const bodyText = await result.response.clone().text().catch(() => "");
|
|
399
|
+
if (this._isRetryable400(bodyText)) {
|
|
400
|
+
args.log?.debug?.("RETRY", "400 → 429 remap (transient Kiro error)");
|
|
401
|
+
result.response = new Response(bodyText, {
|
|
402
|
+
status: HTTP_STATUS.RATE_LIMITED,
|
|
403
|
+
statusText: "Too Many Requests",
|
|
404
|
+
headers: result.response.headers
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (result?.response?.ok) this.attachIntegrityGate(result, args);
|
|
409
|
+
return result;
|
|
410
|
+
}
|
|
132
411
|
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
412
|
+
attachIntegrityGate(result, args) {
|
|
413
|
+
const abortController = new AbortController();
|
|
414
|
+
const maxBytes = envPositiveInt("KIRO_TOOL_CALL_REPAIR_BUFFER_MAX_BYTES", KIRO_REPAIR_BUFFER_MAX_BYTES);
|
|
415
|
+
const legacyTimeout = envPositiveInt("KIRO_TOOL_CALL_REPAIR_TIMEOUT_MS", STREAM_FIRST_CHUNK_TIMEOUT_MS);
|
|
416
|
+
const ttftTimeoutMs = envPositiveInt("KIRO_TOOL_CALL_REPAIR_TTFT_TIMEOUT_MS", legacyTimeout);
|
|
417
|
+
const stallTimeoutMs = envPositiveInt("KIRO_TOOL_CALL_REPAIR_STALL_TIMEOUT_MS", legacyTimeout);
|
|
418
|
+
const repairEnabled = args.credentials?.providerSpecificData?.kiroToolCallRepair !== false &&
|
|
419
|
+
process.env.KIRO_TOOL_CALL_REPAIR !== "false";
|
|
420
|
+
const forwardAbort = () => abortController.abort(args.signal?.reason);
|
|
421
|
+
args.signal?.addEventListener("abort", forwardAbort, { once: true });
|
|
422
|
+
let open = true;
|
|
423
|
+
let heartbeatTimer;
|
|
424
|
+
|
|
425
|
+
const stream = new ReadableStream({
|
|
426
|
+
start: async (controller) => {
|
|
427
|
+
const heartbeat = () => {
|
|
428
|
+
if (!open) return;
|
|
429
|
+
try {
|
|
430
|
+
controller.enqueue(encoder.encode(": kiro-validation\n\n"));
|
|
431
|
+
} catch {
|
|
432
|
+
open = false;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
heartbeat();
|
|
436
|
+
heartbeatTimer = setInterval(heartbeat, KIRO_REPAIR_HEARTBEAT_MS);
|
|
437
|
+
|
|
438
|
+
try {
|
|
439
|
+
const bytes = await this.runIntegrityRecovery(result.response, args, {
|
|
440
|
+
signal: abortController.signal,
|
|
441
|
+
maxBytes,
|
|
442
|
+
ttftTimeoutMs,
|
|
443
|
+
stallTimeoutMs,
|
|
444
|
+
repairEnabled
|
|
445
|
+
});
|
|
446
|
+
if (abortController.signal.aborted) throw makeAbortError(abortController.signal.reason);
|
|
447
|
+
controller.enqueue(bytes);
|
|
448
|
+
controller.close();
|
|
449
|
+
} catch (error) {
|
|
450
|
+
if (open && error.name === "AbortError") {
|
|
451
|
+
controller.error(error);
|
|
452
|
+
} else if (open && error.name !== "AbortError") {
|
|
453
|
+
controller.enqueue(encodeSSEError(
|
|
454
|
+
"kiro_integrity_gate_failed",
|
|
455
|
+
error.message || "Kiro integrity validation failed"
|
|
456
|
+
));
|
|
457
|
+
controller.close();
|
|
458
|
+
}
|
|
459
|
+
} finally {
|
|
460
|
+
open = false;
|
|
461
|
+
clearInterval(heartbeatTimer);
|
|
462
|
+
args.signal?.removeEventListener?.("abort", forwardAbort);
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
cancel(reason) {
|
|
466
|
+
open = false;
|
|
467
|
+
clearInterval(heartbeatTimer);
|
|
468
|
+
abortController.abort(reason || "client cancelled");
|
|
469
|
+
}
|
|
470
|
+
});
|
|
136
471
|
|
|
137
|
-
|
|
138
|
-
|
|
472
|
+
result.response = new Response(stream, {
|
|
473
|
+
status: result.response.status,
|
|
474
|
+
statusText: result.response.statusText,
|
|
475
|
+
headers: { ...SSE_HEADERS }
|
|
476
|
+
});
|
|
477
|
+
}
|
|
139
478
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
479
|
+
async runIntegrityRecovery(rawResponse, args, options) {
|
|
480
|
+
const first = await this.readRecoverableIntegrityAttempt(
|
|
481
|
+
rawResponse,
|
|
482
|
+
args.model,
|
|
483
|
+
options,
|
|
484
|
+
"initial"
|
|
485
|
+
);
|
|
486
|
+
if (first.kind === "complete") return first.bytes;
|
|
487
|
+
if (first.kind === "terminal_stop" || first.kind === "upstream_error") {
|
|
488
|
+
return this.integrityFailureSSE(first);
|
|
489
|
+
}
|
|
490
|
+
if (first.kind === "invalid_tool" && !options.repairEnabled) {
|
|
491
|
+
return encodeSSEError("invalid_kiro_tool_call", first.message, first.diagnostics);
|
|
492
|
+
}
|
|
144
493
|
|
|
145
|
-
|
|
494
|
+
const repairKind = ["ellipsis", "short_final", "invalid_tool"].includes(first.kind)
|
|
495
|
+
? first.kind
|
|
496
|
+
: null;
|
|
497
|
+
const repairBody = repairKind
|
|
498
|
+
? appendRepairInstruction(args.body, repairKind === "invalid_tool" ? "tool" : repairKind)
|
|
499
|
+
: structuredClone(args.body || {});
|
|
500
|
+
|
|
501
|
+
const retry = await BaseExecutor.prototype.execute.call(this, {
|
|
502
|
+
...args,
|
|
503
|
+
body: repairBody,
|
|
504
|
+
signal: options.signal
|
|
505
|
+
});
|
|
506
|
+
if (!retry?.response?.ok) {
|
|
507
|
+
let body = "";
|
|
146
508
|
try {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// Headers received — body streaming is now governed by the stall watchdog.
|
|
154
|
-
clearTimeout(connectTimer);
|
|
509
|
+
body = await readResponsePrefix(
|
|
510
|
+
retry?.response,
|
|
511
|
+
options.signal,
|
|
512
|
+
Math.min(options.maxBytes, 4096),
|
|
513
|
+
options.stallTimeoutMs
|
|
514
|
+
);
|
|
155
515
|
} catch (error) {
|
|
156
|
-
|
|
157
|
-
// Connect timeout is internal: convert to a retryable network error
|
|
158
|
-
const isConnectTimeout = connectCtrl.signal.aborted && error.name === "AbortError";
|
|
159
|
-
if (isConnectTimeout) {
|
|
160
|
-
if (maxRetries > 0 && retryAttempts < maxRetries) {
|
|
161
|
-
retryAttempts++;
|
|
162
|
-
const backoffMs = this._computeBackoff(retryAttempts);
|
|
163
|
-
log?.debug?.("RETRY", `connect timeout retry ${retryAttempts}/${maxRetries} after ${(backoffMs / 1000).toFixed(1)}s`);
|
|
164
|
-
await new Promise(resolve => setTimeout(resolve, backoffMs));
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
throw new Error(`Kiro upstream connect timeout after ${FETCH_CONNECT_TIMEOUT_MS}ms`);
|
|
168
|
-
}
|
|
169
|
-
throw error;
|
|
516
|
+
if (error.name === "AbortError") throw error;
|
|
170
517
|
}
|
|
518
|
+
return encodeSSEError(
|
|
519
|
+
"kiro_integrity_retry_upstream_error",
|
|
520
|
+
body || `Kiro integrity retry failed with HTTP ${retry?.response?.status || 502}`,
|
|
521
|
+
{ status: retry?.response?.status || 502 }
|
|
522
|
+
);
|
|
523
|
+
}
|
|
171
524
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
525
|
+
const second = await this.readRecoverableIntegrityAttempt(
|
|
526
|
+
retry.response,
|
|
527
|
+
args.model,
|
|
528
|
+
options,
|
|
529
|
+
"retry"
|
|
530
|
+
);
|
|
531
|
+
if (second.kind === "complete") return second.bytes;
|
|
532
|
+
if (second.kind === "terminal_stop" || second.kind === "upstream_error") {
|
|
533
|
+
return this.integrityFailureSSE(second);
|
|
534
|
+
}
|
|
535
|
+
const code = second.kind === "ellipsis"
|
|
536
|
+
? "kiro_ellipsis_retry_failed"
|
|
537
|
+
: second.kind === "short_final"
|
|
538
|
+
? "kiro_short_final_retry_failed"
|
|
539
|
+
: second.kind === "invalid_tool"
|
|
540
|
+
? "kiro_tool_call_repair_retry_failed"
|
|
541
|
+
: "kiro_missing_terminal_retry_failed";
|
|
542
|
+
return encodeSSEError(
|
|
543
|
+
code,
|
|
544
|
+
`Kiro integrity validation failed after one bounded retry: ${second.message || second.kind}`,
|
|
545
|
+
{ attempts: [first.diagnostics, second.diagnostics].filter(Boolean) }
|
|
546
|
+
);
|
|
547
|
+
}
|
|
186
548
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
549
|
+
integrityFailureSSE(attempt) {
|
|
550
|
+
const disposition = attempt.diagnostics?.stop_disposition;
|
|
551
|
+
const code = attempt.diagnostics?.terminal_provenance === "integrity_buffer_exceeded"
|
|
552
|
+
? "kiro_integrity_buffer_exceeded"
|
|
553
|
+
: attempt.kind === "upstream_error"
|
|
554
|
+
? "kiro_upstream_eventstream_error"
|
|
555
|
+
: disposition === "terminal_refusal"
|
|
556
|
+
? "kiro_terminal_refusal"
|
|
557
|
+
: disposition === "terminal_incomplete"
|
|
558
|
+
? "kiro_terminal_incomplete"
|
|
559
|
+
: "kiro_unknown_stop_reason";
|
|
560
|
+
return encodeSSEError(code, attempt.message || "Kiro stream ended with a terminal failure", attempt.diagnostics);
|
|
561
|
+
}
|
|
194
562
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
563
|
+
async readRecoverableIntegrityAttempt(rawResponse, model, options, attempt) {
|
|
564
|
+
try {
|
|
565
|
+
return await this.readIntegrityAttempt(rawResponse, model, options, attempt);
|
|
566
|
+
} catch (error) {
|
|
567
|
+
if (error.name === "AbortError") throw error;
|
|
568
|
+
return {
|
|
569
|
+
kind: "missing_terminal",
|
|
570
|
+
message: error.message || "Kiro transport read failed",
|
|
571
|
+
diagnostics: {
|
|
572
|
+
attempt,
|
|
573
|
+
terminal_provenance: "transport_read_error",
|
|
574
|
+
transport_state: "upstream_error",
|
|
575
|
+
stop_reason: null,
|
|
576
|
+
stop_disposition: "terminal_incomplete",
|
|
577
|
+
response_state: "no_semantic_output",
|
|
578
|
+
event_counts: {},
|
|
579
|
+
incomplete_frame_bytes: 0
|
|
206
580
|
}
|
|
207
|
-
}
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
}
|
|
208
584
|
|
|
209
|
-
|
|
210
|
-
|
|
585
|
+
async readIntegrityAttempt(rawResponse, model, options, attempt) {
|
|
586
|
+
let diagnostics;
|
|
587
|
+
const transformed = this.transformEventStreamToSSE(rawResponse, model, {
|
|
588
|
+
maxToolBytes: Math.max(1, Math.floor(options.maxBytes / 2)),
|
|
589
|
+
onTerminalState: (value) => {
|
|
590
|
+
diagnostics = value;
|
|
211
591
|
}
|
|
592
|
+
});
|
|
593
|
+
const reader = transformed.body.getReader();
|
|
594
|
+
const chunks = [];
|
|
595
|
+
let totalBytes = 0;
|
|
596
|
+
let sawChunk = false;
|
|
597
|
+
const output = { content: "", reasoning: "", hasToolCalls: false, error: null };
|
|
212
598
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
599
|
+
try {
|
|
600
|
+
while (true) {
|
|
601
|
+
const timeoutMs = sawChunk ? options.stallTimeoutMs : options.ttftTimeoutMs;
|
|
602
|
+
const phase = sawChunk ? "stalled" : "timed out before first chunk";
|
|
603
|
+
const { done, value } = await readWithTimeout(
|
|
604
|
+
reader,
|
|
605
|
+
options.signal,
|
|
606
|
+
timeoutMs,
|
|
607
|
+
`Kiro integrity validation ${phase}`
|
|
608
|
+
);
|
|
609
|
+
if (done) break;
|
|
610
|
+
sawChunk = true;
|
|
611
|
+
totalBytes += value.byteLength;
|
|
612
|
+
if (totalBytes > options.maxBytes) {
|
|
613
|
+
await reader.cancel("kiro_integrity_buffer_exceeded").catch(() => {});
|
|
614
|
+
return {
|
|
615
|
+
kind: "terminal_stop",
|
|
616
|
+
message: `Kiro integrity buffer exceeded ${options.maxBytes} bytes`,
|
|
617
|
+
diagnostics: { terminal_provenance: "integrity_buffer_exceeded" }
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
chunks.push(value);
|
|
621
|
+
inspectSSEChunk(value, output);
|
|
622
|
+
}
|
|
623
|
+
} catch (error) {
|
|
624
|
+
await reader.cancel(error.message).catch(() => {});
|
|
625
|
+
throw error;
|
|
216
626
|
}
|
|
217
|
-
}
|
|
218
627
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
628
|
+
const safeDiagnostics = {
|
|
629
|
+
attempt,
|
|
630
|
+
terminal_provenance: diagnostics?.terminal_provenance || "missing_terminal_diagnostics",
|
|
631
|
+
transport_state: diagnostics?.transport_state || "unknown",
|
|
632
|
+
stop_reason: diagnostics?.stop_reason || null,
|
|
633
|
+
stop_disposition: diagnostics?.stop_disposition || "terminal_incomplete",
|
|
634
|
+
response_state: diagnostics?.response_state || "no_semantic_output",
|
|
635
|
+
event_counts: diagnostics?.event_counts || {},
|
|
636
|
+
incomplete_frame_bytes: diagnostics?.incomplete_frame_bytes || 0
|
|
637
|
+
};
|
|
638
|
+
if (safeDiagnostics.stop_disposition === "retryable_protocol_failure") {
|
|
639
|
+
const kind = safeDiagnostics.terminal_provenance === "invalid_tool_call"
|
|
640
|
+
? "invalid_tool"
|
|
641
|
+
: "retryable_stop";
|
|
642
|
+
return { kind, message: output.error?.message, diagnostics: safeDiagnostics };
|
|
643
|
+
}
|
|
644
|
+
if (safeDiagnostics.stop_disposition === "terminal_incomplete" ||
|
|
645
|
+
safeDiagnostics.stop_disposition === "terminal_refusal" ||
|
|
646
|
+
safeDiagnostics.stop_disposition === "unknown_failure") {
|
|
647
|
+
const kind = safeDiagnostics.terminal_provenance === "upstream_eventstream_error"
|
|
648
|
+
? "upstream_error"
|
|
649
|
+
: safeDiagnostics.terminal_provenance === "integrity_buffer_exceeded"
|
|
650
|
+
? "terminal_stop"
|
|
651
|
+
: ["metadata_stop_reason", "message_stop_event"].includes(safeDiagnostics.terminal_provenance)
|
|
652
|
+
? "terminal_stop"
|
|
653
|
+
: "missing_terminal";
|
|
654
|
+
return { kind, message: output.error?.message, diagnostics: safeDiagnostics };
|
|
655
|
+
}
|
|
656
|
+
if (output.error) {
|
|
657
|
+
return { kind: "missing_terminal", message: output.error.message, diagnostics: safeDiagnostics };
|
|
658
|
+
}
|
|
659
|
+
if (!output.hasToolCalls) {
|
|
660
|
+
if (isEllipsisOnly(output.content) ||
|
|
661
|
+
(!output.content.trim() && isEllipsisOnly(output.reasoning))) {
|
|
662
|
+
return { kind: "ellipsis", diagnostics: safeDiagnostics };
|
|
663
|
+
}
|
|
664
|
+
if (isShortFutureAction(output.content)) {
|
|
665
|
+
return { kind: "short_final", diagnostics: safeDiagnostics };
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return { kind: "complete", bytes: concatChunks(chunks, totalBytes), diagnostics: safeDiagnostics };
|
|
227
669
|
}
|
|
228
670
|
|
|
229
|
-
|
|
230
|
-
* Transform AWS EventStream binary response to SSE text stream
|
|
231
|
-
* Using TransformStream instead of ReadableStream.pull() to avoid Workers timeout
|
|
232
|
-
*/
|
|
233
|
-
transformEventStreamToSSE(response, model, streamWatchdogEnabled = true) {
|
|
234
|
-
let buffer = new Uint8Array(0);
|
|
235
|
-
let chunkIndex = 0;
|
|
671
|
+
transformEventStreamToSSE(response, model, options = {}) {
|
|
236
672
|
const responseId = `chatcmpl-${Date.now()}`;
|
|
237
673
|
const created = Math.floor(Date.now() / 1000);
|
|
238
674
|
const capabilityModel = resolveKiroModel(model).upstream;
|
|
239
675
|
const contextWindow = getCapabilitiesForModel("kiro", capabilityModel).contextWindow || 200000;
|
|
676
|
+
const eventCounts = {};
|
|
240
677
|
const state = {
|
|
241
|
-
|
|
242
|
-
|
|
678
|
+
buffer: new Uint8Array(0),
|
|
679
|
+
chunkIndex: 0,
|
|
680
|
+
toolCounter: 0,
|
|
681
|
+
tools: new Map(),
|
|
682
|
+
bufferedToolBytes: 0,
|
|
683
|
+
hasText: false,
|
|
684
|
+
hasReasoning: false,
|
|
685
|
+
hasCode: false,
|
|
243
686
|
hasToolCalls: false,
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
687
|
+
sawToolUse: false,
|
|
688
|
+
explicitStop: false,
|
|
689
|
+
stopReason: null,
|
|
690
|
+
terminalProvenance: null,
|
|
691
|
+
transportState: "consuming_response",
|
|
692
|
+
totalContentLength: 0,
|
|
693
|
+
contextUsagePercentage: 0,
|
|
694
|
+
hasContextUsage: false,
|
|
695
|
+
hasMetering: false,
|
|
696
|
+
usage: null,
|
|
697
|
+
inThinking: false,
|
|
698
|
+
toolValidationError: null,
|
|
699
|
+
validatedFrames: 0,
|
|
700
|
+
finished: false
|
|
249
701
|
};
|
|
250
702
|
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
703
|
+
const diagnostics = (overrides = {}) => ({
|
|
704
|
+
terminal_provenance: state.terminalProvenance || "clean_eventstream_eof",
|
|
705
|
+
transport_state: state.transportState,
|
|
706
|
+
stop_reason: state.stopReason,
|
|
707
|
+
stop_disposition: stopDisposition(state.stopReason, state.hasToolCalls),
|
|
708
|
+
response_state: state.hasToolCalls
|
|
709
|
+
? "valid_tool"
|
|
710
|
+
: state.hasText || state.hasReasoning || state.hasCode
|
|
711
|
+
? "text_reasoning"
|
|
712
|
+
: state.explicitStop
|
|
713
|
+
? "explicit_stop"
|
|
714
|
+
: "no_semantic_output",
|
|
715
|
+
event_counts: { ...eventCounts },
|
|
716
|
+
incomplete_frame_bytes: state.buffer.byteLength,
|
|
717
|
+
...overrides
|
|
718
|
+
});
|
|
719
|
+
const sseChunk = (delta, finishReason = null, usage) => encoder.encode(`data: ${JSON.stringify({
|
|
720
|
+
id: responseId,
|
|
721
|
+
object: "chat.completion.chunk",
|
|
722
|
+
created,
|
|
723
|
+
model,
|
|
724
|
+
choices: [{ index: 0, delta, finish_reason: finishReason }],
|
|
725
|
+
...(usage ? { usage } : {})
|
|
726
|
+
})}\n\n`);
|
|
727
|
+
const emitDelta = (controller, delta) => {
|
|
728
|
+
if (state.chunkIndex === 0) delta = { role: "assistant", ...delta };
|
|
729
|
+
state.chunkIndex++;
|
|
730
|
+
controller.enqueue(sseChunk(delta));
|
|
731
|
+
};
|
|
732
|
+
const fail = (controller, provenance, code, message, extra = {}) => {
|
|
733
|
+
state.finished = true;
|
|
734
|
+
state.terminalProvenance = provenance;
|
|
735
|
+
state.transportState = extra.transport_state || "corrupt_frame";
|
|
736
|
+
const detail = diagnostics({
|
|
737
|
+
stop_disposition: extra.stop_disposition || "terminal_incomplete",
|
|
738
|
+
...extra
|
|
739
|
+
});
|
|
740
|
+
options.onTerminalState?.(detail);
|
|
741
|
+
controller.enqueue(encodeSSEError(code, message, detail));
|
|
742
|
+
};
|
|
743
|
+
const assertToolBufferBound = () => {
|
|
744
|
+
if (state.bufferedToolBytes <= (options.maxToolBytes || KIRO_REPAIR_BUFFER_MAX_BYTES / 2)) return;
|
|
745
|
+
const error = new Error("Kiro buffered tool input exceeded the integrity memory bound");
|
|
746
|
+
error.code = "KIRO_BUFFER_EXCEEDED";
|
|
747
|
+
throw error;
|
|
748
|
+
};
|
|
749
|
+
const appendToolInput = (tool, input) => {
|
|
750
|
+
if (input === undefined) return;
|
|
751
|
+
if (typeof input === "string") {
|
|
752
|
+
if (tool.inputKind && tool.inputKind !== "string") throw new Error("Kiro tool input changed fragment type");
|
|
753
|
+
tool.inputKind = "string";
|
|
754
|
+
tool.inputChunks ||= [];
|
|
755
|
+
tool.inputChunks.push(input);
|
|
756
|
+
state.bufferedToolBytes += encoder.encode(input).byteLength;
|
|
757
|
+
} else if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
758
|
+
if (tool.inputKind && tool.inputKind !== "object") throw new Error("Kiro tool input changed fragment type");
|
|
759
|
+
tool.inputKind = "object";
|
|
760
|
+
state.bufferedToolBytes -= tool.inputBytes || 0;
|
|
761
|
+
tool.inputObject = input;
|
|
762
|
+
tool.inputBytes = encoder.encode(JSON.stringify(input)).byteLength;
|
|
763
|
+
state.bufferedToolBytes += tool.inputBytes;
|
|
764
|
+
} else {
|
|
765
|
+
throw new Error("Kiro tool input must be a JSON object");
|
|
766
|
+
}
|
|
767
|
+
assertToolBufferBound();
|
|
768
|
+
};
|
|
769
|
+
const parsedToolInput = (tool) => {
|
|
770
|
+
if (!tool.inputKind) throw new Error("Kiro tool call is missing input");
|
|
771
|
+
if (tool.inputKind === "object") return tool.inputObject;
|
|
772
|
+
try {
|
|
773
|
+
const input = JSON.parse(tool.inputChunks.join(""));
|
|
774
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error("not an object");
|
|
775
|
+
return input;
|
|
776
|
+
} catch (error) {
|
|
777
|
+
throw new Error(`Kiro tool input must be valid object JSON (${error.message})`);
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
const emitTools = (controller) => {
|
|
781
|
+
for (const tool of state.tools.values()) {
|
|
782
|
+
// Validate per tool, not per turn: one unusable fragment used to throw out
|
|
783
|
+
// of emitTools and take every other complete tool call in the same turn
|
|
784
|
+
// with it, which the client saw as a turn that answered nothing.
|
|
785
|
+
let input;
|
|
786
|
+
try {
|
|
787
|
+
input = parsedToolInput(tool);
|
|
788
|
+
if (tool.name === "tool_call") {
|
|
789
|
+
if (typeof input.name !== "string" || !input.name.trim()) {
|
|
790
|
+
throw new Error("Invalid Kiro tool_call payload: missing nested MCP tool name");
|
|
322
791
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const chunk = {
|
|
327
|
-
id: responseId,
|
|
328
|
-
object: "chat.completion.chunk",
|
|
329
|
-
created,
|
|
330
|
-
model,
|
|
331
|
-
choices: [{
|
|
332
|
-
index: 0,
|
|
333
|
-
delta: chunkIndex === 0
|
|
334
|
-
? { role: "assistant", content }
|
|
335
|
-
: { content },
|
|
336
|
-
finish_reason: null
|
|
337
|
-
}]
|
|
338
|
-
};
|
|
339
|
-
chunkIndex++;
|
|
340
|
-
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(chunk)}\n\n`));
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Handle reasoningContentEvent (Kiro thinking / reasoning)
|
|
344
|
-
// Kiro returns reasoning as a separate event when the request system
|
|
345
|
-
// prompt contains <thinking_mode>enabled</thinking_mode>. Surface it
|
|
346
|
-
// as OpenAI delta.reasoning_content so downstream translators can map
|
|
347
|
-
// it back to Claude thinking blocks / Anthropic reasoning, etc.
|
|
348
|
-
if (eventType === "reasoningContentEvent") {
|
|
349
|
-
const reasoning = event.payload?.reasoningContentEvent || event.payload || {};
|
|
350
|
-
const reasoningText = (typeof reasoning === "string")
|
|
351
|
-
? reasoning
|
|
352
|
-
: (reasoning.text || reasoning.content || "");
|
|
353
|
-
if (reasoningText) {
|
|
354
|
-
state.hasReasoningContent = true;
|
|
355
|
-
state.totalContentLength += reasoningText.length;
|
|
356
|
-
|
|
357
|
-
const reasoningDelta = state.reasoningChunkCount === 0 && chunkIndex === 0
|
|
358
|
-
? { role: "assistant", reasoning_content: reasoningText }
|
|
359
|
-
: { reasoning_content: reasoningText };
|
|
360
|
-
|
|
361
|
-
const chunk = {
|
|
362
|
-
id: responseId,
|
|
363
|
-
object: "chat.completion.chunk",
|
|
364
|
-
created,
|
|
365
|
-
model,
|
|
366
|
-
choices: [{
|
|
367
|
-
index: 0,
|
|
368
|
-
delta: reasoningDelta,
|
|
369
|
-
finish_reason: null
|
|
370
|
-
}]
|
|
371
|
-
};
|
|
372
|
-
chunkIndex++;
|
|
373
|
-
state.reasoningChunkCount++;
|
|
374
|
-
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(chunk)}\n\n`));
|
|
792
|
+
if (!Object.prototype.hasOwnProperty.call(input, "arguments")) {
|
|
793
|
+
throw new Error("Invalid Kiro tool_call payload: missing nested MCP tool arguments");
|
|
375
794
|
}
|
|
376
795
|
}
|
|
796
|
+
} catch (error) {
|
|
797
|
+
state.droppedTools = (state.droppedTools || 0) + 1;
|
|
798
|
+
state.toolValidationError ||= error.message;
|
|
799
|
+
console.error(`[Kiro] dropping unusable tool call ${tool.id} (${tool.name}): ${error.message}`);
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
const index = state.toolCounter++;
|
|
803
|
+
emitDelta(controller, {
|
|
804
|
+
tool_calls: [{
|
|
805
|
+
index,
|
|
806
|
+
id: tool.id,
|
|
807
|
+
type: "function",
|
|
808
|
+
function: { name: tool.name, arguments: "" }
|
|
809
|
+
}]
|
|
810
|
+
});
|
|
811
|
+
const serializedInput = JSON.stringify(input);
|
|
812
|
+
emitDelta(controller, {
|
|
813
|
+
tool_calls: [{ index, function: { arguments: serializedInput } }]
|
|
814
|
+
});
|
|
815
|
+
// Tool arguments are billed output like any other completion bytes. They
|
|
816
|
+
// were never added to totalContentLength, so the /4 estimator in finish()
|
|
817
|
+
// reported OUT 0 -- or the Math.max floor of 1 -- for every turn whose
|
|
818
|
+
// entire answer was a tool call.
|
|
819
|
+
state.totalContentLength += tool.name.length + serializedInput.length;
|
|
820
|
+
state.hasToolCalls = true;
|
|
821
|
+
}
|
|
822
|
+
state.tools.clear();
|
|
823
|
+
state.bufferedToolBytes = 0;
|
|
824
|
+
// A declared tool turn that emitted no usable call is only fatal when the
|
|
825
|
+
// turn produced nothing else. Throwing unconditionally here escaped
|
|
826
|
+
// emitTools() with provenance "invalid_tool_call", which the integrity gate
|
|
827
|
+
// re-derived into a repair retry -- discarding text the client had already
|
|
828
|
+
// been promised.
|
|
829
|
+
if (state.stopReason === "tool_use" && !state.hasToolCalls &&
|
|
830
|
+
!state.hasText && !state.hasReasoning && !state.hasCode) {
|
|
831
|
+
throw new Error("Kiro tool_use stop reason did not include a complete tool call");
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
const processEvent = (event, controller) => {
|
|
835
|
+
const messageType = event.headers[":message-type"];
|
|
836
|
+
if (messageType === "error" || messageType === "exception") {
|
|
837
|
+
fail(
|
|
838
|
+
controller,
|
|
839
|
+
"upstream_eventstream_error",
|
|
840
|
+
"kiro_upstream_eventstream_error",
|
|
841
|
+
event.payload?.message || `Kiro upstream sent an EventStream ${messageType}`,
|
|
842
|
+
{ transport_state: "upstream_error" }
|
|
843
|
+
);
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
377
846
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}]
|
|
390
|
-
};
|
|
391
|
-
chunkIndex++;
|
|
392
|
-
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(chunk)}\n\n`));
|
|
847
|
+
const eventType = event.headers[":event-type"] || "";
|
|
848
|
+
const eventCountKey = KIRO_EVENT_TYPES.has(eventType) ? eventType : "other";
|
|
849
|
+
eventCounts[eventCountKey] = (eventCounts[eventCountKey] || 0) + 1;
|
|
850
|
+
if (eventType === "assistantResponseEvent" && typeof event.payload?.content === "string") {
|
|
851
|
+
let content = event.payload.content;
|
|
852
|
+
if (state.inThinking) {
|
|
853
|
+
const end = content.indexOf("</thinking>");
|
|
854
|
+
if (end < 0) content = "";
|
|
855
|
+
else {
|
|
856
|
+
state.inThinking = false;
|
|
857
|
+
content = content.slice(end + 11).replace(/^\n/u, "");
|
|
393
858
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const toolName = singleToolUse.name || "";
|
|
404
|
-
const toolInput = singleToolUse.input;
|
|
405
|
-
|
|
406
|
-
let toolIndex;
|
|
407
|
-
const isNewTool = !state.seenToolIds.has(toolCallId);
|
|
408
|
-
|
|
409
|
-
if (isNewTool) {
|
|
410
|
-
toolIndex = state.toolCallIndex++;
|
|
411
|
-
state.seenToolIds.set(toolCallId, toolIndex);
|
|
412
|
-
|
|
413
|
-
const startChunk = {
|
|
414
|
-
id: responseId,
|
|
415
|
-
object: "chat.completion.chunk",
|
|
416
|
-
created,
|
|
417
|
-
model,
|
|
418
|
-
choices: [{
|
|
419
|
-
index: 0,
|
|
420
|
-
delta: {
|
|
421
|
-
...(chunkIndex === 0 ? { role: "assistant" } : {}),
|
|
422
|
-
tool_calls: [{
|
|
423
|
-
index: toolIndex,
|
|
424
|
-
id: toolCallId,
|
|
425
|
-
type: "function",
|
|
426
|
-
function: {
|
|
427
|
-
name: toolName,
|
|
428
|
-
arguments: ""
|
|
429
|
-
}
|
|
430
|
-
}]
|
|
431
|
-
},
|
|
432
|
-
finish_reason: null
|
|
433
|
-
}]
|
|
434
|
-
};
|
|
435
|
-
chunkIndex++;
|
|
436
|
-
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(startChunk)}\n\n`));
|
|
437
|
-
} else {
|
|
438
|
-
toolIndex = state.seenToolIds.get(toolCallId);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
if (toolInput !== undefined) {
|
|
442
|
-
let argumentsStr;
|
|
443
|
-
|
|
444
|
-
if (typeof toolInput === 'string') {
|
|
445
|
-
argumentsStr = toolInput;
|
|
446
|
-
} else if (typeof toolInput === 'object') {
|
|
447
|
-
argumentsStr = JSON.stringify(toolInput);
|
|
448
|
-
} else {
|
|
449
|
-
continue;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const argsChunk = {
|
|
453
|
-
id: responseId,
|
|
454
|
-
object: "chat.completion.chunk",
|
|
455
|
-
created,
|
|
456
|
-
model,
|
|
457
|
-
choices: [{
|
|
458
|
-
index: 0,
|
|
459
|
-
delta: {
|
|
460
|
-
tool_calls: [{
|
|
461
|
-
index: toolIndex,
|
|
462
|
-
function: {
|
|
463
|
-
arguments: argumentsStr
|
|
464
|
-
}
|
|
465
|
-
}]
|
|
466
|
-
},
|
|
467
|
-
finish_reason: null
|
|
468
|
-
}]
|
|
469
|
-
};
|
|
470
|
-
chunkIndex++;
|
|
471
|
-
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(argsChunk)}\n\n`));
|
|
472
|
-
}
|
|
859
|
+
} else {
|
|
860
|
+
const start = content.indexOf("<thinking>");
|
|
861
|
+
if (start >= 0) {
|
|
862
|
+
const end = content.indexOf("</thinking>", start + 10);
|
|
863
|
+
if (end < 0) {
|
|
864
|
+
state.inThinking = true;
|
|
865
|
+
content = content.slice(0, start);
|
|
866
|
+
} else {
|
|
867
|
+
content = content.slice(0, start) + content.slice(end + 11).replace(/^\n/u, "");
|
|
473
868
|
}
|
|
474
869
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
870
|
+
}
|
|
871
|
+
if (content || !state.hasReasoning) {
|
|
872
|
+
state.hasText ||= content.length > 0;
|
|
873
|
+
state.totalContentLength += content.length;
|
|
874
|
+
emitDelta(controller, { content });
|
|
875
|
+
}
|
|
876
|
+
} else if (eventType === "reasoningContentEvent") {
|
|
877
|
+
const value = event.payload?.reasoningContentEvent || event.payload || {};
|
|
878
|
+
const content = typeof value === "string" ? value : value.text || value.content || "";
|
|
879
|
+
if (content) {
|
|
880
|
+
state.hasReasoning = true;
|
|
881
|
+
state.totalContentLength += content.length;
|
|
882
|
+
emitDelta(controller, { reasoning_content: content });
|
|
883
|
+
}
|
|
884
|
+
} else if (eventType === "codeEvent" && typeof event.payload?.content === "string") {
|
|
885
|
+
state.hasCode = true;
|
|
886
|
+
state.totalContentLength += event.payload.content.length;
|
|
887
|
+
emitDelta(controller, { content: event.payload.content });
|
|
888
|
+
} else if (eventType === "toolUseEvent") {
|
|
889
|
+
state.sawToolUse = true;
|
|
890
|
+
const values = Array.isArray(event.payload) ? event.payload : [event.payload];
|
|
891
|
+
if (!values[0]) throw new Error("Kiro toolUseEvent is empty");
|
|
892
|
+
for (const value of values) {
|
|
893
|
+
const name = typeof value?.name === "string" ? value.name.trim() : "";
|
|
894
|
+
if (!name) throw new Error("Kiro toolUseEvent is missing a tool name");
|
|
895
|
+
let id;
|
|
896
|
+
if (value.toolUseId == null) {
|
|
897
|
+
id = `call_${created}_${state.tools.size + 1}`;
|
|
898
|
+
} else if (typeof value.toolUseId !== "string" || !value.toolUseId.trim()) {
|
|
899
|
+
throw new Error("Kiro toolUseEvent has an invalid toolUseId");
|
|
900
|
+
} else {
|
|
901
|
+
id = value.toolUseId;
|
|
498
902
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
state.
|
|
903
|
+
let tool = state.tools.get(id);
|
|
904
|
+
if (!tool) {
|
|
905
|
+
tool = { id, name };
|
|
906
|
+
state.tools.set(id, tool);
|
|
907
|
+
state.bufferedToolBytes += encoder.encode(id).byteLength + encoder.encode(name).byteLength + 32;
|
|
908
|
+
assertToolBufferBound();
|
|
909
|
+
} else if (tool.name !== name) {
|
|
910
|
+
throw new Error("Kiro tool name changed between fragments");
|
|
503
911
|
}
|
|
912
|
+
appendToolInput(tool, value.input);
|
|
913
|
+
}
|
|
914
|
+
} else if (eventType === "messageStopEvent") {
|
|
915
|
+
state.explicitStop = true;
|
|
916
|
+
const reason = normalizeStopReason(
|
|
917
|
+
event.payload?.stopReason ?? event.payload?.stop_reason
|
|
918
|
+
) || (state.sawToolUse ? "tool_use" : "end_turn");
|
|
919
|
+
const merged = mergeStopReason(state.stopReason, reason);
|
|
920
|
+
if (merged !== state.stopReason) state.terminalProvenance = "message_stop_event";
|
|
921
|
+
state.stopReason = merged;
|
|
922
|
+
} else if (eventType === "metadataEvent" || eventType === "MetadataEvent") {
|
|
923
|
+
const metadata = event.payload?.metadataEvent || event.payload?.metadata || event.payload;
|
|
924
|
+
const reason = normalizeStopReason(metadata?.stopReason ?? metadata?.stop_reason);
|
|
925
|
+
if (reason) {
|
|
926
|
+
state.explicitStop = true;
|
|
927
|
+
const merged = mergeStopReason(state.stopReason, reason);
|
|
928
|
+
if (merged !== state.stopReason) state.terminalProvenance = "metadata_stop_reason";
|
|
929
|
+
state.stopReason = merged;
|
|
930
|
+
}
|
|
931
|
+
} else if (eventType === "contextUsageEvent") {
|
|
932
|
+
const percentage = Number(event.payload?.contextUsagePercentage);
|
|
933
|
+
if (Number.isFinite(percentage)) {
|
|
934
|
+
state.contextUsagePercentage = percentage;
|
|
935
|
+
state.hasContextUsage = true;
|
|
936
|
+
}
|
|
937
|
+
} else if (eventType === "meteringEvent") {
|
|
938
|
+
state.hasMetering = true;
|
|
939
|
+
const metering = event.payload?.meteringEvent || event.payload || {};
|
|
940
|
+
const credits = Number(metering.usage);
|
|
941
|
+
if (Number.isFinite(credits)) {
|
|
942
|
+
state.usage = {
|
|
943
|
+
...(state.usage || {}),
|
|
944
|
+
kiro_credits: credits,
|
|
945
|
+
kiro_credit_unit: typeof metering.unit === "string" ? metering.unit : "credit"
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
} else if (eventType === "metricsEvent") {
|
|
949
|
+
const metrics = event.payload?.metricsEvent || event.payload || {};
|
|
950
|
+
const prompt = Number(metrics.inputTokens) || 0;
|
|
951
|
+
const completion = Number(metrics.outputTokens) || 0;
|
|
952
|
+
if (prompt || completion) {
|
|
953
|
+
state.usage = {
|
|
954
|
+
...(state.usage || {}),
|
|
955
|
+
prompt_tokens: prompt,
|
|
956
|
+
completion_tokens: completion,
|
|
957
|
+
total_tokens: prompt + completion
|
|
958
|
+
};
|
|
959
|
+
const cacheRead = Number(metrics.cacheReadInputTokens || metrics.cache_read_input_tokens) || 0;
|
|
960
|
+
const cacheCreate = Number(metrics.cacheCreationInputTokens || metrics.cache_creation_input_tokens) || 0;
|
|
961
|
+
if (cacheRead) state.usage.cache_read_input_tokens = cacheRead;
|
|
962
|
+
if (cacheCreate) state.usage.cache_creation_input_tokens = cacheCreate;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return true;
|
|
966
|
+
};
|
|
967
|
+
const processBytes = (chunk, controller) => {
|
|
968
|
+
const combinedLength = state.buffer.byteLength + chunk.byteLength;
|
|
969
|
+
if (combinedLength > (options.maxRawBytes || EVENTSTREAM_MAX_MESSAGE_BYTES)) {
|
|
970
|
+
fail(
|
|
971
|
+
controller,
|
|
972
|
+
"corrupt_eventstream_frame",
|
|
973
|
+
"kiro_missing_terminal",
|
|
974
|
+
"Kiro EventStream buffered bytes exceed the protocol bound"
|
|
975
|
+
);
|
|
976
|
+
return false;
|
|
977
|
+
}
|
|
978
|
+
if (state.buffer.byteLength === 0) {
|
|
979
|
+
state.buffer = chunk;
|
|
980
|
+
} else {
|
|
981
|
+
const joined = new Uint8Array(combinedLength);
|
|
982
|
+
joined.set(state.buffer);
|
|
983
|
+
joined.set(chunk, state.buffer.byteLength);
|
|
984
|
+
state.buffer = joined;
|
|
985
|
+
}
|
|
504
986
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
987
|
+
while (state.buffer.byteLength >= 12) {
|
|
988
|
+
const view = new DataView(state.buffer.buffer, state.buffer.byteOffset);
|
|
989
|
+
if (view.getUint32(8, false) !== crc32(state.buffer.subarray(0, 8))) {
|
|
990
|
+
fail(controller, "corrupt_eventstream_frame", "kiro_missing_terminal", "Kiro EventStream prelude CRC mismatch");
|
|
991
|
+
return false;
|
|
992
|
+
}
|
|
993
|
+
const totalLength = view.getUint32(0, false);
|
|
994
|
+
const headersLength = view.getUint32(4, false);
|
|
995
|
+
if (totalLength < 16 || totalLength > EVENTSTREAM_MAX_MESSAGE_BYTES ||
|
|
996
|
+
headersLength > EVENTSTREAM_MAX_HEADERS_BYTES || headersLength > totalLength - 16) {
|
|
997
|
+
fail(controller, "corrupt_eventstream_frame", "kiro_missing_terminal", "Kiro EventStream frame bounds are invalid");
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
if (state.buffer.byteLength < totalLength) break;
|
|
1001
|
+
const frame = state.buffer.slice(0, totalLength);
|
|
1002
|
+
state.buffer = state.buffer.slice(totalLength);
|
|
1003
|
+
let event;
|
|
1004
|
+
try {
|
|
1005
|
+
event = parseEventFrame(frame);
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
fail(controller, "corrupt_eventstream_frame", "kiro_missing_terminal", error.message);
|
|
1008
|
+
return false;
|
|
1009
|
+
}
|
|
1010
|
+
state.transportState = "valid_complete_frame";
|
|
1011
|
+
state.validatedFrames++;
|
|
1012
|
+
try {
|
|
1013
|
+
if (!processEvent(event, controller)) return false;
|
|
1014
|
+
} catch (error) {
|
|
1015
|
+
const bufferExceeded = error.code === "KIRO_BUFFER_EXCEEDED";
|
|
1016
|
+
if (!bufferExceeded) {
|
|
1017
|
+
// Keep whatever is already buffered: the rejected fragment belongs to
|
|
1018
|
+
// one tool, and clearing the map dropped the complete calls too.
|
|
1019
|
+
state.toolValidationError ||= error.message;
|
|
1020
|
+
console.error(`[Kiro] tool fragment rejected, keeping ${state.tools.size} buffered tool(s): ${error.message}`);
|
|
1021
|
+
continue;
|
|
532
1022
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const estimatedOutputTokens = state.totalContentLength > 0
|
|
542
|
-
? Math.max(1, Math.floor(state.totalContentLength / 4))
|
|
543
|
-
: 0;
|
|
544
|
-
|
|
545
|
-
// Estimate input tokens from contextUsagePercentage
|
|
546
|
-
const estimatedInputTokens = state.contextUsagePercentage > 0
|
|
547
|
-
? Math.floor(state.contextUsagePercentage * contextWindow / 100)
|
|
548
|
-
: 0;
|
|
549
|
-
|
|
550
|
-
state.usage = {
|
|
551
|
-
prompt_tokens: estimatedInputTokens,
|
|
552
|
-
completion_tokens: estimatedOutputTokens,
|
|
553
|
-
total_tokens: estimatedInputTokens + estimatedOutputTokens
|
|
554
|
-
};
|
|
1023
|
+
fail(
|
|
1024
|
+
controller,
|
|
1025
|
+
"integrity_buffer_exceeded",
|
|
1026
|
+
"kiro_integrity_buffer_exceeded",
|
|
1027
|
+
error.message,
|
|
1028
|
+
{
|
|
1029
|
+
transport_state: state.transportState,
|
|
1030
|
+
stop_disposition: "terminal_incomplete"
|
|
555
1031
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
id: responseId,
|
|
559
|
-
object: "chat.completion.chunk",
|
|
560
|
-
created,
|
|
561
|
-
model,
|
|
562
|
-
choices: [{
|
|
563
|
-
index: 0,
|
|
564
|
-
delta: {},
|
|
565
|
-
finish_reason: state.hasToolCalls ? "tool_calls" : "stop"
|
|
566
|
-
}]
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
// Include usage in final chunk if available
|
|
570
|
-
if (state.usage) {
|
|
571
|
-
finishChunk.usage = state.usage;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(finishChunk)}\n\n`));
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
if (iterations >= maxIterations) {
|
|
579
|
-
console.warn("[Kiro] Max iterations reached in event parsing");
|
|
1032
|
+
);
|
|
1033
|
+
return false;
|
|
580
1034
|
}
|
|
1035
|
+
}
|
|
1036
|
+
return true;
|
|
1037
|
+
};
|
|
1038
|
+
const finish = (controller) => {
|
|
1039
|
+
if (state.finished) return;
|
|
1040
|
+
if (state.buffer.byteLength) {
|
|
1041
|
+
fail(
|
|
1042
|
+
controller,
|
|
1043
|
+
"incomplete_eventstream_frame",
|
|
1044
|
+
"kiro_missing_terminal",
|
|
1045
|
+
"Kiro EventStream ended with a truncated frame",
|
|
1046
|
+
{ transport_state: "incomplete_frame" }
|
|
1047
|
+
);
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
state.transportState = "clean_eof";
|
|
1051
|
+
const declaredDisposition = stopDisposition(state.stopReason, state.sawToolUse);
|
|
1052
|
+
// model_context_window_exceeded / max_tokens map to terminal_incomplete. When
|
|
1053
|
+
// they arrive after the model already streamed content, fail() threw away a
|
|
1054
|
+
// complete-enough answer; a truncated turn is what finish_reason "length" is
|
|
1055
|
+
// for. chunkIndex > 0 means at least one delta already reached the client.
|
|
1056
|
+
const declaredTruncatedAfterOutput = declaredDisposition === "terminal_incomplete" &&
|
|
1057
|
+
KIRO_TRUNCATION_STOP_REASONS.has(state.stopReason) && state.chunkIndex > 0;
|
|
1058
|
+
if (declaredTruncatedAfterOutput) {
|
|
1059
|
+
console.error(`[Kiro] truncated after ${state.chunkIndex} chunk(s) (stop_reason=${state.stopReason}); keeping output`);
|
|
1060
|
+
}
|
|
1061
|
+
if (!declaredTruncatedAfterOutput && ["retryable_protocol_failure", "terminal_incomplete", "terminal_refusal", "unknown_failure"].includes(declaredDisposition)) {
|
|
1062
|
+
const code = declaredDisposition === "retryable_protocol_failure"
|
|
1063
|
+
? "kiro_retryable_protocol_failure"
|
|
1064
|
+
: declaredDisposition === "terminal_refusal"
|
|
1065
|
+
? "kiro_terminal_refusal"
|
|
1066
|
+
: declaredDisposition === "terminal_incomplete"
|
|
1067
|
+
? "kiro_terminal_incomplete"
|
|
1068
|
+
: "kiro_unknown_stop_reason";
|
|
1069
|
+
fail(
|
|
1070
|
+
controller,
|
|
1071
|
+
state.terminalProvenance || "metadata_stop_reason",
|
|
1072
|
+
code,
|
|
1073
|
+
`Kiro ended with non-success stop reason: ${state.stopReason}`,
|
|
1074
|
+
{ transport_state: state.transportState, stop_disposition: declaredDisposition }
|
|
1075
|
+
);
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
try {
|
|
1079
|
+
emitTools(controller);
|
|
1080
|
+
} catch (error) {
|
|
1081
|
+
fail(
|
|
1082
|
+
controller,
|
|
1083
|
+
"invalid_tool_call",
|
|
1084
|
+
"invalid_kiro_tool_call",
|
|
1085
|
+
error.message,
|
|
1086
|
+
{ transport_state: state.transportState, stop_disposition: "retryable_protocol_failure" }
|
|
1087
|
+
);
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
// Fail only when the turn has nothing usable left. emitTools() validates
|
|
1091
|
+
// per tool and drops just the unusable ones, so this has to run AFTER it:
|
|
1092
|
+
// before, the rejected tool was still buffered and tools.size was never 0.
|
|
1093
|
+
// A turn that also produced text keeps that text -- the dropped call is
|
|
1094
|
+
// logged, not fatal.
|
|
1095
|
+
if (state.toolValidationError && !state.hasToolCalls &&
|
|
1096
|
+
!state.hasText && !state.hasReasoning && !state.hasCode) {
|
|
1097
|
+
fail(
|
|
1098
|
+
controller,
|
|
1099
|
+
"invalid_tool_call",
|
|
1100
|
+
"invalid_kiro_tool_call",
|
|
1101
|
+
state.toolValidationError,
|
|
1102
|
+
{ transport_state: state.transportState, stop_disposition: "retryable_protocol_failure" }
|
|
1103
|
+
);
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
581
1106
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
1107
|
+
const hasOutput = state.hasText || state.hasReasoning || state.hasCode || state.hasToolCalls;
|
|
1108
|
+
if (!hasOutput && !state.explicitStop) {
|
|
1109
|
+
fail(
|
|
1110
|
+
controller,
|
|
1111
|
+
"empty_response_eof",
|
|
1112
|
+
"kiro_missing_terminal",
|
|
1113
|
+
"Kiro EventStream ended without model output",
|
|
1114
|
+
{ transport_state: state.transportState }
|
|
1115
|
+
);
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
590
1118
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
1119
|
+
const disposition = stopDisposition(state.stopReason, state.hasToolCalls);
|
|
1120
|
+
// Same reasoning as declaredTruncatedAfterOutput above.
|
|
1121
|
+
const truncatedAfterOutput = disposition === "terminal_incomplete" &&
|
|
1122
|
+
KIRO_TRUNCATION_STOP_REASONS.has(state.stopReason) && state.chunkIndex > 0;
|
|
1123
|
+
if (truncatedAfterOutput) {
|
|
1124
|
+
console.error(`[Kiro] truncated after ${state.chunkIndex} chunk(s) (stop_reason=${state.stopReason}); closing as length`);
|
|
1125
|
+
}
|
|
1126
|
+
if (!truncatedAfterOutput && ["retryable_protocol_failure", "terminal_incomplete", "terminal_refusal", "unknown_failure"].includes(disposition)) {
|
|
1127
|
+
const code = disposition === "retryable_protocol_failure"
|
|
1128
|
+
? "kiro_retryable_protocol_failure"
|
|
1129
|
+
: disposition === "terminal_refusal"
|
|
1130
|
+
? "kiro_terminal_refusal"
|
|
1131
|
+
: disposition === "terminal_incomplete"
|
|
1132
|
+
? "kiro_terminal_incomplete"
|
|
1133
|
+
: "kiro_unknown_stop_reason";
|
|
1134
|
+
fail(
|
|
1135
|
+
controller,
|
|
1136
|
+
state.terminalProvenance || "metadata_stop_reason",
|
|
1137
|
+
code,
|
|
1138
|
+
`Kiro ended with non-success stop reason: ${state.stopReason}`,
|
|
1139
|
+
{ transport_state: state.transportState, stop_disposition: disposition }
|
|
1140
|
+
);
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
608
1143
|
|
|
609
|
-
|
|
610
|
-
|
|
1144
|
+
if (state.hasMetering && state.hasContextUsage && !state.usage?.total_tokens) {
|
|
1145
|
+
const completion = state.totalContentLength
|
|
1146
|
+
? Math.max(1, Math.floor(state.totalContentLength / 4))
|
|
1147
|
+
: 0;
|
|
1148
|
+
const prompt = Math.floor(state.contextUsagePercentage * contextWindow / 100);
|
|
1149
|
+
state.usage = {
|
|
1150
|
+
...(state.usage || {}),
|
|
1151
|
+
prompt_tokens: prompt,
|
|
1152
|
+
completion_tokens: completion,
|
|
1153
|
+
total_tokens: prompt + completion
|
|
1154
|
+
};
|
|
611
1155
|
}
|
|
612
|
-
|
|
1156
|
+
const finishReason = truncatedAfterOutput
|
|
1157
|
+
? "length"
|
|
1158
|
+
: state.hasToolCalls
|
|
1159
|
+
? "tool_calls"
|
|
1160
|
+
: disposition === "length"
|
|
1161
|
+
? "length"
|
|
1162
|
+
: "stop";
|
|
1163
|
+
controller.enqueue(sseChunk({}, finishReason, state.usage));
|
|
1164
|
+
controller.enqueue(encoder.encode(SSE_DONE));
|
|
1165
|
+
state.finished = true;
|
|
1166
|
+
options.onTerminalState?.(diagnostics({
|
|
1167
|
+
terminal_provenance: state.terminalProvenance || "clean_eventstream_eof",
|
|
1168
|
+
transport_state: state.transportState,
|
|
1169
|
+
// Report what this exit actually did, not the raw disposition. The
|
|
1170
|
+
// integrity gate re-derives its verdict from stop_disposition, so
|
|
1171
|
+
// reporting "terminal_incomplete" for a turn we deliberately kept made
|
|
1172
|
+
// it discard the very bytes we just released to the client.
|
|
1173
|
+
stop_disposition: truncatedAfterOutput ? "length" : disposition
|
|
1174
|
+
}));
|
|
1175
|
+
};
|
|
613
1176
|
|
|
614
|
-
// Pipe response body through transform stream
|
|
615
1177
|
if (!response.body) {
|
|
616
|
-
|
|
1178
|
+
const detail = diagnostics({
|
|
1179
|
+
terminal_provenance: "missing_response_body",
|
|
1180
|
+
transport_state: "missing_body",
|
|
1181
|
+
stop_disposition: "terminal_incomplete"
|
|
1182
|
+
});
|
|
1183
|
+
options.onTerminalState?.(detail);
|
|
1184
|
+
return new Response(encodeSSEError(
|
|
1185
|
+
"kiro_missing_terminal",
|
|
1186
|
+
"Kiro response did not include an EventStream body",
|
|
1187
|
+
detail
|
|
1188
|
+
), { status: response.status, headers: { ...SSE_HEADERS } });
|
|
617
1189
|
}
|
|
618
|
-
const transformedStream = response.body.pipeThrough(transformStream);
|
|
619
1190
|
|
|
620
|
-
|
|
1191
|
+
const reader = response.body.getReader();
|
|
1192
|
+
const stream = new ReadableStream({
|
|
1193
|
+
start: async (controller) => {
|
|
1194
|
+
try {
|
|
1195
|
+
while (!state.finished) {
|
|
1196
|
+
const { done, value } = await reader.read();
|
|
1197
|
+
if (done) break;
|
|
1198
|
+
const chunksBefore = state.chunkIndex;
|
|
1199
|
+
const framesBefore = state.validatedFrames;
|
|
1200
|
+
if (!processBytes(value, controller)) {
|
|
1201
|
+
await reader.cancel("invalid Kiro EventStream").catch(() => {});
|
|
1202
|
+
break;
|
|
1203
|
+
}
|
|
1204
|
+
if (state.validatedFrames > framesBefore && state.chunkIndex === chunksBefore) {
|
|
1205
|
+
controller.enqueue(encoder.encode(": kiro-upstream\n\n"));
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
finish(controller);
|
|
1209
|
+
controller.close();
|
|
1210
|
+
} catch (error) {
|
|
1211
|
+
if (!state.finished) {
|
|
1212
|
+
fail(
|
|
1213
|
+
controller,
|
|
1214
|
+
"upstream_read_error",
|
|
1215
|
+
"kiro_missing_terminal",
|
|
1216
|
+
error.message || "Kiro EventStream read failed",
|
|
1217
|
+
{ transport_state: "upstream_error" }
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
controller.close();
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
cancel(reason) {
|
|
1224
|
+
return reader.cancel(reason);
|
|
1225
|
+
}
|
|
1226
|
+
});
|
|
1227
|
+
return new Response(stream, {
|
|
621
1228
|
status: response.status,
|
|
622
1229
|
statusText: response.statusText,
|
|
623
1230
|
headers: { ...SSE_HEADERS }
|
|
@@ -647,65 +1254,90 @@ export class KiroExecutor extends BaseExecutor {
|
|
|
647
1254
|
/**
|
|
648
1255
|
* Parse AWS EventStream frame
|
|
649
1256
|
*/
|
|
650
|
-
function parseEventFrame(data) {
|
|
651
|
-
try {
|
|
652
|
-
const view = new DataView(data.buffer, data.byteOffset);
|
|
653
|
-
const headersLength = view.getUint32(4, false);
|
|
654
|
-
|
|
655
|
-
// Parse headers
|
|
656
|
-
const headers = {};
|
|
657
|
-
let offset = 12; // After prelude
|
|
658
|
-
const headerEnd = 12 + headersLength;
|
|
659
1257
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
1258
|
+
function parseEventFrame(data) {
|
|
1259
|
+
if (!(data instanceof Uint8Array) || data.byteLength < 16) {
|
|
1260
|
+
throw new Error("AWS EventStream frame is shorter than 16 bytes");
|
|
1261
|
+
}
|
|
1262
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
1263
|
+
const totalLength = view.getUint32(0, false);
|
|
1264
|
+
const headersLength = view.getUint32(4, false);
|
|
1265
|
+
if (totalLength !== data.byteLength) {
|
|
1266
|
+
throw new Error("AWS EventStream frame length does not match its prelude");
|
|
1267
|
+
}
|
|
1268
|
+
if (totalLength > EVENTSTREAM_MAX_MESSAGE_BYTES ||
|
|
1269
|
+
headersLength > EVENTSTREAM_MAX_HEADERS_BYTES ||
|
|
1270
|
+
headersLength > totalLength - 16) {
|
|
1271
|
+
throw new Error("AWS EventStream frame bounds are invalid");
|
|
1272
|
+
}
|
|
1273
|
+
if (view.getUint32(8, false) !== crc32(data.subarray(0, 8))) {
|
|
1274
|
+
throw new Error("AWS EventStream prelude CRC mismatch");
|
|
1275
|
+
}
|
|
1276
|
+
if (view.getUint32(totalLength - 4, false) !== crc32(data.subarray(0, totalLength - 4))) {
|
|
1277
|
+
throw new Error("AWS EventStream message CRC mismatch");
|
|
1278
|
+
}
|
|
675
1279
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1280
|
+
const headers = Object.create(null);
|
|
1281
|
+
const names = new Set();
|
|
1282
|
+
let offset = 12;
|
|
1283
|
+
const headerEnd = offset + headersLength;
|
|
1284
|
+
const requireBytes = (count) => {
|
|
1285
|
+
if (offset + count > headerEnd) {
|
|
1286
|
+
throw new Error("AWS EventStream header exceeds its declared bounds");
|
|
682
1287
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
1288
|
+
};
|
|
1289
|
+
|
|
1290
|
+
while (offset < headerEnd) {
|
|
1291
|
+
requireBytes(1);
|
|
1292
|
+
const nameLength = data[offset++];
|
|
1293
|
+
requireBytes(nameLength + 1);
|
|
1294
|
+
const name = decoder.decode(data.subarray(offset, offset + nameLength));
|
|
1295
|
+
offset += nameLength;
|
|
1296
|
+
if (names.has(name)) throw new Error(`AWS EventStream contains duplicate header: ${name}`);
|
|
1297
|
+
names.add(name);
|
|
1298
|
+
const type = data[offset++];
|
|
1299
|
+
|
|
1300
|
+
if (type === 0 || type === 1) {
|
|
1301
|
+
headers[name] = type === 0;
|
|
1302
|
+
} else if (type === 2) {
|
|
1303
|
+
requireBytes(1);
|
|
1304
|
+
headers[name] = view.getInt8(offset);
|
|
1305
|
+
offset += 1;
|
|
1306
|
+
} else if (type === 3) {
|
|
1307
|
+
requireBytes(2);
|
|
1308
|
+
headers[name] = view.getInt16(offset, false);
|
|
1309
|
+
offset += 2;
|
|
1310
|
+
} else if (type === 4) {
|
|
1311
|
+
requireBytes(4);
|
|
1312
|
+
headers[name] = view.getInt32(offset, false);
|
|
1313
|
+
offset += 4;
|
|
1314
|
+
} else if (type === 5 || type === 8) {
|
|
1315
|
+
requireBytes(8);
|
|
1316
|
+
offset += 8;
|
|
1317
|
+
} else if (type === 6 || type === 7) {
|
|
1318
|
+
requireBytes(2);
|
|
1319
|
+
const valueLength = view.getUint16(offset, false);
|
|
1320
|
+
offset += 2;
|
|
1321
|
+
requireBytes(valueLength);
|
|
1322
|
+
const bytes = data.subarray(offset, offset + valueLength);
|
|
1323
|
+
headers[name] = type === 7 ? decoder.decode(bytes) : bytes;
|
|
1324
|
+
offset += valueLength;
|
|
1325
|
+
} else if (type === 9) {
|
|
1326
|
+
requireBytes(16);
|
|
1327
|
+
offset += 16;
|
|
1328
|
+
} else {
|
|
1329
|
+
throw new Error(`AWS EventStream header ${name} has unknown type ${type}`);
|
|
704
1330
|
}
|
|
1331
|
+
}
|
|
705
1332
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
1333
|
+
const payloadBytes = data.subarray(headerEnd, totalLength - 4);
|
|
1334
|
+
if (payloadBytes.byteLength === 0) return { headers, payload: null };
|
|
1335
|
+
const payloadText = decoder.decode(payloadBytes);
|
|
1336
|
+
if (!payloadText.trim()) return { headers, payload: null };
|
|
1337
|
+
try {
|
|
1338
|
+
return { headers, payload: JSON.parse(payloadText) };
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
throw new Error(`AWS EventStream payload is not valid JSON (${error.message})`);
|
|
709
1341
|
}
|
|
710
1342
|
}
|
|
711
1343
|
|