|
1019 | 1019 | { id:'GEMMA_3N_E4B_IT', displayName:'Gemma 3n E4B it (offline)', modelName:'gemma-3n-e4b-it', apiProvider:'GOOGLE', supportsScreenshot:true, supportsTopK:true, supportsThinking:false, isOffline:true, hint:'4.92 GB download required.', strike:false }, |
1020 | 1020 | { id:'GEMMA_4_E4B_IT', displayName:'Gemma 4 E4B it (offline)', modelName:'gemma-4-e4b-it', apiProvider:'GOOGLE', supportsScreenshot:false, supportsTopK:true, supportsThinking:false, isOffline:true, hint:'3.40 GB download required.', strike:false }, |
1021 | 1021 | { id:'HUMAN_EXPERT', displayName:'Human Expert', modelName:'human-expert', apiProvider:'HUMAN_EXPERT', supportsScreenshot:true, supportsTopK:false, supportsThinking:false, isOffline:false, hint:'Requires Pro subscription.', strike:false }, |
1022 | | - { id:'GLM_5V_TURBO_VERCEL', displayName:'GLM 5V Turbo (Vercel)', modelName:'zai/glm-5v-turbo', apiProvider:'VERCEL', supportsScreenshot:true, supportsTopK:false, supportsThinking:false, isOffline:false, hint:'Credit or debit card required - $1.20/M input | $0.24/M cache read | $4/M output', strike:false }, |
| 1022 | + { id:'GLM_5V_TURBO_VERCEL', displayName:'GLM 5V Turbo (Vercel)', modelName:'zai/glm-5v-turbo', apiProvider:'VERCEL', supportsScreenshot:true, supportsTopK:false, supportsThinking:true, isOffline:false, hint:'Credit or debit card required - $1.20/M input | $0.24/M cache read | $4/M output - caching and thinking enabled', strike:false }, |
1023 | 1023 | { id:'GPT_5_1_CODEX_MAX', displayName:'GPT-5.1 Codex Max (Vercel)', modelName:'openai/gpt-5.1-codex-max', apiProvider:'VERCEL', supportsScreenshot:false, supportsTopK:true, supportsThinking:true, isOffline:false, hint:'Vercel requires a credit card.',strike:false }, |
1024 | 1024 | { id:'GPT_5_1_CODEX_MINI', displayName:'GPT-5.1 Codex Mini (Vercel)', modelName:'openai/gpt-5.1-codex-mini', apiProvider:'VERCEL', supportsScreenshot:false, supportsTopK:true, supportsThinking:true, isOffline:false, hint:'Vercel requires a credit card.',strike:false }, |
1025 | 1025 | { id:'GPT_5_NANO', displayName:'GPT-5 Nano (Vercel)', modelName:'openai/gpt-5-nano', apiProvider:'VERCEL', supportsScreenshot:false, supportsTopK:true, supportsThinking:false, isOffline:false, hint:'Vercel requires a credit card.',strike:false }, |
|
3024 | 3024 | } |
3025 | 3025 | } |
3026 | 3026 |
|
3027 | | -/* ── VERCEL API (dedicated - matches callVercelApi in ScreenCaptureVercelClient.kt) ── |
3028 | | - NOTE: this is NOT the general Vercel AI Gateway - it's this project's own proxy at |
3029 | | - v0-screen-operator-clon-pi.vercel.app, authenticated with an "x-api-key" header |
3030 | | - (not "Authorization: Bearer"), plain string message content, streaming SSE. */ |
| 3027 | +/* ── VERCEL AI GATEWAY ─────────────────────────────────────────── |
| 3028 | + Uses the public OpenAI-compatible Chat Completions endpoint directly from the |
| 3029 | + WebView. The former project-specific proxy no longer exists, which made WebView |
| 3030 | + fetches fail before the request could reach the model. AI Gateway accepts the |
| 3031 | + configured Vercel AI Gateway key as a Bearer token and supports CORS for WebViews. */ |
3031 | 3032 | async function _callVercel(payload) { |
3032 | 3033 | const keys = Bridge.getAllApiKeys('VERCEL'); |
3033 | 3034 | if (!keys.length) { |
|
3061 | 3062 | const requestBody = { model: payload.modelName, messages, stream: true }; |
3062 | 3063 | if (payload.temperature !== undefined && payload.temperature > 0) requestBody.temperature = payload.temperature; |
3063 | 3064 | if (payload.topP !== undefined && payload.topP > 0) requestBody.top_p = payload.topP; |
3064 | | - // Enable extended reasoning for Codex and other reasoning-capable models via Vercel proxy. |
| 3065 | + // AI Gateway's provider-neutral `reasoning` object enables reasoning for every |
| 3066 | + // supported model. GLM-5V-Turbo supports thinking but not a selectable effort |
| 3067 | + // level, so deliberately send only `enabled` for it. The gateway translates this |
| 3068 | + // to Z.AI's native thinking setting without sending an unsupported level. |
3065 | 3069 | if (payload.supportsThinking) { |
3066 | | - requestBody.reasoning_effort = 'high'; |
| 3070 | + requestBody.reasoning = payload.modelName === 'zai/glm-5v-turbo' |
| 3071 | + ? { enabled: true } |
| 3072 | + : { effort: 'high' }; |
3067 | 3073 | } |
3068 | 3074 |
|
| 3075 | + const vercelChatEndpoint = 'https://ai-gateway.vercel.sh/v1/chat/completions'; |
| 3076 | + const vercelHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + apiKey }; |
| 3077 | + |
3069 | 3078 | window.__customModelAbortController = new AbortController(); |
3070 | 3079 | let acc = ''; |
3071 | 3080 | let thinkingAcc = ''; |
3072 | 3081 | try { |
3073 | | - let response = await fetch('https://v0-screen-operator-clon-pi.vercel.app/api/chat', { |
| 3082 | + let response = await fetch(vercelChatEndpoint, { |
3074 | 3083 | method: 'POST', |
3075 | | - headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey }, |
| 3084 | + headers: vercelHeaders, |
3076 | 3085 | body: JSON.stringify(requestBody), |
3077 | 3086 | signal: window.__customModelAbortController.signal, |
3078 | 3087 | }); |
|
3091 | 3100 | apiKey = keys[keyIdx]; |
3092 | 3101 | let retryResp; |
3093 | 3102 | try { |
3094 | | - retryResp = await fetch('https://v0-screen-operator-clon-pi.vercel.app/api/chat', { |
| 3103 | + retryResp = await fetch(vercelChatEndpoint, { |
3095 | 3104 | method: 'POST', |
3096 | | - headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey }, |
| 3105 | + headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + apiKey }, |
3097 | 3106 | body: JSON.stringify(requestBody), |
3098 | 3107 | signal: window.__customModelAbortController.signal, |
3099 | 3108 | }); |
|
0 commit comments