@iaforged/context-code 2.3.5 → 2.3.6

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.
@@ -1 +1 @@
1
- import{clearAuthRelatedCaches as e,performLogout as o}from"../../commands/logout/logout.js";import{setMainLoopModelOverride as i}from"../../bootstrap/state.js";import{getSecureStorage as t}from"../../utils/secureStorage/index.js";import{logEvent as r}from"../../services/analytics/index.js";import{getSSLErrorHint as s}from"../../services/api/errorUtils.js";import{fetchAndStoreClaudeCodeFirstTokenDate as a}from"../../services/api/firstTokenDate.js";import{createAndStoreApiKey as n,fetchAndStoreUserRoles as c,refreshOAuthToken as l,shouldUseClaudeAIAuth as p,storeOAuthAccountInfo as u}from"../../services/oauth/client.js";import{getOauthProfileFromOauthToken as d}from"../../services/oauth/getOauthProfile.js";import{OAuthService as m}from"../../services/oauth/index.js";import{startGeminiCliOAuthFlow as g}from"../../services/oauth/geminiCli.js";import{clearOAuthTokenCache as f,getAnthropicApiKeyWithSource as h,getAuthTokenSource as v,getClaudeAIOAuthTokens as w,getOpenAIOAuthTokens as _,getOauthAccountInfo as x,removeApiKey as A,saveOpenAIOAuthTokens as O,saveGeminiGoogleOAuthTokens as E,saveProviderApiKey as y,getSubscriptionType as C,isUsing3PServices as b,saveOAuthTokensIfNeeded as j,validateForceLoginOrg as T,removeProviderScopedCredentials as P,removeProviderApiKey as k}from"../../utils/auth.js";import{saveGlobalConfig as U}from"../../utils/config.js";import{logForDebugging as S}from"../../utils/debug.js";import{isRunningOnHomespace as $}from"../../utils/envUtils.js";import{errorMessage as I}from"../../utils/errors.js";import{logError as z}from"../../utils/log.js";import{getAPIProvider as H}from"../../utils/model/providers.js";import{setStoredActiveProviderPreference as L}from"../../utils/model/providerProfilesDb.js";import{isProfiledProvider as D,setActiveProfileForProvider as N}from"../../utils/model/providerProfiles.js";import{getLastUsedProviderProfile as R,removeProviderProfile as K}from"../../utils/model/providerProfiles.js";import{clearProviderBaseUrl as W,setProviderBaseUrl as B}from"../../utils/model/providerBaseUrls.js";import{getInitialSettings as F}from"../../utils/settings/settings.js";import{jsonStringify as M}from"../../utils/slowOperations.js";import{buildAccountProperties as X,buildAPIProviderProperties as Y}from"../../utils/status.js";export async function installOAuthTokens(o,s="anthropic",l){if(l||await async function(e){const{flushTelemetry:o}=await import("../../utils/telemetry/instrumentation.js");if(await o(),"openai"===e)return void _.cache?.clear?.();await A();const i=t(),r=i.read();if(r){const e=Object.fromEntries(Object.entries(r.providerProfileOauth??{}).filter(([e])=>!e.startsWith("claude/"))),{claudeAiOauth:o,...t}=r,s={...t,providerProfileOauth:e};Object.keys(s).length>0?i.update(s):i.delete()}w.cache?.clear?.(),U(e=>({...e,oauthAccount:void 0}))}(s),"anthropic"===s){const e=o.profile??await d(o.accessToken);e?u({accountUuid:e.account.uuid,emailAddress:e.account.email,organizationUuid:e.organization.uuid,displayName:e.account.display_name||void 0,hasExtraUsageEnabled:e.organization.has_extra_usage_enabled??void 0,billingType:e.organization.billing_type??void 0,subscriptionCreatedAt:e.organization.subscription_created_at??void 0,accountCreatedAt:e.account.created_at}):o.tokenAccount&&u({accountUuid:o.tokenAccount.uuid,emailAddress:o.tokenAccount.emailAddress,organizationUuid:o.tokenAccount.organizationUuid})}const m="openai"===s?O(o,l):j(o,l);if(f(),m.warning&&r("tengu_oauth_storage_warning",{warning:m.warning}),"anthropic"===s&&await c(o.accessToken).catch(e=>S(String(e),{level:"error"})),"anthropic"===s&&p(o.scopes))await a().catch(e=>S(String(e),{level:"error"}));else if("anthropic"===s){if(!await n(o.accessToken))throw new Error("No se pudo crear la API key. El servidor aceptó la solicitud pero no devolvió una clave.")}L("openai"===s?"openai":"claude"),i(void 0),await e()}export async function authLogin({email:e,sso:o,console:i,claudeai:t,provider:a}){i&&t&&(process.stderr.write("Error: --console and --claudeai cannot be used together.\n"),process.exit(1));const n=F(),c=n.forceLoginMethod?"claudeai"===n.forceLoginMethod:!i,u=n.forceLoginOrgUUID,d=a?.trim().toLowerCase(),f=process.env.CONTEXT_CODE_OAUTH_REFRESH_TOKEN??process.env.CLAUDE_CODE_OAUTH_REFRESH_TOKEN;if(f){const e=process.env.CONTEXT_CODE_OAUTH_SCOPES??process.env.CLAUDE_CODE_OAUTH_SCOPES;e||(process.stderr.write('CONTEXT_CODE_OAUTH_SCOPES (legacy: CLAUDE_CODE_OAUTH_SCOPES) is required when using CONTEXT_CODE_OAUTH_REFRESH_TOKEN.\nSet it to the space-separated scopes the refresh token was issued with\n(e.g. "user:inference" or "user:profile user:inference user:sessions:claude_code user:mcp_servers").\n'),process.exit(1));const o=e.split(/\s+/).filter(Boolean);try{r("tengu_login_from_refresh_token",{});const e=await l(f,{scopes:o});await installOAuthTokens(e);const i=await T();i.valid||(process.stderr.write(i.message+"\n"),process.exit(1)),U(e=>e.hasCompletedOnboarding?e:{...e,hasCompletedOnboarding:!0}),r("tengu_oauth_success",{loginWithClaudeAi:p(e.scopes)}),process.stdout.write("Inicio de sesión exitoso.\n"),process.exit(0)}catch(e){z(e);const o=s(e);process.stderr.write(`Error al iniciar sesión: ${I(e)}\n${o?o+"\n":""}`),process.exit(1)}}const h=o?"sso":void 0,v=new m;try{if(r("tengu_oauth_flow_start",{loginWithClaudeAi:c}),"gemini-google"===d){const e=await g();E(e),L("gemini-google"),process.stdout.write("Inicio de sesión exitoso.\n"),process.exit(0)}const o="openai"===d?"openai":"anthropic",i="openai"!==o&&c,t=await v.startOAuthFlow(async e=>{process.stdout.write("Abriendo el navegador para iniciar sesión…\n"),process.stdout.write(`Si el navegador no se abre, visita: ${e}\n`)},{loginWithClaudeAi:i,provider:o,loginHint:e,loginMethod:h,orgUUID:u});if(await installOAuthTokens(t,o),"anthropic"===o){const e=await T();e.valid||(process.stderr.write(e.message+"\n"),process.exit(1))}r("tengu_oauth_success",{loginWithClaudeAi:i}),process.stdout.write("Inicio de sesión exitoso.\n"),process.exit(0)}catch(e){z(e);const o=s(e);process.stderr.write(`Error al iniciar sesión: ${I(e)}\n${o?o+"\n":""}`),process.exit(1)}finally{v.cleanup()}}export async function authStatus(e){const{source:o,hasToken:i}=v(),{source:t}=h(),r=!!process.env.ANTHROPIC_API_KEY&&!$(),s=H(),a=x(),n=C(),c=b(),l=i||"none"!==t||r||c;let p="none";if("openai"===s?p="openai":c?p="third_party":"claude.ai"===o?p="claude.ai":"apiKeyHelper"===o?p="api_key_helper":"none"!==o?p="oauth_token":"ANTHROPIC_API_KEY"===t||r?p="api_key":"/login managed key"===t&&(p="claude.ai"),e.text){const e=[...X(),...Y()];let o=!1;for(const i of e){const e="string"==typeof i.value?i.value:Array.isArray(i.value)?i.value.join(", "):null;null!==e&&"none"!==e&&(o=!0,i.label?process.stdout.write(`${i.label}: ${e}\n`):process.stdout.write(`${e}\n`))}!o&&r&&process.stdout.write("API key: ANTHROPIC_API_KEY\n"),l||process.stdout.write("openai"===s?"Sesión no iniciada. Ejecuta context auth login para autenticarte con OpenAI / Codex.\n":"Sesión no iniciada. Ejecuta context auth login para autenticarte.\n")}else{const e="none"!==t?t:r?"ANTHROPIC_API_KEY":null,o={loggedIn:l,authMethod:p,apiProvider:s};e&&(o.apiKeySource=e),"claude.ai"===p&&(o.email=a?.emailAddress??null,o.orgId=a?.organizationUuid??null,o.orgName=a?.organizationName??null,o.subscriptionType=n??null),process.stdout.write(M(o,null,2)+"\n")}process.exit(l?0:1)}export async function authLogout(){try{await o({clearOnboarding:!1})}catch{process.stderr.write("Error al cerrar sesión.\n"),process.exit(1)}process.stdout.write(`Sesión cerrada exitosamente de tu cuenta ${function(){const e=H();return"openai"===e?"OpenAI / Codex":"bedrock"===e?"AWS Bedrock":"vertex"===e?"Google Vertex AI":"foundry"===e?"Microsoft Foundry":"Anthropic"}()}.\n`),process.exit(0)}export async function authProviderApiKey(e){const o=e.provider.trim().toLowerCase(),i=["openrouter","ollama-cloud","gemini-api","zai","minimax","nvidia","deepseek","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi","openai"];i.includes(o)||(process.stderr.write(`Provider no soportado para API key: ${o}. Soportados: ${i.join(", ")}\n`),process.exit(1));const t=e.profile?.trim();t&&D(o)&&N(o,t),await y(o,e.apiKey),L(o),process.stdout.write(`API key guardada para ${o}${t?` (perfil ${t})`:""}.\n`),process.exit(0)}export async function authProviderBaseUrl(e){const o=e.provider.trim().toLowerCase(),i=["ollama","ollama-cloud","openrouter","gemini-google","zai","minimax","nvidia","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"];i.includes(o)||(process.stderr.write(`Provider no soportado para base URL: ${o}. Soportados: ${i.join(", ")}\n`),process.exit(1));const t=e.profile?.trim();t&&D(o)&&N(o,t);const r=B(o,e.baseUrl);L(o),process.stdout.write(`Base URL guardada para ${o}: ${r}${t?` (perfil ${t})`:""}.\n`),process.exit(0)}export async function authSetProviderPreference(e){const o=e.provider.trim().toLowerCase();L(o),process.stdout.write(`Provider activo establecido a ${o}.\n`),process.exit(0)}export async function authProviderRemove(e){const o=e.provider.trim().toLowerCase();o||(process.stderr.write("Debes indicar un provider.\n"),process.exit(1));const i=o,t=e.profile?.trim();let r=null;if(D(i)){const e=t||R(i)?.name;if(e){const o=K(i,e);o&&(await P(o.id),r=`${o.provider}/${o.name}`)}}["openrouter","ollama-cloud","gemini-api","zai","minimax","nvidia","deepseek","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi","openai"].includes(o)&&await k(o);["ollama","ollama-cloud","openrouter","gemini-google","zai","minimax","nvidia","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"].includes(o)&&W(o),process.stdout.write(r?`Proveedor eliminado: ${r}.\n`:`Credenciales/base URL limpiadas para ${o}.\n`),process.exit(0)}
1
+ import{clearAuthRelatedCaches as e,performLogout as o}from"../../commands/logout/logout.js";import{setMainLoopModelOverride as i}from"../../bootstrap/state.js";import{getSecureStorage as t}from"../../utils/secureStorage/index.js";import{logEvent as r}from"../../services/analytics/index.js";import{getSSLErrorHint as s}from"../../services/api/errorUtils.js";import{fetchAndStoreClaudeCodeFirstTokenDate as a}from"../../services/api/firstTokenDate.js";import{createAndStoreApiKey as n,fetchAndStoreUserRoles as c,refreshOAuthToken as l,shouldUseClaudeAIAuth as p,storeOAuthAccountInfo as u}from"../../services/oauth/client.js";import{getOauthProfileFromOauthToken as d}from"../../services/oauth/getOauthProfile.js";import{OAuthService as m}from"../../services/oauth/index.js";import{startGeminiCliOAuthFlow as g}from"../../services/oauth/geminiCli.js";import{clearOAuthTokenCache as f,getAnthropicApiKeyWithSource as h,getAuthTokenSource as v,getClaudeAIOAuthTokens as w,getOpenAIOAuthTokens as _,getOauthAccountInfo as x,removeApiKey as A,saveOpenAIOAuthTokens as O,saveGeminiGoogleOAuthTokens as E,saveProviderApiKey as y,getSubscriptionType as C,isUsing3PServices as b,saveOAuthTokensIfNeeded as j,validateForceLoginOrg as T,removeProviderScopedCredentials as P,removeProviderApiKey as k}from"../../utils/auth.js";import{saveGlobalConfig as U}from"../../utils/config.js";import{logForDebugging as S}from"../../utils/debug.js";import{isRunningOnHomespace as $}from"../../utils/envUtils.js";import{errorMessage as I}from"../../utils/errors.js";import{logError as z}from"../../utils/log.js";import{getAPIProvider as H}from"../../utils/model/providers.js";import{setStoredActiveProviderPreference as L}from"../../utils/model/providerProfilesDb.js";import{isProfiledProvider as D,setActiveProfileForProvider as N}from"../../utils/model/providerProfiles.js";import{getLastUsedProviderProfile as R,removeProviderProfile as K}from"../../utils/model/providerProfiles.js";import{clearProviderBaseUrl as W,setProviderBaseUrl as B}from"../../utils/model/providerBaseUrls.js";import{getInitialSettings as F}from"../../utils/settings/settings.js";import{jsonStringify as M}from"../../utils/slowOperations.js";import{buildAccountProperties as X,buildAPIProviderProperties as Y}from"../../utils/status.js";export async function installOAuthTokens(o,s="anthropic",l){if(l||await async function(e){const{flushTelemetry:o}=await import("../../utils/telemetry/instrumentation.js");if(await o(),"openai"===e)return void _.cache?.clear?.();await A();const i=t(),r=i.read();if(r){const e=Object.fromEntries(Object.entries(r.providerProfileOauth??{}).filter(([e])=>!e.startsWith("claude/"))),{claudeAiOauth:o,...t}=r,s={...t,providerProfileOauth:e};Object.keys(s).length>0?i.update(s):i.delete()}w.cache?.clear?.(),U(e=>({...e,oauthAccount:void 0}))}(s),"anthropic"===s){const e=o.profile??await d(o.accessToken);e?u({accountUuid:e.account.uuid,emailAddress:e.account.email,organizationUuid:e.organization.uuid,displayName:e.account.display_name||void 0,hasExtraUsageEnabled:e.organization.has_extra_usage_enabled??void 0,billingType:e.organization.billing_type??void 0,subscriptionCreatedAt:e.organization.subscription_created_at??void 0,accountCreatedAt:e.account.created_at}):o.tokenAccount&&u({accountUuid:o.tokenAccount.uuid,emailAddress:o.tokenAccount.emailAddress,organizationUuid:o.tokenAccount.organizationUuid})}const m="openai"===s?O(o,l):j(o,l);if(f(),m.warning&&r("tengu_oauth_storage_warning",{warning:m.warning}),"anthropic"===s&&await c(o.accessToken).catch(e=>S(String(e),{level:"error"})),"anthropic"===s&&p(o.scopes))await a().catch(e=>S(String(e),{level:"error"}));else if("anthropic"===s){if(!await n(o.accessToken))throw new Error("No se pudo crear la API key. El servidor aceptó la solicitud pero no devolvió una clave.")}L("openai"===s?"openai":"claude"),i(void 0),await e()}export async function authLogin({email:e,sso:o,console:i,claudeai:t,provider:a}){i&&t&&(process.stderr.write("Error: --console and --claudeai cannot be used together.\n"),process.exit(1));const n=F(),c=n.forceLoginMethod?"claudeai"===n.forceLoginMethod:!i,u=n.forceLoginOrgUUID,d=a?.trim().toLowerCase(),f=process.env.CONTEXT_CODE_OAUTH_REFRESH_TOKEN??process.env.CLAUDE_CODE_OAUTH_REFRESH_TOKEN;if(f){const e=process.env.CONTEXT_CODE_OAUTH_SCOPES??process.env.CLAUDE_CODE_OAUTH_SCOPES;e||(process.stderr.write('CONTEXT_CODE_OAUTH_SCOPES (legacy: CLAUDE_CODE_OAUTH_SCOPES) is required when using CONTEXT_CODE_OAUTH_REFRESH_TOKEN.\nSet it to the space-separated scopes the refresh token was issued with\n(e.g. "user:inference" or "user:profile user:inference user:sessions:claude_code user:mcp_servers").\n'),process.exit(1));const o=e.split(/\s+/).filter(Boolean);try{r("tengu_login_from_refresh_token",{});const e=await l(f,{scopes:o});await installOAuthTokens(e);const i=await T();i.valid||(process.stderr.write(i.message+"\n"),process.exit(1)),U(e=>e.hasCompletedOnboarding?e:{...e,hasCompletedOnboarding:!0}),r("tengu_oauth_success",{loginWithClaudeAi:p(e.scopes)}),process.stdout.write("Inicio de sesión exitoso.\n"),process.exit(0)}catch(e){z(e);const o=s(e);process.stderr.write(`Error al iniciar sesión: ${I(e)}\n${o?o+"\n":""}`),process.exit(1)}}const h=o?"sso":void 0,v=new m;try{if(r("tengu_oauth_flow_start",{loginWithClaudeAi:c}),"gemini-google"===d){const e=await g();E(e),L("gemini-google"),process.stdout.write("Inicio de sesión exitoso.\n"),process.exit(0)}const o="openai"===d?"openai":"anthropic",i="openai"!==o&&c,t=await v.startOAuthFlow(async e=>{process.stdout.write("Abriendo el navegador para iniciar sesión…\n"),process.stdout.write(`Si el navegador no se abre, visita: ${e}\n`)},{loginWithClaudeAi:i,provider:o,loginHint:e,loginMethod:h,orgUUID:u});if(await installOAuthTokens(t,o),"anthropic"===o){const e=await T();e.valid||(process.stderr.write(e.message+"\n"),process.exit(1))}r("tengu_oauth_success",{loginWithClaudeAi:i}),process.stdout.write("Inicio de sesión exitoso.\n"),process.exit(0)}catch(e){z(e);const o=s(e);process.stderr.write(`Error al iniciar sesión: ${I(e)}\n${o?o+"\n":""}`),process.exit(1)}finally{v.cleanup()}}export async function authStatus(e){const{source:o,hasToken:i}=v(),{source:t}=h(),r=!!process.env.ANTHROPIC_API_KEY&&!$(),s=H(),a=x(),n=C(),c=b(),l=i||"none"!==t||r||c;let p="none";if("openai"===s?p="openai":c?p="third_party":"claude.ai"===o?p="claude.ai":"apiKeyHelper"===o?p="api_key_helper":"none"!==o?p="oauth_token":"ANTHROPIC_API_KEY"===t||r?p="api_key":"/login managed key"===t&&(p="claude.ai"),e.text){const e=[...X(),...Y()];let o=!1;for(const i of e){const e="string"==typeof i.value?i.value:Array.isArray(i.value)?i.value.join(", "):null;null!==e&&"none"!==e&&(o=!0,i.label?process.stdout.write(`${i.label}: ${e}\n`):process.stdout.write(`${e}\n`))}!o&&r&&process.stdout.write("API key: ANTHROPIC_API_KEY\n"),l||process.stdout.write("openai"===s?"Sesión no iniciada. Ejecuta context auth login para autenticarte con OpenAI / Codex.\n":"Sesión no iniciada. Ejecuta context auth login para autenticarte.\n")}else{const e="none"!==t?t:r?"ANTHROPIC_API_KEY":null,o={loggedIn:l,authMethod:p,apiProvider:s};e&&(o.apiKeySource=e),"claude.ai"===p&&(o.email=a?.emailAddress??null,o.orgId=a?.organizationUuid??null,o.orgName=a?.organizationName??null,o.subscriptionType=n??null),process.stdout.write(M(o,null,2)+"\n")}process.exit(l?0:1)}export async function authLogout(){try{await o({clearOnboarding:!1})}catch{process.stderr.write("Error al cerrar sesión.\n"),process.exit(1)}process.stdout.write(`Sesión cerrada exitosamente de tu cuenta ${function(){const e=H();return"openai"===e?"OpenAI / Codex":"bedrock"===e?"AWS Bedrock":"vertex"===e?"Google Vertex AI":"foundry"===e?"Microsoft Foundry":"Anthropic"}()}.\n`),process.exit(0)}export async function authProviderApiKey(e){const o=e.provider.trim().toLowerCase(),i=["openrouter","ollama-cloud","gemini-api","zai","minimax","nvidia","deepseek","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi","openai"];i.includes(o)||(process.stderr.write(`Provider no soportado para API key: ${o}. Soportados: ${i.join(", ")}\n`),process.exit(1));const t=e.profile?.trim();t&&D(o)&&N(o,t),await y(o,e.apiKey),L(o),process.stdout.write(`API key guardada para ${o}${t?` (perfil ${t})`:""}.\n`),process.exit(0)}export async function authProviderBaseUrl(e){const o=e.provider.trim().toLowerCase(),i=["ollama","ollama-cloud","lmstudio","openrouter","gemini-google","zai","minimax","nvidia","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"];i.includes(o)||(process.stderr.write(`Provider no soportado para base URL: ${o}. Soportados: ${i.join(", ")}\n`),process.exit(1));const t=e.profile?.trim();t&&D(o)&&N(o,t);const r=B(o,e.baseUrl);L(o),process.stdout.write(`Base URL guardada para ${o}: ${r}${t?` (perfil ${t})`:""}.\n`),process.exit(0)}export async function authSetProviderPreference(e){const o=e.provider.trim().toLowerCase();L(o),process.stdout.write(`Provider activo establecido a ${o}.\n`),process.exit(0)}export async function authProviderRemove(e){const o=e.provider.trim().toLowerCase();o||(process.stderr.write("Debes indicar un provider.\n"),process.exit(1));const i=o,t=e.profile?.trim();let r=null;if(D(i)){const e=t||R(i)?.name;if(e){const o=K(i,e);o&&(await P(o.id),r=`${o.provider}/${o.name}`)}}["openrouter","ollama-cloud","gemini-api","zai","minimax","nvidia","deepseek","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi","openai"].includes(o)&&await k(o);["ollama","ollama-cloud","lmstudio","openrouter","gemini-google","zai","minimax","nvidia","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"].includes(o)&&W(o),process.stdout.write(r?`Proveedor eliminado: ${r}.\n`:`Credenciales/base URL limpiadas para ${o}.\n`),process.exit(0)}
@@ -1 +1 @@
1
- import{fetchProviderModels as e}from"../../utils/model/providerModels.js";import{VISIBLE_PROVIDERS as i}from"../../utils/model/providerCatalog.js";import{getAPIProvider as o}from"../../utils/model/providers.js";const r=[{id:"claude-opus-4-7",label:"Opus 4.7",description:"Mas capaz, ideal para tareas complejas."},{id:"claude-sonnet-4-6",label:"Sonnet 4.6",description:"Balanceado, recomendado para uso general."},{id:"claude-haiku-4-5-20251001",label:"Haiku 4.5",description:"Rapido y economico."},{id:"opus",label:"opus (alias)",description:"Alias dinamico al Opus por defecto."},{id:"sonnet",label:"sonnet (alias)",description:"Alias dinamico al Sonnet por defecto."},{id:"haiku",label:"haiku (alias)",description:"Alias dinamico al Haiku por defecto."}],a={claude:"firstParty",openai:"openai",openrouter:"openrouter",ollama:"ollama","ollama-cloud":"ollama-cloud","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"zai",minimax:"minimax",nvidia:"nvidia",deepseek:"deepseek",xai:"xai",gmi:"gmi",novita:"novita",stepfun:"stepfun",huggingface:"huggingface","opencode-zen":"opencode-zen",arcee:"arcee",alibaba:"alibaba",kimi:"kimi","custom-openai":"custom-openai","custom-anthropic":"custom-anthropic",bedrock:"bedrock",vertex:"vertex",foundry:"foundry",firstparty:"firstParty",anthropic:"firstParty"};export async function modelListHandler(t){let n;if(t.provider){const e=function(e){if(!e)return null;const o=e.trim().toLowerCase();if(a[o])return a[o];const r=i.find(e=>e.label.toLowerCase()===o);if(r)return a[r.id]??null;const t=i.find(e=>e.label.toLowerCase().includes(o)||o.includes(e.id));return t?a[t.id]??null:null}(t.provider);e||(process.stderr.write(`Provider desconocido: ${t.provider}\n`),process.exit(2)),n=e}else n=o();let s=[],l=null;try{s=(await e(n)).map(e=>({id:e.value,label:e.label,description:e.description}))}catch(e){l=e instanceof Error?e.message:String(e)}if(0===s.length&&function(e){return"firstParty"===e||"bedrock"===e||"vertex"===e||"foundry"===e}(n)&&(s=r),t.json)process.stdout.write(JSON.stringify({provider:n,models:s,error:l})+"\n");else{process.stdout.write(`Modelos disponibles (${n}):\n`),0===s.length&&(process.stdout.write(" (sin modelos detectados)\n"),l&&process.stdout.write(` Error: ${l}\n`));for(const e of s)process.stdout.write(` ${e.id}${e.label&&e.label!==e.id?` - ${e.label}`:""}\n`),e.description&&process.stdout.write(` ${e.description}\n`)}process.exit(0)}
1
+ import{fetchProviderModels as e}from"../../utils/model/providerModels.js";import{VISIBLE_PROVIDERS as i}from"../../utils/model/providerCatalog.js";import{getAPIProvider as o}from"../../utils/model/providers.js";const r=[{id:"claude-opus-4-7",label:"Opus 4.7",description:"Mas capaz, ideal para tareas complejas."},{id:"claude-sonnet-4-6",label:"Sonnet 4.6",description:"Balanceado, recomendado para uso general."},{id:"claude-haiku-4-5-20251001",label:"Haiku 4.5",description:"Rapido y economico."},{id:"opus",label:"opus (alias)",description:"Alias dinamico al Opus por defecto."},{id:"sonnet",label:"sonnet (alias)",description:"Alias dinamico al Sonnet por defecto."},{id:"haiku",label:"haiku (alias)",description:"Alias dinamico al Haiku por defecto."}],a={claude:"firstParty",openai:"openai",openrouter:"openrouter",ollama:"ollama","ollama-cloud":"ollama-cloud",lmstudio:"lmstudio","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"zai",minimax:"minimax",nvidia:"nvidia",deepseek:"deepseek",xai:"xai",gmi:"gmi",novita:"novita",stepfun:"stepfun",huggingface:"huggingface","opencode-zen":"opencode-zen",arcee:"arcee",alibaba:"alibaba",kimi:"kimi","custom-openai":"custom-openai","custom-anthropic":"custom-anthropic",bedrock:"bedrock",vertex:"vertex",foundry:"foundry",firstparty:"firstParty",anthropic:"firstParty"};export async function modelListHandler(t){let s;if(t.provider){const e=function(e){if(!e)return null;const o=e.trim().toLowerCase();if(a[o])return a[o];const r=i.find(e=>e.label.toLowerCase()===o);if(r)return a[r.id]??null;const t=i.find(e=>e.label.toLowerCase().includes(o)||o.includes(e.id));return t?a[t.id]??null:null}(t.provider);e||(process.stderr.write(`Provider desconocido: ${t.provider}\n`),process.exit(2)),s=e}else s=o();let n=[],l=null;try{n=(await e(s)).map(e=>({id:e.value,label:e.label,description:e.description}))}catch(e){l=e instanceof Error?e.message:String(e)}if(0===n.length&&function(e){return"firstParty"===e||"bedrock"===e||"vertex"===e||"foundry"===e}(s)&&(n=r),t.json)process.stdout.write(JSON.stringify({provider:s,models:n,error:l})+"\n");else{process.stdout.write(`Modelos disponibles (${s}):\n`),0===n.length&&(process.stdout.write(" (sin modelos detectados)\n"),l&&process.stdout.write(` Error: ${l}\n`));for(const e of n)process.stdout.write(` ${e.id}${e.label&&e.label!==e.id?` - ${e.label}`:""}\n`),e.description&&process.stdout.write(` ${e.description}\n`)}process.exit(0)}
@@ -1 +1 @@
1
- import{getVisibleProvider as e}from"../../utils/model/providerCatalog.js";import{buildAgentDetailMessage as r,buildAgentSummary as t,createAgent as o,deleteAgent as a,getAgent as n,isKnownAgentProvider as i,listAgents as s,setAgentModelByName as l,setAgentOrchestratorByName as u,setAgentRoleByName as c}from"./agentStore.js";function parseProvider(e){const r=function(e){if(!e)return null;switch(e.trim().toLowerCase()){case"z.ai":case"z-ai":return"zai";case"open-router":return"openrouter";case"ollama-cloud":case"ollama_cloud":case"ollamacloud":return"ollama-cloud";case"gemini":case"gemini-api-key":case"google-ai":return"gemini-api";case"gemini-google":case"google":case"google-oauth":return"gemini-google";default:return e.trim().toLowerCase()}}(e);return r&&i(r)?r:null}function getProviderLabel(r){return e(r).label}async function buildListMessageAsync(e){const r=await s(e);if(0===r.length)return e?`No hay agentes guardados para ${getProviderLabel(e)}.`:"No hay agentes guardados.";const o=[],a=e?[[e,r]]:Array.from(r.reduce((e,r)=>{const t=e.get(r.provider)??[];return t.push(r),e.set(r.provider,t),e},new Map));for(const[r,n]of a){e||o.push(""),o.push(`${getProviderLabel(r)}:`);for(const e of n)o.push(t(e))}return o.join("\n").trimStart()}const d=[{name:"orchestrator",role:"orchestrator",isOrchestrator:!0},{name:"backend",role:"backend",isOrchestrator:!1},{name:"frontend",role:"frontend",isOrchestrator:!1},{name:"qa",role:"qa",isOrchestrator:!1}];async function bootstrapProviderAgents(e){const r=[];for(const t of d){const a=await n(e.provider,t.name),i=a??await o({provider:e.provider,name:t.name,profileName:e.profileName}),s=await c(e.provider,i.name,t.role),d=await u(e.provider,i.name,t.isOrchestrator),p=await l(e.provider,i.name,e.model);r.push(`${a?"actualizado":"creado"} ${e.provider}/${i.name} role=${s?.roleKind??t.role} orchestrator=${d?.isOrchestrator?"true":"false"} model=${p?.modelOverride??"sin override"}`)}return[`Setup completado para ${getProviderLabel(e.provider)} (${d.length} agentes):`,...r].join("\n")}export const call=async(e,t)=>{const i=e.trim();if(!i||"list"===i.toLowerCase())return{type:"text",value:await buildListMessageAsync()};const s=i.split(/\s+/).filter(Boolean),d=s[0]?.toLowerCase();if("list"===d){const e=parseProvider(s[1]);return s[1]&&!e?{type:"text",value:`Proveedor invalido: ${s[1]}`}:{type:"text",value:await buildListMessageAsync(e??void 0)}}const p=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("create"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]);if(!t)return null;const o=r[2]?.trim();return o?{provider:t,name:o,profileName:r.slice(3).join(" ").trim()||void 0}:null}(i);if(p)try{const e=await n(p.provider,p.name);if(e)return{type:"text",value:`El agente ya existe: ${e.provider}/${e.name}`};const r=await o(p);return{type:"text",value:`Agente creado: ${r.provider}/${r.name}\nPerfil vinculado: ${r.profile?`${r.profile.provider}/${r.profile.name}`:"sin perfil"}`}}catch(e){return{type:"text",value:`No se pudo crear el agente: ${e instanceof Error?e.message:String(e)}`}}const m=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("setup"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]);if(!t)return null;const o=r[2],a=r.slice(3).join(" ").trim();return{provider:t,model:o&&!["-","none","clear"].includes(o.toLowerCase())?o.trim():null,profileName:a||void 0}}(i);if(m)try{return{type:"text",value:await bootstrapProviderAgents(m)}}catch(e){return{type:"text",value:`No se pudo ejecutar setup: ${e instanceof Error?e.message:String(e)}`}}const v=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("show"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim();return t&&o?{provider:t,name:o}:null}(i);if(v){const e=await n(v.provider,v.name);return e?{type:"text",value:r(e)}:{type:"text",value:`No existe el agente ${v.provider}/${v.name}.`}}const f=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("delete"!==r[0]?.toLowerCase()&&"remove"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim();return t&&o?{provider:t,name:o}:null}(i);if(f){return await a(f.provider,f.name)?{type:"text",value:`Agente eliminado: ${f.provider}/${f.name}`}:{type:"text",value:`No existe el agente ${f.provider}/${f.name}.`}}const g=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("set-role"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim(),a=r.slice(3).join(" ").trim();return t&&o&&a?{provider:t,name:o,role:a}:null}(i);if(g)try{const e=await c(g.provider,g.name,g.role);return e?{type:"text",value:`Rol actualizado para ${e.provider}/${e.name}: ${e.roleKind??"worker"}`}:{type:"text",value:`No existe el agente ${g.provider}/${g.name}.`}}catch(e){return{type:"text",value:`No se pudo actualizar el rol: ${e instanceof Error?e.message:String(e)}`}}const $=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("set-orchestrator"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim(),a=function(e){if(!e)return null;switch(e.trim().toLowerCase()){case"true":case"1":case"yes":case"y":case"si":case"s":case"on":return!0;case"false":case"0":case"no":case"n":case"off":return!1;default:return null}}(r[3]);return t&&o&&null!==a?{provider:t,name:o,isOrchestrator:a}:null}(i);if($){const e=await u($.provider,$.name,$.isOrchestrator);return e?{type:"text",value:`Orquestador actualizado para ${e.provider}/${e.name}: ${e.isOrchestrator?"true":"false"}`}:{type:"text",value:`No existe el agente ${$.provider}/${$.name}.`}}const y=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("set-model"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim();return t&&o&&0!==r.slice(3).length?{provider:t,name:o,model:function(e){const r=e.join(" ").trim();return r?["clear","default","reset","none"].includes(r.toLowerCase())?null:r:null}(r.slice(3))}:null}(i);if(y)try{const e=await l(y.provider,y.name,y.model);return e?{type:"text",value:e.modelOverride?`Modelo actualizado para ${e.provider}/${e.name}: ${e.modelOverride}`:`Modelo limpiado para ${e.provider}/${e.name}`}:{type:"text",value:`No existe el agente ${y.provider}/${y.name}.`}}catch(e){return{type:"text",value:`No se pudo actualizar el modelo: ${e instanceof Error?e.message:String(e)}`}}return{type:"text",value:["Uso: /agent, /agent list [proveedor], /agent create <proveedor> <name> [profile],","/agent setup <proveedor> [model] [profile],","/agent show <proveedor> <name>, /agent delete <proveedor> <name>, /agent set-role <proveedor> <name> <role>,","/agent set-orchestrator <proveedor> <name> <true|false>, /agent set-model <proveedor> <name> <model|clear>"].join(" ")}};
1
+ import{getVisibleProvider as e}from"../../utils/model/providerCatalog.js";import{buildAgentDetailMessage as r,buildAgentSummary as t,createAgent as o,deleteAgent as a,getAgent as n,isKnownAgentProvider as i,listAgents as s,setAgentModelByName as l,setAgentOrchestratorByName as u,setAgentRoleByName as c}from"./agentStore.js";function parseProvider(e){const r=function(e){if(!e)return null;switch(e.trim().toLowerCase()){case"z.ai":case"z-ai":return"zai";case"open-router":return"openrouter";case"ollama-cloud":case"ollama_cloud":case"ollamacloud":return"ollama-cloud";case"lm-studio":case"lm_studio":case"lmstudio":return"lmstudio";case"gemini":case"gemini-api-key":case"google-ai":return"gemini-api";case"gemini-google":case"google":case"google-oauth":return"gemini-google";default:return e.trim().toLowerCase()}}(e);return r&&i(r)?r:null}function getProviderLabel(r){return e(r).label}async function buildListMessageAsync(e){const r=await s(e);if(0===r.length)return e?`No hay agentes guardados para ${getProviderLabel(e)}.`:"No hay agentes guardados.";const o=[],a=e?[[e,r]]:Array.from(r.reduce((e,r)=>{const t=e.get(r.provider)??[];return t.push(r),e.set(r.provider,t),e},new Map));for(const[r,n]of a){e||o.push(""),o.push(`${getProviderLabel(r)}:`);for(const e of n)o.push(t(e))}return o.join("\n").trimStart()}const d=[{name:"orchestrator",role:"orchestrator",isOrchestrator:!0},{name:"backend",role:"backend",isOrchestrator:!1},{name:"frontend",role:"frontend",isOrchestrator:!1},{name:"qa",role:"qa",isOrchestrator:!1}];async function bootstrapProviderAgents(e){const r=[];for(const t of d){const a=await n(e.provider,t.name),i=a??await o({provider:e.provider,name:t.name,profileName:e.profileName}),s=await c(e.provider,i.name,t.role),d=await u(e.provider,i.name,t.isOrchestrator),p=await l(e.provider,i.name,e.model);r.push(`${a?"actualizado":"creado"} ${e.provider}/${i.name} role=${s?.roleKind??t.role} orchestrator=${d?.isOrchestrator?"true":"false"} model=${p?.modelOverride??"sin override"}`)}return[`Setup completado para ${getProviderLabel(e.provider)} (${d.length} agentes):`,...r].join("\n")}export const call=async(e,t)=>{const i=e.trim();if(!i||"list"===i.toLowerCase())return{type:"text",value:await buildListMessageAsync()};const s=i.split(/\s+/).filter(Boolean),d=s[0]?.toLowerCase();if("list"===d){const e=parseProvider(s[1]);return s[1]&&!e?{type:"text",value:`Proveedor invalido: ${s[1]}`}:{type:"text",value:await buildListMessageAsync(e??void 0)}}const p=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("create"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]);if(!t)return null;const o=r[2]?.trim();return o?{provider:t,name:o,profileName:r.slice(3).join(" ").trim()||void 0}:null}(i);if(p)try{const e=await n(p.provider,p.name);if(e)return{type:"text",value:`El agente ya existe: ${e.provider}/${e.name}`};const r=await o(p);return{type:"text",value:`Agente creado: ${r.provider}/${r.name}\nPerfil vinculado: ${r.profile?`${r.profile.provider}/${r.profile.name}`:"sin perfil"}`}}catch(e){return{type:"text",value:`No se pudo crear el agente: ${e instanceof Error?e.message:String(e)}`}}const m=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("setup"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]);if(!t)return null;const o=r[2],a=r.slice(3).join(" ").trim();return{provider:t,model:o&&!["-","none","clear"].includes(o.toLowerCase())?o.trim():null,profileName:a||void 0}}(i);if(m)try{return{type:"text",value:await bootstrapProviderAgents(m)}}catch(e){return{type:"text",value:`No se pudo ejecutar setup: ${e instanceof Error?e.message:String(e)}`}}const v=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("show"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim();return t&&o?{provider:t,name:o}:null}(i);if(v){const e=await n(v.provider,v.name);return e?{type:"text",value:r(e)}:{type:"text",value:`No existe el agente ${v.provider}/${v.name}.`}}const f=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("delete"!==r[0]?.toLowerCase()&&"remove"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim();return t&&o?{provider:t,name:o}:null}(i);if(f){return await a(f.provider,f.name)?{type:"text",value:`Agente eliminado: ${f.provider}/${f.name}`}:{type:"text",value:`No existe el agente ${f.provider}/${f.name}.`}}const g=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("set-role"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim(),a=r.slice(3).join(" ").trim();return t&&o&&a?{provider:t,name:o,role:a}:null}(i);if(g)try{const e=await c(g.provider,g.name,g.role);return e?{type:"text",value:`Rol actualizado para ${e.provider}/${e.name}: ${e.roleKind??"worker"}`}:{type:"text",value:`No existe el agente ${g.provider}/${g.name}.`}}catch(e){return{type:"text",value:`No se pudo actualizar el rol: ${e instanceof Error?e.message:String(e)}`}}const $=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("set-orchestrator"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim(),a=function(e){if(!e)return null;switch(e.trim().toLowerCase()){case"true":case"1":case"yes":case"y":case"si":case"s":case"on":return!0;case"false":case"0":case"no":case"n":case"off":return!1;default:return null}}(r[3]);return t&&o&&null!==a?{provider:t,name:o,isOrchestrator:a}:null}(i);if($){const e=await u($.provider,$.name,$.isOrchestrator);return e?{type:"text",value:`Orquestador actualizado para ${e.provider}/${e.name}: ${e.isOrchestrator?"true":"false"}`}:{type:"text",value:`No existe el agente ${$.provider}/${$.name}.`}}const y=function(e){const r=e.trim().split(/\s+/).filter(Boolean);if("set-model"!==r[0]?.toLowerCase())return null;const t=parseProvider(r[1]),o=r[2]?.trim();return t&&o&&0!==r.slice(3).length?{provider:t,name:o,model:function(e){const r=e.join(" ").trim();return r?["clear","default","reset","none"].includes(r.toLowerCase())?null:r:null}(r.slice(3))}:null}(i);if(y)try{const e=await l(y.provider,y.name,y.model);return e?{type:"text",value:e.modelOverride?`Modelo actualizado para ${e.provider}/${e.name}: ${e.modelOverride}`:`Modelo limpiado para ${e.provider}/${e.name}`}:{type:"text",value:`No existe el agente ${y.provider}/${y.name}.`}}catch(e){return{type:"text",value:`No se pudo actualizar el modelo: ${e instanceof Error?e.message:String(e)}`}}return{type:"text",value:["Uso: /agent, /agent list [proveedor], /agent create <proveedor> <name> [profile],","/agent setup <proveedor> [model] [profile],","/agent show <proveedor> <name>, /agent delete <proveedor> <name>, /agent set-role <proveedor> <name> <role>,","/agent set-orchestrator <proveedor> <name> <true|false>, /agent set-model <proveedor> <name> <model|clear>"].join(" ")}};
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import{jsx as r}from"react/jsx-runtime";import{resetCostState as o}from"../../bootstrap/state.js";import{clearTrustedDeviceToken as t,enrollTrustedDevice as i}from"../../bridge/trustedDevice.js";import{ConsoleOAuthFlow as n}from"../../components/ConsoleOAuthFlow.js";import{useKeybinding as a}from"../../keybindings/useKeybinding.js";import{useMainLoopModel as s}from"../../hooks/useMainLoopModel.js";import{Box as m}from"../../ink.js";import{refreshGrowthBookAfterAuthChange as l}from"../../services/analytics/growthbook.js";import{refreshPolicyLimits as d}from"../../services/policyLimits/index.js";import{refreshRemoteManagedSettings as c}from"../../services/remoteManagedSettings/index.js";import{stripSignatureBlocks as u}from"../../utils/messages.js";import{checkAndDisableAutoModeIfNeeded as p,checkAndDisableBypassPermissionsIfNeeded as g,resetAutoModeGateCheck as P,resetBypassPermissionsCheck as f}from"../../utils/permissions/bypassPermissionsKillswitch.js";import{getAPIProvider as v}from"../../utils/model/providers.js";import{switchProviderPreference as M}from"../../utils/model/providerSwitch.js";import{resetUserCache as N}from"../../utils/user.js";import{applySuccessfulLogin as x,isCoreAuthEnabled as j,parseLoginProfileName as h}from"../../core/auth/loginCore.js";export async function call(n,a,s){const m=h(s);return r(Login,{profileName:m,onDone:async(r,s,v,h)=>{if(a.onChangeAPIKey(),a.setMessages(u),r){if(j()){const r=x({context:a,profileName:m,previousModel:s,previousProvider:v,targetProvider:h,transcriptClassifierEnabled:e("TRANSCRIPT_CLASSIFIER")});return r.shouldOpenModelPicker?void n(r.message,{nextInput:"/model",submitNextInput:!0}):void n(r.message)}const r="openai"===h?M({currentModel:s,currentProvider:v,targetProvider:"openai",targetProfileName:m}):"openrouter"===h?M({currentModel:s,currentProvider:v,targetProvider:"openrouter",targetProfileName:m}):"ollama"===h?M({currentModel:s,currentProvider:v,targetProvider:"ollama",targetProfileName:m}):"ollama-cloud"===h?M({currentModel:s,currentProvider:v,targetProvider:"ollama-cloud",targetProfileName:m}):"gemini-api"===h?M({currentModel:s,currentProvider:v,targetProvider:"gemini-api",targetProfileName:m}):"gemini-google"===h?M({currentModel:s,currentProvider:v,targetProvider:"gemini-google",targetProfileName:m}):"zai"===h?M({currentModel:s,currentProvider:v,targetProvider:"zai",targetProfileName:m}):"minimax"===h?M({currentModel:s,currentProvider:v,targetProvider:"minimax",targetProfileName:m}):"nvidia"===h?M({currentModel:s,currentProvider:v,targetProvider:"nvidia",targetProfileName:m}):"deepseek"===h?M({currentModel:s,currentProvider:v,targetProvider:"deepseek",targetProfileName:m}):"custom-openai"===h?M({currentModel:s,currentProvider:v,targetProvider:"custom-openai",targetProfileName:m}):"custom-anthropic"===h?M({currentModel:s,currentProvider:v,targetProvider:"custom-anthropic",targetProfileName:m}):h&&["xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"].includes(h)?M({currentModel:s,currentProvider:v,targetProvider:h,targetProfileName:m}):M({currentModel:s,currentProvider:v,targetProvider:"claude",targetProfileName:m});o(),c(),d(),N(),l(),t(),i(),f();const u=a.getAppState();if(g(u.toolPermissionContext,a.setAppState),e("TRANSCRIPT_CLASSIFIER")&&(P(),p(u.toolPermissionContext,a.setAppState,u.fastMode)),a.setAppState(e=>({...e,mainLoopModel:r,mainLoopModelForSession:r,authVersion:e.authVersion+1})),!r)return void n(m?`Inicio de sesion exitoso en el perfil "${m}". Selecciona ahora el modelo para este perfil.`:"Inicio de sesion exitoso. Selecciona ahora el modelo para este perfil.",{nextInput:"/model",submitNextInput:!0})}n(r?"Inicio de sesión exitoso":"Acceso interrumpido")}})}export function Login(e){const o=s(),t=v();return a("confirm:no",()=>e.onDone(!1,o,t),{context:"Confirmation"}),r(m,{flexDirection:"column",gap:1,children:r(n,{onDone:r=>e.onDone(!0,o,t,r),startingMessage:e.startingMessage,profileName:e.profileName})})}
1
+ import{feature as e}from"../../recovery/bunBundleShim.js";import{jsx as r}from"react/jsx-runtime";import{resetCostState as o}from"../../bootstrap/state.js";import{clearTrustedDeviceToken as t,enrollTrustedDevice as i}from"../../bridge/trustedDevice.js";import{ConsoleOAuthFlow as n}from"../../components/ConsoleOAuthFlow.js";import{useKeybinding as a}from"../../keybindings/useKeybinding.js";import{useMainLoopModel as s}from"../../hooks/useMainLoopModel.js";import{Box as m}from"../../ink.js";import{refreshGrowthBookAfterAuthChange as l}from"../../services/analytics/growthbook.js";import{refreshPolicyLimits as d}from"../../services/policyLimits/index.js";import{refreshRemoteManagedSettings as c}from"../../services/remoteManagedSettings/index.js";import{stripSignatureBlocks as u}from"../../utils/messages.js";import{checkAndDisableAutoModeIfNeeded as p,checkAndDisableBypassPermissionsIfNeeded as g,resetAutoModeGateCheck as P,resetBypassPermissionsCheck as f}from"../../utils/permissions/bypassPermissionsKillswitch.js";import{getAPIProvider as v}from"../../utils/model/providers.js";import{switchProviderPreference as M}from"../../utils/model/providerSwitch.js";import{resetUserCache as N}from"../../utils/user.js";import{applySuccessfulLogin as x,isCoreAuthEnabled as j,parseLoginProfileName as h}from"../../core/auth/loginCore.js";export async function call(n,a,s){const m=h(s);return r(Login,{profileName:m,onDone:async(r,s,v,h)=>{if(a.onChangeAPIKey(),a.setMessages(u),r){if(j()){const r=x({context:a,profileName:m,previousModel:s,previousProvider:v,targetProvider:h,transcriptClassifierEnabled:e("TRANSCRIPT_CLASSIFIER")});return r.shouldOpenModelPicker?void n(r.message,{nextInput:"/model",submitNextInput:!0}):void n(r.message)}const r="openai"===h?M({currentModel:s,currentProvider:v,targetProvider:"openai",targetProfileName:m}):"openrouter"===h?M({currentModel:s,currentProvider:v,targetProvider:"openrouter",targetProfileName:m}):"ollama"===h?M({currentModel:s,currentProvider:v,targetProvider:"ollama",targetProfileName:m}):"ollama-cloud"===h?M({currentModel:s,currentProvider:v,targetProvider:"ollama-cloud",targetProfileName:m}):"lmstudio"===h?M({currentModel:s,currentProvider:v,targetProvider:"lmstudio",targetProfileName:m}):"gemini-api"===h?M({currentModel:s,currentProvider:v,targetProvider:"gemini-api",targetProfileName:m}):"gemini-google"===h?M({currentModel:s,currentProvider:v,targetProvider:"gemini-google",targetProfileName:m}):"zai"===h?M({currentModel:s,currentProvider:v,targetProvider:"zai",targetProfileName:m}):"minimax"===h?M({currentModel:s,currentProvider:v,targetProvider:"minimax",targetProfileName:m}):"nvidia"===h?M({currentModel:s,currentProvider:v,targetProvider:"nvidia",targetProfileName:m}):"deepseek"===h?M({currentModel:s,currentProvider:v,targetProvider:"deepseek",targetProfileName:m}):"custom-openai"===h?M({currentModel:s,currentProvider:v,targetProvider:"custom-openai",targetProfileName:m}):"custom-anthropic"===h?M({currentModel:s,currentProvider:v,targetProvider:"custom-anthropic",targetProfileName:m}):h&&["xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"].includes(h)?M({currentModel:s,currentProvider:v,targetProvider:h,targetProfileName:m}):M({currentModel:s,currentProvider:v,targetProvider:"claude",targetProfileName:m});o(),c(),d(),N(),l(),t(),i(),f();const u=a.getAppState();if(g(u.toolPermissionContext,a.setAppState),e("TRANSCRIPT_CLASSIFIER")&&(P(),p(u.toolPermissionContext,a.setAppState,u.fastMode)),a.setAppState(e=>({...e,mainLoopModel:r,mainLoopModelForSession:r,authVersion:e.authVersion+1})),!r)return void n(m?`Inicio de sesion exitoso en el perfil "${m}". Selecciona ahora el modelo para este perfil.`:"Inicio de sesion exitoso. Selecciona ahora el modelo para este perfil.",{nextInput:"/model",submitNextInput:!0})}n(r?"Inicio de sesión exitoso":"Acceso interrumpido")}})}export function Login(e){const o=s(),t=v();return a("confirm:no",()=>e.onDone(!1,o,t),{context:"Confirmation"}),r(m,{flexDirection:"column",gap:1,children:r(n,{onDone:r=>e.onDone(!0,o,t,r),startingMessage:e.startingMessage,profileName:e.profileName})})}
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as o from"react";import{Box as i,Text as n,useInput as l}from"../../ink.js";import{Dialog as t}from"../../components/design-system/Dialog.js";import{useMainLoopModel as a}from"../../hooks/useMainLoopModel.js";import{useSetAppState as s}from"../../state/AppState.js";import{getAPIProvider as c}from"../../utils/model/providers.js";import{finalizeProviderProfilesMigration as u,getProviderProfilesDbPath as d,getProviderProfilesStorageBackend as f,getProviderProfilesStorageMode as m,purgeLegacyProviderStateInConfig as p,setStoredActiveProviderPreference as v}from"../../utils/model/providerProfilesDb.js";import{clearAllProviderProfiles as g,createProviderProfile as $,findProviderProfileByName as N,getActiveProviderProfile as P,getLastUsedProviderProfile as h,getProviderProfile as L,isProfiledProvider as w,listProviderProfiles as C,removeProviderProfile as j,renameProviderProfile as y,setActiveProviderProfile as S,setProviderProfileAgentNameByName as b,setProviderProfileLastModelByName as x}from"../../utils/model/providerProfiles.js";import{fetchProviderModels as M}from"../../utils/model/providerModels.js";import{VISIBLE_PROVIDERS as A}from"../../utils/model/providerCatalog.js";import{switchProviderPreference as E}from"../../utils/model/providerSwitch.js";import{removeAllProviderScopedCredentials as B,removeProviderScopedCredentials as I,renameProviderScopedCredentials as z}from"../../utils/auth.js";import{clearAuthRelatedCaches as D}from"../logout/logout.js";import{getSecureStorage as U}from"../../utils/secureStorage/index.js";import{getLegacyCredentialsFilePath as q,getSecureStorageDbPath as k,getSecureStorageKeyPath as K,hasLegacyCredentialsFile as Q,isSecureStorageEncrypted as R}from"../../utils/secureStorage/sqliteStorage.js";function normalizeProviderInput(e){if(e)switch(e.trim().toLowerCase()){case"z.ai":case"z-ai":return"zai";case"open-router":return"openrouter";case"ollama-cloud":case"ollama_cloud":case"ollamacloud":return"ollama-cloud";case"gemini":case"gemini-api-key":case"google-ai":return"gemini-api";case"gemini-google":case"google":case"google-oauth":return"gemini-google";default:return e.trim().toLowerCase()}}function getProviderLabel(e){return A.find(r=>r.id===e)?.label??e}function formatProfileLine(e,r){const o=L(r);if(!o)return null;const i=P(),n=h(e),l=[i?.id===o.id?"active":null,n?.id===o.id?"last":null].filter(Boolean),t=l.length>0?` [${l.join(", ")}]`:"",a=[`agent=${o.agentName}`,o.baseUrl?`url=${o.baseUrl}`:null,o.lastModel?`model=${o.lastModel}`:null].filter(Boolean).join(" | ");return`- ${o.provider}/${o.name}${t}${a?` -> ${a}`:""}`}function getProviderStorageModeLabel(){const e=f(),r=m();return"sqlite"!==e?"Legacy fallback":"sqlite-only"===r?"SQLite-only":"SQLite (migracion pendiente)"}function reconcileActiveProviderProfileState(){const e=P();if(e)return void v(e.provider);const r=C()[0];r?(S(r.id),v(r.provider)):v(null)}function RemoveAllProfilesConfirmation({onDone:a,context:s}){const[c,u]=o.useState(!1);return l((e,r)=>{if(!c)return"y"===e||"Y"===e?(u(!0),void async function(e,r){try{const o=g();reconcileActiveProviderProfileState(),await B(),await D(),r.onChangeAPIKey(),e(o.length>0?`Se eliminaron todos los perfiles guardados (${o.length}).`:"No habia perfiles guardados para eliminar.")}catch(r){e(`No se pudieron eliminar todos los perfiles: ${r instanceof Error?r.message:String(r)}`)}}(a,s)):void(("n"===e||"N"===e||r.escape)&&a("Eliminacion de perfiles cancelada."))},{isActive:!0}),e(t,{title:"Eliminar todos los perfiles",subtitle:"Esta accion elimina todos los perfiles guardados y sus credenciales asociadas por perfil.",onCancel:()=>{c||a("Eliminacion de perfiles cancelada.")},color:"error",inputGuide:()=>e(n,{children:"y: confirmar eliminacion total · n/Esc: cancelar"}),children:r(i,{flexDirection:"column",children:[e(n,{children:"Se borraran todos los perfiles persistidos de proveedores."}),e(n,{dimColor:!0,children:"Los fallbacks legacy de compatibilidad no se eliminan con este comando."}),c?e(n,{children:"Eliminando perfiles..."}):null]})})}function SwitchProfileOnMount({onDone:e,context:r,provider:i,profileName:n}){const l=a(),t=s();return o.useEffect(()=>{(async()=>{try{const o=E({currentModel:l,currentProvider:c(),targetProvider:i,targetProfileName:n});await D(),r.onChangeAPIKey(),t(e=>({...e,mainLoopModel:o,mainLoopModelForSession:null}));const a=h(i);e(o?`Perfil activo cambiado a ${i}/${a?.name??n} - modelo restaurado: ${o}`:`Perfil activo cambiado a ${i}/${a?.name??n}`)}catch(r){const o=r instanceof Error?r.message:String(r);e(`No se pudo activar el perfil: ${o}`)}})()},[r,l,e,n,i,t]),null}export async function call(r,o,i){const n=i?.trim();if(!n||"list"===n.toLowerCase())return r(function(){const e=A.map(e=>e.id).filter(w),r=[],o=P();r.push(o?`Perfil activo: ${o.provider}/${o.name} (${o.agentName})`:"Perfil activo: ninguno");for(const o of e){const e=C(o);if(r.push(""),r.push(`${getProviderLabel(o)}:`),0!==e.length)for(const i of e){const e=formatProfileLine(o,i.id);e&&r.push(e)}else r.push("- sin perfiles guardados")}return r.join("\n")}()),null;if("current"===n.toLowerCase())return r(function(){const e=P();return e?[`Proveedor: ${getProviderLabel(e.provider)}`,`Perfil: ${e.name}`,`AgentName: ${e.agentName}`,e.baseUrl?`Base URL: ${e.baseUrl}`:null,e.lastModel?`Ultimo modelo: ${e.lastModel}`:null].filter(Boolean).join("\n"):"No hay perfil activo."}()),null;if(function(e){if(!e)return!1;const r=e.trim().toLowerCase();return"migrate"===r||"migrar"===r||"finalize-migration"===r||"finalizar-migracion"===r}(n))return r(function(){const e=U();try{u()}catch{p()}"sqlite"===e.name&&e.read();const r=["Migracion revisada.",`Persistencia providers: ${getProviderStorageModeLabel()}`,`Provider DB: ${d()}`,`Credenciales providers: ${"sqlite"===e.name?"SQLite (cifrado local)":e.name}`];return"sqlite"===e.name&&(r.push(`Credenciales DB: ${k()}`),r.push(`Clave cifrado: ${K()}`),r.push("Estado cifrado credenciales: "+(R()?"Cifrado activo":"Sin payload o pendiente")),r.push("Legacy credentials file: "+(Q()?`Presente (${q()})`:"No presente"))),r.join("\n")}()),null;const l=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("create"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r.slice(2).join(" ").trim();return i?{provider:o,profileName:i}:null}(n);if(l){const e=N(l.provider,l.profileName);if(e)return r(`Ya existe el perfil ${e.provider}/${e.name}.`),null;const o=$({provider:l.provider,name:l.profileName});return reconcileActiveProviderProfileState(),r(`Perfil creado: ${o.provider}/${o.name}`),null}const t=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("use"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);return o&&w(o)?{provider:o,profileName:r.slice(2).join(" ").trim()||void 0}:null}(n);if(t)return e(SwitchProfileOnMount,{onDone:r,context:o,provider:t.provider,profileName:t.profileName});const a=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("rename"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r[2]?.trim(),n=r.slice(3).join(" ").trim();return i&&n?{provider:o,currentName:i,nextName:n}:null}(n);if(a){if(!N(a.provider,a.currentName))return r(`No existe el perfil ${a.provider}/${a.currentName}.`),null;try{const e=y(a.provider,a.currentName,a.nextName);if(!e)return r(`No existe el perfil ${a.provider}/${a.currentName}.`),null;await z(e.previousId,e.profile.id),await D(),o.onChangeAPIKey(),r(`Perfil renombrado: ${a.provider}/${a.currentName} -> ${e.profile.name}`)}catch(e){r(`No se pudo renombrar el perfil: ${e instanceof Error?e.message:String(e)}`)}return null}const s=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("remove"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r.slice(2).join(" ").trim();return i?{provider:o,profileName:i}:null}(n);if(s){if(!N(s.provider,s.profileName))return r(`No existe el perfil ${s.provider}/${s.profileName}.`),null;try{const e=j(s.provider,s.profileName);if(!e)return r(`No existe el perfil ${s.provider}/${s.profileName}.`),null;await I(e.id),reconcileActiveProviderProfileState(),await D(),o.onChangeAPIKey(),r(`Perfil eliminado: ${e.provider}/${e.name}`)}catch(e){r(`No se pudo eliminar el perfil: ${e instanceof Error?e.message:String(e)}`)}return null}if(function(e){if(!e)return!1;const r=e.trim().split(/\s+/).filter(Boolean),o=r[0]?.toLowerCase(),i=r[1]?.toLowerCase();return"remove"===o&&"all"===i&&2===r.length||"clear-all"===o&&1===r.length||"clear"===o&&1===r.length||"clear"===o&&"all"===i&&2===r.length}(n))return e(RemoveAllProfilesConfirmation,{onDone:r,context:o});const f=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("model"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r[2]?.trim(),n=r.slice(3).join(" ").trim();return i&&n?{provider:o,profileName:i,model:["clear","default","reset","none"].includes(n.toLowerCase())?null:n}:null}(n);if(f){if(!N(f.provider,f.profileName))return r(`No existe el perfil ${f.provider}/${f.profileName}.`),null;const e=await async function(e,r){if(!r||"claude"===e)return{valid:!0};const o=await M(e);if(0===o.length)return{valid:!0,warning:`No se pudo validar el catálogo de ${getProviderLabel(e)}. El modelo se guardó sin validación remota.`};const i=r.toLowerCase();return o.some(e=>e.value.toLowerCase()===i||e.label.toLowerCase()===i)?{valid:!0}:{valid:!1,error:`El modelo '${r}' no pertenece al catálogo actual de ${getProviderLabel(e)}.`}}(f.provider,f.model);if(!e.valid)return r(e.error),null;const i=x(f.provider,f.profileName,f.model);if(!i)return r(`No existe el perfil ${f.provider}/${f.profileName}.`),null;const n=P();return n?.id===i.id&&c()===i.provider&&(await D(),o.onChangeAPIKey()),r(f.model?`${e.warning?`${e.warning} `:""}Modelo guardado para ${i.provider}/${i.name}: ${f.model}`:`Modelo limpiado para ${i.provider}/${i.name}`),null}const m=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("agent"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r[2]?.trim(),n=r.slice(3).join(" ").trim();return i&&n?{provider:o,profileName:i,agentName:n}:null}(n);if(m){if(!N(m.provider,m.profileName))return r(`No existe el perfil ${m.provider}/${m.profileName}.`),null;try{const e=b(m.provider,m.profileName,m.agentName);if(!e)return r(`No existe el perfil ${m.provider}/${m.profileName}.`),null;r(`AgentName guardado para ${e.provider}/${e.name}: ${e.agentName}`)}catch(e){r(`No se pudo guardar el agentName: ${e instanceof Error?e.message:String(e)}`)}return null}return r("Uso: /perfil, /perfil list, /perfil current, /perfil migrate, /perfil create <proveedor> <perfil>, /perfil use <proveedor> [perfil], /perfil rename <proveedor> <actual> <nuevo>, /perfil remove <proveedor> <perfil>, /perfil remove all, /perfil clear, /perfil clear all, /perfil model <proveedor> <perfil> <modelo|clear>, /perfil agent <proveedor> <perfil> <agentName>"),null}
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as o from"react";import{Box as i,Text as n,useInput as l}from"../../ink.js";import{Dialog as t}from"../../components/design-system/Dialog.js";import{useMainLoopModel as a}from"../../hooks/useMainLoopModel.js";import{useSetAppState as s}from"../../state/AppState.js";import{getAPIProvider as c}from"../../utils/model/providers.js";import{finalizeProviderProfilesMigration as u,getProviderProfilesDbPath as d,getProviderProfilesStorageBackend as f,getProviderProfilesStorageMode as m,purgeLegacyProviderStateInConfig as p,setStoredActiveProviderPreference as v}from"../../utils/model/providerProfilesDb.js";import{clearAllProviderProfiles as g,createProviderProfile as $,findProviderProfileByName as N,getActiveProviderProfile as P,getLastUsedProviderProfile as h,getProviderProfile as L,isProfiledProvider as w,listProviderProfiles as C,removeProviderProfile as j,renameProviderProfile as y,setActiveProviderProfile as S,setProviderProfileAgentNameByName as b,setProviderProfileLastModelByName as x}from"../../utils/model/providerProfiles.js";import{fetchProviderModels as M}from"../../utils/model/providerModels.js";import{VISIBLE_PROVIDERS as A}from"../../utils/model/providerCatalog.js";import{switchProviderPreference as E}from"../../utils/model/providerSwitch.js";import{removeAllProviderScopedCredentials as B,removeProviderScopedCredentials as I,renameProviderScopedCredentials as z}from"../../utils/auth.js";import{clearAuthRelatedCaches as D}from"../logout/logout.js";import{getSecureStorage as U}from"../../utils/secureStorage/index.js";import{getLegacyCredentialsFilePath as q,getSecureStorageDbPath as k,getSecureStorageKeyPath as K,hasLegacyCredentialsFile as Q,isSecureStorageEncrypted as R}from"../../utils/secureStorage/sqliteStorage.js";function normalizeProviderInput(e){if(e)switch(e.trim().toLowerCase()){case"z.ai":case"z-ai":return"zai";case"open-router":return"openrouter";case"ollama-cloud":case"ollama_cloud":case"ollamacloud":return"ollama-cloud";case"lm-studio":case"lm_studio":case"lmstudio":return"lmstudio";case"gemini":case"gemini-api-key":case"google-ai":return"gemini-api";case"gemini-google":case"google":case"google-oauth":return"gemini-google";default:return e.trim().toLowerCase()}}function getProviderLabel(e){return A.find(r=>r.id===e)?.label??e}function formatProfileLine(e,r){const o=L(r);if(!o)return null;const i=P(),n=h(e),l=[i?.id===o.id?"active":null,n?.id===o.id?"last":null].filter(Boolean),t=l.length>0?` [${l.join(", ")}]`:"",a=[`agent=${o.agentName}`,o.baseUrl?`url=${o.baseUrl}`:null,o.lastModel?`model=${o.lastModel}`:null].filter(Boolean).join(" | ");return`- ${o.provider}/${o.name}${t}${a?` -> ${a}`:""}`}function getProviderStorageModeLabel(){const e=f(),r=m();return"sqlite"!==e?"Legacy fallback":"sqlite-only"===r?"SQLite-only":"SQLite (migracion pendiente)"}function reconcileActiveProviderProfileState(){const e=P();if(e)return void v(e.provider);const r=C()[0];r?(S(r.id),v(r.provider)):v(null)}function RemoveAllProfilesConfirmation({onDone:a,context:s}){const[c,u]=o.useState(!1);return l((e,r)=>{if(!c)return"y"===e||"Y"===e?(u(!0),void async function(e,r){try{const o=g();reconcileActiveProviderProfileState(),await B(),await D(),r.onChangeAPIKey(),e(o.length>0?`Se eliminaron todos los perfiles guardados (${o.length}).`:"No habia perfiles guardados para eliminar.")}catch(r){e(`No se pudieron eliminar todos los perfiles: ${r instanceof Error?r.message:String(r)}`)}}(a,s)):void(("n"===e||"N"===e||r.escape)&&a("Eliminacion de perfiles cancelada."))},{isActive:!0}),e(t,{title:"Eliminar todos los perfiles",subtitle:"Esta accion elimina todos los perfiles guardados y sus credenciales asociadas por perfil.",onCancel:()=>{c||a("Eliminacion de perfiles cancelada.")},color:"error",inputGuide:()=>e(n,{children:"y: confirmar eliminacion total · n/Esc: cancelar"}),children:r(i,{flexDirection:"column",children:[e(n,{children:"Se borraran todos los perfiles persistidos de proveedores."}),e(n,{dimColor:!0,children:"Los fallbacks legacy de compatibilidad no se eliminan con este comando."}),c?e(n,{children:"Eliminando perfiles..."}):null]})})}function SwitchProfileOnMount({onDone:e,context:r,provider:i,profileName:n}){const l=a(),t=s();return o.useEffect(()=>{(async()=>{try{const o=E({currentModel:l,currentProvider:c(),targetProvider:i,targetProfileName:n});await D(),r.onChangeAPIKey(),t(e=>({...e,mainLoopModel:o,mainLoopModelForSession:null}));const a=h(i);e(o?`Perfil activo cambiado a ${i}/${a?.name??n} - modelo restaurado: ${o}`:`Perfil activo cambiado a ${i}/${a?.name??n}`)}catch(r){const o=r instanceof Error?r.message:String(r);e(`No se pudo activar el perfil: ${o}`)}})()},[r,l,e,n,i,t]),null}export async function call(r,o,i){const n=i?.trim();if(!n||"list"===n.toLowerCase())return r(function(){const e=A.map(e=>e.id).filter(w),r=[],o=P();r.push(o?`Perfil activo: ${o.provider}/${o.name} (${o.agentName})`:"Perfil activo: ninguno");for(const o of e){const e=C(o);if(r.push(""),r.push(`${getProviderLabel(o)}:`),0!==e.length)for(const i of e){const e=formatProfileLine(o,i.id);e&&r.push(e)}else r.push("- sin perfiles guardados")}return r.join("\n")}()),null;if("current"===n.toLowerCase())return r(function(){const e=P();return e?[`Proveedor: ${getProviderLabel(e.provider)}`,`Perfil: ${e.name}`,`AgentName: ${e.agentName}`,e.baseUrl?`Base URL: ${e.baseUrl}`:null,e.lastModel?`Ultimo modelo: ${e.lastModel}`:null].filter(Boolean).join("\n"):"No hay perfil activo."}()),null;if(function(e){if(!e)return!1;const r=e.trim().toLowerCase();return"migrate"===r||"migrar"===r||"finalize-migration"===r||"finalizar-migracion"===r}(n))return r(function(){const e=U();try{u()}catch{p()}"sqlite"===e.name&&e.read();const r=["Migracion revisada.",`Persistencia providers: ${getProviderStorageModeLabel()}`,`Provider DB: ${d()}`,`Credenciales providers: ${"sqlite"===e.name?"SQLite (cifrado local)":e.name}`];return"sqlite"===e.name&&(r.push(`Credenciales DB: ${k()}`),r.push(`Clave cifrado: ${K()}`),r.push("Estado cifrado credenciales: "+(R()?"Cifrado activo":"Sin payload o pendiente")),r.push("Legacy credentials file: "+(Q()?`Presente (${q()})`:"No presente"))),r.join("\n")}()),null;const l=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("create"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r.slice(2).join(" ").trim();return i?{provider:o,profileName:i}:null}(n);if(l){const e=N(l.provider,l.profileName);if(e)return r(`Ya existe el perfil ${e.provider}/${e.name}.`),null;const o=$({provider:l.provider,name:l.profileName});return reconcileActiveProviderProfileState(),r(`Perfil creado: ${o.provider}/${o.name}`),null}const t=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("use"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);return o&&w(o)?{provider:o,profileName:r.slice(2).join(" ").trim()||void 0}:null}(n);if(t)return e(SwitchProfileOnMount,{onDone:r,context:o,provider:t.provider,profileName:t.profileName});const a=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("rename"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r[2]?.trim(),n=r.slice(3).join(" ").trim();return i&&n?{provider:o,currentName:i,nextName:n}:null}(n);if(a){if(!N(a.provider,a.currentName))return r(`No existe el perfil ${a.provider}/${a.currentName}.`),null;try{const e=y(a.provider,a.currentName,a.nextName);if(!e)return r(`No existe el perfil ${a.provider}/${a.currentName}.`),null;await z(e.previousId,e.profile.id),await D(),o.onChangeAPIKey(),r(`Perfil renombrado: ${a.provider}/${a.currentName} -> ${e.profile.name}`)}catch(e){r(`No se pudo renombrar el perfil: ${e instanceof Error?e.message:String(e)}`)}return null}const s=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("remove"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r.slice(2).join(" ").trim();return i?{provider:o,profileName:i}:null}(n);if(s){if(!N(s.provider,s.profileName))return r(`No existe el perfil ${s.provider}/${s.profileName}.`),null;try{const e=j(s.provider,s.profileName);if(!e)return r(`No existe el perfil ${s.provider}/${s.profileName}.`),null;await I(e.id),reconcileActiveProviderProfileState(),await D(),o.onChangeAPIKey(),r(`Perfil eliminado: ${e.provider}/${e.name}`)}catch(e){r(`No se pudo eliminar el perfil: ${e instanceof Error?e.message:String(e)}`)}return null}if(function(e){if(!e)return!1;const r=e.trim().split(/\s+/).filter(Boolean),o=r[0]?.toLowerCase(),i=r[1]?.toLowerCase();return"remove"===o&&"all"===i&&2===r.length||"clear-all"===o&&1===r.length||"clear"===o&&1===r.length||"clear"===o&&"all"===i&&2===r.length}(n))return e(RemoveAllProfilesConfirmation,{onDone:r,context:o});const f=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("model"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r[2]?.trim(),n=r.slice(3).join(" ").trim();return i&&n?{provider:o,profileName:i,model:["clear","default","reset","none"].includes(n.toLowerCase())?null:n}:null}(n);if(f){if(!N(f.provider,f.profileName))return r(`No existe el perfil ${f.provider}/${f.profileName}.`),null;const e=await async function(e,r){if(!r||"claude"===e)return{valid:!0};const o=await M(e);if(0===o.length)return{valid:!0,warning:`No se pudo validar el catálogo de ${getProviderLabel(e)}. El modelo se guardó sin validación remota.`};const i=r.toLowerCase();return o.some(e=>e.value.toLowerCase()===i||e.label.toLowerCase()===i)?{valid:!0}:{valid:!1,error:`El modelo '${r}' no pertenece al catálogo actual de ${getProviderLabel(e)}.`}}(f.provider,f.model);if(!e.valid)return r(e.error),null;const i=x(f.provider,f.profileName,f.model);if(!i)return r(`No existe el perfil ${f.provider}/${f.profileName}.`),null;const n=P();return n?.id===i.id&&c()===i.provider&&(await D(),o.onChangeAPIKey()),r(f.model?`${e.warning?`${e.warning} `:""}Modelo guardado para ${i.provider}/${i.name}: ${f.model}`:`Modelo limpiado para ${i.provider}/${i.name}`),null}const m=function(e){if(!e)return null;const r=e.trim().split(/\s+/).filter(Boolean);if("agent"!==r[0]?.toLowerCase())return null;const o=normalizeProviderInput(r[1]);if(!o||!w(o))return null;const i=r[2]?.trim(),n=r.slice(3).join(" ").trim();return i&&n?{provider:o,profileName:i,agentName:n}:null}(n);if(m){if(!N(m.provider,m.profileName))return r(`No existe el perfil ${m.provider}/${m.profileName}.`),null;try{const e=b(m.provider,m.profileName,m.agentName);if(!e)return r(`No existe el perfil ${m.provider}/${m.profileName}.`),null;r(`AgentName guardado para ${e.provider}/${e.name}: ${e.agentName}`)}catch(e){r(`No se pudo guardar el agentName: ${e instanceof Error?e.message:String(e)}`)}return null}return r("Uso: /perfil, /perfil list, /perfil current, /perfil migrate, /perfil create <proveedor> <perfil>, /perfil use <proveedor> [perfil], /perfil rename <proveedor> <actual> <nuevo>, /perfil remove <proveedor> <perfil>, /perfil remove all, /perfil clear, /perfil clear all, /perfil model <proveedor> <perfil> <modelo|clear>, /perfil agent <proveedor> <perfil> <agentName>"),null}
@@ -1 +1 @@
1
- export default{type:"local-jsx",name:"provider",aliases:["proveedor","proveedores"],description:"Cambiar entre proveedores y configurar endpoints sin cerrar sesion",argumentHint:"[list|current|clear all|claude|openai|openrouter|ollama|ollama-cloud|gemini-api|gemini-google|zai|minimax|nvidia|deepseek|custom-openai|custom-anthropic] [baseURL|clear]",isEnabled:()=>!0,load:()=>import("./provider.js")};
1
+ export default{type:"local-jsx",name:"provider",aliases:["proveedor","proveedores"],description:"Cambiar entre proveedores y configurar endpoints sin cerrar sesion",argumentHint:"[list|current|clear all|claude|openai|openrouter|ollama|ollama-cloud|lmstudio|gemini-api|gemini-google|zai|minimax|nvidia|deepseek|custom-openai|custom-anthropic] [baseURL|clear]",isEnabled:()=>!0,load:()=>import("./provider.js")};
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Select as o}from"../../components/CustomSelect/select.js";import*as a from"react";import{Box as i,Text as n,useInput as t}from"../../ink.js";import{Dialog as l}from"../../components/design-system/Dialog.js";import{useMainLoopModel as s}from"../../hooks/useMainLoopModel.js";import{useSetAppState as d}from"../../state/AppState.js";import{getStoredActiveProviderPreference as c,setStoredActiveProviderPreference as u}from"../../utils/model/providerProfilesDb.js";import{getCoreCurrentProviderProfile as p,getCoreProviderLabel as m,isCoreProviderEnabled as g,isCoreSelectedProfileReady as f,listCoreProviderProfiles as v,normalizeCoreProviderInput as b,setCoreActiveProfile as P,switchCoreProvider as h}from"../../core/providers/providerCore.js";import{getAPIProvider as y,isGeminiApiProviderConfigured as $,isGeminiGoogleProviderConfigured as C,isNvidiaProviderConfigured as U,isOllamaCloudProviderConfigured as L,isMiniMaxProviderConfigured as w,isOpenAIProviderConfigured as A,isOpenRouterProviderConfigured as I,isZAIProviderConfigured as E}from"../../utils/model/providers.js";import{clearProviderBaseUrl as k,getConfiguredProviderBaseUrl as x,getDefaultProviderBaseUrl as S,isProviderBaseUrlCustomized as M,setProviderBaseUrl as R}from"../../utils/model/providerBaseUrls.js";import{getVisibleProvider as j,VISIBLE_PROVIDERS as N}from"../../utils/model/providerCatalog.js";import{clearAllProviderProfiles as O,getActiveProviderProfile as D,getLastUsedProviderProfile as z,isProfiledProvider as B,listProviderProfiles as G,setActiveProfileForProvider as q,setActiveProviderProfile as T}from"../../utils/model/providerProfiles.js";import{switchProviderPreference as V}from"../../utils/model/providerSwitch.js";import{clearAuthRelatedCaches as W}from"../logout/logout.js";import{call as F}from"../login/login.js";import{call as K}from"../login-openai/login-openai.js";import Y from"chalk";import{getStoredProviderOAuthTokens as Z,hasStoredProviderApiKey as _,hasStoredProviderOAuthTokens as H,removeAllProviderScopedCredentials as J}from"../../utils/auth.js";const Q=["openrouter","ollama","ollama-cloud","gemini-api","gemini-google","zai","minimax","nvidia","deepseek","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi","custom-openai","custom-anthropic"];function isConfigurableBaseUrlProvider(e){return Q.includes(e)}function isProviderConfigured(e){return"claude"===e?H("claude"):"openai"===e?A():"openrouter"===e?I():"gemini-api"===e?$():"gemini-google"===e?C():"ollama"===e||("ollama-cloud"===e?L():"zai"===e?E():"minimax"===e?w():"nvidia"===e?U():_(e))}function getProviderLabel(e){return g()?m(e):j(e).label}function getCurrentProviderBaseUrl(e){return M(e)?x(e):S(e)}function getProviderSetupMessage(e){const r=getCurrentProviderBaseUrl(e);switch(e){case"ollama":return`Ollama usa un servidor local compatible. Endpoint actual: ${r}. Puedes cambiarlo con /provider ollama <baseURL> o restaurar el default con /provider ollama clear.`;case"ollama-cloud":return`Ollama Cloud usa por defecto tu host local autenticado. Endpoint actual: ${r}. Ejecuta 'ollama signin' y luego usa /provider ollama-cloud.`;case"gemini-api":return`Gemini API requiere una API key de Google AI Studio. Endpoint actual: ${r}. Usa /login para guardarla o /provider gemini-api <baseURL> para cambiar el endpoint.`;case"gemini-google":return`Gemini Google usa OAuth compatible con Gemini CLI. Endpoint actual: ${r}. Usa /login y elige Gemini Google para abrir el navegador y guardar el token.`;case"zai":return"Z.AI requiere una API key. Usa /login para guardarla y /provider zai <baseURL> para cambiar el endpoint si hace falta.";case"minimax":return"MiniMax requiere una API key. Usa /login para guardarla. El endpoint por defecto es Anthropic-compatible (https://api.minimax.io/anthropic) y puedes cambiarlo con /provider minimax <baseURL>.";case"nvidia":return"NVIDIA requiere una API key. Usa /login para guardarla. El endpoint por defecto es https://integrate.api.nvidia.com/v1 y puedes cambiarlo con /provider nvidia <baseURL>.";case"deepseek":return`DeepSeek requiere una API key. Usa /login para guardarla. Endpoint actual: ${r}. Puedes cambiarlo con /provider deepseek <baseURL>.`;case"custom-openai":return`Custom OpenAI usa un endpoint y API key personalizados. Endpoint actual: ${r}. Usa /login para configurarlo desde cero o /provider custom-openai <baseURL> para cambiar solo el endpoint.`;case"custom-anthropic":return`Custom Anthropic usa un endpoint y API key personalizados. Endpoint actual: ${r}. Usa /login para configurarlo desde cero o /provider custom-anthropic <baseURL> para cambiar solo el endpoint.`;default:if(["xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"].includes(e)){return`${getProviderLabel(e)} requiere una API key. Usa /login para guardarla y /provider ${e} <baseURL> para cambiar el endpoint si hace falta.`}return"OpenRouter requiere una API key. Usa /login para guardarla y /provider openrouter <baseURL> para cambiar el endpoint si hace falta."}}function isUrlLike(e){const r=e.toLowerCase();return!(!r.startsWith("http://")&&!r.startsWith("https://"))||(!!r.startsWith("localhost")||(/\.[a-z]{2,}/i.test(r)||/:\d+/.test(r)||/^(\d{1,3}\.){3}\d{1,3}/.test(r)))}async function switchProvider(e){const r=g()?h({currentModel:e.currentModel,currentProvider:e.currentProvider,targetProvider:e.target,targetProfileName:e.targetProfileName}).restoredModel:V({currentModel:e.currentModel,currentProvider:e.currentProvider,targetProvider:e.target,targetProfileName:e.targetProfileName});await W(),e.context.onChangeAPIKey();const o=B(e.target)&&z(e.target)?` · perfil ${z(e.target).name}`:"";return{message:r?`Proveedor cambiado a ${getProviderLabel(e.target)}${o} - modelo restaurado: ${r}`:`Proveedor cambiado a ${getProviderLabel(e.target)}${o} - cargando modelo predeterminado`,restoredModel:r}}function isSelectedProfileReady(e,r){if(g())return f(e,r);if(!r||!B(e))return!0;const o=z(e);return!!o&&("claude"===e?H("claude",o.id):"openai"===e?H("openai",o.id):"gemini-google"===e?C():"ollama"===e||"ollama-cloud"===e||_(e,o.id))}function RemoveAllProvidersConfirmation({onDone:o,context:s}){const[d,c]=a.useState(!1);return t((e,r)=>{if(!d)return"y"===e||"Y"===e?(c(!0),void async function(e,r){try{const o=O(),a=D();if(a)u(a.provider);else{const e=G()[0];e?(T(e.id),u(e.provider)):u(null)}await J(),await W(),r.onChangeAPIKey(),e(o.length>0?`Se eliminaron correctamente todos los perfiles (${o.length}) y credenciales de los proveedores de IA.`:"Se eliminaron correctamente todas las credenciales de proveedores. No habia perfiles guardados.")}catch(r){e(`No se pudieron eliminar las credenciales y perfiles de proveedores: ${r instanceof Error?r.message:String(r)}`)}}(o,s)):void(("n"===e||"N"===e||r.escape)&&o("Eliminacion de proveedores y credenciales cancelada."))},{isActive:!0}),e(l,{title:"Eliminar todos los proveedores y perfiles",subtitle:"Esta accion elimina todos los perfiles guardados, sus credenciales asociadas y limpia todas las API keys persistidas.",onCancel:()=>{d||o("Eliminacion de proveedores y credenciales cancelada.")},color:"error",inputGuide:()=>e(n,{children:"y: confirmar eliminacion total · n/Esc: cancelar"}),children:r(i,{flexDirection:"column",children:[e(n,{children:"Se borraran todas las credenciales (API keys / OAuth) y perfiles persistidos de todos los proveedores."}),e(n,{dimColor:!0,children:"Esta accion es irreversible y te desconectara de todos los servicios de IA."}),d?e(n,{children:"Eliminando configuraciones..."}):null]})})}export async function call(r,o,a){const i=a?.trim(),n=i?.split(/\s+/).filter(Boolean)??[],t=n[0]?.toLowerCase(),l=n[1]?.toLowerCase();if("clear"===t&&"all"===l&&2===n.length||"clear-all"===t&&1===n.length||"clear"===t&&1===n.length||"remove"===t&&"all"===l&&2===n.length)return e(RemoveAllProvidersConfirmation,{onDone:r,context:o});if("list"===t){const e=g(),o=e?v():null,a=e?Object.values(o.providers).flat():G(),i=e?o.activeProfile:D(),n=e?o.providers:a.reduce((e,r)=>(e[r.provider]||(e[r.provider]=[]),e[r.provider].push(r),e),{});let t="\n"+Y.cyan.bold(" +----------------------------------------------------------+")+"\n";t+=Y.cyan.bold(" | ")+Y.white.bold("GESTIÓN DE PROVEEDORES Y CUENTAS")+Y.cyan.bold(" |")+"\n",t+=Y.cyan.bold(" +----------------------------------------------------------+")+"\n";const l=N.filter(e=>e.implemented);for(const e of l){const r=e.id,o=n[r]??[];if(t+=`\n ${Y.magenta.bold("♦")}${Y.bgMagenta.white.bold(" "+e.label.toUpperCase()+" ")}${Y.magenta.bold("♦")} ${Y.dim("("+r+")")}\n`,0===o.length){const e=isProviderConfigured(r)?Y.green("● Configurado (sin perfil creado)"):Y.yellow("○ Sin perfiles");t+=` ${Y.dim("•")} ${Y.white("sin perfiles".padEnd(15))} ${e}\n`;continue}for(const e of o){const r=e.id===i?.id;let o=!1;o="claude"===e.provider||"openai"===e.provider?!!Z(e.provider,e.id):"ollama"===e.provider||"ollama-cloud"===e.provider||_(e.provider,e.id);t+=` ${r?Y.cyan("●"):Y.dim("○")} ${r?Y.cyan.bold(e.name.padEnd(15)):Y.white(e.name.padEnd(15))} ${o?Y.green("● Conectado"):Y.red("○ Desconectado")} ${r?Y.bgCyan.black(" ACTUAL "):""}\n`,e.baseUrl&&(t+=` ${Y.dim("+-")} ${Y.blue("→")} ${Y.dim(e.baseUrl)}\n`)}}return t+="\n"+Y.cyan.bold(" ► Guía rápida:")+"\n",t+=` ${Y.dim("•")} Cambiar perfil: ${Y.yellow("/provider [id] perfil [nombre]")}\n`,t+=` ${Y.dim("•")} Nueva cuenta: ${Y.yellow("/login --profile [nombre]")}\n`,t+=` ${Y.dim("•")} Ver actual: ${Y.yellow("/provider current")}\n`,t+=` ${Y.dim("•")} Limpiar todo: ${Y.yellow("/provider clear all")}\n`,r(t),null}if("current"===t){const e=g()?p().activeProfile:D();if(!e)return r(Y.yellow("No hay un perfil de proveedor activo configurado.")),null;const o=j(e.provider);let a=`\n${Y.cyan.bold("Perfil actual:")}\n`;return a+=`${Y.white("Proveedor:")} ${Y.magenta(o.label)}\n`,a+=`${Y.white("Nombre:")} ${Y.cyan(e.name)}\n`,e.baseUrl&&(a+=`${Y.white("Endpoint:")} ${Y.blue(e.baseUrl)}\n`),r(a),null}const s=function(e){if(g())return b(e);if(e)switch(e.trim().toLowerCase()){case"z.ai":case"z-ai":return"zai";case"open-router":return"openrouter";case"ollama-cloud":case"ollama_cloud":case"ollamacloud":return"ollama-cloud";case"gemini":case"gemini-api-key":case"google-ai":case"google-ai-studio":return"gemini-api";case"gemini-google":case"google":case"google-oauth":return"gemini-google";default:return e.trim().toLowerCase()}}(t);if(s){if(!N.find(e=>e.id===s))return r(`Proveedor no reconocido: ${s}. Opciones: ${N.map(e=>e.id).join(", ")}`),null;const a=function(e,r){if(!r||!B(e))return null;const o=r.trim().split(/\s+/).filter(Boolean);if(o.length<2)return null;if("profile"===o[1]?.toLowerCase()||"perfil"===o[1]?.toLowerCase())return o.slice(2).join(" ").trim()||null;const a=o[1];return["set","set-url","base-url","baseurl","url","endpoint","clear","reset","default","restore"].includes(a.toLowerCase())||isUrlLike(a)?null:a}(s,i);if(a&&B(s)&&(g()?P(s,a):q(s,a)),!("claude"!==s||H("claude")&&isSelectedProfileReady(s,a)))return F(r,o);if(!("openai"!==s||A()&&isSelectedProfileReady(s,a)))return K(r,o);const n=function(e,r){if(!r||!isConfigurableBaseUrlProvider(e))return{};const o=r.trim().split(/\s+/).filter(Boolean);if(o.length<2)return{};if("profile"===o[1]?.toLowerCase()||"perfil"===o[1]?.toLowerCase())return{};const a=o[1]?.toLowerCase(),i=["set","set-url","base-url","baseurl","url","endpoint"].includes(a),n=(i?o.slice(2):o.slice(1)).join(" ").trim();return n?["clear","reset","default","restore"].includes(n.toLowerCase())?{clear:!0}:i||isUrlLike(n)?{baseUrl:n}:{}:{}}(s,i);let t=null;if(n.clear&&isConfigurableBaseUrlProvider(s))k(s),t=`Base URL de ${getProviderLabel(s)} restaurada a ${getCurrentProviderBaseUrl(s)}`;else if(n.baseUrl&&isConfigurableBaseUrlProvider(s))try{const e=R(s,n.baseUrl);t=`Base URL de ${getProviderLabel(s)} guardada: ${e}`}catch(e){return r(e instanceof Error?e.message:`No se pudo guardar la base URL para ${getProviderLabel(s)}.`),null}return isProviderConfigured(s)&&isSelectedProfileReady(s,a)?e(SwitchProviderOnMount,{onDone:r,context:o,target:s,baseUrlMessage:t,targetProfileName:a}):(r(function(e,r){if("claude"===e)return"Redirigiendo a inicio de sesion de Claude...";if("openai"===e)return"Redirigiendo a inicio de sesion de OpenAI...";const o=isConfigurableBaseUrlProvider(e)?getProviderSetupMessage(e):null;return r&&o?`${r} - ${o}`:r??o??`Proveedor preparado: ${getProviderLabel(e)}`}(s,t)),null)}return e(ProviderPicker,{onDone:r,context:o})}function SwitchProviderOnMount({onDone:e,context:r,target:o,baseUrlMessage:i,targetProfileName:n}){const t=s(),l=d();return a.useEffect(()=>{(async()=>{try{const a=await switchProvider({context:r,currentModel:t,currentProvider:y(),target:o,targetProfileName:n});l(e=>({...e,mainLoopModel:a.restoredModel,mainLoopModelForSession:null})),e(i?`${i} - ${a.message}`:a.message)}catch(r){const o=r instanceof Error?r.message:String(r);e(`No se pudo cambiar de proveedor: ${o}`)}})()},[i,r,t,e,l,o,n]),null}function ProviderPicker({onDone:a,context:t}){const l=s(),u=d(),p=y(),m=c(),g=N.filter(e=>e.implemented).map(e=>{const r="claude"===e.id&&"firstParty"===p||e.id===p,o=isProviderConfigured(e.id),a=r?" [active]":o?" [ready]":" [setup]";return{label:`${e.label}${a}`,value:e.id}});const f=m??("firstParty"===p?"claude":p);return r(i,{flexDirection:"column",gap:1,children:[e(n,{bold:!0,color:"cyan",children:"Selecciona el proveedor de IA para Context Code:"}),e(n,{dimColor:!0,children:"Puedes usar la API oficial de Claude, OpenAI o proveedores compatibles con OpenAI."}),e(o,{options:g,defaultValue:f,onChange:async function(e){try{const r=e;if("claude"===r&&!H("claude"))return void a("No hay sesión de Claude. Lanzando /login...",{nextInput:"/login",submitNextInput:!0});if("openai"===r&&!A())return void a("No hay sesión de OpenAI. Lanzando /login-openai...",{nextInput:"/login-openai",submitNextInput:!0});if(!isProviderConfigured(r))return void a(getProviderSetupMessage(r));const o=await switchProvider({context:t,currentModel:l,currentProvider:p,target:r});u(e=>({...e,mainLoopModel:o.restoredModel,mainLoopModelForSession:null})),a(o.message)}catch(e){const r=e instanceof Error?e.message:String(e);a(`No se pudo cambiar de proveedor: ${r}`)}}}),r(i,{marginTop:1,flexDirection:"column",children:[r(n,{dimColor:!0,children:["- Usa ",e(n,{bold:!0,children:"/login"})," para configurar las API keys."]}),r(n,{dimColor:!0,children:["- Usa ",e(n,{bold:!0,children:"/provider openrouter https://..."})," para guardar una base URL personalizada."]}),r(n,{dimColor:!0,children:["- ",e(n,{bold:!0,children:"Ollama"})," usa ",getCurrentProviderBaseUrl("ollama")," por defecto."]})]})]})}
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Select as o}from"../../components/CustomSelect/select.js";import*as a from"react";import{Box as i,Text as n,useInput as t}from"../../ink.js";import{Dialog as l}from"../../components/design-system/Dialog.js";import{useMainLoopModel as s}from"../../hooks/useMainLoopModel.js";import{useSetAppState as d}from"../../state/AppState.js";import{getStoredActiveProviderPreference as c,setStoredActiveProviderPreference as u}from"../../utils/model/providerProfilesDb.js";import{getCoreCurrentProviderProfile as p,getCoreProviderLabel as m,isCoreProviderEnabled as g,isCoreSelectedProfileReady as f,listCoreProviderProfiles as v,normalizeCoreProviderInput as b,setCoreActiveProfile as P,switchCoreProvider as h}from"../../core/providers/providerCore.js";import{getAPIProvider as y,isGeminiApiProviderConfigured as $,isGeminiGoogleProviderConfigured as C,isNvidiaProviderConfigured as U,isOllamaCloudProviderConfigured as L,isMiniMaxProviderConfigured as w,isOpenAIProviderConfigured as A,isOpenRouterProviderConfigured as I,isZAIProviderConfigured as E}from"../../utils/model/providers.js";import{clearProviderBaseUrl as k,getConfiguredProviderBaseUrl as x,getDefaultProviderBaseUrl as S,isProviderBaseUrlCustomized as M,setProviderBaseUrl as R}from"../../utils/model/providerBaseUrls.js";import{getVisibleProvider as j,VISIBLE_PROVIDERS as N}from"../../utils/model/providerCatalog.js";import{clearAllProviderProfiles as O,getActiveProviderProfile as D,getLastUsedProviderProfile as z,isProfiledProvider as B,listProviderProfiles as G,setActiveProfileForProvider as q,setActiveProviderProfile as T}from"../../utils/model/providerProfiles.js";import{switchProviderPreference as V}from"../../utils/model/providerSwitch.js";import{clearAuthRelatedCaches as W}from"../logout/logout.js";import{call as F}from"../login/login.js";import{call as K}from"../login-openai/login-openai.js";import Y from"chalk";import{getStoredProviderOAuthTokens as _,hasStoredProviderApiKey as Z,hasStoredProviderOAuthTokens as H,removeAllProviderScopedCredentials as J}from"../../utils/auth.js";const Q=["openrouter","ollama","ollama-cloud","lmstudio","gemini-api","gemini-google","zai","minimax","nvidia","deepseek","xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi","custom-openai","custom-anthropic"];function isConfigurableBaseUrlProvider(e){return Q.includes(e)}function isProviderConfigured(e){return"claude"===e?H("claude"):"openai"===e?A():"openrouter"===e?I():"gemini-api"===e?$():"gemini-google"===e?C():"ollama"===e||("ollama-cloud"===e?L():"zai"===e?E():"minimax"===e?w():"nvidia"===e?U():Z(e))}function getProviderLabel(e){return g()?m(e):j(e).label}function getCurrentProviderBaseUrl(e){return M(e)?x(e):S(e)}function getProviderSetupMessage(e){const r=getCurrentProviderBaseUrl(e);switch(e){case"ollama":return`Ollama usa un servidor local compatible. Endpoint actual: ${r}. Puedes cambiarlo con /provider ollama <baseURL> o restaurar el default con /provider ollama clear.`;case"ollama-cloud":return`Ollama Cloud usa por defecto tu host local autenticado. Endpoint actual: ${r}. Ejecuta 'ollama signin' y luego usa /provider ollama-cloud.`;case"gemini-api":return`Gemini API requiere una API key de Google AI Studio. Endpoint actual: ${r}. Usa /login para guardarla o /provider gemini-api <baseURL> para cambiar el endpoint.`;case"gemini-google":return`Gemini Google usa OAuth compatible con Gemini CLI. Endpoint actual: ${r}. Usa /login y elige Gemini Google para abrir el navegador y guardar el token.`;case"zai":return"Z.AI requiere una API key. Usa /login para guardarla y /provider zai <baseURL> para cambiar el endpoint si hace falta.";case"minimax":return"MiniMax requiere una API key. Usa /login para guardarla. El endpoint por defecto es Anthropic-compatible (https://api.minimax.io/anthropic) y puedes cambiarlo con /provider minimax <baseURL>.";case"nvidia":return"NVIDIA requiere una API key. Usa /login para guardarla. El endpoint por defecto es https://integrate.api.nvidia.com/v1 y puedes cambiarlo con /provider nvidia <baseURL>.";case"deepseek":return`DeepSeek requiere una API key. Usa /login para guardarla. Endpoint actual: ${r}. Puedes cambiarlo con /provider deepseek <baseURL>.`;case"custom-openai":return`Custom OpenAI usa un endpoint y API key personalizados. Endpoint actual: ${r}. Usa /login para configurarlo desde cero o /provider custom-openai <baseURL> para cambiar solo el endpoint.`;case"custom-anthropic":return`Custom Anthropic usa un endpoint y API key personalizados. Endpoint actual: ${r}. Usa /login para configurarlo desde cero o /provider custom-anthropic <baseURL> para cambiar solo el endpoint.`;default:if(["xai","gmi","novita","stepfun","huggingface","opencode-zen","arcee","alibaba","kimi"].includes(e)){return`${getProviderLabel(e)} requiere una API key. Usa /login para guardarla y /provider ${e} <baseURL> para cambiar el endpoint si hace falta.`}return"OpenRouter requiere una API key. Usa /login para guardarla y /provider openrouter <baseURL> para cambiar el endpoint si hace falta."}}function isUrlLike(e){const r=e.toLowerCase();return!(!r.startsWith("http://")&&!r.startsWith("https://"))||(!!r.startsWith("localhost")||(/\.[a-z]{2,}/i.test(r)||/:\d+/.test(r)||/^(\d{1,3}\.){3}\d{1,3}/.test(r)))}async function switchProvider(e){const r=g()?h({currentModel:e.currentModel,currentProvider:e.currentProvider,targetProvider:e.target,targetProfileName:e.targetProfileName}).restoredModel:V({currentModel:e.currentModel,currentProvider:e.currentProvider,targetProvider:e.target,targetProfileName:e.targetProfileName});await W(),e.context.onChangeAPIKey();const o=B(e.target)&&z(e.target)?` · perfil ${z(e.target).name}`:"";return{message:r?`Proveedor cambiado a ${getProviderLabel(e.target)}${o} - modelo restaurado: ${r}`:`Proveedor cambiado a ${getProviderLabel(e.target)}${o} - cargando modelo predeterminado`,restoredModel:r}}function isSelectedProfileReady(e,r){if(g())return f(e,r);if(!r||!B(e))return!0;const o=z(e);return!!o&&("claude"===e?H("claude",o.id):"openai"===e?H("openai",o.id):"gemini-google"===e?C():"ollama"===e||"ollama-cloud"===e||Z(e,o.id))}function RemoveAllProvidersConfirmation({onDone:o,context:s}){const[d,c]=a.useState(!1);return t((e,r)=>{if(!d)return"y"===e||"Y"===e?(c(!0),void async function(e,r){try{const o=O(),a=D();if(a)u(a.provider);else{const e=G()[0];e?(T(e.id),u(e.provider)):u(null)}await J(),await W(),r.onChangeAPIKey(),e(o.length>0?`Se eliminaron correctamente todos los perfiles (${o.length}) y credenciales de los proveedores de IA.`:"Se eliminaron correctamente todas las credenciales de proveedores. No habia perfiles guardados.")}catch(r){e(`No se pudieron eliminar las credenciales y perfiles de proveedores: ${r instanceof Error?r.message:String(r)}`)}}(o,s)):void(("n"===e||"N"===e||r.escape)&&o("Eliminacion de proveedores y credenciales cancelada."))},{isActive:!0}),e(l,{title:"Eliminar todos los proveedores y perfiles",subtitle:"Esta accion elimina todos los perfiles guardados, sus credenciales asociadas y limpia todas las API keys persistidas.",onCancel:()=>{d||o("Eliminacion de proveedores y credenciales cancelada.")},color:"error",inputGuide:()=>e(n,{children:"y: confirmar eliminacion total · n/Esc: cancelar"}),children:r(i,{flexDirection:"column",children:[e(n,{children:"Se borraran todas las credenciales (API keys / OAuth) y perfiles persistidos de todos los proveedores."}),e(n,{dimColor:!0,children:"Esta accion es irreversible y te desconectara de todos los servicios de IA."}),d?e(n,{children:"Eliminando configuraciones..."}):null]})})}export async function call(r,o,a){const i=a?.trim(),n=i?.split(/\s+/).filter(Boolean)??[],t=n[0]?.toLowerCase(),l=n[1]?.toLowerCase();if("clear"===t&&"all"===l&&2===n.length||"clear-all"===t&&1===n.length||"clear"===t&&1===n.length||"remove"===t&&"all"===l&&2===n.length)return e(RemoveAllProvidersConfirmation,{onDone:r,context:o});if("list"===t){const e=g(),o=e?v():null,a=e?Object.values(o.providers).flat():G(),i=e?o.activeProfile:D(),n=e?o.providers:a.reduce((e,r)=>(e[r.provider]||(e[r.provider]=[]),e[r.provider].push(r),e),{});let t="\n"+Y.cyan.bold(" +----------------------------------------------------------+")+"\n";t+=Y.cyan.bold(" | ")+Y.white.bold("GESTIÓN DE PROVEEDORES Y CUENTAS")+Y.cyan.bold(" |")+"\n",t+=Y.cyan.bold(" +----------------------------------------------------------+")+"\n";const l=N.filter(e=>e.implemented);for(const e of l){const r=e.id,o=n[r]??[];if(t+=`\n ${Y.magenta.bold("♦")}${Y.bgMagenta.white.bold(" "+e.label.toUpperCase()+" ")}${Y.magenta.bold("♦")} ${Y.dim("("+r+")")}\n`,0===o.length){const e=isProviderConfigured(r)?Y.green("● Configurado (sin perfil creado)"):Y.yellow("○ Sin perfiles");t+=` ${Y.dim("•")} ${Y.white("sin perfiles".padEnd(15))} ${e}\n`;continue}for(const e of o){const r=e.id===i?.id;let o=!1;o="claude"===e.provider||"openai"===e.provider?!!_(e.provider,e.id):"ollama"===e.provider||"ollama-cloud"===e.provider||Z(e.provider,e.id);t+=` ${r?Y.cyan("●"):Y.dim("○")} ${r?Y.cyan.bold(e.name.padEnd(15)):Y.white(e.name.padEnd(15))} ${o?Y.green("● Conectado"):Y.red("○ Desconectado")} ${r?Y.bgCyan.black(" ACTUAL "):""}\n`,e.baseUrl&&(t+=` ${Y.dim("+-")} ${Y.blue("→")} ${Y.dim(e.baseUrl)}\n`)}}return t+="\n"+Y.cyan.bold(" ► Guía rápida:")+"\n",t+=` ${Y.dim("•")} Cambiar perfil: ${Y.yellow("/provider [id] perfil [nombre]")}\n`,t+=` ${Y.dim("•")} Nueva cuenta: ${Y.yellow("/login --profile [nombre]")}\n`,t+=` ${Y.dim("•")} Ver actual: ${Y.yellow("/provider current")}\n`,t+=` ${Y.dim("•")} Limpiar todo: ${Y.yellow("/provider clear all")}\n`,r(t),null}if("current"===t){const e=g()?p().activeProfile:D();if(!e)return r(Y.yellow("No hay un perfil de proveedor activo configurado.")),null;const o=j(e.provider);let a=`\n${Y.cyan.bold("Perfil actual:")}\n`;return a+=`${Y.white("Proveedor:")} ${Y.magenta(o.label)}\n`,a+=`${Y.white("Nombre:")} ${Y.cyan(e.name)}\n`,e.baseUrl&&(a+=`${Y.white("Endpoint:")} ${Y.blue(e.baseUrl)}\n`),r(a),null}const s=function(e){if(g())return b(e);if(e)switch(e.trim().toLowerCase()){case"z.ai":case"z-ai":return"zai";case"open-router":return"openrouter";case"ollama-cloud":case"ollama_cloud":case"ollamacloud":return"ollama-cloud";case"lm-studio":case"lm_studio":case"lmstudio":return"lmstudio";case"gemini":case"gemini-api-key":case"google-ai":case"google-ai-studio":return"gemini-api";case"gemini-google":case"google":case"google-oauth":return"gemini-google";default:return e.trim().toLowerCase()}}(t);if(s){if(!N.find(e=>e.id===s))return r(`Proveedor no reconocido: ${s}. Opciones: ${N.map(e=>e.id).join(", ")}`),null;const a=function(e,r){if(!r||!B(e))return null;const o=r.trim().split(/\s+/).filter(Boolean);if(o.length<2)return null;if("profile"===o[1]?.toLowerCase()||"perfil"===o[1]?.toLowerCase())return o.slice(2).join(" ").trim()||null;const a=o[1];return["set","set-url","base-url","baseurl","url","endpoint","clear","reset","default","restore"].includes(a.toLowerCase())||isUrlLike(a)?null:a}(s,i);if(a&&B(s)&&(g()?P(s,a):q(s,a)),!("claude"!==s||H("claude")&&isSelectedProfileReady(s,a)))return F(r,o);if(!("openai"!==s||A()&&isSelectedProfileReady(s,a)))return K(r,o);const n=function(e,r){if(!r||!isConfigurableBaseUrlProvider(e))return{};const o=r.trim().split(/\s+/).filter(Boolean);if(o.length<2)return{};if("profile"===o[1]?.toLowerCase()||"perfil"===o[1]?.toLowerCase())return{};const a=o[1]?.toLowerCase(),i=["set","set-url","base-url","baseurl","url","endpoint"].includes(a),n=(i?o.slice(2):o.slice(1)).join(" ").trim();return n?["clear","reset","default","restore"].includes(n.toLowerCase())?{clear:!0}:i||isUrlLike(n)?{baseUrl:n}:{}:{}}(s,i);let t=null;if(n.clear&&isConfigurableBaseUrlProvider(s))k(s),t=`Base URL de ${getProviderLabel(s)} restaurada a ${getCurrentProviderBaseUrl(s)}`;else if(n.baseUrl&&isConfigurableBaseUrlProvider(s))try{const e=R(s,n.baseUrl);t=`Base URL de ${getProviderLabel(s)} guardada: ${e}`}catch(e){return r(e instanceof Error?e.message:`No se pudo guardar la base URL para ${getProviderLabel(s)}.`),null}return isProviderConfigured(s)&&isSelectedProfileReady(s,a)?e(SwitchProviderOnMount,{onDone:r,context:o,target:s,baseUrlMessage:t,targetProfileName:a}):(r(function(e,r){if("claude"===e)return"Redirigiendo a inicio de sesion de Claude...";if("openai"===e)return"Redirigiendo a inicio de sesion de OpenAI...";const o=isConfigurableBaseUrlProvider(e)?getProviderSetupMessage(e):null;return r&&o?`${r} - ${o}`:r??o??`Proveedor preparado: ${getProviderLabel(e)}`}(s,t)),null)}return e(ProviderPicker,{onDone:r,context:o})}function SwitchProviderOnMount({onDone:e,context:r,target:o,baseUrlMessage:i,targetProfileName:n}){const t=s(),l=d();return a.useEffect(()=>{(async()=>{try{const a=await switchProvider({context:r,currentModel:t,currentProvider:y(),target:o,targetProfileName:n});l(e=>({...e,mainLoopModel:a.restoredModel,mainLoopModelForSession:null})),e(i?`${i} - ${a.message}`:a.message)}catch(r){const o=r instanceof Error?r.message:String(r);e(`No se pudo cambiar de proveedor: ${o}`)}})()},[i,r,t,e,l,o,n]),null}function ProviderPicker({onDone:a,context:t}){const l=s(),u=d(),p=y(),m=c(),g=N.filter(e=>e.implemented).map(e=>{const r="claude"===e.id&&"firstParty"===p||e.id===p,o=isProviderConfigured(e.id),a=r?" [active]":o?" [ready]":" [setup]";return{label:`${e.label}${a}`,value:e.id}});const f=m??("firstParty"===p?"claude":p);return r(i,{flexDirection:"column",gap:1,children:[e(n,{bold:!0,color:"cyan",children:"Selecciona el proveedor de IA para Context Code:"}),e(n,{dimColor:!0,children:"Puedes usar la API oficial de Claude, OpenAI o proveedores compatibles con OpenAI."}),e(o,{options:g,defaultValue:f,onChange:async function(e){try{const r=e;if("claude"===r&&!H("claude"))return void a("No hay sesión de Claude. Lanzando /login...",{nextInput:"/login",submitNextInput:!0});if("openai"===r&&!A())return void a("No hay sesión de OpenAI. Lanzando /login-openai...",{nextInput:"/login-openai",submitNextInput:!0});if(!isProviderConfigured(r))return void a(getProviderSetupMessage(r));const o=await switchProvider({context:t,currentModel:l,currentProvider:p,target:r});u(e=>({...e,mainLoopModel:o.restoredModel,mainLoopModelForSession:null})),a(o.message)}catch(e){const r=e instanceof Error?e.message:String(e);a(`No se pudo cambiar de proveedor: ${r}`)}}}),r(i,{marginTop:1,flexDirection:"column",children:[r(n,{dimColor:!0,children:["- Usa ",e(n,{bold:!0,children:"/login"})," para configurar las API keys."]}),r(n,{dimColor:!0,children:["- Usa ",e(n,{bold:!0,children:"/provider openrouter https://..."})," para guardar una base URL personalizada."]}),r(n,{dimColor:!0,children:["- ",e(n,{bold:!0,children:"Ollama"})," usa ",getCurrentProviderBaseUrl("ollama")," por defecto."]})]})]})}
@@ -1 +1 @@
1
- import{resetCostState as e}from"../../bootstrap/state.js";import{clearTrustedDeviceToken as o,enrollTrustedDevice as r}from"../../bridge/trustedDevice.js";import{refreshGrowthBookAfterAuthChange as t}from"../../services/analytics/growthbook.js";import{refreshPolicyLimits as s}from"../../services/policyLimits/index.js";import{refreshRemoteManagedSettings as i}from"../../services/remoteManagedSettings/index.js";import{stripSignatureBlocks as n}from"../../utils/messages.js";import{checkAndDisableAutoModeIfNeeded as a,checkAndDisableBypassPermissionsIfNeeded as l,resetAutoModeGateCheck as p,resetBypassPermissionsCheck as m}from"../../utils/permissions/bypassPermissionsKillswitch.js";import{switchProviderPreference as c}from"../../utils/model/providerSwitch.js";import{resetUserCache as d}from"../../utils/user.js";export function isCoreAuthEnabled(){return"0"!==process.env.CORE_AUTH_ENABLED}export function parseLoginProfileName(e){const o=e?.trim()??"";if(!o)return;const r=o.split(/\s+/).filter(Boolean),t=r.findIndex(e=>"--profile"===e||"-p"===e);return-1!==t&&r[t+1]?r[t+1]:r.length>0&&!r[0].startsWith("-")?r[0]:void 0}function resolveProvider(e){return e||"claude"}export function applySuccessfulLogin(f){const{context:u,profileName:v,previousModel:g,previousProvider:P,targetProvider:h,transcriptClassifierEnabled:x}=f;u.onChangeAPIKey(),u.setMessages(n);const S=c({currentModel:g,currentProvider:P,targetProvider:resolveProvider(h),targetProfileName:v});e(),i(),s(),d(),t(),o(),r(),m();const j=u.getAppState();l(j.toolPermissionContext,u.setAppState),x&&(p(),a(j.toolPermissionContext,u.setAppState,j.fastMode)),u.setAppState(e=>({...e,mainLoopModel:S,mainLoopModelForSession:S,authVersion:e.authVersion+1}));const M=!S;return{restoredModel:S,message:M?v?`Inicio de sesion exitoso en el perfil "${v}". Selecciona ahora el modelo para este perfil.`:"Inicio de sesion exitoso. Selecciona ahora el modelo para este perfil.":"Inicio de sesión exitoso",shouldOpenModelPicker:M}}
1
+ import{resetCostState as e}from"../../bootstrap/state.js";import{clearTrustedDeviceToken as o,enrollTrustedDevice as r}from"../../bridge/trustedDevice.js";import{refreshGrowthBookAfterAuthChange as t}from"../../services/analytics/growthbook.js";import{refreshPolicyLimits as s}from"../../services/policyLimits/index.js";import{refreshRemoteManagedSettings as i}from"../../services/remoteManagedSettings/index.js";import{stripSignatureBlocks as n}from"../../utils/messages.js";import{checkAndDisableAutoModeIfNeeded as a,checkAndDisableBypassPermissionsIfNeeded as p,resetAutoModeGateCheck as l,resetBypassPermissionsCheck as c}from"../../utils/permissions/bypassPermissionsKillswitch.js";import{switchProviderPreference as m}from"../../utils/model/providerSwitch.js";import{resetUserCache as d}from"../../utils/user.js";export function isCoreAuthEnabled(){return"0"!==process.env.CORE_AUTH_ENABLED}export function parseLoginProfileName(e){const o=e?.trim()??"";if(!o)return;const r=o.split(/\s+/).filter(Boolean),t=r.findIndex(e=>"--profile"===e||"-p"===e);return-1!==t&&r[t+1]?r[t+1]:r.length>0&&!r[0].startsWith("-")?r[0]:void 0}function resolveProvider(e){return e&&"anthropic"!==e?e:"claude"}export function applySuccessfulLogin(f){const{context:u,profileName:v,previousModel:g,previousProvider:h,targetProvider:P,transcriptClassifierEnabled:x}=f;u.onChangeAPIKey(),u.setMessages(n);const S=m({currentModel:g,currentProvider:h,targetProvider:resolveProvider(P),targetProfileName:v});e(),i(),s(),d(),t(),o(),r(),c();const j=u.getAppState();p(j.toolPermissionContext,u.setAppState),x&&(l(),a(j.toolPermissionContext,u.setAppState,j.fastMode)),u.setAppState(e=>({...e,mainLoopModel:S,mainLoopModelForSession:S,authVersion:e.authVersion+1}));const M=!S;return{restoredModel:S,message:M?v?`Inicio de sesion exitoso en el perfil "${v}". Selecciona ahora el modelo para este perfil.`:"Inicio de sesion exitoso. Selecciona ahora el modelo para este perfil.":"Inicio de sesión exitoso",shouldOpenModelPicker:M}}
@@ -1 +1 @@
1
- export class CoreLlmClient{credentialProvider;constructor(e){this.credentialProvider=e}async chat(e){const t=await this.credentialProvider(e.provider,e.profileId),o=t.baseUrl||this.resolveBaseUrl(e.provider,e.profileId);return"claude"===e.provider||o.toLowerCase().includes("anthropic")?this.callAnthropic(e,t,o):this.callOpenAICompatible(e,t,o)}async callOpenAICompatible(e,t){const o=this.resolveBaseUrl(e.provider),s={"Content-Type":"application/json"};t.token&&(s.Authorization=`Bearer ${t.token}`);const a=await fetch(`${o}/chat/completions`,{method:"POST",headers:s,body:JSON.stringify({model:e.model,messages:e.messages,tools:e.tools,temperature:e.temperature??.2})});if(!a.ok){const e=await a.text();throw new Error(`LLM Error (${a.status}): ${e}`)}const n=await a.json();return{content:n.choices?.[0]?.message?.content??null,toolCalls:n.choices?.[0]?.message?.tool_calls?.map(e=>({id:e.id,name:e.function.name,arguments:e.function.arguments})),usage:{promptTokens:n.usage?.prompt_tokens??0,completionTokens:n.usage?.completion_tokens??0}}}async callAnthropic(e,t,o){const s={"Content-Type":"application/json","x-api-key":t.token||""};"claude"===e.provider&&(s["anthropic-version"]="2023-06-01");const a=e.messages.find(e=>"system"===e.role)?.content,n=e.messages.filter(e=>"system"!==e.role).map(e=>({role:"assistant"===e.role?"assistant":"user",content:e.content})),i={model:e.model,max_tokens:e.maxTokens??4096,messages:n,system:a,tools:e.tools?.map(e=>({name:e.name,description:e.description,input_schema:e.parameters})),temperature:e.temperature??.2},r=o.endsWith("/messages")?o:`${o.replace(/\/+$/,"")}/v1/messages`,p=await fetch(r,{method:"POST",headers:s,body:JSON.stringify(i)});if(!p.ok){const e=await p.text();throw new Error(`Anthropic Error (${p.status}): ${e}`)}const l=await p.json(),c=l.content.find(e=>"text"===e.type)?.text??null,m=l.content.filter(e=>"tool_use"===e.type).map(e=>({id:e.id,name:e.name,arguments:JSON.stringify(e.input)}));return{content:c,toolCalls:m.length>0?m:void 0,usage:{promptTokens:l.usage?.input_tokens??0,completionTokens:l.usage?.output_tokens??0}}}resolveBaseUrl(e,t){this.credentialProvider;const o={claude:"https://api.anthropic.com",openai:"https://api.openai.com/v1",openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.chat/v1"};return o[e]||o.openai}}
1
+ export class CoreLlmClient{credentialProvider;constructor(e){this.credentialProvider=e}async chat(e){const t=await this.credentialProvider(e.provider,e.profileId),o=t.baseUrl||this.resolveBaseUrl(e.provider,e.profileId);return"claude"===e.provider||o.toLowerCase().includes("anthropic")?this.callAnthropic(e,t,o):this.callOpenAICompatible(e,t,o)}async callOpenAICompatible(e,t){const o=this.resolveBaseUrl(e.provider),s={"Content-Type":"application/json"};t.token&&(s.Authorization=`Bearer ${t.token}`);const a=await fetch(`${o}/chat/completions`,{method:"POST",headers:s,body:JSON.stringify({model:e.model,messages:e.messages,tools:e.tools,temperature:e.temperature??.2})});if(!a.ok){const e=await a.text();throw new Error(`LLM Error (${a.status}): ${e}`)}const n=await a.json();return{content:n.choices?.[0]?.message?.content??null,toolCalls:n.choices?.[0]?.message?.tool_calls?.map(e=>({id:e.id,name:e.function.name,arguments:e.function.arguments})),usage:{promptTokens:n.usage?.prompt_tokens??0,completionTokens:n.usage?.completion_tokens??0}}}async callAnthropic(e,t,o){const s={"Content-Type":"application/json","x-api-key":t.token||""};"claude"===e.provider&&(s["anthropic-version"]="2023-06-01");const a=e.messages.find(e=>"system"===e.role)?.content,n=e.messages.filter(e=>"system"!==e.role).map(e=>({role:"assistant"===e.role?"assistant":"user",content:e.content})),i={model:e.model,max_tokens:e.maxTokens??4096,messages:n,system:a,tools:e.tools?.map(e=>({name:e.name,description:e.description,input_schema:e.parameters})),temperature:e.temperature??.2},r=o.endsWith("/messages")?o:`${o.replace(/\/+$/,"")}/v1/messages`,p=await fetch(r,{method:"POST",headers:s,body:JSON.stringify(i)});if(!p.ok){const e=await p.text();throw new Error(`Anthropic Error (${p.status}): ${e}`)}const l=await p.json(),c=l.content.find(e=>"text"===e.type)?.text??null,m=l.content.filter(e=>"tool_use"===e.type).map(e=>({id:e.id,name:e.name,arguments:JSON.stringify(e.input)}));return{content:c,toolCalls:m.length>0?m:void 0,usage:{promptTokens:l.usage?.input_tokens??0,completionTokens:l.usage?.output_tokens??0}}}resolveBaseUrl(e,t){this.credentialProvider;const o={claude:"https://api.anthropic.com",openai:"https://api.openai.com/v1",openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.chat/v1"};return o[e]||o.openai}}
@@ -1 +1 @@
1
- export const PROVIDER_COMPATIBILITY_SAMPLES={claude:{accepts:["claude-sonnet-4-5"],rejects:["gpt-4o"]},openai:{accepts:["gpt-4.1","o3","codex-mini-latest"],rejects:["claude-sonnet-4-5"]},"gemini-api":{accepts:["gemini-3.5-pro"],rejects:["gpt-4o"]},"gemini-google":{accepts:["gemini-3.5-flash"],rejects:["claude-sonnet-4-5"]},openrouter:{accepts:["anthropic/claude-sonnet-4"],rejects:[]},ollama:{accepts:["llama3.1:8b"],rejects:[]},"ollama-cloud":{accepts:["llama3.3:70b-instruct-q8_0"],rejects:[]},zai:{accepts:["glm-4.5"],rejects:[]},minimax:{accepts:["MiniMax-M2.7"],rejects:[]},nvidia:{accepts:["meta/llama-3.1-70b-instruct"],rejects:[]},deepseek:{accepts:["deepseek-chat","deepseek-reasoner"],rejects:["gpt-4o"]}};export function validateProviderModelCompatibility(e,t){const a=(t??"").trim();if(!a)return{provider:e,model:"",compatible:!1,reason:"empty-model"};const i=a.toLowerCase();if("claude"===e)return{provider:e,model:a,compatible:i.startsWith("claude-"),reason:"claude-prefix"};if("openai"===e){return{provider:e,model:a,compatible:i.startsWith("gpt-")||i.startsWith("o1")||i.startsWith("o3")||i.startsWith("o4")||i.startsWith("codex-"),reason:"openai-family"}}return"gemini-api"===e||"gemini-google"===e?{provider:e,model:a,compatible:i.startsWith("gemini-"),reason:"gemini-prefix"}:"deepseek"===e?{provider:e,model:a,compatible:i.startsWith("deepseek-"),reason:"deepseek-prefix"}:{provider:e,model:a,compatible:!0,reason:"dynamic-catalog"}}
1
+ export const PROVIDER_COMPATIBILITY_SAMPLES={claude:{accepts:["claude-sonnet-4-5"],rejects:["gpt-4o"]},openai:{accepts:["gpt-4.1","o3","codex-mini-latest"],rejects:["claude-sonnet-4-5"]},"gemini-api":{accepts:["gemini-3.5-pro"],rejects:["gpt-4o"]},"gemini-google":{accepts:["gemini-3.5-flash"],rejects:["claude-sonnet-4-5"]},openrouter:{accepts:["anthropic/claude-sonnet-4"],rejects:[]},ollama:{accepts:["llama3.1:8b"],rejects:[]},"ollama-cloud":{accepts:["llama3.3:70b-instruct-q8_0"],rejects:[]},lmstudio:{accepts:["*"],rejects:[]},zai:{accepts:["glm-4.5"],rejects:[]},minimax:{accepts:["MiniMax-M2.7"],rejects:[]},nvidia:{accepts:["meta/llama-3.1-70b-instruct"],rejects:[]},deepseek:{accepts:["deepseek-chat","deepseek-reasoner"],rejects:["gpt-4o"]}};export function validateProviderModelCompatibility(e,t){const a=(t??"").trim();if(!a)return{provider:e,model:"",compatible:!1,reason:"empty-model"};const i=a.toLowerCase();if("claude"===e)return{provider:e,model:a,compatible:i.startsWith("claude-"),reason:"claude-prefix"};if("openai"===e){return{provider:e,model:a,compatible:i.startsWith("gpt-")||i.startsWith("o1")||i.startsWith("o3")||i.startsWith("o4")||i.startsWith("codex-"),reason:"openai-family"}}return"gemini-api"===e||"gemini-google"===e?{provider:e,model:a,compatible:i.startsWith("gemini-"),reason:"gemini-prefix"}:"deepseek"===e?{provider:e,model:a,compatible:i.startsWith("deepseek-"),reason:"deepseek-prefix"}:{provider:e,model:a,compatible:!0,reason:"dynamic-catalog"}}
@@ -1 +1 @@
1
- import{APIUserAbortError as e}from"@anthropic-ai/sdk/error.js";import{randomUUID as t}from"node:crypto";import{checkAndRefreshOpenAIOAuthTokenIfNeeded as n,getGeminiGoogleAuthHeaders as o,getOpenAICompatibleAccessToken as r,getOpenAIAccessToken as s,handleOpenAIOAuth401Error as i}from"../../utils/auth.js";import{getAPIProvider as a,isOpenAICompatibleProvider as u}from"../../utils/model/providers.js";import{getConfiguredProviderBaseUrl as l}from"../../utils/model/providerBaseUrls.js";import{getOpenAIOriginator as c}from"../../constants/oauth.js";import{errorMessage as p}from"../../utils/errors.js";import{logForDebugging as m}from"../../utils/debug.js";import{logError as d}from"../../utils/log.js";import{createAssistantAPIErrorMessage as f,createAssistantMessage as g,createUserMessage as y}from"../../utils/messages.js";import{addToTotalSessionCost as h}from"../../cost-tracker.js";import{calculateUSDCost as _}from"../../utils/modelCost.js";import{toolToAPISchema as A}from"../../utils/api.js";import{jsonStringify as O}from"../../utils/slowOperations.js";function getOpenAIMaxTimeoutRetries(){const e=process.env.CONTEXT_CODE_MAX_RETRIES;if(!e)return 10;const t=Number.parseInt(e,10);return!Number.isFinite(t)||t<0?10:t}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function isPlainObject(e){if(!isRecord(e))return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function isJwtToken(e){return 3===e.split(".").length}function getOpenAICompatibleProvider(){const e=a();return u(e)?e:"openai"}function getOpenAICompatibleProviderLabel(e=getOpenAICompatibleProvider()){switch(e){case"openrouter":return"OpenRouter";case"ollama":return"Ollama";case"ollama-cloud":return"Ollama Cloud";case"gemini-api":return"Gemini API";case"gemini-google":return"Gemini Google";case"zai":return"Z.AI";case"nvidia":return"NVIDIA NIM";case"custom-openai":return"Custom OpenAI";default:return"OpenAI"}}function getOpenAIBaseUrl(e=getOpenAICompatibleProvider()){if("openrouter"===e){const e=process.env.OPENROUTER_BASE_URL||l("openrouter")||"https://openrouter.ai/api/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("ollama"===e){const e=process.env.OLLAMA_BASE_URL||l("ollama")||"http://localhost:11434/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("ollama-cloud"===e){const e=process.env.OLLAMA_CLOUD_BASE_URL||process.env.OLLAMA_BASE_URL||l("ollama-cloud")||"http://localhost:11434/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("zai"===e){const e=process.env.ZAI_BASE_URL||l("zai")||"https://api.z.ai/api/coding/paas/v4";return e.endsWith("/")?e.slice(0,-1):e}if("gemini-api"===e||"gemini-google"===e){const t=("gemini-api"===e?process.env.GEMINI_BASE_URL||process.env.GEMINI_API_BASE_URL:process.env.GEMINI_GOOGLE_BASE_URL||process.env.GEMINI_BASE_URL)||l(e)||"https://generativelanguage.googleapis.com/v1beta/openai";return t.endsWith("/")?t.slice(0,-1):t}if("nvidia"===e){const e=process.env.NVIDIA_BASE_URL||l("nvidia")||"https://integrate.api.nvidia.com/v1";return e.endsWith("/")?e.slice(0,-1):e}if("custom-openai"===e){let e=l("custom-openai")||"https://api.openai.com/v1";return e.startsWith("http://chinai.iaforged.com")&&(e=e.replace("http://chinai.iaforged.com","https://chinai.iaforged.com")),e.endsWith("/")?e.slice(0,-1):e}if("openai"!==e&&"custom-openai"!==e){const t=l(e);return t.endsWith("/")?t.slice(0,-1):t}const t=process.env.OPENAI_API_BASE_URL||process.env.OPENAI_BASE_URL||"https://api.openai.com/v1";return t.endsWith("/v1")?t:t.endsWith("/")?`${t}v1`:`${t}/v1`}async function getOpenAIRequestHeaders(e=getOpenAICompatibleProvider()){return"gemini-google"===e?o():function(e=getOpenAICompatibleProvider()){const t=r(e);if(isLocalOllamaProviderHost(e,getOpenAIBaseUrl(e)))return{"Content-Type":"application/json"};if(!t)throw new Error(`${getOpenAICompatibleProviderLabel(e)} is selected but no credentials were found.`);return"custom-openai"===e?{Authorization:`Bearer ${t}`,"X-API-Key":t,"api-key":t,"Content-Type":"application/json"}:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}}(e)}function isLocalOllamaProviderHost(e,t=getOpenAIBaseUrl(e)){return("ollama"===e||"ollama-cloud"===e)&&(t.includes("localhost")||t.includes("127.0.0.1"))}function getOpenAIAccessTokenOrThrow(e=getOpenAICompatibleProvider()){if(isLocalOllamaProviderHost(e))return"ollama";if("gemini-google"===e)return r(e)||"google-application-default-credentials";const t=r(e);if(!t)throw new Error(`${getOpenAICompatibleProviderLabel(e)} is selected but no credentials were found.`);return t}async function maybeRefreshOpenAICompatibleAuth(e=getOpenAICompatibleProvider()){"openai"===e&&await n()}async function maybeRecoverOpenAICompatible401(e,t=getOpenAICompatibleProvider()){if("openai"!==t)return null;if(!await i(e))return null;const n=s();return n&&n!==e?n:null}function toInputText(e){return{type:"input_text",text:e}}function toOutputText(e){return{type:"output_text",text:e}}function normalizeBlocksForRole(e,t){return"assistant"!==t?e:e.map(e=>"input_text"===e.type?toOutputText(e.text):e)}function stringifyBlockContent(e){return"string"==typeof e?e:Array.isArray(e)?e.map(e=>"string"==typeof e?e:e&&"object"==typeof e&&"type"in e&&"text"===e.type&&"text"in e&&"string"==typeof e.text?e.text:O(e)).join("\n"):null==e?"":O(e)}function normalizeResponseContent(e){return Array.isArray(e)?e:null==e?[]:[e]}function blockToOpenAIContentBlocks(e){if(!isRecord(e))return null;if("text"===e.type&&"string"==typeof e.text)return[toInputText(e.text)];if("image"===e.type){const t=isRecord(e.source)?e.source:null,n=t?function(e){if("base64"===e.type){const t=e.media_type,n=e.data;return"string"!=typeof t||"string"!=typeof n?null:{type:"input_image",image_url:`data:${t};base64,${n}`}}return"url"===e.type&&"string"==typeof e.url?{type:"input_image",image_url:e.url}:"file"===e.type&&"string"==typeof e.file_id?{type:"input_image",file_id:e.file_id}:null}(t):null;return n?[n]:null}if("document"===e.type){const t=isRecord(e.source)?e.source:null;if(!t)return null;const n=function(e,t){return"file"===e.type&&"string"==typeof e.file_id?{type:"input_file",file_id:e.file_id}:"base64"===e.type&&"string"==typeof e.data?"string"!=typeof e.media_type?null:{type:"input_file",file_data:e.data,..."string"==typeof t&&t?{filename:t}:{}}:"url"===e.type&&"string"==typeof e.url?{type:"input_file",file_url:e.url,..."string"==typeof t&&t?{filename:t}:{}}:"text"===e.type&&"string"==typeof e.data?toInputText(e.data):null}(t,"string"==typeof e.title?e.title:void 0);if(n)return[n];if("content"===t.type&&"string"==typeof t.content)return[toInputText(t.content)];if("content"===t.type&&Array.isArray(t.content)){const e=[];for(const n of t.content){const t=blockToOpenAIContentBlocks(n);t&&e.push(...t)}return e.length>0?e:null}return null}if("search_result"===e.type&&Array.isArray(e.content)){const t=[];"string"==typeof e.title&&e.title.trim()&&t.push(e.title.trim()),"string"==typeof e.source&&e.source.trim()&&t.push(e.source.trim());for(const n of e.content)if(n&&"object"==typeof n&&"text"in n){const e=n.text;"string"==typeof e&&e.trim()&&t.push(e.trim())}return[toInputText(t.join("\n\n"))]}if("container_upload"===e.type&&"string"==typeof e.file_id)return[{type:"input_file",file_id:e.file_id}];if(("bash_code_execution_output"===e.type||"mcp_tool_result"===e.type||"code_execution_tool_result"===e.type||"web_search_tool_result"===e.type||"web_fetch_tool_result"===e.type||"text_editor_code_execution_tool_result"===e.type||"tool_search_tool_result"===e.type)&&"content"in e){const t=e.content;if("string"==typeof t)return[toInputText(t)];if(Array.isArray(t)){const e=[];for(const n of t){const t=blockToOpenAIContentBlocks(n);t&&e.push(...t)}return e.length>0?e:null}}if("content"in e&&("string"==typeof e.content||Array.isArray(e.content))){const t=e.content;if("string"==typeof t)return[toInputText(t)];const n=[];for(const e of t){const t=blockToOpenAIContentBlocks(e);t&&n.push(...t)}return n.length>0?n:null}return"data"in e&&"string"==typeof e.data?[toInputText(e.data)]:null}function toolResultContentToOpenAIOutput(e){if("string"==typeof e)return e;if(!Array.isArray(e))return stringifyBlockContent(e);const t=[];for(const n of e){const e=blockToOpenAIContentBlocks(n);if(e&&e.length>0){t.push(...e);continue}const o=stringifyBlockContent(n).trim();o&&t.push(toInputText(o))}return 0===t.length?"":t.every(e=>"input_text"===e.type)?t.map(e=>e.text).join("\n\n"):t}function messageToOpenAIInput(e){if(!e.message||"user"!==e.type&&"assistant"!==e.type)return[];const t=Array.isArray(e.message.content)?e.message.content:[{type:"text",text:String(e.message.content??"")}],n="assistant"===e.type?"assistant":"user",o=[],r=[],flushMessage=()=>{0!==r.length&&(o.push({type:"message",role:n,content:[...r]}),r.length=0)};for(const s of t){if("assistant"===e.type&&"tool_use"===s.type&&"string"==typeof s.id&&"string"==typeof s.name){flushMessage(),o.push({type:"function_call",call_id:s.id,name:s.name,arguments:O(s.input??{})});continue}if("user"===e.type&&"tool_result"===s.type&&"string"==typeof s.tool_use_id){flushMessage(),o.push({type:"function_call_output",call_id:s.tool_use_id,output:toolResultContentToOpenAIOutput(s.content)});continue}if("thinking"===s.type||"redacted_thinking"===s.type)continue;const t=blockToOpenAIContentBlocks(s);t&&t.length>0?r.push(...normalizeBlocksForRole(t,n)):r.push(..."assistant"===n?[toOutputText(stringifyBlockContent(s))]:[toInputText(stringifyBlockContent(s))])}return flushMessage(),o}async function readOpenAIResponseBody(e){const t=await e.text();if(!t.trim())return{};const n=t.trim();if(n.startsWith("data:")||n.startsWith("event:"))return function(e){const t=[];for(const n of e.split(/\r?\n\r?\n/)){const e=n.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===e.length)continue;const o=e.filter(e=>e.startsWith("data:")).map(e=>e.slice(5).trim());if(0===o.length)continue;const r=o.join("\n").trim();if(r&&"[DONE]"!==r)try{const e=JSON.parse(r);isRecord(e)&&t.push(e)}catch{}}let n=null,o=null;const r=[];let s="";for(const i of t){const t="string"==typeof i.type?i.type:"";"response.completed"===t&&isRecord(i.response)?n={...i.response,raw_error_text:e}:"error"!==t?"response.output_item.done"===t&&isRecord(i.item)?r.push(i.item):"response.output_text.delta"!==t||"string"!=typeof i.delta?"response.output_text.done"===t&&"string"==typeof i.text&&(s=i.text):s+=i.delta:"string"==typeof i.message&&i.message.trim()?o=i.message:isRecord(i.error)&&"string"==typeof i.error.message&&(o=i.error.message)}if(n)return(!n.output||0===n.output.length)&&r.length>0&&(n.output=r),!n.output_text&&s&&(n.output_text=s),!n.error&&o&&(n.error={message:o}),n;if(r.length>0||s||o)return{output:r.length>0?r:void 0,output_text:s||void 0,error:o?{message:o}:void 0,raw_error_text:e};return{error:{message:e},raw_error_text:e}}(t);try{const e=JSON.parse(t);return isRecord(e)&&"string"==typeof e.error?{...e,error:{message:e.error},raw_error_text:t}:isRecord(e)?{...e,raw_error_text:t}:{error:{message:t},raw_error_text:t}}catch{return{error:{message:t},raw_error_text:t}}}function buildOpenAIErrorMessage(e){const t=e.data.error?.message?.trim()||e.data.raw_error_text?.trim()||`OpenAI request failed (${e.status} ${e.statusText})`,n=/requires a subscription|upgrade for access/i.test(t)?`El modelo ${e.model??"seleccionado"} requiere una suscripcion de Ollama Cloud. Cambia a otro modelo en /model o actualiza tu plan de Ollama.`:t,o=e.data.raw_error_text?.trim(),r=o&&o!==t&&o!==n?o.replace(/\s+/g," ").slice(0,400):null;return r?`${n} [model=${e.model??"unknown"} endpoint=${e.url}] ${r}`:`${n} [model=${e.model??"unknown"} endpoint=${e.url}]`}function blockToChatContentPart(e){if("text"===e.type&&"string"==typeof e.text)return{type:"text",text:e.text};if("image"===e.type){const t=isRecord(e.source)?e.source:null;if(!t)return null;if("base64"===t.type&&"string"==typeof t.data&&"string"==typeof t.media_type)return{type:"image_url",image_url:{url:`data:${t.media_type};base64,${t.data}`}};if("url"===t.type&&"string"==typeof t.url)return{type:"image_url",image_url:{url:t.url}}}const t=stringifyBlockContent(e);return t?{type:"text",text:t}:null}function toolResultToString(e){return"string"==typeof e?e:Array.isArray(e)?e.map(e=>"string"==typeof e?e:isRecord(e)&&"string"==typeof e.text?e.text:stringifyBlockContent(e)).filter(Boolean).join("\n"):stringifyBlockContent(e)}function messageToChatMessages(e){if(!e.message||"user"!==e.type&&"assistant"!==e.type)return[];const t=e.message.content,n=Array.isArray(t)?t:[{type:"text",text:String(t??"")}];if("assistant"===e.type){const e=[],t=[];for(const o of n)"thinking"!==o.type&&"redacted_thinking"!==o.type&&("tool_use"===o.type&&"string"==typeof o.id&&"string"==typeof o.name?e.push({id:o.id,type:"function",function:{name:o.name,arguments:O(o.input??{})}}):"text"===o.type&&"string"==typeof o.text&&o.text.trim()&&t.push(o.text));const o={role:"assistant",content:t.join("\n")};return e.length>0&&(o.tool_calls=e),[o]}const o=[],r=[];for(const e of n)if("tool_result"===e.type&&"string"==typeof e.tool_use_id)o.push({role:"tool",tool_call_id:e.tool_use_id,content:toolResultToString(e.content)});else{const t=blockToChatContentPart(e);t&&r.push(t)}const s=[...o];if(r.length>0){const e=r.every(e=>"text"===e.type);s.push({role:"user",content:e?r.map(e=>e.text).join("\n"):r})}return s}function parseChatCompletionResponse(e){const t=[];for(const n of e.choices??[]){const e=n.message;if(e){"string"==typeof e.content&&e.content.trim()&&t.push({type:"text",text:e.content});for(const n of e.tool_calls??[])t.push({type:"tool_use",id:n.id,name:n.function?.name??"tool",input:parseFunctionCallArguments(n.function?.arguments)})}}return{content:t}}function getChatUsage(e){if("number"==typeof e.usage?.prompt_tokens||"number"==typeof e.usage?.completion_tokens)return{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}function buildChatToolChoice(e){if(!e.toolChoice)return"auto";switch(e.toolChoice.type){case"auto":default:return"auto";case"any":return"required";case"none":return"none";case"tool":return"string"==typeof e.toolChoice.name?{type:"function",function:{name:e.toolChoice.name}}:"auto"}}function chatContentToGeminiParts(e){return"string"==typeof e?e?[{text:e}]:[]:Array.isArray(e)?e.map(e=>"text"===e.type?e.text?{text:e.text}:null:"image_url"===e.type?{text:`[Image input: ${e.image_url.url}]`}:null).filter(e=>null!==e):[]}function buildGeminiContents(e){const t=new Map,n=[];for(const o of e){if("system"===o.role)continue;if("assistant"===o.role){const e=chatContentToGeminiParts(o.content);for(const n of o.tool_calls??[]){t.set(n.id,n.function.name);const o=parseFunctionCallArguments(n.function.arguments);e.push({functionCall:{name:n.function.name,args:isPlainObject(o)?o:{raw:o}}})}e.length>0&&n.push({role:"model",parts:e});continue}if("tool"===o.role){const e=o.tool_call_id?t.get(o.tool_call_id)??"tool":"tool";n.push({role:"function",parts:[{functionResponse:{name:e,response:{result:o.content??""}}}]});continue}const e=chatContentToGeminiParts(o.content);e.length>0&&n.push({role:"user",parts:e})}return n.length>0?n:[{role:"user",parts:[{text:""}]}]}function getGeminiEnumType(e){switch(typeof e){case"string":return"string";case"number":return Number.isInteger(e)?"integer":"number";case"boolean":return"boolean";default:return}}function sanitizeGeminiSchema(e){if(!isRecord(e))return{type:"object",properties:{}};const t=Array.isArray(e.anyOf)?e.anyOf:Array.isArray(e.any_of)?e.any_of:null,n=Array.isArray(e.oneOf)?e.oneOf:Array.isArray(e.one_of)?e.one_of:null;if(t||n){const e=function(e){const t=[];let n,o=!1;for(const r of e){if(!isRecord(r))return null;if("null"===r.type){o=!0;continue}const e=void 0!==r.const?[r.const]:Array.isArray(r.enum)?r.enum:null;if(!e)return null;for(const o of e){const e=getGeminiEnumType(o);if(!e)return null;if(n&&n!==e)return null;n=e,t.push(o)}}return n&&0!==t.length?{type:n,enum:Array.from(new Set(t)),...o?{nullable:!0}:{}}:null}(t??n??[]);return e||{anyOf:(t??n??[]).map(sanitizeGeminiSchema)}}const o={},r=e.type;if(Array.isArray(r)){const e=r.find(e=>"null"!==e);"string"==typeof e&&(o.type=e),r.includes("null")&&(o.nullable=!0)}else"string"==typeof r&&(o.type=r);for(const t of["title","description","format","nullable","minimum","maximum","minItems","maxItems","minLength","maxLength","pattern"])void 0!==e[t]&&(o[t]=e[t]);if(Array.isArray(e.enum)?o.enum=e.enum:void 0!==e.const&&(o.enum=[e.const]),!o.type&&Array.isArray(o.enum)&&o.enum.length>0&&(o.type=getGeminiEnumType(o.enum[0])),void 0!==e.exclusiveMinimum&&void 0===o.minimum&&(o.minimum="number"==typeof e.exclusiveMinimum?e.exclusiveMinimum:e.minimum),void 0!==e.exclusiveMaximum&&void 0===o.maximum&&(o.maximum="number"==typeof e.exclusiveMaximum?e.exclusiveMaximum:e.maximum),isRecord(e.items)?o.items=sanitizeGeminiSchema(e.items):Array.isArray(e.items)&&e.items.length>0&&(o.items=sanitizeGeminiSchema(e.items[0])),isRecord(e.properties)){const t={};for(const[n,o]of Object.entries(e.properties))t[n]=sanitizeGeminiSchema(o);o.properties=t}return Array.isArray(e.required)&&(o.required=e.required.filter(e=>"string"==typeof e)),o.type||(o.type=o.properties?"object":o.items?"array":"object"),"object"!==o.type||o.properties||(o.properties={}),o}async function postGeminiCodeAssist(e,t,n,o){const r=await fetch(`https://cloudcode-pa.googleapis.com/v1internal:${e}`,{method:"POST",headers:t,body:O(n),signal:o});return{response:r,data:await readOpenAIResponseBody(r)}}function getGeminiCodeAssistMetadata(e){return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI",...e?{duetProject:e}:{}}}async function resolveGeminiCodeAssistProject(e,t){const n=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim()||void 0,o={...n?{cloudaicompanionProject:n}:{},metadata:getGeminiCodeAssistMetadata(n)},{response:r,data:s}=await postGeminiCodeAssist("loadCodeAssist",e,o,t);if(!r.ok)return n;if("string"==typeof s.cloudaicompanionProject)return s.cloudaicompanionProject;if(n)return n;const i=Array.isArray(s.allowedTiers)?s.allowedTiers.filter(isRecord):[],a=i.find(e=>!0===e.isDefault)??i[0],u="string"==typeof a?.id?a.id:void 0;if(!u)return;const{response:l,data:c}=await postGeminiCodeAssist("onboardUser",e,{tierId:u,metadata:getGeminiCodeAssistMetadata()},t);if(!l.ok)return;const p=isRecord(c.response)?c.response:c,m=isRecord(p.cloudaicompanionProject)?p.cloudaicompanionProject:null;return"string"==typeof m?.id?m.id:void 0}async function createGeminiGoogleChatCompletionResponse(e){const{model:n,chatMessages:r,chatTools:s,toolChoice:i,signal:a,maxOutputTokens:u,temperature:l}=e,c=await o(),p=await resolveGeminiCodeAssistProject(c,a),d={};u&&(d.maxOutputTokens=u),void 0!==l&&(d.temperature=l);const f={contents:buildGeminiContents(r),session_id:t()},g=r.filter(e=>"system"===e.role&&"string"==typeof e.content).map(e=>e.content).join("\n\n");g&&(f.systemInstruction={role:"user",parts:[{text:g}]});const y=function(e){if(0!==e.length)return[{functionDeclarations:e.map(e=>({name:e.function.name,description:e.function.description,parameters:sanitizeGeminiSchema(e.function.parameters??{type:"object",properties:{}})}))}]}(s);y&&(f.tools=y);const h=function(e){if("auto"!==e)return"none"===e?{functionCallingConfig:{mode:"NONE"}}:"required"===e?{functionCallingConfig:{mode:"ANY"}}:{functionCallingConfig:{mode:"ANY",allowedFunctionNames:[e.function.name]}}}(i);h&&(f.toolConfig=h),Object.keys(d).length>0&&(f.generationConfig=d);let _=n;const A=n.toLowerCase();_=A.includes("flash")?"gemini-3-flash-preview":(A.includes("pro"),"gemini-3.1-pro-preview");const C={model:_,...p?{project:p}:{},user_prompt_id:t(),request:f},b="https://cloudcode-pa.googleapis.com/v1internal:generateContent";m(`[Gemini Google] codeassist generateContent request model=${_} (original=${n}) messages=${r.length} tools=${s.length} endpoint=${b}`);const{response:x,data:I}=await postGeminiCodeAssist("generateContent",c,C,a);if(!x.ok)throw m(`[Gemini Google] codeassist generateContent error status=${x.status} model=${n} endpoint=${b} body=${(I.error?.message??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:x.status,statusText:x.statusText,url:b,model:n,data:I}));return function(e){const n=e.response?.candidates??[];return{id:e.traceId,choices:n.map(e=>{const n=[],o=[];for(const r of e.content?.parts??[])"text"in r&&"string"==typeof r.text&&n.push(r.text),"functionCall"in r&&r.functionCall?.name&&o.push({id:`call_${t().replace(/-/g,"")}`,type:"function",function:{name:r.functionCall.name,arguments:O(r.functionCall.args??{})}});return{message:{content:n.join("")||null,tool_calls:o.length>0?o:void 0},finish_reason:e.finishReason}}),usage:{prompt_tokens:e.response?.usageMetadata?.promptTokenCount,completion_tokens:e.response?.usageMetadata?.candidatesTokenCount}}}(I)}async function createChatCompletionResponse({messages:e,systemPrompt:t,tools:n,signal:o,options:s}){const i=getOpenAICompatibleProvider();await maybeRefreshOpenAICompatibleAuth(i);const a=t.join("\n\n"),u=[...a?[{role:"system",content:a}]:[],...e.flatMap(messageToChatMessages)],l=function(e){return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.parameters,...e.strict?{strict:!0}:{}}}))}(await buildOpenAITools(n,s)),c={model:s.model,messages:u,stream:"custom-openai"!==i,..."custom-openai"!==i?{stream_options:{include_usage:!0}}:{}};if(l.length>0&&(c.tools=l,c.tool_choice=buildChatToolChoice(s)),shouldDisableParallelToolCalls(s)&&(c.parallel_tool_calls=!1),s.maxOutputTokensOverride&&(c.max_tokens=s.maxOutputTokensOverride),void 0!==s.temperatureOverride&&(c.temperature=s.temperatureOverride),s.effortValue&&(c.reasoning_effort=s.effortValue),"gemini-google"===i)return createGeminiGoogleChatCompletionResponse({model:String(s.model),chatMessages:u,chatTools:l,toolChoice:buildChatToolChoice(s),signal:o,maxOutputTokens:s.maxOutputTokensOverride,temperature:s.temperatureOverride});const p=getOpenAIMaxTimeoutRetries(),sendRequest=async(e=r(i)??"",t=0)=>{const n=`${getOpenAIBaseUrl(i)}/chat/completions`;m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions request model=${s.model} messages=${u.length} tools=${l.length} endpoint=${n}${t>0?` (retry ${t})`:""}`);const a=12e4,d=new AbortController,f=setTimeout(()=>d.abort(),a),onAbort=()=>d.abort();o?.addEventListener("abort",onAbort);try{if("custom-openai"===i)try{const e=require("fs"),t=`--- NUEVA SOLICITUD A CHINAI ---\nFecha: ${(new Date).toISOString()}\nURL: ${n}\nHeaders: ${JSON.stringify(await getOpenAIRequestHeaders(i),null,2)}\nBody: ${JSON.stringify(c,null,2)}\n\n`;e.writeFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",t)}catch(e){}m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions REQUEST BODY: ${O(c).slice(0,3e3)}`);const o=await fetch(n,{method:"POST",headers:await getOpenAIRequestHeaders(i),body:O(c),signal:d.signal}),r=await o.text();if("custom-openai"===i)try{const e=require("fs"),t=`--- RESPUESTA DE CHINAI ---\nStatus: ${o.status} ${o.statusText}\nBody: ${r}\n\n`;e.appendFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",t)}catch(e){}let a;m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions RAW response status=${o.status} bodyLength=${r.length} bodyPreview=${r.slice(0,3e3)}`);const u=r.trim();if(u.startsWith("data:")||u.startsWith("event:")){const e=function(e){const t=[];for(const n of e.split(/\r?\n\r?\n/)){const e=n.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.startsWith("data:")).map(e=>e.slice(5).trim());if(0===e.length)continue;const o=e.join("\n").trim();if(o&&"[DONE]"!==o)try{const e=JSON.parse(o);isRecord(e)&&t.push(e)}catch{}}if(0===t.length)return null;if(!t.some(e=>{const t=e.object;return"string"==typeof t&&t.startsWith("chat.completion")}))return null;let n,o,r,s,i="",a="";const u=new Map;for(const e of t){if(n||"string"!=typeof e.id||(n=e.id),isRecord(e.usage)){const t=e.usage;"number"==typeof t.prompt_tokens&&(r=t.prompt_tokens),"number"==typeof t.completion_tokens&&(s=t.completion_tokens)}const t=Array.isArray(e.choices)?e.choices:[];for(const e of t){if(!isRecord(e))continue;"string"==typeof e.finish_reason&&(o=e.finish_reason);const t=isRecord(e.delta)?e.delta:null,n=isRecord(e.message)?e.message:null,r=t??n;if(!r)continue;"string"==typeof r.content&&(i+=r.content),"string"==typeof r.reasoning_content&&(a+=r.reasoning_content);const s=Array.isArray(r.tool_calls)?r.tool_calls:[];for(const e of s){if(!isRecord(e))continue;const t="number"==typeof e.index?e.index:0,n=u.get(t)??{arguments:""};"string"==typeof e.id&&(n.id=e.id);const o=isRecord(e.function)?e.function:null;o&&("string"==typeof o.name&&(n.name=o.name),"string"==typeof o.arguments&&(n.arguments+=o.arguments)),u.set(t,n)}}}const l=i||(a?a.trim():""),c=[];for(const[,e]of[...u.entries()].sort((e,t)=>e[0]-t[0]))e.name&&c.push({id:e.id??`call_${c.length}`,type:"function",function:{name:e.name,arguments:e.arguments}});return{id:n,choices:[{message:{content:l||null,...c.length>0?{tool_calls:c}:{}},finish_reason:o}],usage:{prompt_tokens:r,completion_tokens:s}}}(r);if(e)a=e;else try{a=JSON.parse(r)}catch{a={error:{message:r.slice(0,500)}}}}else if(u)try{a=JSON.parse(r)}catch{a={error:{message:r.slice(0,500)}}}else a={};if(504===o.status&&t<1)return m(`[${getOpenAICompatibleProviderLabel(i)}] 504 Gateway Timeout, reintentando...`,{level:"warn"}),sendRequest(e,t+1);if(401===o.status){const n=await maybeRecoverOpenAICompatible401(e,i);if(n)return sendRequest(n,t)}if(!o.ok)throw m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions error status=${o.status} model=${s.model} endpoint=${n} body=${(a.error?.message??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:o.status,statusText:o.statusText,url:n,model:String(s.model),data:a}));return a}catch(n){if(n instanceof Error&&"AbortError"===n.name&&!o?.aborted){if(t<p){const n=1e3*Math.pow(2,t);return m(`[${getOpenAICompatibleProviderLabel(i)}] timeout local tras 120000ms, reintentando en ${n}ms (intento ${t+1}/${p})`,{level:"warn"}),await new Promise(e=>setTimeout(e,n)),sendRequest(e,t+1)}throw new Error("La solicitud expiró tras 120s. El servidor tardó demasiado en responder.")}throw n}finally{clearTimeout(f),o?.removeEventListener("abort",onAbort)}};return getOpenAIAccessTokenOrThrow(i),sendRequest()}async function buildOpenAITools(e,t){return(await Promise.all(e.map(n=>A(n,{getToolPermissionContext:t.getToolPermissionContext,tools:e,agents:t.agents,allowedAgentTypes:t.allowedAgentTypes,model:t.model})))).map(e=>({type:"function",name:e.name,description:e.description,parameters:e.input_schema,...e.strict?{strict:!0}:{}}))}function buildToolChoice(e){if(!e.toolChoice)return"auto";switch(e.toolChoice.type){case"auto":default:return"auto";case"any":return"required";case"none":return"none";case"tool":return"string"==typeof e.toolChoice.name?{type:"function",name:e.toolChoice.name}:"auto"}}function shouldDisableParallelToolCalls(e){const t=e.toolChoice;return Boolean(t&&"disable_parallel_tool_use"in t&&!0===t.disable_parallel_tool_use)}function parseFunctionCallArguments(e){if(isPlainObject(e))return e;if("string"!=typeof e)return null==e?{}:{raw:e};try{const t=JSON.parse(e);return isPlainObject(t)?t:{raw:t}}catch{return{raw:e}}}function parseOutputItems(e){const t=[];for(const n of e.output??[])if(n&&"object"==typeof n){if("function_call"===n.type){const e=parseFunctionCallArguments(n.arguments);t.push({type:"tool_use",id:String(n.call_id??n.id??""),name:String(n.name??"tool"),input:e});continue}if("message"===n.type)for(const e of normalizeResponseContent(n.content)){if("string"==typeof e){t.push({type:"text",text:e});continue}if(!e||"object"!=typeof e||!("type"in e))continue;const n=String(e.type??""),o="string"==typeof e.text?e.text??"":"string"==typeof e.refusal?e.refusal??"":"";"output_text"!==n&&"text"!==n&&"refusal"!==n||!o||t.push({type:"text",text:o})}}return 0===t.length&&"string"==typeof e.output_text&&t.push({type:"text",text:e.output_text}),{content:t}}function getUsage(e){if("number"==typeof e.usage?.input_tokens||"number"==typeof e.usage?.output_tokens)return{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}function sideQueryMessageToOpenAIInput(e){const t=Array.isArray(e.content)?e.content.filter(e=>"text"===e?.type&&"string"==typeof e.text).map(e=>toInputText(e.text)):[toInputText(String(e.content??""))];return[{type:"message",role:e.role,content:t.length>0?t:[toInputText("")]}]}function sideQueryToolToOpenAITool(e){return{type:"function",name:e.name,description:e.description,parameters:e.input_schema??{type:"object",properties:{}}}}function buildSideQueryToolChoice(e){return e&&"auto"!==e?"none"===e||"none"===e.type?"none":"any"===e.type?"required":"auto"===e.type?"auto":"string"==typeof e.name&&e.name?{type:"function",name:e.name}:"auto":"auto"}function sideQueryMessageToChatMessage(e){const t=Array.isArray(e.content)?e.content.filter(e=>"text"===e?.type&&"string"==typeof e.text).map(e=>e.text).join("\n"):String(e.content??"");return{role:e.role,content:t}}function sideQueryToolToChatTool(e){return{type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema??{type:"object",properties:{}}}}}export async function queryOpenAISideQuery({model:e,systemPrompt:t,messages:n,tools:o,toolChoice:s,outputFormat:i,signal:a,maxOutputTokens:u,temperature:l}){const c=getOpenAICompatibleProvider();await maybeRefreshOpenAICompatibleAuth(c);const p=getOpenAIBaseUrl(c),d=r(c);if(!("openai"===c&&d&&isJwtToken(d))){const r=[...t?[{role:"system",content:t}]:[],...n.map(sideQueryMessageToChatMessage)],d={model:e,messages:r,stream:!1},f=o?.map(sideQueryToolToChatTool)??[],g=function(e){const t=buildSideQueryToolChoice(e);return"auto"===t||"none"===t?t:"required"===t?"required":{type:"function",function:{name:t.name}}}(s);if(f.length>0&&(d.tools=f,d.tool_choice=g),"json_schema"===i?.type&&(d.response_format={type:"json_schema",json_schema:{name:"side_query_output",strict:!0,schema:i.schema}}),u&&(d.max_tokens=u),void 0!==l&&(d.temperature=l),"gemini-google"===c){const t=await createGeminiGoogleChatCompletionResponse({model:e,chatMessages:r,chatTools:f,toolChoice:g,signal:a,maxOutputTokens:u,temperature:l});return{id:t.id,content:parseChatCompletionResponse(t).content,usage:getChatUsage(t)}}const y=`${p}/chat/completions`,h=await getOpenAIRequestHeaders(c);if("custom-openai"===c)try{const e=require("fs"),t=`--- NUEVA SOLICITUD DE VALIDACION DE MODELO A CHINAI ---\nFecha: ${(new Date).toISOString()}\nURL: ${y}\nHeaders: ${JSON.stringify(h,null,2)}\nBody: ${JSON.stringify(d,null,2)}\n\n`;e.appendFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",t)}catch(e){}const _=await fetch(y,{method:"POST",headers:h,body:O(d),signal:a});if("custom-openai"===c)try{const e=_.clone(),t=await e.text(),n=require("fs"),o=`--- RESPUESTA DE VALIDACION DE MODELO DE CHINAI ---\nStatus: ${_.status} ${_.statusText}\nBody: ${t}\n\n`;n.appendFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",o)}catch(e){}const A=await readOpenAIResponseBody(_);if(!_.ok)throw m(`[${getOpenAICompatibleProviderLabel(c)}] sideQuery chat.completions error status=${_.status} model=${e} endpoint=${y} body=${(A.error?.message??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:_.status,statusText:_.statusText,url:y,model:e,data:A}));return{id:A.id,content:parseChatCompletionResponse(A).content,usage:getChatUsage(A)}}const f={model:e,input:n.flatMap(sideQueryMessageToOpenAIInput),instructions:t,stream:!1,store:!1};o&&o.length>0&&(f.tools=o.map(sideQueryToolToOpenAITool),f.tool_choice=buildSideQueryToolChoice(s)),"json_schema"===i?.type&&(f.text={format:{type:"json_schema",name:"side_query_output",strict:!0,schema:i.schema}}),u&&(f.max_output_tokens=u),void 0!==l&&(f.temperature=l);const g=`${p}/responses`,y=await fetch(g,{method:"POST",headers:await getOpenAIRequestHeaders(c),body:O(f),signal:a}),h=await readOpenAIResponseBody(y);if(!y.ok)throw m(`[${getOpenAICompatibleProviderLabel(c)}] sideQuery error status=${y.status} model=${e} endpoint=${p}/responses body=${(h.raw_error_text??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:y.status,statusText:y.statusText,url:`${p}/responses`,model:e,data:h}));return{id:h.id,content:parseOutputItems(h).content,usage:getUsage(h)}}async function createOpenAIResponse(e){const{messages:t,systemPrompt:n,tools:o,signal:r,options:s}=e,i=getOpenAICompatibleProvider();await maybeRefreshOpenAICompatibleAuth(i);const a=getOpenAIAccessTokenOrThrow(i),u="openai"===i&&isJwtToken(a);if(!u){const t=await createChatCompletionResponse(e);return{id:t.id,output:t.choices?.flatMap(e=>{const t=[];if(e.message?.content&&t.push({type:"message",role:"assistant",content:[e.message.content]}),e.message?.tool_calls)for(const n of e.message.tool_calls)t.push({type:"function_call",call_id:n.id,name:n.function.name,arguments:n.function.arguments});return t})??[],usage:{input_tokens:t.usage?.prompt_tokens,output_tokens:t.usage?.completion_tokens}}}const l=t.flatMap(messageToOpenAIInput),p=await buildOpenAITools(o,s),d={model:s.model,input:l,instructions:n.join("\n\n"),tools:p,tool_choice:buildToolChoice(s),stream:!1,store:!1};shouldDisableParallelToolCalls(s)&&(d.parallel_tool_calls=!1),s.maxOutputTokensOverride&&(d.max_output_tokens=s.maxOutputTokensOverride),void 0!==s.temperatureOverride&&(d.temperature=s.temperatureOverride),s.effortValue&&(d.reasoning={effort:s.effortValue});const f=getOpenAIMaxTimeoutRetries(),sendRequest=async(e,t=0)=>{const n=u?{...d,stream:!0}:d;let o,a;if(u){const t=function(e){try{const t=JSON.parse(atob(e.split(".")[1])),n=t?.["https://api.openai.com/auth"]?.chatgpt_account_id;if(!n)throw new Error("No account ID in token");return n}catch{throw new Error("Failed to extract chatgpt-account-id from OAuth token")}}(e);o=function(){const e=(process.env.OPENAI_OAUTH_BASE_URL||"https://chatgpt.com/backend-api").replace(/\/+$/,"");return e.endsWith("/codex/responses")?e:e.endsWith("/codex")?`${e}/responses`:`${e}/codex/responses`}(),a={Authorization:`Bearer ${e}`,"chatgpt-account-id":t,"OpenAI-Beta":"responses=experimental",originator:c(),"content-type":"application/json",accept:"application/json"}}else o=`${getOpenAIBaseUrl(i)}/responses`,a={Authorization:`Bearer ${e}`,"Content-Type":"application/json"};const l=12e4,p=new AbortController,g=setTimeout(()=>p.abort(),l),onAbort=()=>p.abort();r?.addEventListener("abort",onAbort);try{const r=await fetch(o,{method:"POST",headers:a,body:O(n),signal:p.signal}),l=await readOpenAIResponseBody(r);if(504===r.status&&t<1)return m(`[${getOpenAICompatibleProviderLabel(i)}] responses 504 Gateway Timeout, reintentando...`,{level:"warn"}),sendRequest(e,t+1);if(401===r.status){const n=await maybeRecoverOpenAICompatible401(e,i);if(n)return sendRequest(n,t)}if(!r.ok)throw m(`[${getOpenAICompatibleProviderLabel(i)}] responses error status=${r.status} model=${s.model} endpoint=${o} oauth=${u} body=${(l.raw_error_text??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:r.status,statusText:r.statusText,url:o,model:String(s.model),data:l}));return l}catch(n){if(n instanceof Error&&"AbortError"===n.name&&!r?.aborted){if(t<f){const n=1e3*Math.pow(2,t);return m(`[${getOpenAICompatibleProviderLabel(i)}] responses timeout local tras 120000ms, reintentando en ${n}ms (intento ${t+1}/${f})`,{level:"warn"}),await new Promise(e=>setTimeout(e,n)),sendRequest(e,t+1)}throw new Error("La solicitud expiró tras 120s. El servidor tardó demasiado en responder.")}throw n}finally{clearTimeout(g),r?.removeEventListener("abort",onAbort)}};return sendRequest(a)}export async function*queryOpenAIModelWithStreaming({messages:t,systemPrompt:n,thinkingConfig:o,tools:r,signal:s,options:i}){try{for(let e=1;e<=2;e++){const o=await createOpenAIResponse({messages:1===e?t:[...t,y({content:"System reminder: your previous response for this turn was empty. Continue the current task without asking the user to repeat themselves. If a tool call is needed, emit the appropriate tool call now. Do not return an empty response.",isMeta:!0})],systemPrompt:n,tools:r,signal:s,options:i}),{content:a}=parseOutputItems(o),u=getUsage(o);if(u)try{const e={input_tokens:u.input_tokens??0,output_tokens:u.output_tokens??0,cache_read_input_tokens:0,cache_creation_input_tokens:0},t=String(i.model),n=_(t,e);h(n,e,t)}catch(e){d(e)}if(a.length>0)return void(yield g({content:a,usage:u}));if(!(e<2))return void(yield f({content:"OpenAI returned no content after retrying."}));m(`[${getOpenAICompatibleProviderLabel(getOpenAICompatibleProvider())}] empty model response with no content; retrying request (${e}/1)`,{level:"warn"})}}catch(t){if(s.aborted)throw new e;d(t),yield f({content:p(t),errorDetails:p(t)})}}
1
+ import{APIUserAbortError as e}from"@anthropic-ai/sdk/error.js";import{randomUUID as t}from"node:crypto";import{checkAndRefreshOpenAIOAuthTokenIfNeeded as n,getGeminiGoogleAuthHeaders as o,getOpenAICompatibleAccessToken as r,getOpenAIAccessToken as s,handleOpenAIOAuth401Error as i}from"../../utils/auth.js";import{getAPIProvider as a,isOpenAICompatibleProvider as u}from"../../utils/model/providers.js";import{getConfiguredProviderBaseUrl as l}from"../../utils/model/providerBaseUrls.js";import{getOpenAIOriginator as c}from"../../constants/oauth.js";import{errorMessage as p}from"../../utils/errors.js";import{logForDebugging as m}from"../../utils/debug.js";import{logError as d}from"../../utils/log.js";import{createAssistantAPIErrorMessage as f,createAssistantMessage as g,createUserMessage as y}from"../../utils/messages.js";import{addToTotalSessionCost as h}from"../../cost-tracker.js";import{calculateUSDCost as _}from"../../utils/modelCost.js";import{toolToAPISchema as A}from"../../utils/api.js";import{jsonStringify as O}from"../../utils/slowOperations.js";function getOpenAIMaxTimeoutRetries(){const e=process.env.CONTEXT_CODE_MAX_RETRIES;if(!e)return 10;const t=Number.parseInt(e,10);return!Number.isFinite(t)||t<0?10:t}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function isPlainObject(e){if(!isRecord(e))return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function isJwtToken(e){return 3===e.split(".").length}function getOpenAICompatibleProvider(){const e=a();return u(e)?e:"openai"}function getOpenAICompatibleProviderLabel(e=getOpenAICompatibleProvider()){switch(e){case"openrouter":return"OpenRouter";case"ollama":return"Ollama";case"ollama-cloud":return"Ollama Cloud";case"lmstudio":return"LM Studio";case"gemini-api":return"Gemini API";case"gemini-google":return"Gemini Google";case"zai":return"Z.AI";case"nvidia":return"NVIDIA NIM";case"custom-openai":return"Custom OpenAI";default:return"OpenAI"}}function getOpenAIBaseUrl(e=getOpenAICompatibleProvider()){if("openrouter"===e){const e=process.env.OPENROUTER_BASE_URL||l("openrouter")||"https://openrouter.ai/api/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("ollama"===e){const e=process.env.OLLAMA_BASE_URL||l("ollama")||"http://localhost:11434/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("ollama-cloud"===e){const e=process.env.OLLAMA_CLOUD_BASE_URL||process.env.OLLAMA_BASE_URL||l("ollama-cloud")||"http://localhost:11434/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("lmstudio"===e){const e=process.env.LMSTUDIO_BASE_URL||process.env.LM_STUDIO_BASE_URL||l("lmstudio")||"http://localhost:1234/v1";return e.endsWith("/v1")?e:e.endsWith("/")?`${e}v1`:`${e}/v1`}if("zai"===e){const e=process.env.ZAI_BASE_URL||l("zai")||"https://api.z.ai/api/coding/paas/v4";return e.endsWith("/")?e.slice(0,-1):e}if("gemini-api"===e||"gemini-google"===e){const t=("gemini-api"===e?process.env.GEMINI_BASE_URL||process.env.GEMINI_API_BASE_URL:process.env.GEMINI_GOOGLE_BASE_URL||process.env.GEMINI_BASE_URL)||l(e)||"https://generativelanguage.googleapis.com/v1beta/openai";return t.endsWith("/")?t.slice(0,-1):t}if("nvidia"===e){const e=process.env.NVIDIA_BASE_URL||l("nvidia")||"https://integrate.api.nvidia.com/v1";return e.endsWith("/")?e.slice(0,-1):e}if("custom-openai"===e){let e=l("custom-openai")||"https://api.openai.com/v1";return e.startsWith("http://chinai.iaforged.com")&&(e=e.replace("http://chinai.iaforged.com","https://chinai.iaforged.com")),e.endsWith("/")?e.slice(0,-1):e}if("openai"!==e&&"custom-openai"!==e){const t=l(e);return t.endsWith("/")?t.slice(0,-1):t}const t=process.env.OPENAI_API_BASE_URL||process.env.OPENAI_BASE_URL||"https://api.openai.com/v1";return t.endsWith("/v1")?t:t.endsWith("/")?`${t}v1`:`${t}/v1`}async function getOpenAIRequestHeaders(e=getOpenAICompatibleProvider()){return"gemini-google"===e?o():function(e=getOpenAICompatibleProvider()){const t=r(e);if(isLocalOllamaProviderHost(e,getOpenAIBaseUrl(e)))return{"Content-Type":"application/json"};if(!t)throw new Error(`${getOpenAICompatibleProviderLabel(e)} is selected but no credentials were found.`);return"custom-openai"===e?{Authorization:`Bearer ${t}`,"X-API-Key":t,"api-key":t,"Content-Type":"application/json"}:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"}}(e)}function isLocalOllamaProviderHost(e,t=getOpenAIBaseUrl(e)){return("ollama"===e||"ollama-cloud"===e)&&(t.includes("localhost")||t.includes("127.0.0.1"))}function getOpenAIAccessTokenOrThrow(e=getOpenAICompatibleProvider()){if(isLocalOllamaProviderHost(e))return"ollama";if("gemini-google"===e)return r(e)||"google-application-default-credentials";const t=r(e);if(!t)throw new Error(`${getOpenAICompatibleProviderLabel(e)} is selected but no credentials were found.`);return t}async function maybeRefreshOpenAICompatibleAuth(e=getOpenAICompatibleProvider()){"openai"===e&&await n()}async function maybeRecoverOpenAICompatible401(e,t=getOpenAICompatibleProvider()){if("openai"!==t)return null;if(!await i(e))return null;const n=s();return n&&n!==e?n:null}function toInputText(e){return{type:"input_text",text:e}}function toOutputText(e){return{type:"output_text",text:e}}function normalizeBlocksForRole(e,t){return"assistant"!==t?e:e.map(e=>"input_text"===e.type?toOutputText(e.text):e)}function stringifyBlockContent(e){return"string"==typeof e?e:Array.isArray(e)?e.map(e=>"string"==typeof e?e:e&&"object"==typeof e&&"type"in e&&"text"===e.type&&"text"in e&&"string"==typeof e.text?e.text:O(e)).join("\n"):null==e?"":O(e)}function normalizeResponseContent(e){return Array.isArray(e)?e:null==e?[]:[e]}function blockToOpenAIContentBlocks(e){if(!isRecord(e))return null;if("text"===e.type&&"string"==typeof e.text)return[toInputText(e.text)];if("image"===e.type){const t=isRecord(e.source)?e.source:null,n=t?function(e){if("base64"===e.type){const t=e.media_type,n=e.data;return"string"!=typeof t||"string"!=typeof n?null:{type:"input_image",image_url:`data:${t};base64,${n}`}}return"url"===e.type&&"string"==typeof e.url?{type:"input_image",image_url:e.url}:"file"===e.type&&"string"==typeof e.file_id?{type:"input_image",file_id:e.file_id}:null}(t):null;return n?[n]:null}if("document"===e.type){const t=isRecord(e.source)?e.source:null;if(!t)return null;const n=function(e,t){return"file"===e.type&&"string"==typeof e.file_id?{type:"input_file",file_id:e.file_id}:"base64"===e.type&&"string"==typeof e.data?"string"!=typeof e.media_type?null:{type:"input_file",file_data:e.data,..."string"==typeof t&&t?{filename:t}:{}}:"url"===e.type&&"string"==typeof e.url?{type:"input_file",file_url:e.url,..."string"==typeof t&&t?{filename:t}:{}}:"text"===e.type&&"string"==typeof e.data?toInputText(e.data):null}(t,"string"==typeof e.title?e.title:void 0);if(n)return[n];if("content"===t.type&&"string"==typeof t.content)return[toInputText(t.content)];if("content"===t.type&&Array.isArray(t.content)){const e=[];for(const n of t.content){const t=blockToOpenAIContentBlocks(n);t&&e.push(...t)}return e.length>0?e:null}return null}if("search_result"===e.type&&Array.isArray(e.content)){const t=[];"string"==typeof e.title&&e.title.trim()&&t.push(e.title.trim()),"string"==typeof e.source&&e.source.trim()&&t.push(e.source.trim());for(const n of e.content)if(n&&"object"==typeof n&&"text"in n){const e=n.text;"string"==typeof e&&e.trim()&&t.push(e.trim())}return[toInputText(t.join("\n\n"))]}if("container_upload"===e.type&&"string"==typeof e.file_id)return[{type:"input_file",file_id:e.file_id}];if(("bash_code_execution_output"===e.type||"mcp_tool_result"===e.type||"code_execution_tool_result"===e.type||"web_search_tool_result"===e.type||"web_fetch_tool_result"===e.type||"text_editor_code_execution_tool_result"===e.type||"tool_search_tool_result"===e.type)&&"content"in e){const t=e.content;if("string"==typeof t)return[toInputText(t)];if(Array.isArray(t)){const e=[];for(const n of t){const t=blockToOpenAIContentBlocks(n);t&&e.push(...t)}return e.length>0?e:null}}if("content"in e&&("string"==typeof e.content||Array.isArray(e.content))){const t=e.content;if("string"==typeof t)return[toInputText(t)];const n=[];for(const e of t){const t=blockToOpenAIContentBlocks(e);t&&n.push(...t)}return n.length>0?n:null}return"data"in e&&"string"==typeof e.data?[toInputText(e.data)]:null}function toolResultContentToOpenAIOutput(e){if("string"==typeof e)return e;if(!Array.isArray(e))return stringifyBlockContent(e);const t=[];for(const n of e){const e=blockToOpenAIContentBlocks(n);if(e&&e.length>0){t.push(...e);continue}const o=stringifyBlockContent(n).trim();o&&t.push(toInputText(o))}return 0===t.length?"":t.every(e=>"input_text"===e.type)?t.map(e=>e.text).join("\n\n"):t}function messageToOpenAIInput(e){if(!e.message||"user"!==e.type&&"assistant"!==e.type)return[];const t=Array.isArray(e.message.content)?e.message.content:[{type:"text",text:String(e.message.content??"")}],n="assistant"===e.type?"assistant":"user",o=[],r=[],flushMessage=()=>{0!==r.length&&(o.push({type:"message",role:n,content:[...r]}),r.length=0)};for(const s of t){if("assistant"===e.type&&"tool_use"===s.type&&"string"==typeof s.id&&"string"==typeof s.name){flushMessage(),o.push({type:"function_call",call_id:s.id,name:s.name,arguments:O(s.input??{})});continue}if("user"===e.type&&"tool_result"===s.type&&"string"==typeof s.tool_use_id){flushMessage(),o.push({type:"function_call_output",call_id:s.tool_use_id,output:toolResultContentToOpenAIOutput(s.content)});continue}if("thinking"===s.type||"redacted_thinking"===s.type)continue;const t=blockToOpenAIContentBlocks(s);t&&t.length>0?r.push(...normalizeBlocksForRole(t,n)):r.push(..."assistant"===n?[toOutputText(stringifyBlockContent(s))]:[toInputText(stringifyBlockContent(s))])}return flushMessage(),o}async function readOpenAIResponseBody(e){const t=await e.text();if(!t.trim())return{};const n=t.trim();if(n.startsWith("data:")||n.startsWith("event:"))return function(e){const t=[];for(const n of e.split(/\r?\n\r?\n/)){const e=n.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===e.length)continue;const o=e.filter(e=>e.startsWith("data:")).map(e=>e.slice(5).trim());if(0===o.length)continue;const r=o.join("\n").trim();if(r&&"[DONE]"!==r)try{const e=JSON.parse(r);isRecord(e)&&t.push(e)}catch{}}let n=null,o=null;const r=[];let s="";for(const i of t){const t="string"==typeof i.type?i.type:"";"response.completed"===t&&isRecord(i.response)?n={...i.response,raw_error_text:e}:"error"!==t?"response.output_item.done"===t&&isRecord(i.item)?r.push(i.item):"response.output_text.delta"!==t||"string"!=typeof i.delta?"response.output_text.done"===t&&"string"==typeof i.text&&(s=i.text):s+=i.delta:"string"==typeof i.message&&i.message.trim()?o=i.message:isRecord(i.error)&&"string"==typeof i.error.message&&(o=i.error.message)}if(n)return(!n.output||0===n.output.length)&&r.length>0&&(n.output=r),!n.output_text&&s&&(n.output_text=s),!n.error&&o&&(n.error={message:o}),n;if(r.length>0||s||o)return{output:r.length>0?r:void 0,output_text:s||void 0,error:o?{message:o}:void 0,raw_error_text:e};return{error:{message:e},raw_error_text:e}}(t);try{const e=JSON.parse(t);return isRecord(e)&&"string"==typeof e.error?{...e,error:{message:e.error},raw_error_text:t}:isRecord(e)?{...e,raw_error_text:t}:{error:{message:t},raw_error_text:t}}catch{return{error:{message:t},raw_error_text:t}}}function buildOpenAIErrorMessage(e){const t=e.data.error?.message?.trim()||e.data.raw_error_text?.trim()||`OpenAI request failed (${e.status} ${e.statusText})`,n=/requires a subscription|upgrade for access/i.test(t)?`El modelo ${e.model??"seleccionado"} requiere una suscripcion de Ollama Cloud. Cambia a otro modelo en /model o actualiza tu plan de Ollama.`:t,o=e.data.raw_error_text?.trim(),r=o&&o!==t&&o!==n?o.replace(/\s+/g," ").slice(0,400):null;return r?`${n} [model=${e.model??"unknown"} endpoint=${e.url}] ${r}`:`${n} [model=${e.model??"unknown"} endpoint=${e.url}]`}function blockToChatContentPart(e){if("text"===e.type&&"string"==typeof e.text)return{type:"text",text:e.text};if("image"===e.type){const t=isRecord(e.source)?e.source:null;if(!t)return null;if("base64"===t.type&&"string"==typeof t.data&&"string"==typeof t.media_type)return{type:"image_url",image_url:{url:`data:${t.media_type};base64,${t.data}`}};if("url"===t.type&&"string"==typeof t.url)return{type:"image_url",image_url:{url:t.url}}}const t=stringifyBlockContent(e);return t?{type:"text",text:t}:null}function toolResultToString(e){return"string"==typeof e?e:Array.isArray(e)?e.map(e=>"string"==typeof e?e:isRecord(e)&&"string"==typeof e.text?e.text:stringifyBlockContent(e)).filter(Boolean).join("\n"):stringifyBlockContent(e)}function messageToChatMessages(e){if(!e.message||"user"!==e.type&&"assistant"!==e.type)return[];const t=e.message.content,n=Array.isArray(t)?t:[{type:"text",text:String(t??"")}];if("assistant"===e.type){const e=[],t=[];for(const o of n)"thinking"!==o.type&&"redacted_thinking"!==o.type&&("tool_use"===o.type&&"string"==typeof o.id&&"string"==typeof o.name?e.push({id:o.id,type:"function",function:{name:o.name,arguments:O(o.input??{})}}):"text"===o.type&&"string"==typeof o.text&&o.text.trim()&&t.push(o.text));const o={role:"assistant",content:t.join("\n")};return e.length>0&&(o.tool_calls=e),[o]}const o=[],r=[];for(const e of n)if("tool_result"===e.type&&"string"==typeof e.tool_use_id)o.push({role:"tool",tool_call_id:e.tool_use_id,content:toolResultToString(e.content)});else{const t=blockToChatContentPart(e);t&&r.push(t)}const s=[...o];if(r.length>0){const e=r.every(e=>"text"===e.type);s.push({role:"user",content:e?r.map(e=>e.text).join("\n"):r})}return s}function parseChatCompletionResponse(e){const t=[];for(const n of e.choices??[]){const e=n.message;if(e){"string"==typeof e.content&&e.content.trim()&&t.push({type:"text",text:e.content});for(const n of e.tool_calls??[])t.push({type:"tool_use",id:n.id,name:n.function?.name??"tool",input:parseFunctionCallArguments(n.function?.arguments)})}}return{content:t}}function getChatUsage(e){if("number"==typeof e.usage?.prompt_tokens||"number"==typeof e.usage?.completion_tokens)return{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}function buildChatToolChoice(e){if(!e.toolChoice)return"auto";switch(e.toolChoice.type){case"auto":default:return"auto";case"any":return"required";case"none":return"none";case"tool":return"string"==typeof e.toolChoice.name?{type:"function",function:{name:e.toolChoice.name}}:"auto"}}function chatContentToGeminiParts(e){return"string"==typeof e?e?[{text:e}]:[]:Array.isArray(e)?e.map(e=>"text"===e.type?e.text?{text:e.text}:null:"image_url"===e.type?{text:`[Image input: ${e.image_url.url}]`}:null).filter(e=>null!==e):[]}function buildGeminiContents(e){const t=new Map,n=[];for(const o of e){if("system"===o.role)continue;if("assistant"===o.role){const e=chatContentToGeminiParts(o.content);for(const n of o.tool_calls??[]){t.set(n.id,n.function.name);const o=parseFunctionCallArguments(n.function.arguments);e.push({functionCall:{name:n.function.name,args:isPlainObject(o)?o:{raw:o}}})}e.length>0&&n.push({role:"model",parts:e});continue}if("tool"===o.role){const e=o.tool_call_id?t.get(o.tool_call_id)??"tool":"tool";n.push({role:"function",parts:[{functionResponse:{name:e,response:{result:o.content??""}}}]});continue}const e=chatContentToGeminiParts(o.content);e.length>0&&n.push({role:"user",parts:e})}return n.length>0?n:[{role:"user",parts:[{text:""}]}]}function getGeminiEnumType(e){switch(typeof e){case"string":return"string";case"number":return Number.isInteger(e)?"integer":"number";case"boolean":return"boolean";default:return}}function sanitizeGeminiSchema(e){if(!isRecord(e))return{type:"object",properties:{}};const t=Array.isArray(e.anyOf)?e.anyOf:Array.isArray(e.any_of)?e.any_of:null,n=Array.isArray(e.oneOf)?e.oneOf:Array.isArray(e.one_of)?e.one_of:null;if(t||n){const e=function(e){const t=[];let n,o=!1;for(const r of e){if(!isRecord(r))return null;if("null"===r.type){o=!0;continue}const e=void 0!==r.const?[r.const]:Array.isArray(r.enum)?r.enum:null;if(!e)return null;for(const o of e){const e=getGeminiEnumType(o);if(!e)return null;if(n&&n!==e)return null;n=e,t.push(o)}}return n&&0!==t.length?{type:n,enum:Array.from(new Set(t)),...o?{nullable:!0}:{}}:null}(t??n??[]);return e||{anyOf:(t??n??[]).map(sanitizeGeminiSchema)}}const o={},r=e.type;if(Array.isArray(r)){const e=r.find(e=>"null"!==e);"string"==typeof e&&(o.type=e),r.includes("null")&&(o.nullable=!0)}else"string"==typeof r&&(o.type=r);for(const t of["title","description","format","nullable","minimum","maximum","minItems","maxItems","minLength","maxLength","pattern"])void 0!==e[t]&&(o[t]=e[t]);if(Array.isArray(e.enum)?o.enum=e.enum:void 0!==e.const&&(o.enum=[e.const]),!o.type&&Array.isArray(o.enum)&&o.enum.length>0&&(o.type=getGeminiEnumType(o.enum[0])),void 0!==e.exclusiveMinimum&&void 0===o.minimum&&(o.minimum="number"==typeof e.exclusiveMinimum?e.exclusiveMinimum:e.minimum),void 0!==e.exclusiveMaximum&&void 0===o.maximum&&(o.maximum="number"==typeof e.exclusiveMaximum?e.exclusiveMaximum:e.maximum),isRecord(e.items)?o.items=sanitizeGeminiSchema(e.items):Array.isArray(e.items)&&e.items.length>0&&(o.items=sanitizeGeminiSchema(e.items[0])),isRecord(e.properties)){const t={};for(const[n,o]of Object.entries(e.properties))t[n]=sanitizeGeminiSchema(o);o.properties=t}return Array.isArray(e.required)&&(o.required=e.required.filter(e=>"string"==typeof e)),o.type||(o.type=o.properties?"object":o.items?"array":"object"),"object"!==o.type||o.properties||(o.properties={}),o}async function postGeminiCodeAssist(e,t,n,o){const r=await fetch(`https://cloudcode-pa.googleapis.com/v1internal:${e}`,{method:"POST",headers:t,body:O(n),signal:o});return{response:r,data:await readOpenAIResponseBody(r)}}function getGeminiCodeAssistMetadata(e){return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI",...e?{duetProject:e}:{}}}async function resolveGeminiCodeAssistProject(e,t){const n=process.env.GEMINI_GOOGLE_PROJECT_ID?.trim()||void 0,o={...n?{cloudaicompanionProject:n}:{},metadata:getGeminiCodeAssistMetadata(n)},{response:r,data:s}=await postGeminiCodeAssist("loadCodeAssist",e,o,t);if(!r.ok)return n;if("string"==typeof s.cloudaicompanionProject)return s.cloudaicompanionProject;if(n)return n;const i=Array.isArray(s.allowedTiers)?s.allowedTiers.filter(isRecord):[],a=i.find(e=>!0===e.isDefault)??i[0],u="string"==typeof a?.id?a.id:void 0;if(!u)return;const{response:l,data:c}=await postGeminiCodeAssist("onboardUser",e,{tierId:u,metadata:getGeminiCodeAssistMetadata()},t);if(!l.ok)return;const p=isRecord(c.response)?c.response:c,m=isRecord(p.cloudaicompanionProject)?p.cloudaicompanionProject:null;return"string"==typeof m?.id?m.id:void 0}async function createGeminiGoogleChatCompletionResponse(e){const{model:n,chatMessages:r,chatTools:s,toolChoice:i,signal:a,maxOutputTokens:u,temperature:l}=e,c=await o(),p=await resolveGeminiCodeAssistProject(c,a),d={};u&&(d.maxOutputTokens=u),void 0!==l&&(d.temperature=l);const f={contents:buildGeminiContents(r),session_id:t()},g=r.filter(e=>"system"===e.role&&"string"==typeof e.content).map(e=>e.content).join("\n\n");g&&(f.systemInstruction={role:"user",parts:[{text:g}]});const y=function(e){if(0!==e.length)return[{functionDeclarations:e.map(e=>({name:e.function.name,description:e.function.description,parameters:sanitizeGeminiSchema(e.function.parameters??{type:"object",properties:{}})}))}]}(s);y&&(f.tools=y);const h=function(e){if("auto"!==e)return"none"===e?{functionCallingConfig:{mode:"NONE"}}:"required"===e?{functionCallingConfig:{mode:"ANY"}}:{functionCallingConfig:{mode:"ANY",allowedFunctionNames:[e.function.name]}}}(i);h&&(f.toolConfig=h),Object.keys(d).length>0&&(f.generationConfig=d);let _=n;const A=n.toLowerCase();_=A.includes("flash")?"gemini-3-flash-preview":(A.includes("pro"),"gemini-3.1-pro-preview");const C={model:_,...p?{project:p}:{},user_prompt_id:t(),request:f},b="https://cloudcode-pa.googleapis.com/v1internal:generateContent";m(`[Gemini Google] codeassist generateContent request model=${_} (original=${n}) messages=${r.length} tools=${s.length} endpoint=${b}`);const{response:x,data:I}=await postGeminiCodeAssist("generateContent",c,C,a);if(!x.ok)throw m(`[Gemini Google] codeassist generateContent error status=${x.status} model=${n} endpoint=${b} body=${(I.error?.message??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:x.status,statusText:x.statusText,url:b,model:n,data:I}));return function(e){const n=e.response?.candidates??[];return{id:e.traceId,choices:n.map(e=>{const n=[],o=[];for(const r of e.content?.parts??[])"text"in r&&"string"==typeof r.text&&n.push(r.text),"functionCall"in r&&r.functionCall?.name&&o.push({id:`call_${t().replace(/-/g,"")}`,type:"function",function:{name:r.functionCall.name,arguments:O(r.functionCall.args??{})}});return{message:{content:n.join("")||null,tool_calls:o.length>0?o:void 0},finish_reason:e.finishReason}}),usage:{prompt_tokens:e.response?.usageMetadata?.promptTokenCount,completion_tokens:e.response?.usageMetadata?.candidatesTokenCount}}}(I)}async function createChatCompletionResponse({messages:e,systemPrompt:t,tools:n,signal:o,options:s}){const i=getOpenAICompatibleProvider();await maybeRefreshOpenAICompatibleAuth(i);const a=t.join("\n\n"),u=[...a?[{role:"system",content:a}]:[],...e.flatMap(messageToChatMessages)],l=function(e){return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.parameters,...e.strict?{strict:!0}:{}}}))}(await buildOpenAITools(n,s)),c={model:s.model,messages:u,stream:"custom-openai"!==i,..."custom-openai"!==i?{stream_options:{include_usage:!0}}:{}};if(l.length>0&&(c.tools=l,c.tool_choice=buildChatToolChoice(s)),shouldDisableParallelToolCalls(s)&&(c.parallel_tool_calls=!1),s.maxOutputTokensOverride&&(c.max_tokens=s.maxOutputTokensOverride),void 0!==s.temperatureOverride&&(c.temperature=s.temperatureOverride),s.effortValue&&(c.reasoning_effort=s.effortValue),"gemini-google"===i)return createGeminiGoogleChatCompletionResponse({model:String(s.model),chatMessages:u,chatTools:l,toolChoice:buildChatToolChoice(s),signal:o,maxOutputTokens:s.maxOutputTokensOverride,temperature:s.temperatureOverride});const p=getOpenAIMaxTimeoutRetries(),sendRequest=async(e=r(i)??"",t=0)=>{const n=`${getOpenAIBaseUrl(i)}/chat/completions`;m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions request model=${s.model} messages=${u.length} tools=${l.length} endpoint=${n}${t>0?` (retry ${t})`:""}`);const a=12e4,d=new AbortController,f=setTimeout(()=>d.abort(),a),onAbort=()=>d.abort();o?.addEventListener("abort",onAbort);try{if("custom-openai"===i)try{const e=require("fs"),t=`--- NUEVA SOLICITUD A CHINAI ---\nFecha: ${(new Date).toISOString()}\nURL: ${n}\nHeaders: ${JSON.stringify(await getOpenAIRequestHeaders(i),null,2)}\nBody: ${JSON.stringify(c,null,2)}\n\n`;e.writeFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",t)}catch(e){}m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions REQUEST BODY: ${O(c).slice(0,3e3)}`);const o=await fetch(n,{method:"POST",headers:await getOpenAIRequestHeaders(i),body:O(c),signal:d.signal}),r=await o.text();if("custom-openai"===i)try{const e=require("fs"),t=`--- RESPUESTA DE CHINAI ---\nStatus: ${o.status} ${o.statusText}\nBody: ${r}\n\n`;e.appendFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",t)}catch(e){}let a;m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions RAW response status=${o.status} bodyLength=${r.length} bodyPreview=${r.slice(0,3e3)}`);const u=r.trim();if(u.startsWith("data:")||u.startsWith("event:")){const e=function(e){const t=[];for(const n of e.split(/\r?\n\r?\n/)){const e=n.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.startsWith("data:")).map(e=>e.slice(5).trim());if(0===e.length)continue;const o=e.join("\n").trim();if(o&&"[DONE]"!==o)try{const e=JSON.parse(o);isRecord(e)&&t.push(e)}catch{}}if(0===t.length)return null;if(!t.some(e=>{const t=e.object;return"string"==typeof t&&t.startsWith("chat.completion")}))return null;let n,o,r,s,i="",a="";const u=new Map;for(const e of t){if(n||"string"!=typeof e.id||(n=e.id),isRecord(e.usage)){const t=e.usage;"number"==typeof t.prompt_tokens&&(r=t.prompt_tokens),"number"==typeof t.completion_tokens&&(s=t.completion_tokens)}const t=Array.isArray(e.choices)?e.choices:[];for(const e of t){if(!isRecord(e))continue;"string"==typeof e.finish_reason&&(o=e.finish_reason);const t=isRecord(e.delta)?e.delta:null,n=isRecord(e.message)?e.message:null,r=t??n;if(!r)continue;"string"==typeof r.content&&(i+=r.content),"string"==typeof r.reasoning_content&&(a+=r.reasoning_content);const s=Array.isArray(r.tool_calls)?r.tool_calls:[];for(const e of s){if(!isRecord(e))continue;const t="number"==typeof e.index?e.index:0,n=u.get(t)??{arguments:""};"string"==typeof e.id&&(n.id=e.id);const o=isRecord(e.function)?e.function:null;o&&("string"==typeof o.name&&(n.name=o.name),"string"==typeof o.arguments&&(n.arguments+=o.arguments)),u.set(t,n)}}}const l=i||(a?a.trim():""),c=[];for(const[,e]of[...u.entries()].sort((e,t)=>e[0]-t[0]))e.name&&c.push({id:e.id??`call_${c.length}`,type:"function",function:{name:e.name,arguments:e.arguments}});return{id:n,choices:[{message:{content:l||null,...c.length>0?{tool_calls:c}:{}},finish_reason:o}],usage:{prompt_tokens:r,completion_tokens:s}}}(r);if(e)a=e;else try{a=JSON.parse(r)}catch{a={error:{message:r.slice(0,500)}}}}else if(u)try{a=JSON.parse(r)}catch{a={error:{message:r.slice(0,500)}}}else a={};if(504===o.status&&t<1)return m(`[${getOpenAICompatibleProviderLabel(i)}] 504 Gateway Timeout, reintentando...`,{level:"warn"}),sendRequest(e,t+1);if(401===o.status){const n=await maybeRecoverOpenAICompatible401(e,i);if(n)return sendRequest(n,t)}if(!o.ok)throw m(`[${getOpenAICompatibleProviderLabel(i)}] chat.completions error status=${o.status} model=${s.model} endpoint=${n} body=${(a.error?.message??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:o.status,statusText:o.statusText,url:n,model:String(s.model),data:a}));return a}catch(n){if(n instanceof Error&&"AbortError"===n.name&&!o?.aborted){if(t<p){const n=1e3*Math.pow(2,t);return m(`[${getOpenAICompatibleProviderLabel(i)}] timeout local tras 120000ms, reintentando en ${n}ms (intento ${t+1}/${p})`,{level:"warn"}),await new Promise(e=>setTimeout(e,n)),sendRequest(e,t+1)}throw new Error("La solicitud expiró tras 120s. El servidor tardó demasiado en responder.")}throw n}finally{clearTimeout(f),o?.removeEventListener("abort",onAbort)}};return getOpenAIAccessTokenOrThrow(i),sendRequest()}async function buildOpenAITools(e,t){return(await Promise.all(e.map(n=>A(n,{getToolPermissionContext:t.getToolPermissionContext,tools:e,agents:t.agents,allowedAgentTypes:t.allowedAgentTypes,model:t.model})))).map(e=>({type:"function",name:e.name,description:e.description,parameters:e.input_schema,...e.strict?{strict:!0}:{}}))}function buildToolChoice(e){if(!e.toolChoice)return"auto";switch(e.toolChoice.type){case"auto":default:return"auto";case"any":return"required";case"none":return"none";case"tool":return"string"==typeof e.toolChoice.name?{type:"function",name:e.toolChoice.name}:"auto"}}function shouldDisableParallelToolCalls(e){const t=e.toolChoice;return Boolean(t&&"disable_parallel_tool_use"in t&&!0===t.disable_parallel_tool_use)}function parseFunctionCallArguments(e){if(isPlainObject(e))return e;if("string"!=typeof e)return null==e?{}:{raw:e};try{const t=JSON.parse(e);return isPlainObject(t)?t:{raw:t}}catch{return{raw:e}}}function parseOutputItems(e){const t=[];for(const n of e.output??[])if(n&&"object"==typeof n){if("function_call"===n.type){const e=parseFunctionCallArguments(n.arguments);t.push({type:"tool_use",id:String(n.call_id??n.id??""),name:String(n.name??"tool"),input:e});continue}if("message"===n.type)for(const e of normalizeResponseContent(n.content)){if("string"==typeof e){t.push({type:"text",text:e});continue}if(!e||"object"!=typeof e||!("type"in e))continue;const n=String(e.type??""),o="string"==typeof e.text?e.text??"":"string"==typeof e.refusal?e.refusal??"":"";"output_text"!==n&&"text"!==n&&"refusal"!==n||!o||t.push({type:"text",text:o})}}return 0===t.length&&"string"==typeof e.output_text&&t.push({type:"text",text:e.output_text}),{content:t}}function getUsage(e){if("number"==typeof e.usage?.input_tokens||"number"==typeof e.usage?.output_tokens)return{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}function sideQueryMessageToOpenAIInput(e){const t=Array.isArray(e.content)?e.content.filter(e=>"text"===e?.type&&"string"==typeof e.text).map(e=>toInputText(e.text)):[toInputText(String(e.content??""))];return[{type:"message",role:e.role,content:t.length>0?t:[toInputText("")]}]}function sideQueryToolToOpenAITool(e){return{type:"function",name:e.name,description:e.description,parameters:e.input_schema??{type:"object",properties:{}}}}function buildSideQueryToolChoice(e){return e&&"auto"!==e?"none"===e||"none"===e.type?"none":"any"===e.type?"required":"auto"===e.type?"auto":"string"==typeof e.name&&e.name?{type:"function",name:e.name}:"auto":"auto"}function sideQueryMessageToChatMessage(e){const t=Array.isArray(e.content)?e.content.filter(e=>"text"===e?.type&&"string"==typeof e.text).map(e=>e.text).join("\n"):String(e.content??"");return{role:e.role,content:t}}function sideQueryToolToChatTool(e){return{type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema??{type:"object",properties:{}}}}}export async function queryOpenAISideQuery({model:e,systemPrompt:t,messages:n,tools:o,toolChoice:s,outputFormat:i,signal:a,maxOutputTokens:u,temperature:l}){const c=getOpenAICompatibleProvider();await maybeRefreshOpenAICompatibleAuth(c);const p=getOpenAIBaseUrl(c),d=r(c);if(!("openai"===c&&d&&isJwtToken(d))){const r=[...t?[{role:"system",content:t}]:[],...n.map(sideQueryMessageToChatMessage)],d={model:e,messages:r,stream:!1},f=o?.map(sideQueryToolToChatTool)??[],g=function(e){const t=buildSideQueryToolChoice(e);return"auto"===t||"none"===t?t:"required"===t?"required":{type:"function",function:{name:t.name}}}(s);if(f.length>0&&(d.tools=f,d.tool_choice=g),"json_schema"===i?.type&&(d.response_format={type:"json_schema",json_schema:{name:"side_query_output",strict:!0,schema:i.schema}}),u&&(d.max_tokens=u),void 0!==l&&(d.temperature=l),"gemini-google"===c){const t=await createGeminiGoogleChatCompletionResponse({model:e,chatMessages:r,chatTools:f,toolChoice:g,signal:a,maxOutputTokens:u,temperature:l});return{id:t.id,content:parseChatCompletionResponse(t).content,usage:getChatUsage(t)}}const y=`${p}/chat/completions`,h=await getOpenAIRequestHeaders(c);if("custom-openai"===c)try{const e=require("fs"),t=`--- NUEVA SOLICITUD DE VALIDACION DE MODELO A CHINAI ---\nFecha: ${(new Date).toISOString()}\nURL: ${y}\nHeaders: ${JSON.stringify(h,null,2)}\nBody: ${JSON.stringify(d,null,2)}\n\n`;e.appendFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",t)}catch(e){}const _=await fetch(y,{method:"POST",headers:h,body:O(d),signal:a});if("custom-openai"===c)try{const e=_.clone(),t=await e.text(),n=require("fs"),o=`--- RESPUESTA DE VALIDACION DE MODELO DE CHINAI ---\nStatus: ${_.status} ${_.statusText}\nBody: ${t}\n\n`;n.appendFileSync("d:/Documents/GitHub/Claude/claude-code_V1/Context_Code_V1/chat-debug.txt",o)}catch(e){}const A=await readOpenAIResponseBody(_);if(!_.ok)throw m(`[${getOpenAICompatibleProviderLabel(c)}] sideQuery chat.completions error status=${_.status} model=${e} endpoint=${y} body=${(A.error?.message??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:_.status,statusText:_.statusText,url:y,model:e,data:A}));return{id:A.id,content:parseChatCompletionResponse(A).content,usage:getChatUsage(A)}}const f={model:e,input:n.flatMap(sideQueryMessageToOpenAIInput),instructions:t,stream:!1,store:!1};o&&o.length>0&&(f.tools=o.map(sideQueryToolToOpenAITool),f.tool_choice=buildSideQueryToolChoice(s)),"json_schema"===i?.type&&(f.text={format:{type:"json_schema",name:"side_query_output",strict:!0,schema:i.schema}}),u&&(f.max_output_tokens=u),void 0!==l&&(f.temperature=l);const g=`${p}/responses`,y=await fetch(g,{method:"POST",headers:await getOpenAIRequestHeaders(c),body:O(f),signal:a}),h=await readOpenAIResponseBody(y);if(!y.ok)throw m(`[${getOpenAICompatibleProviderLabel(c)}] sideQuery error status=${y.status} model=${e} endpoint=${p}/responses body=${(h.raw_error_text??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:y.status,statusText:y.statusText,url:`${p}/responses`,model:e,data:h}));return{id:h.id,content:parseOutputItems(h).content,usage:getUsage(h)}}async function createOpenAIResponse(e){const{messages:t,systemPrompt:n,tools:o,signal:r,options:s}=e,i=getOpenAICompatibleProvider();await maybeRefreshOpenAICompatibleAuth(i);const a=getOpenAIAccessTokenOrThrow(i),u="openai"===i&&isJwtToken(a);if(!u){const t=await createChatCompletionResponse(e);return{id:t.id,output:t.choices?.flatMap(e=>{const t=[];if(e.message?.content&&t.push({type:"message",role:"assistant",content:[e.message.content]}),e.message?.tool_calls)for(const n of e.message.tool_calls)t.push({type:"function_call",call_id:n.id,name:n.function.name,arguments:n.function.arguments});return t})??[],usage:{input_tokens:t.usage?.prompt_tokens,output_tokens:t.usage?.completion_tokens}}}const l=t.flatMap(messageToOpenAIInput),p=await buildOpenAITools(o,s),d={model:s.model,input:l,instructions:n.join("\n\n"),tools:p,tool_choice:buildToolChoice(s),stream:!1,store:!1};shouldDisableParallelToolCalls(s)&&(d.parallel_tool_calls=!1),s.maxOutputTokensOverride&&(d.max_output_tokens=s.maxOutputTokensOverride),void 0!==s.temperatureOverride&&(d.temperature=s.temperatureOverride),s.effortValue&&(d.reasoning={effort:s.effortValue});const f=getOpenAIMaxTimeoutRetries(),sendRequest=async(e,t=0)=>{const n=u?{...d,stream:!0}:d;let o,a;if(u){const t=function(e){try{const t=JSON.parse(atob(e.split(".")[1])),n=t?.["https://api.openai.com/auth"]?.chatgpt_account_id;if(!n)throw new Error("No account ID in token");return n}catch{throw new Error("Failed to extract chatgpt-account-id from OAuth token")}}(e);o=function(){const e=(process.env.OPENAI_OAUTH_BASE_URL||"https://chatgpt.com/backend-api").replace(/\/+$/,"");return e.endsWith("/codex/responses")?e:e.endsWith("/codex")?`${e}/responses`:`${e}/codex/responses`}(),a={Authorization:`Bearer ${e}`,"chatgpt-account-id":t,"OpenAI-Beta":"responses=experimental",originator:c(),"content-type":"application/json",accept:"application/json"}}else o=`${getOpenAIBaseUrl(i)}/responses`,a={Authorization:`Bearer ${e}`,"Content-Type":"application/json"};const l=12e4,p=new AbortController,g=setTimeout(()=>p.abort(),l),onAbort=()=>p.abort();r?.addEventListener("abort",onAbort);try{const r=await fetch(o,{method:"POST",headers:a,body:O(n),signal:p.signal}),l=await readOpenAIResponseBody(r);if(504===r.status&&t<1)return m(`[${getOpenAICompatibleProviderLabel(i)}] responses 504 Gateway Timeout, reintentando...`,{level:"warn"}),sendRequest(e,t+1);if(401===r.status){const n=await maybeRecoverOpenAICompatible401(e,i);if(n)return sendRequest(n,t)}if(!r.ok)throw m(`[${getOpenAICompatibleProviderLabel(i)}] responses error status=${r.status} model=${s.model} endpoint=${o} oauth=${u} body=${(l.raw_error_text??"").replace(/\s+/g," ").slice(0,500)}`,{level:"error"}),new Error(buildOpenAIErrorMessage({status:r.status,statusText:r.statusText,url:o,model:String(s.model),data:l}));return l}catch(n){if(n instanceof Error&&"AbortError"===n.name&&!r?.aborted){if(t<f){const n=1e3*Math.pow(2,t);return m(`[${getOpenAICompatibleProviderLabel(i)}] responses timeout local tras 120000ms, reintentando en ${n}ms (intento ${t+1}/${f})`,{level:"warn"}),await new Promise(e=>setTimeout(e,n)),sendRequest(e,t+1)}throw new Error("La solicitud expiró tras 120s. El servidor tardó demasiado en responder.")}throw n}finally{clearTimeout(g),r?.removeEventListener("abort",onAbort)}};return sendRequest(a)}export async function*queryOpenAIModelWithStreaming({messages:t,systemPrompt:n,thinkingConfig:o,tools:r,signal:s,options:i}){try{for(let e=1;e<=2;e++){const o=await createOpenAIResponse({messages:1===e?t:[...t,y({content:"System reminder: your previous response for this turn was empty. Continue the current task without asking the user to repeat themselves. If a tool call is needed, emit the appropriate tool call now. Do not return an empty response.",isMeta:!0})],systemPrompt:n,tools:r,signal:s,options:i}),{content:a}=parseOutputItems(o),u=getUsage(o);if(u)try{const e={input_tokens:u.input_tokens??0,output_tokens:u.output_tokens??0,cache_read_input_tokens:0,cache_creation_input_tokens:0},t=String(i.model),n=_(t,e);h(n,e,t)}catch(e){d(e)}if(a.length>0)return void(yield g({content:a,usage:u}));if(!(e<2))return void(yield f({content:"OpenAI returned no content after retrying."}));m(`[${getOpenAICompatibleProviderLabel(getOpenAICompatibleProvider())}] empty model response with no content; retrying request (${e}/1)`,{level:"warn"})}}catch(t){if(s.aborted)throw new e;d(t),yield f({content:p(t),errorDetails:p(t)})}}