@amir83nasr/10router 0.1.10 → 0.1.12
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +6 -5
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +23 -23
- package/.next/routes-manifest.json +6 -0
- package/.next/server/app/(dashboard)/dashboard/basic-chat/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js +2 -2
- package/.next/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/cli-tools/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/combos/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/console-log/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/endpoint/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/media-providers/systemone/[id]/page.js +2 -2
- package/.next/server/app/(dashboard)/dashboard/media-providers/systemone/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/media-providers/systemone/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/media-providers/systemone/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/profile/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
- package/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/providers/new/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/providers/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/proxy-pools/page.js +2 -2
- package/.next/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/pxpipe/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/quota/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/token-saver/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/usage/page.js +1 -1
- package/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +6 -6
- package/.next/server/app/_not-found.segments/_full.segment.rsc +6 -6
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/auth/login/route.js +1 -1
- package/.next/server/app/api/auth/logout/route.js +1 -1
- package/.next/server/app/api/auth/oidc/callback/route.js +1 -1
- package/.next/server/app/api/auth/oidc/start/route.js +1 -1
- package/.next/server/app/api/auth/oidc/test/route.js +1 -1
- package/.next/server/app/api/auth/reset-password/route.js +1 -1
- package/.next/server/app/api/auth/saml/acs/route.js +1 -1
- package/.next/server/app/api/auth/saml/metadata/route.js +1 -1
- package/.next/server/app/api/auth/saml/start/route.js +2 -2
- package/.next/server/app/api/auth/saml/test/route.js +1 -1
- package/.next/server/app/api/auth/status/route.js +1 -1
- package/.next/server/app/api/changelog/route.js +1 -1
- package/.next/server/app/api/cli-tools/all-statuses/route.js +1 -1
- package/.next/server/app/api/cli-tools/claude-settings/route.js +1 -1
- package/.next/server/app/api/cli-tools/codex-settings/route.js +1 -1
- package/.next/server/app/api/cli-tools/cowork-mcp-registry/route.js +1 -1
- package/.next/server/app/api/cli-tools/cowork-mcp-tools/route.js +2 -2
- package/.next/server/app/api/cli-tools/cowork-settings/route.js +1 -1
- package/.next/server/app/api/cli-tools/dsh-settings/route.js +1 -1
- package/.next/server/app/api/cli-tools/opencode-settings/route.js +1 -1
- package/.next/server/app/api/combos/[id]/route.js +1 -1
- package/.next/server/app/api/combos/route.js +1 -1
- package/.next/server/app/api/dashboard/chat/completions/route.js +1 -0
- package/.next/server/app/api/dashboard/chat/completions/route.js.nft.json +1 -0
- package/.next/server/app/api/dashboard/chat/completions/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/headroom/extras/route.js +1 -1
- package/.next/server/app/api/headroom/proxy/[...path]/route.js +1 -1
- package/.next/server/app/api/headroom/restart/route.js +1 -1
- package/.next/server/app/api/headroom/start/route.js +1 -1
- package/.next/server/app/api/headroom/status/route.js +1 -1
- package/.next/server/app/api/headroom/stop/route.js +1 -1
- package/.next/server/app/api/health/route.js +1 -1
- package/.next/server/app/api/init/route.js +1 -1
- package/.next/server/app/api/keys/[id]/route.js +1 -1
- package/.next/server/app/api/keys/route.js +1 -1
- package/.next/server/app/api/locale/route.js +1 -1
- package/.next/server/app/api/mcp/[plugin]/message/route.js +1 -1
- package/.next/server/app/api/mcp/[plugin]/sse/route.js +2 -2
- package/.next/server/app/api/media-providers/tts/deepgram/voices/route.js +1 -1
- package/.next/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
- package/.next/server/app/api/media-providers/tts/inworld/voices/route.js +1 -1
- package/.next/server/app/api/media-providers/tts/minimax/voices/route.js +1 -1
- package/.next/server/app/api/media-providers/tts/voices/route.js +1 -1
- package/.next/server/app/api/models/alias/route.js +1 -1
- package/.next/server/app/api/models/availability/route.js +1 -1
- package/.next/server/app/api/models/catalog-sync/route.js +1 -1
- package/.next/server/app/api/models/custom/route.js +1 -1
- package/.next/server/app/api/models/disabled/route.js +1 -1
- package/.next/server/app/api/models/route.js +1 -1
- package/.next/server/app/api/models/test/route.js +1 -1
- package/.next/server/app/api/oauth/[provider]/[action]/route.js +1 -1
- package/.next/server/app/api/oauth/codex/bulk-import/route.js +1 -1
- package/.next/server/app/api/oauth/codex/import-token/route.js +1 -1
- package/.next/server/app/api/oauth/cursor/auto-import/route.js +2 -2
- package/.next/server/app/api/oauth/cursor/import/route.js +1 -1
- package/.next/server/app/api/oauth/gitlab/pat/route.js +1 -1
- package/.next/server/app/api/oauth/grok-cli/bulk-import/route.js +1 -1
- package/.next/server/app/api/oauth/iflow/cookie/route.js +1 -1
- package/.next/server/app/api/oauth/xiaomi-mimo/api-key/route.js +1 -1
- package/.next/server/app/api/oauth/xiaomi-mimo/auto-import/route.js +2 -2
- package/.next/server/app/api/pricing/route.js +1 -1
- package/.next/server/app/api/provider-nodes/[id]/route.js +1 -1
- package/.next/server/app/api/provider-nodes/route.js +1 -1
- package/.next/server/app/api/provider-nodes/validate/route.js +1 -1
- package/.next/server/app/api/providers/[id]/models/route.js +1 -1
- package/.next/server/app/api/providers/[id]/route.js +1 -1
- package/.next/server/app/api/providers/[id]/test/route.js +1 -1
- package/.next/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/.next/server/app/api/providers/client/route.js +1 -1
- package/.next/server/app/api/providers/kilo/free-models/route.js +1 -1
- package/.next/server/app/api/providers/route.js +1 -1
- package/.next/server/app/api/providers/suggested-models/route.js +1 -1
- package/.next/server/app/api/providers/test-batch/route.js +1 -1
- package/.next/server/app/api/providers/validate/route.js +1 -1
- package/.next/server/app/api/proxy-pools/[id]/route.js +1 -1
- package/.next/server/app/api/proxy-pools/[id]/test/route.js +1 -1
- package/.next/server/app/api/proxy-pools/cloudflare-deploy/route.js +1 -1
- package/.next/server/app/api/proxy-pools/deno-deploy/route.js +2 -2
- package/.next/server/app/api/proxy-pools/route.js +1 -1
- package/.next/server/app/api/proxy-pools/vercel-deploy/route.js +2 -2
- package/.next/server/app/api/pxpipe/health/route.js +1 -1
- package/.next/server/app/api/pxpipe/install/route.js +1 -1
- package/.next/server/app/api/pxpipe/logs/route.js +1 -1
- package/.next/server/app/api/pxpipe/restart/route.js +1 -1
- package/.next/server/app/api/pxpipe/start/route.js +1 -1
- package/.next/server/app/api/pxpipe/stats/route.js +1 -1
- package/.next/server/app/api/pxpipe/status/route.js +1 -1
- package/.next/server/app/api/pxpipe/stop/route.js +1 -1
- package/.next/server/app/api/settings/database/route.js +1 -1
- package/.next/server/app/api/settings/proxy-test/route.js +1 -1
- package/.next/server/app/api/settings/require-login/route.js +1 -1
- package/.next/server/app/api/settings/route.js +1 -1
- package/.next/server/app/api/shutdown/route.js +1 -1
- package/.next/server/app/api/tags/route.js +1 -1
- package/.next/server/app/api/translator/console-logs/route.js +1 -1
- package/.next/server/app/api/translator/console-logs/stream/route.js +2 -2
- package/.next/server/app/api/translator/load/route.js +1 -1
- package/.next/server/app/api/translator/save/route.js +1 -1
- package/.next/server/app/api/translator/send/route.js +1 -1
- package/.next/server/app/api/translator/translate/route.js +1 -1
- package/.next/server/app/api/tunnel/disable/route.js +1 -1
- package/.next/server/app/api/tunnel/enable/route.js +1 -1
- package/.next/server/app/api/tunnel/status/route.js +1 -1
- package/.next/server/app/api/tunnel/tailscale-check/route.js +1 -1
- package/.next/server/app/api/tunnel/tailscale-disable/route.js +1 -1
- package/.next/server/app/api/tunnel/tailscale-enable/route.js +1 -1
- package/.next/server/app/api/tunnel/tailscale-install/route.js +3 -3
- package/.next/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
- package/.next/server/app/api/usage/[connectionId]/route.js +1 -1
- package/.next/server/app/api/usage/chart/route.js +1 -1
- package/.next/server/app/api/usage/health/route.js +1 -1
- package/.next/server/app/api/usage/history/route.js +1 -1
- package/.next/server/app/api/usage/logs/route.js +1 -1
- package/.next/server/app/api/usage/providers/route.js +1 -1
- package/.next/server/app/api/usage/request-details/route.js +1 -1
- package/.next/server/app/api/usage/request-logs/route.js +1 -1
- package/.next/server/app/api/usage/stats/route.js +1 -1
- package/.next/server/app/api/usage/stream/route.js +2 -2
- package/.next/server/app/api/v1/api/chat/route.js +1 -1
- package/.next/server/app/api/v1/audio/speech/route.js +1 -1
- package/.next/server/app/api/v1/audio/transcriptions/route.js +1 -1
- package/.next/server/app/api/v1/audio/voices/route.js +1 -1
- package/.next/server/app/api/v1/chat/completions/route.js +1 -1
- package/.next/server/app/api/v1/embeddings/route.js +1 -1
- package/.next/server/app/api/v1/images/generations/route.js +2 -2
- package/.next/server/app/api/v1/messages/count_tokens/route.js +1 -1
- package/.next/server/app/api/v1/messages/route.js +1 -1
- package/.next/server/app/api/v1/models/[...model]/route.js +1 -1
- package/.next/server/app/api/v1/models/info/route.js +1 -1
- package/.next/server/app/api/v1/models/route.js +1 -1
- package/.next/server/app/api/v1/responses/compact/route.js +1 -1
- package/.next/server/app/api/v1/responses/route.js +1 -1
- package/.next/server/app/api/v1/route.js +1 -1
- package/.next/server/app/api/v1/search/route.js +1 -1
- package/.next/server/app/api/v1/systemone/route.js +1 -1
- package/.next/server/app/api/v1/videos/[id]/route.js +1 -1
- package/.next/server/app/api/v1/videos/edits/route.js +1 -1
- package/.next/server/app/api/v1/videos/extensions/route.js +1 -1
- package/.next/server/app/api/v1/videos/generations/route.js +1 -1
- package/.next/server/app/api/v1/web/fetch/route.js +1 -1
- package/.next/server/app/api/v1beta/models/[...path]/route.js +1 -1
- package/.next/server/app/api/v1beta/models/route.js +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/api/version/shutdown/route.js +1 -1
- package/.next/server/app/api/version/update/route.js +1 -1
- package/.next/server/app/callback/page.js +1 -1
- package/.next/server/app/callback/page_client-reference-manifest.js +1 -1
- package/.next/server/app/callback.html +1 -1
- package/.next/server/app/callback.rsc +6 -6
- package/.next/server/app/callback.segments/_full.segment.rsc +6 -6
- package/.next/server/app/callback.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/dashboard/basic-chat.html +1 -1
- package/.next/server/app/dashboard/basic-chat.rsc +8 -8
- package/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/basic-chat.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/cli-tools.html +1 -1
- package/.next/server/app/dashboard/cli-tools.rsc +9 -9
- package/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/cli-tools.segments/_full.segment.rsc +9 -9
- package/.next/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/combos.html +1 -1
- package/.next/server/app/dashboard/combos.rsc +8 -8
- package/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/combos.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/endpoint.html +1 -1
- package/.next/server/app/dashboard/endpoint.rsc +9 -9
- package/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/endpoint.segments/_full.segment.rsc +9 -9
- package/.next/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/media-providers/systemone.html +1 -1
- package/.next/server/app/dashboard/media-providers/systemone.rsc +8 -8
- package/.next/server/app/dashboard/media-providers/systemone.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/systemone/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/media-providers/systemone.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/media-providers/systemone.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/profile.html +1 -1
- package/.next/server/app/dashboard/profile.rsc +8 -8
- package/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/profile.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/providers/new.html +1 -1
- package/.next/server/app/dashboard/providers/new.rsc +8 -8
- package/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/providers/new.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/providers.html +1 -1
- package/.next/server/app/dashboard/providers.rsc +8 -8
- package/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/providers.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/proxy-pools.html +1 -1
- package/.next/server/app/dashboard/proxy-pools.rsc +8 -8
- package/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/pxpipe.html +1 -1
- package/.next/server/app/dashboard/pxpipe.rsc +7 -7
- package/.next/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +7 -7
- package/.next/server/app/dashboard/pxpipe.segments/_full.segment.rsc +7 -7
- package/.next/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/quota.html +2 -2
- package/.next/server/app/dashboard/quota.rsc +9 -9
- package/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +9 -9
- package/.next/server/app/dashboard/quota.segments/_full.segment.rsc +9 -9
- package/.next/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/settings/pricing/page.js +1 -1
- package/.next/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/.next/server/app/dashboard/settings/pricing.html +1 -1
- package/.next/server/app/dashboard/settings/pricing.rsc +6 -6
- package/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +6 -6
- package/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/dashboard/token-saver.html +1 -1
- package/.next/server/app/dashboard/token-saver.rsc +7 -7
- package/.next/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +7 -7
- package/.next/server/app/dashboard/token-saver.segments/_full.segment.rsc +7 -7
- package/.next/server/app/dashboard/token-saver.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard/usage.html +2 -2
- package/.next/server/app/dashboard/usage.rsc +8 -8
- package/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard/usage.segments/_full.segment.rsc +8 -8
- package/.next/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/dashboard.html +1 -1
- package/.next/server/app/dashboard.rsc +9 -9
- package/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +8 -8
- package/.next/server/app/dashboard.segments/_full.segment.rsc +9 -9
- package/.next/server/app/dashboard.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +6 -6
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/index.segments/_full.segment.rsc +6 -6
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/landing/page.js +1 -1
- package/.next/server/app/landing/page_client-reference-manifest.js +1 -1
- package/.next/server/app/landing.html +1 -1
- package/.next/server/app/landing.rsc +6 -6
- package/.next/server/app/landing.segments/_full.segment.rsc +6 -6
- package/.next/server/app/landing.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/login/page.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.rsc +6 -6
- package/.next/server/app/login.segments/_full.segment.rsc +6 -6
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/manifest.webmanifest/route.js +2 -2
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +6 -5
- package/.next/server/chunks/1011.js +1 -1
- package/.next/server/chunks/1194.js +1 -1
- package/.next/server/chunks/1289.js +1 -1
- package/.next/server/chunks/1633.js +1 -1
- package/.next/server/chunks/1985.js +1 -1
- package/.next/server/chunks/2282.js +6 -6
- package/.next/server/chunks/2339.js +1 -1
- package/.next/server/chunks/2706.js +1 -1
- package/.next/server/chunks/2801.js +1 -1
- package/.next/server/chunks/3034.js +1 -1
- package/.next/server/chunks/3425.js +1 -1
- package/.next/server/chunks/4129.js +1 -1
- package/.next/server/chunks/6056.js +1 -1
- package/.next/server/chunks/7348.js +1 -1
- package/.next/server/chunks/7816.js +1 -1
- package/.next/server/chunks/9429.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/C423Aljus-j0GJlKCHgC1/_buildManifest.js +1 -0
- package/.next/static/chunks/1278-3b5ed69340ddb23f.js +1 -0
- package/.next/static/chunks/159-89c77cec422bd76f.js +1 -0
- package/.next/static/chunks/2392-b07fcae4714087ef.js +65 -0
- package/.next/static/chunks/2441-96064c4ee1216099.js +1 -0
- package/.next/static/chunks/{2836-d97f0aa2718945d5.js → 2836-4781ea7374870f4a.js} +1 -1
- package/.next/static/chunks/9320-ae7eb68edeb92e89.js +3 -0
- package/.next/static/chunks/{9369-0d43b295968c2168.js → 9369-07e432041bb48a39.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/basic-chat/page-34f4d77aa3df67a8.js +1 -0
- package/.next/static/chunks/app/(dashboard)/dashboard/cli-tools/[toolId]/{page-e8bceccb95695755.js → page-36ad70a4f906c64b.js} +2 -2
- package/.next/static/chunks/app/(dashboard)/dashboard/cli-tools/{page-adee408d9de02423.js → page-aae6be7f75fcd819.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/combos/{page-d4c1e29e8d038f09.js → page-18212c87b17b33cf.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/console-log/{page-36c9e8748d6f3f0c.js → page-52b5a6dc2c2d2d93.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/endpoint/page-9287a3cbd098b9c4.js +1 -0
- package/.next/static/chunks/app/(dashboard)/dashboard/media-providers/systemone/[id]/{page-b751d9603cb82e62.js → page-610d962dd8bd1744.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/media-providers/systemone/{page-49b3b4867d06cbe0.js → page-9dbf4cd6901b6042.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/page-1d6e969653676c7d.js +1 -0
- package/.next/static/chunks/app/(dashboard)/dashboard/profile/{page-65b2c7989dbe2663.js → page-2ab30b6e1baf1efd.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-d5d480e209fdc55a.js → page-b17607bc2ed06d50.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/providers/new/{page-7977a61350d874d2.js → page-0e649a78a041306a.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/providers/{page-2396571281d02804.js → page-b10c05192c664e8d.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/proxy-pools/{page-cfd6bcb7e55d7d18.js → page-b33051a3fc600082.js} +2 -2
- package/.next/static/chunks/app/(dashboard)/dashboard/quota/{page-fef6edb7aafd8bd0.js → page-ee2a0fa91d9bea9c.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/usage/{page-697f46461825d7fc.js → page-2457f236bc58e590.js} +1 -1
- package/.next/static/chunks/app/(dashboard)/{layout-5039502fc12707c9.js → layout-7ef1d599b3c4c6d2.js} +1 -1
- package/.next/static/chunks/app/_global-error/page-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/oidc/callback/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/oidc/start/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/oidc/test/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/reset-password/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/saml/acs/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/saml/metadata/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/saml/start/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/saml/test/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/changelog/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/all-statuses/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/claude-settings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/codex-settings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/cowork-mcp-registry/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/cowork-mcp-tools/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/cowork-settings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/dsh-settings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/cli-tools/opencode-settings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/combos/[id]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/combos/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/dashboard/chat/completions/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/headroom/extras/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/headroom/proxy/[...path]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/headroom/restart/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/headroom/start/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/headroom/status/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/headroom/stop/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/health/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/init/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/keys/[id]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/keys/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/locale/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/mcp/[plugin]/message/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/mcp/[plugin]/sse/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/media-providers/tts/deepgram/voices/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/media-providers/tts/elevenlabs/voices/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/media-providers/tts/inworld/voices/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/media-providers/tts/minimax/voices/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/media-providers/tts/voices/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/alias/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/availability/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/catalog-sync/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/custom/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/disabled/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/models/test/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/[provider]/[action]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/codex/bulk-import/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/codex/import-token/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/cursor/auto-import/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/cursor/import/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/gitlab/pat/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/grok-cli/bulk-import/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/iflow/cookie/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/xiaomi-mimo/api-key/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/oauth/xiaomi-mimo/auto-import/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pricing/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/provider-nodes/[id]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/provider-nodes/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/provider-nodes/validate/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/[id]/models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/[id]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/[id]/test/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/[id]/test-models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/client/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/kilo/free-models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/suggested-models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/test-batch/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/providers/validate/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/proxy-pools/[id]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/proxy-pools/[id]/test/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/proxy-pools/cloudflare-deploy/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/proxy-pools/deno-deploy/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/proxy-pools/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/proxy-pools/vercel-deploy/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/health/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/install/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/logs/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/restart/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/start/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/stats/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/status/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/pxpipe/stop/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/settings/database/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/settings/proxy-test/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/settings/require-login/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/settings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/shutdown/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tags/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/translator/console-logs/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/translator/console-logs/stream/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/translator/load/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/translator/save/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/translator/send/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/translator/translate/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/disable/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/enable/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/status/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/tailscale-check/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/tailscale-disable/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/tailscale-enable/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/tunnel/tailscale-install/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/[connectionId]/codex-reset-credits/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/[connectionId]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/chart/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/health/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/history/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/logs/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/providers/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/request-details/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/request-logs/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/stats/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/usage/stream/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/api/chat/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/audio/speech/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/audio/transcriptions/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/audio/voices/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/chat/completions/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/embeddings/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/images/generations/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/messages/count_tokens/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/messages/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/models/[...model]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/models/info/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/responses/compact/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/responses/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/search/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/systemone/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/videos/[id]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/videos/edits/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/videos/extensions/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/videos/generations/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1/web/fetch/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1beta/models/[...path]/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/v1beta/models/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/version/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/version/shutdown/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/api/version/update/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/{layout-8de830cad461f2bd.js → layout-f34e075b1872747e.js} +1 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/app/page-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-a826a2eb5dc30149.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-a826a2eb5dc30149.js +1 -0
- package/.next/static/css/{c66cbd684164cacf.css → a2628e64fa8ac12e.css} +1 -1
- package/CHANGELOG.md +14 -0
- package/bin/update-check.mjs +28 -5
- package/open-sse/providers/registry/opencode-go.js +4 -0
- package/open-sse/providers/registry/opencode-zen.js +4 -0
- package/open-sse/providers/registry/opencode.js +3 -0
- package/open-sse/translator/concerns/thinkingUnified.js +16 -1
- package/open-sse/translator/concerns/toolCall.js +2 -1
- package/open-sse/translator/formats/openai.js +10 -2
- package/open-sse/translator/request/claude-to-openai.js +9 -5
- package/open-sse/translator/response/openai-to-claude.js +66 -32
- package/open-sse/translator/schema/defaults.js +6 -0
- package/open-sse/translator/schema/index.js +1 -1
- package/package.json +2 -1
- package/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.tsx +45 -7
- package/src/app/api/dashboard/chat/completions/route.ts +45 -0
- package/src/app/globals.css +54 -13
- package/src/components/app-sidebar.tsx +1 -0
- package/src/shared/components/Header.tsx +8 -0
- package/.next/static/DaBuw8hGFuPycdhSV3GrJ/_buildManifest.js +0 -1
- package/.next/static/chunks/1278-233a1472e792bb65.js +0 -1
- package/.next/static/chunks/159-ec207a220d7d5c16.js +0 -1
- package/.next/static/chunks/1699-49be310981e2759e.js +0 -67
- package/.next/static/chunks/app/(dashboard)/dashboard/basic-chat/page-ce1364b2b9589785.js +0 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/endpoint/page-67516b120adbc4d7.js +0 -1
- package/.next/static/chunks/app/(dashboard)/dashboard/page-315c9f52c472a700.js +0 -1
- package/.next/static/chunks/app/_global-error/page-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/oidc/callback/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/oidc/start/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/oidc/test/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/reset-password/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/saml/acs/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/saml/metadata/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/saml/start/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/saml/test/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/changelog/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/all-statuses/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/claude-settings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/codex-settings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/cowork-mcp-registry/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/cowork-mcp-tools/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/cowork-settings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/dsh-settings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/cli-tools/opencode-settings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/combos/[id]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/combos/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/headroom/extras/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/headroom/proxy/[...path]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/headroom/restart/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/headroom/start/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/headroom/status/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/headroom/stop/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/health/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/init/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/keys/[id]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/keys/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/locale/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/mcp/[plugin]/message/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/mcp/[plugin]/sse/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/media-providers/tts/deepgram/voices/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/media-providers/tts/elevenlabs/voices/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/media-providers/tts/inworld/voices/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/media-providers/tts/minimax/voices/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/media-providers/tts/voices/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/alias/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/availability/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/catalog-sync/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/custom/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/disabled/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/models/test/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/[provider]/[action]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/codex/bulk-import/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/codex/import-token/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/cursor/auto-import/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/cursor/import/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/gitlab/pat/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/grok-cli/bulk-import/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/iflow/cookie/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/xiaomi-mimo/api-key/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/oauth/xiaomi-mimo/auto-import/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pricing/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/provider-nodes/[id]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/provider-nodes/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/provider-nodes/validate/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/[id]/models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/[id]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/[id]/test/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/[id]/test-models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/client/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/kilo/free-models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/suggested-models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/test-batch/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/providers/validate/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/proxy-pools/[id]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/proxy-pools/[id]/test/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/proxy-pools/cloudflare-deploy/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/proxy-pools/deno-deploy/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/proxy-pools/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/proxy-pools/vercel-deploy/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/health/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/install/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/logs/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/restart/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/start/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/stats/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/status/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/pxpipe/stop/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/settings/database/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/settings/proxy-test/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/settings/require-login/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/settings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/shutdown/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tags/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/translator/console-logs/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/translator/console-logs/stream/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/translator/load/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/translator/save/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/translator/send/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/translator/translate/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/disable/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/enable/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/status/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/tailscale-check/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/tailscale-disable/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/tailscale-enable/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/tunnel/tailscale-install/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/[connectionId]/codex-reset-credits/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/[connectionId]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/chart/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/health/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/history/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/logs/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/providers/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/request-details/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/request-logs/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/stats/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/usage/stream/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/api/chat/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/audio/speech/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/audio/transcriptions/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/audio/voices/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/chat/completions/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/embeddings/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/images/generations/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/messages/count_tokens/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/messages/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/models/[...model]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/models/info/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/responses/compact/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/responses/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/search/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/systemone/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/videos/[id]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/videos/edits/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/videos/extensions/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/videos/generations/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1/web/fetch/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1beta/models/[...path]/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/v1beta/models/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/version/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/version/shutdown/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/api/version/update/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/app/page-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-9a2a13ac6b89ba91.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9a2a13ac6b89ba91.js +0 -1
- /package/.next/static/{DaBuw8hGFuPycdhSV3GrJ → C423Aljus-j0GJlKCHgC1}/_ssgManifest.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to 10Router will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.1.12] — 2026-10-20
|
|
6
|
+
|
|
7
|
+
- Fix: Claude Code routed through the `opencode` free lane failed tool calls with `400 unknown field "thinking"`. The OpenAI-dialect endpoint inherited the model's `zai`/`deepseek` capability thinking shape and sent `body.thinking`; the transport now declares `thinkingFormat: "openai"` (opencode, opencode-zen and opencode-go OpenAI transports) and `resolveFormat` prefers the transport matching the target format. Claude- and Gemini-format transports keep their native shape.
|
|
8
|
+
- Fix: a stream that closed without `finish_reason` left the `tool_use` block open and the message unterminated, so the client dropped the turn as failed. The end-of-stream flush now closes open blocks, emits buffered tool arguments, and always sends `message_delta` + `message_stop`; truncated tool JSON degrades to `end_turn` instead of a broken `tool_use`.
|
|
9
|
+
- Fix: empty `tool_result` content (empty array, image-only, or a missing response) was sent as `""` or `"[]"` and rejected by OpenAI-dialect upstreams with `Message content must contain text`. A shared `EMPTY_TOOL_RESULT` placeholder is now applied when converting Claude tool results, when backfilling missing tool responses, and in `filterToOpenAIFormat`.
|
|
10
|
+
- Fix: the built-in chat page posted to `/api/dashboard/chat/completions`, a route that never existed, so every message 404'd. The route now delegates to `handleChat` and mints/reuses a local API key server-side; the page is reachable from the sidebar, renders markdown, and surfaces SSE error events.
|
|
11
|
+
- Tests: `tests/unit/claude-code-tool-flow.test.js` covers the thinking wire format per provider/transport, stream finalize without `finish_reason`, truncated tool arguments, empty tool results, and the flush contract.
|
|
12
|
+
|
|
13
|
+
## [0.1.11] — 2026-10-18
|
|
14
|
+
|
|
15
|
+
- Fix: the CLI update notice never fired on networks that silently drop IPv6. `registry.npmjs.org` resolves to both A and AAAA records, so Node blackholes the first connection for ~10s before Happy Eyeballs falls back to IPv4, while the check aborted at 3s — a cold check routinely needs 2-14s. Measured 5/8 fetches and 1/12 notices here; the 10s budget now measures 8/8.
|
|
16
|
+
- Fix: a failed check was never remembered, so every invocation re-paid the full timeout stall and then re-served the same stale version ("stale cache beats silence"). Failures are now recorded with a 10-minute cooldown (`FAIL_TTL`, mirroring `FAIL_TTL_MS` in `src/lib/versionCheck.js`), so an unreachable registry costs one stall per window instead of one per run, and a version published during the window still surfaces once the link recovers.
|
|
17
|
+
- Tests: cover the failure memory (no retry inside the cooldown, retry past it) and the recovery path (a version published while the registry was down appears after the cooldown without waiting out `UPDATE_TTL`).
|
|
18
|
+
|
|
5
19
|
## [0.1.10] — 2026-10-18
|
|
6
20
|
|
|
7
21
|
- Fix: every combo edit made from the dashboard failed with a 500 `Failed to update combo`. `PUT /api/combos/[id]` declared the parsed request body as `const` but reassigns it after cleaning the members array, so `Assignment to constant variable` was thrown inside the try and swallowed by the catch; only requests carrying `models` hit it, which is why name-only edits and combo creation worked. Introduced with the member-validation block in v0.1.9.
|
package/bin/update-check.mjs
CHANGED
|
@@ -12,6 +12,18 @@ import path from "node:path";
|
|
|
12
12
|
// per hour of CLI use; offline stays fail-open via stale-cache fallback.
|
|
13
13
|
export const UPDATE_TTL = 3600 * 1000;
|
|
14
14
|
|
|
15
|
+
// The registry resolves to both A and AAAA records. On networks that drop
|
|
16
|
+
// IPv6 silently, Node's first connection attempt blackholes for ~10s before
|
|
17
|
+
// Happy Eyeballs falls back to IPv4, so a cold check routinely needs 2-14s.
|
|
18
|
+
// The old 3s budget aborted nearly every check on such links (measured 5/8),
|
|
19
|
+
// and the failure then re-served the stale version — so 0.1.10 never showed.
|
|
20
|
+
// 10s measured 8/8 here; FAIL_TTL bounds what a genuinely offline run costs.
|
|
21
|
+
const FETCH_TIMEOUT_MS = 10000;
|
|
22
|
+
|
|
23
|
+
// A failed check is remembered, so a bad network costs one stall per window
|
|
24
|
+
// instead of one per invocation. Mirrors FAIL_TTL_MS in src/lib/versionCheck.js.
|
|
25
|
+
export const FAIL_TTL = 10 * 60 * 1000;
|
|
26
|
+
|
|
15
27
|
export function cmpVer(a, b) {
|
|
16
28
|
const pa = String(a).replace(/^v/, "").split("-")[0].split(".").map(Number);
|
|
17
29
|
const pb = String(b).replace(/^v/, "").split("-")[0].split(".").map(Number);
|
|
@@ -28,7 +40,7 @@ export function cmpVer(a, b) {
|
|
|
28
40
|
export async function fetchLatest(pkgName, fetchFn = fetch) {
|
|
29
41
|
try {
|
|
30
42
|
const r = await fetchFn(`https://registry.npmjs.org/${pkgName.replace("/", "%2F")}/latest`, {
|
|
31
|
-
signal: AbortSignal.timeout(
|
|
43
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
32
44
|
});
|
|
33
45
|
if (!r.ok) return null;
|
|
34
46
|
return (await r.json())?.version || null;
|
|
@@ -73,15 +85,26 @@ export async function checkUpdate({
|
|
|
73
85
|
latest = cached?.latest && now - (cached.checkedAt || 0) < UPDATE_TTL ? cached.latest : null;
|
|
74
86
|
}
|
|
75
87
|
if (!latest) {
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
// A recent failure means the registry was unreachable: re-fetching would
|
|
89
|
+
// re-pay the full timeout stall on every invocation. Serve stale instead.
|
|
90
|
+
const cooling = now - (cached?.failedAt || 0) < FAIL_TTL;
|
|
91
|
+
latest = cooling ? cached?.latest || null : await fetchLatest(pkg.name, fetchFn);
|
|
92
|
+
if (!cooling) {
|
|
78
93
|
try {
|
|
79
94
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
80
|
-
fs.writeFileSync(
|
|
95
|
+
fs.writeFileSync(
|
|
96
|
+
cacheFile,
|
|
97
|
+
// On failure keep the last-known version but mark it stale, so the
|
|
98
|
+
// notice still fires from cache while the fetch is in cooldown.
|
|
99
|
+
latest
|
|
100
|
+
? JSON.stringify({ latest, checkedAt: now })
|
|
101
|
+
: JSON.stringify({ latest: cached?.latest || null, checkedAt: 0, failedAt: now }),
|
|
102
|
+
);
|
|
81
103
|
} catch {
|
|
82
104
|
/* cache best-effort */
|
|
83
105
|
}
|
|
84
|
-
}
|
|
106
|
+
}
|
|
107
|
+
if (!latest) latest = cached?.latest || null; // stale cache beats silence
|
|
85
108
|
}
|
|
86
109
|
if (!latest || cmpVer(pkg.version, latest) >= 0) return null;
|
|
87
110
|
const ua = env.npm_config_user_agent || "";
|
|
@@ -31,6 +31,9 @@ export default {
|
|
|
31
31
|
format: "openai",
|
|
32
32
|
baseUrl: "https://opencode.ai/inference/go/v1/chat/completions",
|
|
33
33
|
auth: { combined: true, header: "Authorization", scheme: "bearer" },
|
|
34
|
+
// OpenAI dialect only: the gateway rejects `thinking`/`enable_thinking`
|
|
35
|
+
// (400 unknown field "thinking"), so normalize reasoning to reasoning_effort.
|
|
36
|
+
thinkingFormat: "openai",
|
|
34
37
|
},
|
|
35
38
|
{
|
|
36
39
|
format: "claude",
|
|
@@ -41,6 +44,7 @@ export default {
|
|
|
41
44
|
format: "openai-responses",
|
|
42
45
|
baseUrl: "https://opencode.ai/inference/go/v1/responses",
|
|
43
46
|
auth: { combined: true, header: "Authorization", scheme: "bearer" },
|
|
47
|
+
thinkingFormat: "openai",
|
|
44
48
|
},
|
|
45
49
|
],
|
|
46
50
|
// supportedFormats follow the endpoint table in https://opencode.ai/v2/docs/console/go
|
|
@@ -31,6 +31,9 @@ export default {
|
|
|
31
31
|
format: "openai",
|
|
32
32
|
baseUrl: "https://opencode.ai/inference/openai/v1/chat/completions",
|
|
33
33
|
auth: { combined: true, header: "Authorization", scheme: "bearer" },
|
|
34
|
+
// OpenAI dialect only: the gateway rejects `thinking`/`enable_thinking`
|
|
35
|
+
// (400 unknown field "thinking"), so normalize reasoning to reasoning_effort.
|
|
36
|
+
thinkingFormat: "openai",
|
|
34
37
|
},
|
|
35
38
|
{
|
|
36
39
|
format: "claude",
|
|
@@ -41,6 +44,7 @@ export default {
|
|
|
41
44
|
format: "openai-responses",
|
|
42
45
|
baseUrl: "https://opencode.ai/inference/openai/v1/responses",
|
|
43
46
|
auth: { combined: true, header: "Authorization", scheme: "bearer" },
|
|
47
|
+
thinkingFormat: "openai",
|
|
44
48
|
},
|
|
45
49
|
],
|
|
46
50
|
// supportedFormats follow the per-model API families (chat completions /
|
|
@@ -19,6 +19,9 @@ export default {
|
|
|
19
19
|
},
|
|
20
20
|
forceStream: true,
|
|
21
21
|
noAuth: true,
|
|
22
|
+
// OpenAI dialect only: the gateway rejects `thinking`/`enable_thinking`
|
|
23
|
+
// (400 unknown field "thinking"), so normalize reasoning to reasoning_effort.
|
|
24
|
+
thinkingFormat: "openai",
|
|
22
25
|
quirks: {
|
|
23
26
|
forceAutoToolChoiceModels: [
|
|
24
27
|
"muse-spark-1.2-contributor-free",
|
|
@@ -124,9 +124,24 @@ const NATIVE_ONLY_FORMATS = new Set([
|
|
|
124
124
|
"kiro",
|
|
125
125
|
]); // "kiro" legacy (provider removed)
|
|
126
126
|
|
|
127
|
+
// Provider/transport-level wire override. Multi-endpoint providers declare one
|
|
128
|
+
// entry per endpoint format, so prefer the entry matching targetFormat; fall back
|
|
129
|
+
// to the provider's default transport. The override describes an OpenAI-dialect
|
|
130
|
+
// endpoint, so it only applies on OpenAI-family wires — a Claude/Gemini endpoint
|
|
131
|
+
// keeps deriving its native thinking shape from the capabilities below.
|
|
132
|
+
function providerThinkingFormat(provider, targetFormat) {
|
|
133
|
+
if (targetFormat !== "openai" && targetFormat !== "openai-responses") return null;
|
|
134
|
+
const cfg = provider ? PROVIDERS[provider] : null;
|
|
135
|
+
if (!cfg) return null;
|
|
136
|
+
const entry = Array.isArray(cfg.transports)
|
|
137
|
+
? cfg.transports.find((t) => (t.format || "openai") === targetFormat) || cfg
|
|
138
|
+
: cfg;
|
|
139
|
+
return entry.thinkingFormat || null;
|
|
140
|
+
}
|
|
141
|
+
|
|
127
142
|
function resolveFormat(targetFormat, model, provider) {
|
|
128
143
|
if (targetFormat === "commandcode") return "commandcode";
|
|
129
|
-
const providerFmt = provider
|
|
144
|
+
const providerFmt = providerThinkingFormat(provider, targetFormat);
|
|
130
145
|
if (providerFmt) return providerFmt;
|
|
131
146
|
const caps = getCapabilitiesForModel(provider, model);
|
|
132
147
|
const isOpenAIWire = targetFormat === "openai" || targetFormat === "openai-responses";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Tool call helper functions for translator
|
|
2
2
|
|
|
3
3
|
import { FORMATS } from "../formats.js";
|
|
4
|
+
import { EMPTY_TOOL_RESULT } from "../schema/index.js";
|
|
4
5
|
|
|
5
6
|
// Anthropic tool_use.id must match: ^[a-zA-Z0-9_-]+$
|
|
6
7
|
const TOOL_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
@@ -147,7 +148,7 @@ export function fixMissingToolResponses(body) {
|
|
|
147
148
|
newMessages.push({
|
|
148
149
|
role: "tool",
|
|
149
150
|
tool_call_id: id,
|
|
150
|
-
content:
|
|
151
|
+
content: EMPTY_TOOL_RESULT,
|
|
151
152
|
});
|
|
152
153
|
}
|
|
153
154
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
CLAUDE_BLOCK,
|
|
6
6
|
VALID_OPENAI_CONTENT_TYPES,
|
|
7
7
|
VALID_OPENAI_MESSAGE_TYPES,
|
|
8
|
+
EMPTY_TOOL_RESULT,
|
|
8
9
|
} from "../schema/index.js";
|
|
9
10
|
|
|
10
11
|
// Re-export valid-type lists (moved to schema/blocks.js) to keep existing importers working.
|
|
@@ -26,8 +27,15 @@ export function filterToOpenAIFormat(body, opts = {}) {
|
|
|
26
27
|
// Normalize developer role to system (many providers don't support developer)
|
|
27
28
|
if (msg.role === ROLE.DEVELOPER) msg = { ...msg, role: ROLE.SYSTEM };
|
|
28
29
|
|
|
29
|
-
// Keep tool messages as-is (OpenAI format)
|
|
30
|
-
|
|
30
|
+
// Keep tool messages as-is (OpenAI format) — but an empty one is a 400 on
|
|
31
|
+
// several OpenAI-dialect upstreams ("Message content must contain text").
|
|
32
|
+
if (msg.role === ROLE.TOOL) {
|
|
33
|
+
const empty =
|
|
34
|
+
msg.content === "" ||
|
|
35
|
+
msg.content == null ||
|
|
36
|
+
(Array.isArray(msg.content) && msg.content.length === 0);
|
|
37
|
+
return empty ? { ...msg, content: EMPTY_TOOL_RESULT } : msg;
|
|
38
|
+
}
|
|
31
39
|
|
|
32
40
|
// Keep assistant messages with tool_calls as-is
|
|
33
41
|
if (msg.role === ROLE.ASSISTANT && msg.tool_calls) return msg;
|
|
@@ -2,7 +2,7 @@ import { register } from "../index.js";
|
|
|
2
2
|
import { FORMATS } from "../formats.js";
|
|
3
3
|
import { adjustMaxTokens } from "../formats/maxTokens.js";
|
|
4
4
|
import { encodeDataUri } from "../concerns/image.js";
|
|
5
|
-
import { ROLE, OPENAI_BLOCK, CLAUDE_BLOCK } from "../schema/index.js";
|
|
5
|
+
import { ROLE, OPENAI_BLOCK, CLAUDE_BLOCK, EMPTY_TOOL_RESULT } from "../schema/index.js";
|
|
6
6
|
import { collapseTextParts } from "../concerns/message.js";
|
|
7
7
|
|
|
8
8
|
function stripAnthropicBillingHeader(text) {
|
|
@@ -62,7 +62,7 @@ export function claudeToOpenAIRequest(model, body, stream) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// Fix missing tool responses - OpenAI requires every tool_call to have a response.
|
|
65
|
-
// Local variant: scans contiguous tool replies + inserts
|
|
65
|
+
// Local variant: scans contiguous tool replies + inserts EMPTY_TOOL_RESULT
|
|
66
66
|
// (distinct from the global immediate-next check in concerns/toolCall, runs on the openai leg).
|
|
67
67
|
fixMissingToolResponsesOpenAI(result.messages);
|
|
68
68
|
|
|
@@ -123,7 +123,7 @@ function fixMissingToolResponsesOpenAI(messages) {
|
|
|
123
123
|
const missingResponses = missingIds.map((id) => ({
|
|
124
124
|
role: ROLE.TOOL,
|
|
125
125
|
tool_call_id: id,
|
|
126
|
-
content:
|
|
126
|
+
content: EMPTY_TOOL_RESULT,
|
|
127
127
|
}));
|
|
128
128
|
messages.splice(insertPosition, 0, ...missingResponses);
|
|
129
129
|
i = insertPosition + missingResponses.length - 1;
|
|
@@ -216,7 +216,9 @@ function convertClaudeMessage(msg) {
|
|
|
216
216
|
const textOnly = block.content.filter((c) => c?.type === CLAUDE_BLOCK.TEXT);
|
|
217
217
|
resultContent =
|
|
218
218
|
textOnly.map((c) => c.text).join("\n") ||
|
|
219
|
-
(resultImages.length
|
|
219
|
+
(resultImages.length || block.content.length === 0
|
|
220
|
+
? ""
|
|
221
|
+
: JSON.stringify(block.content));
|
|
220
222
|
} else if (block.content) {
|
|
221
223
|
resultContent = JSON.stringify(block.content);
|
|
222
224
|
}
|
|
@@ -224,7 +226,9 @@ function convertClaudeMessage(msg) {
|
|
|
224
226
|
toolResults.push({
|
|
225
227
|
role: ROLE.TOOL,
|
|
226
228
|
tool_call_id: block.tool_use_id,
|
|
227
|
-
content
|
|
229
|
+
// Empty content is a 400 on several OpenAI-dialect upstreams
|
|
230
|
+
// ("Message content must contain text"); keep a placeholder.
|
|
231
|
+
content: resultContent || EMPTY_TOOL_RESULT,
|
|
228
232
|
});
|
|
229
233
|
// The OpenAI tool role is text-only, so a screenshot or any other image a
|
|
230
234
|
// tool returned would otherwise vanish. Hand it to the model in the user
|
|
@@ -70,9 +70,73 @@ function stopTextBlock(state, results) {
|
|
|
70
70
|
state.textBlockStarted = false;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// Buffered tool args parse as JSON → safe to hand the client a tool_use finish.
|
|
74
|
+
function bufferedArgsComplete(state) {
|
|
75
|
+
for (const [idx] of state.toolCalls) {
|
|
76
|
+
const buffered = state.toolArgBuffers?.get(idx);
|
|
77
|
+
if (!buffered) continue;
|
|
78
|
+
try {
|
|
79
|
+
JSON.parse(buffered);
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Close every open block, flush tool args, then message_delta + message_stop.
|
|
88
|
+
// Shared by the finish_reason path and the end-of-stream flush so a stream that
|
|
89
|
+
// dies without a finish chunk still terminates instead of truncating the turn.
|
|
90
|
+
function emitMessageFinish(state, results, reason) {
|
|
91
|
+
if (state.claudeFinishEmitted) return;
|
|
92
|
+
state.claudeFinishEmitted = true;
|
|
93
|
+
|
|
94
|
+
stopThinkingBlock(state, results);
|
|
95
|
+
stopTextBlock(state, results);
|
|
96
|
+
|
|
97
|
+
for (const [idx, toolInfo] of state.toolCalls) {
|
|
98
|
+
// Emit buffered + sanitized args as single delta before stop
|
|
99
|
+
const buffered = state.toolArgBuffers?.get(idx);
|
|
100
|
+
if (buffered) {
|
|
101
|
+
const sanitized = sanitizeToolArgs(toolInfo.name, buffered);
|
|
102
|
+
results.push({
|
|
103
|
+
type: "content_block_delta",
|
|
104
|
+
index: toolInfo.blockIndex,
|
|
105
|
+
delta: { type: "input_json_delta", partial_json: sanitized },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
results.push({
|
|
109
|
+
type: "content_block_stop",
|
|
110
|
+
index: toolInfo.blockIndex,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Mark finish for later usage injection in stream.js
|
|
115
|
+
state.finishReason = reason;
|
|
116
|
+
|
|
117
|
+
// Use tracked usage (will be estimated in stream.js if not valid)
|
|
118
|
+
const finalUsage = state.usage || { input_tokens: 0, output_tokens: 0 };
|
|
119
|
+
results.push({
|
|
120
|
+
type: "message_delta",
|
|
121
|
+
delta: { stop_reason: convertFinishReason(reason) },
|
|
122
|
+
usage: finalUsage,
|
|
123
|
+
});
|
|
124
|
+
results.push({ type: "message_stop" });
|
|
125
|
+
}
|
|
126
|
+
|
|
73
127
|
// Convert OpenAI stream chunk to Claude format
|
|
74
128
|
export function openaiToClaudeResponse(chunk, state) {
|
|
75
|
-
|
|
129
|
+
// End-of-stream flush (stream.js calls the translator with chunk=null): the
|
|
130
|
+
// upstream can close right after a tool-call delta without ever sending
|
|
131
|
+
// finish_reason, which used to leave the client with an unterminated message.
|
|
132
|
+
if (!chunk) {
|
|
133
|
+
if (!state.messageStartSent || state.claudeFinishEmitted) return null;
|
|
134
|
+
const results = [];
|
|
135
|
+
const reason = state.toolCalls.size > 0 && bufferedArgsComplete(state) ? "tool_calls" : "stop";
|
|
136
|
+
emitMessageFinish(state, results, reason);
|
|
137
|
+
return results;
|
|
138
|
+
}
|
|
139
|
+
if (!chunk.choices?.[0]) return null;
|
|
76
140
|
|
|
77
141
|
const results = [];
|
|
78
142
|
const choice = chunk.choices[0];
|
|
@@ -234,37 +298,7 @@ export function openaiToClaudeResponse(chunk, state) {
|
|
|
234
298
|
|
|
235
299
|
// Finish
|
|
236
300
|
if (choice.finish_reason) {
|
|
237
|
-
|
|
238
|
-
stopTextBlock(state, results);
|
|
239
|
-
|
|
240
|
-
for (const [idx, toolInfo] of state.toolCalls) {
|
|
241
|
-
// Emit buffered + sanitized args as single delta before stop
|
|
242
|
-
const buffered = state.toolArgBuffers?.get(idx);
|
|
243
|
-
if (buffered) {
|
|
244
|
-
const sanitized = sanitizeToolArgs(toolInfo.name, buffered);
|
|
245
|
-
results.push({
|
|
246
|
-
type: "content_block_delta",
|
|
247
|
-
index: toolInfo.blockIndex,
|
|
248
|
-
delta: { type: "input_json_delta", partial_json: sanitized },
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
results.push({
|
|
252
|
-
type: "content_block_stop",
|
|
253
|
-
index: toolInfo.blockIndex,
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Mark finish for later usage injection in stream.js
|
|
258
|
-
state.finishReason = choice.finish_reason;
|
|
259
|
-
|
|
260
|
-
// Use tracked usage (will be estimated in stream.js if not valid)
|
|
261
|
-
const finalUsage = state.usage || { input_tokens: 0, output_tokens: 0 };
|
|
262
|
-
results.push({
|
|
263
|
-
type: "message_delta",
|
|
264
|
-
delta: { stop_reason: convertFinishReason(choice.finish_reason) },
|
|
265
|
-
usage: finalUsage,
|
|
266
|
-
});
|
|
267
|
-
results.push({ type: "message_stop" });
|
|
301
|
+
emitMessageFinish(state, results, choice.finish_reason);
|
|
268
302
|
}
|
|
269
303
|
|
|
270
304
|
return results.length > 0 ? results : null;
|
|
@@ -5,3 +5,9 @@ export const MODEL_FALLBACK = "unknown";
|
|
|
5
5
|
|
|
6
6
|
// Default image mime when source omits it (base64 blobs without a declared type).
|
|
7
7
|
export const DEFAULT_IMAGE_MIME = "image/png";
|
|
8
|
+
|
|
9
|
+
// Placeholder for a tool result with no text (image-only, empty array, or a
|
|
10
|
+
// missing response). OpenAI-dialect wires reject `role:"tool"` with empty
|
|
11
|
+
// content. Deliberately not JSON-shaped: a leading "[" reads as a raw-JSON
|
|
12
|
+
// stringification bug to callers inspecting the bridge.
|
|
13
|
+
export const EMPTY_TOOL_RESULT = "(no output)";
|
|
@@ -8,4 +8,4 @@ export {
|
|
|
8
8
|
VALID_OPENAI_MESSAGE_TYPES,
|
|
9
9
|
} from "./blocks.js";
|
|
10
10
|
export { OPENAI_FINISH, CLAUDE_STOP, GEMINI_FINISH } from "./finishReasons.js";
|
|
11
|
-
export { MODEL_FALLBACK, DEFAULT_IMAGE_MIME } from "./defaults.js";
|
|
11
|
+
export { MODEL_FALLBACK, DEFAULT_IMAGE_MIME, EMPTY_TOOL_RESULT } from "./defaults.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amir83nasr/10router",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/Amir83Nasr/10Router.git"
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"class-variance-authority": "^0.7.1",
|
|
63
63
|
"cn": "^0.3.0",
|
|
64
64
|
"confbox": "^0.2.4",
|
|
65
|
+
"dompurify": "^3.2.7",
|
|
65
66
|
"jose": "^6.1.3",
|
|
66
67
|
"lucide-react": "^1.47.0",
|
|
67
68
|
"marked": "^18.0.1",
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import Icon from "@/shared/components/Icon";
|
|
3
3
|
|
|
4
4
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import DOMPurify from "dompurify";
|
|
6
|
+
import { marked } from "marked";
|
|
5
7
|
import { Badge } from "@/components/ui/badge";
|
|
6
8
|
import { Button } from "@/components/ui/button";
|
|
7
9
|
import { getModelsByProviderId } from "@/shared/constants/models";
|
|
@@ -10,6 +12,8 @@ import {
|
|
|
10
12
|
isOpenAICompatibleProvider,
|
|
11
13
|
} from "@/shared/constants/providers";
|
|
12
14
|
|
|
15
|
+
marked.setOptions({ gfm: true, breaks: true });
|
|
16
|
+
|
|
13
17
|
const STORAGE_KEYS = {
|
|
14
18
|
sessions: "basic-chat.sessions",
|
|
15
19
|
activeSessionId: "basic-chat.activeSessionId",
|
|
@@ -100,6 +104,28 @@ function readAssistantText(chunk) {
|
|
|
100
104
|
return pieces[0] || "";
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
// Errors arrive as SSE events (`{ error }` or a Responses-style `{ type: "error" }`)
|
|
108
|
+
// with no choices; the content-only parse would drop them and end the turn empty.
|
|
109
|
+
function readChunkError(chunk) {
|
|
110
|
+
if (!chunk || typeof chunk !== "object") return "";
|
|
111
|
+
if (chunk.error) return textValue(chunk.error) || "Request failed";
|
|
112
|
+
if (chunk.type === "error") return textValue(chunk.message) || "Request failed";
|
|
113
|
+
return "";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function MarkdownMessage({ text }) {
|
|
117
|
+
const raw = textValue(text);
|
|
118
|
+
const html = useMemo(() => {
|
|
119
|
+
if (!raw) return "";
|
|
120
|
+
// DOMPurify needs a DOM; the server render has none (sessions hydrate from storage).
|
|
121
|
+
if (typeof window === "undefined") return null;
|
|
122
|
+
return DOMPurify.sanitize(marked.parse(raw, { async: false }));
|
|
123
|
+
}, [raw]);
|
|
124
|
+
|
|
125
|
+
if (html === null) return <span className="whitespace-pre-wrap break-words">{raw}</span>;
|
|
126
|
+
return <div className="chat-markdown break-words" dangerouslySetInnerHTML={{ __html: html }} />;
|
|
127
|
+
}
|
|
128
|
+
|
|
103
129
|
async function fileToDataUrl(file) {
|
|
104
130
|
return await new Promise((resolve, reject) => {
|
|
105
131
|
const reader = new FileReader();
|
|
@@ -747,6 +773,7 @@ export default function BasicChatPageClient() {
|
|
|
747
773
|
const decoder = new TextDecoder();
|
|
748
774
|
let buffer = "";
|
|
749
775
|
let assistantText = "";
|
|
776
|
+
let streamError = "";
|
|
750
777
|
|
|
751
778
|
while (true) {
|
|
752
779
|
const { value, done } = await reader.read();
|
|
@@ -765,6 +792,12 @@ export default function BasicChatPageClient() {
|
|
|
765
792
|
|
|
766
793
|
try {
|
|
767
794
|
const chunk = JSON.parse(payload);
|
|
795
|
+
const chunkError = readChunkError(chunk);
|
|
796
|
+
if (chunkError) {
|
|
797
|
+
streamError = chunkError;
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
|
|
768
801
|
const text = readAssistantText(chunk);
|
|
769
802
|
if (!text) continue;
|
|
770
803
|
|
|
@@ -787,13 +820,16 @@ export default function BasicChatPageClient() {
|
|
|
787
820
|
|
|
788
821
|
updateSession(sessionId, (currentSession) => ({
|
|
789
822
|
...currentSession,
|
|
790
|
-
messages: currentSession.messages.map((message) =>
|
|
791
|
-
message.id
|
|
792
|
-
|
|
793
|
-
: message,
|
|
794
|
-
|
|
823
|
+
messages: currentSession.messages.map((message) => {
|
|
824
|
+
if (message.id !== assistantMessageId) return message;
|
|
825
|
+
if (!assistantText && streamError) {
|
|
826
|
+
return { ...message, content: message.content || streamError, status: "error" };
|
|
827
|
+
}
|
|
828
|
+
return { ...message, content: assistantText || message.content, status: "done" };
|
|
829
|
+
}),
|
|
795
830
|
updatedAt: new Date().toISOString(),
|
|
796
831
|
}));
|
|
832
|
+
if (!assistantText && streamError) setLoadError(streamError);
|
|
797
833
|
finalizeSessionTitle(sessionId, userText);
|
|
798
834
|
} catch (error) {
|
|
799
835
|
if (error.name !== "AbortError") {
|
|
@@ -1036,8 +1072,10 @@ export default function BasicChatPageClient() {
|
|
|
1036
1072
|
</div>
|
|
1037
1073
|
) : null}
|
|
1038
1074
|
|
|
1039
|
-
<div
|
|
1040
|
-
{
|
|
1075
|
+
<div
|
|
1076
|
+
className={`break-words text-[15px] leading-7 ${isAssistant ? "" : "whitespace-pre-wrap"}`}
|
|
1077
|
+
>
|
|
1078
|
+
{isAssistant ? <MarkdownMessage text={content} /> : content}
|
|
1041
1079
|
{isAssistant && isStreaming && !streamingText ? (
|
|
1042
1080
|
<span className="inline-block animate-pulse">▋</span>
|
|
1043
1081
|
) : null}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { handleChat } from "@/sse/handlers/chat.js";
|
|
2
|
+
import { getApiKeys, createApiKey } from "@/lib/localDb";
|
|
3
|
+
import { getConsistentMachineId } from "@/shared/utils/machineId";
|
|
4
|
+
|
|
5
|
+
export const dynamic = "force-dynamic";
|
|
6
|
+
|
|
7
|
+
// The browser only holds the dashboard JWT. The LLM handler still enforces
|
|
8
|
+
// requireApiKey, so reuse (or mint) a local key server-side; it never reaches the client.
|
|
9
|
+
async function getInternalApiKey(): Promise<string> {
|
|
10
|
+
const keys = await getApiKeys();
|
|
11
|
+
const active = keys.find((k) => k.isActive !== false);
|
|
12
|
+
if (active) return active.key;
|
|
13
|
+
const created = await createApiKey("Default Key", await getConsistentMachineId());
|
|
14
|
+
return created.key;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function POST(request: Request) {
|
|
18
|
+
let body: unknown;
|
|
19
|
+
try {
|
|
20
|
+
body = await request.json();
|
|
21
|
+
} catch {
|
|
22
|
+
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let apiKey: string;
|
|
26
|
+
try {
|
|
27
|
+
apiKey = await getInternalApiKey();
|
|
28
|
+
} catch {
|
|
29
|
+
return Response.json({ error: "Failed to prepare API key" }, { status: 500 });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Only the body matters here; forwarding the browser's headers would also hand
|
|
33
|
+
// cookies/origin to upstream executors that read rawHeaders.
|
|
34
|
+
const upstreamRequest = new Request(request.url, {
|
|
35
|
+
method: "POST",
|
|
36
|
+
headers: {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
Authorization: `Bearer ${apiKey}`,
|
|
39
|
+
},
|
|
40
|
+
body: JSON.stringify(body),
|
|
41
|
+
signal: request.signal,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return handleChat(upstreamRequest);
|
|
45
|
+
}
|
package/src/app/globals.css
CHANGED
|
@@ -300,57 +300,98 @@
|
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
/* ── MARKDOWN BODY ─────────────────────────────────────── */
|
|
303
|
-
/*
|
|
304
|
-
.changelog-body h1 {
|
|
303
|
+
/* Shared by the changelog modal and chat assistant messages. */
|
|
304
|
+
:is(.changelog-body, .chat-markdown) h1 {
|
|
305
305
|
font-size: 1.4rem;
|
|
306
306
|
font-weight: 700;
|
|
307
307
|
margin: 1.5rem 0 0.75rem;
|
|
308
308
|
padding-bottom: 0.5rem;
|
|
309
309
|
border-bottom: 1px solid var(--border);
|
|
310
310
|
}
|
|
311
|
-
.changelog-body h1:first-child {
|
|
311
|
+
:is(.changelog-body, .chat-markdown) h1:first-child {
|
|
312
312
|
margin-top: 0;
|
|
313
313
|
}
|
|
314
|
-
.changelog-body h2 {
|
|
314
|
+
:is(.changelog-body, .chat-markdown) h2 {
|
|
315
315
|
font-size: 1.3rem;
|
|
316
316
|
font-weight: 700;
|
|
317
317
|
margin: 2.25rem 0 0.6rem;
|
|
318
|
-
color: var(--primary);
|
|
319
318
|
}
|
|
320
|
-
.changelog-body h2:first-child {
|
|
319
|
+
:is(.changelog-body, .chat-markdown) h2:first-child {
|
|
321
320
|
margin-top: 0;
|
|
322
321
|
}
|
|
323
|
-
.
|
|
322
|
+
/* Changelog headings use --primary; chat keeps inherited color (its panel is always dark). */
|
|
323
|
+
.changelog-body h2 {
|
|
324
|
+
color: var(--primary);
|
|
325
|
+
}
|
|
326
|
+
:is(.changelog-body, .chat-markdown) h3 {
|
|
324
327
|
font-size: 0.95rem;
|
|
325
328
|
font-weight: 600;
|
|
326
329
|
margin: 0.75rem 0 0.4rem;
|
|
327
330
|
}
|
|
328
|
-
.changelog-body ul {
|
|
331
|
+
:is(.changelog-body, .chat-markdown) ul {
|
|
329
332
|
list-style: disc;
|
|
330
333
|
padding-left: 1.5rem;
|
|
331
334
|
margin: 0.5rem 0;
|
|
332
335
|
}
|
|
333
|
-
.changelog-body
|
|
336
|
+
:is(.changelog-body, .chat-markdown) ol {
|
|
337
|
+
list-style: decimal;
|
|
338
|
+
padding-left: 1.5rem;
|
|
339
|
+
margin: 0.5rem 0;
|
|
340
|
+
}
|
|
341
|
+
:is(.changelog-body, .chat-markdown) li {
|
|
334
342
|
margin: 0.25rem 0;
|
|
335
343
|
line-height: 1.6;
|
|
336
344
|
}
|
|
337
|
-
.changelog-body p {
|
|
345
|
+
:is(.changelog-body, .chat-markdown) p {
|
|
338
346
|
margin: 0.5rem 0;
|
|
339
347
|
line-height: 1.6;
|
|
340
348
|
}
|
|
341
|
-
.changelog-body code {
|
|
349
|
+
:is(.changelog-body, .chat-markdown) code {
|
|
342
350
|
background: var(--muted);
|
|
343
351
|
padding: 0.1rem 0.35rem;
|
|
344
352
|
border-radius: 4px;
|
|
345
353
|
font-size: 0.875em;
|
|
346
354
|
font-family: ui-monospace, monospace;
|
|
347
355
|
}
|
|
348
|
-
.changelog-body
|
|
356
|
+
:is(.changelog-body, .chat-markdown) pre {
|
|
357
|
+
background: var(--muted);
|
|
358
|
+
border: 1px solid var(--border);
|
|
359
|
+
border-radius: 10px;
|
|
360
|
+
padding: 0.75rem 1rem;
|
|
361
|
+
margin: 0.75rem 0;
|
|
362
|
+
overflow-x: auto;
|
|
363
|
+
}
|
|
364
|
+
:is(.changelog-body, .chat-markdown) pre code {
|
|
365
|
+
background: none;
|
|
366
|
+
padding: 0;
|
|
367
|
+
border-radius: 0;
|
|
368
|
+
font-size: 0.85em;
|
|
369
|
+
line-height: 1.55;
|
|
370
|
+
}
|
|
371
|
+
:is(.changelog-body, .chat-markdown) a {
|
|
349
372
|
color: var(--primary);
|
|
350
373
|
text-decoration: underline;
|
|
351
374
|
}
|
|
352
|
-
.changelog-body hr {
|
|
375
|
+
:is(.changelog-body, .chat-markdown) hr {
|
|
353
376
|
border: none;
|
|
354
377
|
border-top: 1px solid var(--border);
|
|
355
378
|
margin: 1.5rem 0;
|
|
356
379
|
}
|
|
380
|
+
|
|
381
|
+
/* Chat panel is always dark (#212121), so theme tokens resolve to light values there. */
|
|
382
|
+
.chat-markdown h1 {
|
|
383
|
+
border-bottom-color: rgba(255, 255, 255, 0.15);
|
|
384
|
+
}
|
|
385
|
+
.chat-markdown code {
|
|
386
|
+
background: rgba(255, 255, 255, 0.1);
|
|
387
|
+
}
|
|
388
|
+
.chat-markdown pre {
|
|
389
|
+
background: rgba(0, 0, 0, 0.35);
|
|
390
|
+
border-color: rgba(255, 255, 255, 0.12);
|
|
391
|
+
}
|
|
392
|
+
.chat-markdown a {
|
|
393
|
+
color: #7cc4ff;
|
|
394
|
+
}
|
|
395
|
+
.chat-markdown hr {
|
|
396
|
+
border-top-color: rgba(255, 255, 255, 0.15);
|
|
397
|
+
}
|