@iaforged/context-code 2.3.5 → 2.3.7

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{feature as e}from"../../../recovery/bunBundleShim.js";import{jsx as t,jsxs as o,Fragment as n}from"react/jsx-runtime";import{createRequire as a}from"module";const r=a(import.meta.url);import i from"figures";import{useCallback as s,useEffect as l,useLayoutEffect as c,useMemo as d,useRef as p,useState as m}from"react";import{useNotifications as u}from"../../../context/notifications.js";import{logEvent as h}from"../../../services/analytics/index.js";import{useAppState as g,useAppStateStore as f,useSetAppState as C}from"../../../state/AppState.js";import{getSdkBetas as b,getSessionId as x,isSessionPersistenceDisabled as y,setHasExitedPlanMode as P,setNeedsAutoModeExitAttachment as v,setNeedsPlanModeExitAttachment as S}from"../../../bootstrap/state.js";import{generateSessionName as A}from"../../../commands/rename/generateSessionName.js";import{launchUltraplan as R}from"../../../commands/ultraplan.js";import{Box as _,Text as j}from"../../../ink.js";import{AGENT_TOOL_NAME as w}from"../../../tools/AgentTool/constants.js";import{EXIT_PLAN_MODE_V2_TOOL_NAME as k}from"../../../tools/ExitPlanModeTool/constants.js";import{TEAM_CREATE_TOOL_NAME as I}from"../../../tools/TeamCreateTool/constants.js";import{isAgentSwarmsEnabled as T}from"../../../utils/agentSwarmsEnabled.js";import{calculateContextPercentages as M,getContextWindowForModel as E}from"../../../utils/context.js";import{getExternalEditor as L}from"../../../utils/editor.js";import{getDisplayPath as F}from"../../../utils/file.js";import{toIDEDisplayName as D}from"../../../utils/ide.js";import{logError as N}from"../../../utils/log.js";import{enqueuePendingNotification as U}from"../../../utils/messageQueueManager.js";import{createUserMessage as $}from"../../../utils/messages.js";import{getMainLoopModel as B,getRuntimeMainLoopModel as V}from"../../../utils/model/model.js";import{createPromptRuleContent as X,isClassifierPermissionsEnabled as q,PROMPT_PREFIX as O}from"../../../utils/permissions/bashClassifier.js";import{toExternalPermissionMode as z}from"../../../utils/permissions/PermissionMode.js";import{isAutoModeGateEnabled as K,restoreDangerousPermissions as Q,stripDangerousPermissionsForAutoMode as G}from"../../../utils/permissions/permissionSetup.js";import{getPewterLedgerVariant as H,isPlanModeInterviewPhaseEnabled as J}from"../../../utils/planModeV2.js";import{getPlan as W,getPlanFilePath as Y}from"../../../utils/plans.js";import{editFileInEditor as Z,editPromptInEditor as ee}from"../../../utils/promptEditor.js";import{getCurrentSessionTitle as te,getTranscriptPath as oe,saveAgentName as ne,saveCustomTitle as ae}from"../../../utils/sessionStorage.js";import{getSettings_DEPRECATED as re}from"../../../utils/settings/settings.js";import{Select as ie}from"../../CustomSelect/index.js";import{Markdown as se}from"../../Markdown.js";import{PermissionDialog as le}from"../PermissionDialog.js";import{PermissionRuleExplanation as ce}from"../PermissionRuleExplanation.js";const de=e("TRANSCRIPT_CLASSIFIER")?r("../../../utils/permissions/autoModeState.js"):null;import{maybeResizeAndDownsampleImageBlock as pe}from"../../../utils/imageResizer.js";import{cacheImagePath as me,storeImage as ue}from"../../../utils/imageStore.js";export function buildPermissionUpdates(e,t){const o=[{type:"setMode",mode:z(e),destination:"session"}];return q()&&t&&t.length>0&&o.push({type:"addRules",rules:t.map(e=>({toolName:e.tool,ruleContent:X(e.prompt)})),behavior:"allow",destination:"session"}),o}export function autoNameSessionFromPlan(e,t,o){y()||0===re()?.cleanupPeriodDays||!o&&te(x())||A([$({content:e.slice(0,1e3)})],(new AbortController).signal).then(async e=>{if(!e||te(x()))return;const o=x(),n=oe();await ae(o,e,n,"auto"),await ne(o,e,n,"auto"),t(t=>t.standaloneAgentContext?.name===e?t:{...t,standaloneAgentContext:{...t.standaloneAgentContext,name:e}})}).catch(N)}export function ExitPlanModePermissionRequest({toolUseConfirm:a,onDone:r,onReject:b,workerBadge:x,setStickyFooter:y}){const A=g(e=>e.toolPermissionContext),w=C(),M=f(),{addNotification:E}=u(),[B,V]=m(""),[X,z]=m({}),te=p(0),ne=g(e=>e.settings.showClearContextOnPlanAccept)??!1,ae=g(e=>e.ultraplanSessionUrl),re=g(e=>e.ultraplanLaunching),he=!!e("ULTRAPLAN")&&(!ae&&!re),ge=a.assistantMessage.message.usage,{mode:fe,isAutoModeAvailable:Ce,isBypassPermissionsModeAvailable:be}=A,xe=d(()=>buildPlanApprovalOptions({showClearContext:ne,showUltraplan:he,usedPercent:ne?getContextUsedPercent(ge,fe):null,isAutoModeAvailable:Ce,isBypassPermissionsModeAvailable:be,onFeedbackChange:V}),[ne,he,ge,fe,Ce,be]);function onImagePaste(e,t,o,n,a){const r=te.current++,i={id:r,type:"image",content:e,mediaType:t||"image/png",filename:o||"Pasted image",dimensions:n};me(i),ue(i),z(e=>({...e,[r]:i}))}const ye=s(e=>{z(t=>{const o={...t};return delete o[e],o})},[]),Pe=Object.values(X).filter(e=>"image"===e.type),ve=Pe.length>0,Se=a.tool.name===k,Ae=Se?void 0:a.input.plan,Re=Se?Y():void 0,_e=a.input.allowedPrompts,je=Ae??W(),we=!je||""===je.trim(),[ke]=m(()=>H()??void 0),[Ie,Te]=m(()=>Ae||(plan??"No se encontró ningún plan. Por favor, escribe tu plan en el archivo de plan primero.")),[Me,Ee]=m(!1),[Le,Fe]=m(!1);l(()=>{if(Me){const e=setTimeout(Ee,5e3,!1);return()=>clearTimeout(e)}},[Me]);async function handleResponse(t){const o=B.trim(),n=o||void 0;if("ultraplan"===t)return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:"ultraplan",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject("Plan siendo refinado a través de Ultraplan; por favor, espera el resultado."),void R({blurb:"",seedPlan:Ie,getAppState:M.getState,setAppState:M.setState,signal:(new AbortController).signal}).then(e=>U({value:e,mode:"task-notification"})).catch(N);const i=Se&&!Le?{}:{plan:Ie};if(e("TRANSCRIPT_CLASSIFIER")){const e=("yes-resume-auto-mode"===t||"yes-auto-clear-context"===t)&&K(),o=de?.isAutoModeActive()??!1;"no"!==t&&!e&&o&&(de?.setAutoModeActive(!1),v(!0),w(e=>({...e,toolPermissionContext:{...Q(e.toolPermissionContext),prePlanMode:void 0}})))}const s=!!e("TRANSCRIPT_CLASSIFIER")&&"yes-resume-auto-mode"===t,l="yes-accept-edits-keep-context"===t||"yes-default-keep-context"===t||s;if("no"!==t&&autoNameSessionFromPlan(Ie,w,!l),"no"!==t&&!l){let o="default";"yes-bypass-permissions"===t?o="bypassPermissions":"yes-accept-edits"===t?o="acceptEdits":e("TRANSCRIPT_CLASSIFIER")&&"yes-auto-clear-context"===t&&K()&&(o="auto",de?.setAutoModeActive(!0)),h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,clearContext:!0,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n});const i="",s=`\n\nIf you need specific details from before exiting plan mode (like exact code snippets, error messages, or content you generated), read the full transcript at: ${oe()}`,l=T()?`\n\nIf this plan can be broken down into multiple independent tasks, consider using the ${I} tool to create a team and parallelize the work.`:"",c=n?`\n\nUser feedback on this plan: ${n}`:"";return w(e=>({...e,initialMessage:{message:{...$({content:`Implementa el siguiente plan:\n\n${Ie}${i}${s}${l}${c}`}),planContent:Ie},clearContext:!0,mode:o,allowedPrompts:_e}})),P(!0),r(),b(),void a.onReject()}if(e("TRANSCRIPT_CLASSIFIER")&&"yes-resume-auto-mode"===t&&K())return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,clearContext:!1,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n}),P(!0),S(!0),de?.setAutoModeActive(!0),w(e=>({...e,toolPermissionContext:G({...e.toolPermissionContext,mode:"auto",prePlanMode:void 0})})),r(),void a.onAllow(i,[],n);const c={"yes-accept-edits-keep-context":A.isBypassPermissionsModeAvailable?"bypassPermissions":"acceptEdits","yes-default-keep-context":"default",...e("TRANSCRIPT_CLASSIFIER")?{"yes-resume-auto-mode":"default"}:{}}[t];if(c)return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,clearContext:!1,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n}),P(!0),S(!0),r(),void a.onAllow(i,buildPermissionUpdates(c,_e),n);const d={"yes-bypass-permissions":"bypassPermissions","yes-accept-edits":"acceptEdits"}[t];if(d)return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n}),P(!0),S(!0),r(),void a.onAllow(i,buildPermissionUpdates(d,_e),n);if("no"===t){if(!o&&!ve)return;let e;h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),ve&&(e=await Promise.all(Pe.map(async e=>{const t={type:"image",source:{type:"base64",media_type:e.mediaType||"image/png",data:e.content}};return(await pe(t)).block}))),r(),b(),a.onReject(o||(ve?"(See attached image)":void 0),e&&e.length>0?e:void 0)}}const De=L(),Ne=De?D(De):null,Ue=p(handleResponse);Ue.current=handleResponse;const $e=p(void 0);$e.current=()=>{h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject()};const Be=!we&&!!y;if(c(()=>{if(Be)return y(o(_,{flexDirection:"column",borderStyle:"round",borderColor:"planMode",borderLeft:!1,borderRight:!1,borderBottom:!1,paddingX:1,children:[t(j,{dimColor:!0,children:"¿Deseas continuar?"}),t(_,{marginTop:1,children:t(ie,{options:xe,onChange:e=>{Ue.current(e)},onCancel:()=>$e.current?.(),onImagePaste,pastedContents:X,onRemoveImage:ye})}),Ne&&o(_,{flexDirection:"row",gap:1,marginTop:1,children:[t(j,{dimColor:!0,children:"ctrl-g para editar en "}),t(j,{bold:!0,dimColor:!0,children:Ne}),Se&&Re&&o(j,{dimColor:!0,children:[" · ",F(Re)]}),Me&&o(n,{children:[t(j,{dimColor:!0,children:" · "}),o(j,{color:"success",children:[i.tick,"¡Plan guardado!"]})]})]})]})),()=>y(null)},[Be,y,xe,X,Ne,Se,Re,Me]),we){function handleEmptyPlanResponse(t){if("yes"===t){if(h("tengu_plan_exit",{planLengthChars:0,outcome:"yes-default",interviewPhaseEnabled:J(),planStructureVariant:ke}),e("TRANSCRIPT_CLASSIFIER")){(de?.isAutoModeActive()??!1)&&(de?.setAutoModeActive(!1),v(!0),w(e=>({...e,toolPermissionContext:{...Q(e.toolPermissionContext),prePlanMode:void 0}})))}P(!0),S(!0),r(),a.onAllow({},[{type:"setMode",mode:"default",destination:"session"}])}else h("tengu_plan_exit",{planLengthChars:0,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject()}return t(le,{color:"planMode",title:"¿Salir del modo plan?",workerBadge:x,children:o(_,{flexDirection:"column",paddingX:1,marginTop:1,children:[t(j,{children:"Context quiere salir del modo plan"}),t(_,{marginTop:1,children:t(ie,{options:[{label:"Sí",value:"yes"},{label:"No",value:"no"}],onChange:handleEmptyPlanResponse,onCancel:()=>{h("tengu_plan_exit",{planLengthChars:0,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject()}})})]})})}return o(_,{flexDirection:"column",tabIndex:0,autoFocus:!0,onKeyDown:e=>e.ctrl&&"g"===e.key?(e.preventDefault(),h("tengu_plan_external_editor_used",{}),void(async()=>{if(Se&&Re){const e=await Z(Re);e.error&&E({key:"external-editor-error",text:e.error,color:"warning",priority:"high"}),null!==e.content&&(e.content!==Ie&&Fe(!0),Te(e.content),Ee(!0))}else{const e=await ee(Ie);e.error&&E({key:"external-editor-error",text:e.error,color:"warning",priority:"high"}),null!==e.content&&e.content!==Ie&&(Te(e.content),Ee(!0))}})()):e.shift&&"tab"===e.key?(e.preventDefault(),void handleResponse(ne?"yes-accept-edits":"yes-accept-edits-keep-context")):void 0,children:[t(le,{color:"planMode",title:"¿Listo para programar?",innerPaddingX:0,workerBadge:x,children:o(_,{flexDirection:"column",marginTop:1,children:[t(_,{paddingX:1,flexDirection:"column",children:t(j,{children:"Aquí está el plan de Context:"})}),t(_,{borderColor:"subtle",borderStyle:"dashed",flexDirection:"column",borderLeft:!1,borderRight:!1,paddingX:1,marginBottom:1,overflow:"hidden",children:t(se,{children:Ie})}),o(_,{flexDirection:"column",paddingX:1,children:[t(ce,{permissionResult:a.permissionResult,toolType:"tool"}),q()&&_e&&_e.length>0&&o(_,{flexDirection:"column",marginBottom:1,children:[t(j,{bold:!0,children:"Permisos solicitados:"}),_e.map((e,t)=>o(j,{dimColor:!0,children:[" ","· ",e.tool,"(",O," ",e.prompt,")"]},t))]}),!Be&&o(n,{children:[t(j,{dimColor:!0,children:"Context ha elaborado un plan y está listo para ejecutarlo. ¿Deseas continuar?"}),t(_,{marginTop:1,children:t(ie,{options:xe,onChange:handleResponse,onCancel:()=>$e.current?.(),onImagePaste,pastedContents:X,onRemoveImage:ye})})]})]})]})}),!Be&&Ne&&o(_,{flexDirection:"row",gap:1,paddingX:1,marginTop:1,children:[o(_,{children:[t(j,{dimColor:!0,children:"ctrl-g para editar en "}),t(j,{bold:!0,dimColor:!0,children:Ne}),Se&&Re&&o(j,{dimColor:!0,children:[" · ",F(Re)]})]}),Me&&o(_,{children:[t(j,{dimColor:!0,children:" · "}),o(j,{color:"success",children:[i.tick,"¡Plan guardado!"]})]})]})]})}export function buildPlanApprovalOptions({showClearContext:t,showUltraplan:o,usedPercent:n,isAutoModeAvailable:a,isBypassPermissionsModeAvailable:r,onFeedbackChange:i}){const s=[],l=null!==n?` (${n}% usado)`:"";return t&&(e("TRANSCRIPT_CLASSIFIER")&&a?s.push({label:`Sí, borrar contexto${l} y usar modo automático`,value:"yes-auto-clear-context"}):r?s.push({label:`Sí, borrar contexto${l} y omitir permisos`,value:"yes-bypass-permissions"}):s.push({label:`Sí, borrar contexto${l} y auto-aceptar ediciones`,value:"yes-accept-edits"})),e("TRANSCRIPT_CLASSIFIER")&&a?s.push({label:"Sí, y usar modo automático",value:"yes-resume-auto-mode"}):r?s.push({label:"Sí, y omitir permisos",value:"yes-accept-edits-keep-context"}):s.push({label:"Sí, auto-aceptar ediciones",value:"yes-accept-edits-keep-context"}),s.push({label:"Sí, aprobar ediciones manualmente",value:"yes-default-keep-context"}),o&&s.push({label:"No, refinar con Ultraplan en Context Code en la web",value:"ultraplan"}),s.push({type:"input",label:"No, seguir planificando",value:"no",placeholder:"Dile a Context qué cambiar",description:"shift+tab para aprobar con este comentario",onChange:i}),s}function getContextUsedPercent(e,t){if(!e)return null;const o=V({permissionMode:t,mainLoopModel:B(),exceeds200kTokens:!1}),n=E(o,b()),{used:a}=M({input_tokens:e.input_tokens,cache_creation_input_tokens:e.cache_creation_input_tokens??0,cache_read_input_tokens:e.cache_read_input_tokens??0},n);return a}
1
+ import{feature as e}from"../../../recovery/bunBundleShim.js";import{jsx as t,jsxs as o,Fragment as n}from"react/jsx-runtime";import{createRequire as a}from"module";const r=a(import.meta.url);import i from"figures";import{useCallback as s,useEffect as l,useLayoutEffect as c,useMemo as d,useRef as p,useState as m}from"react";import{useNotifications as u}from"../../../context/notifications.js";import{logEvent as h}from"../../../services/analytics/index.js";import{useAppState as g,useAppStateStore as f,useSetAppState as C}from"../../../state/AppState.js";import{getSdkBetas as b,getSessionId as x,isSessionPersistenceDisabled as y,setHasExitedPlanMode as P,setNeedsAutoModeExitAttachment as v,setNeedsPlanModeExitAttachment as S}from"../../../bootstrap/state.js";import{generateSessionName as A}from"../../../commands/rename/generateSessionName.js";import{launchUltraplan as R}from"../../../commands/ultraplan.js";import{Box as _,Text as j}from"../../../ink.js";import{AGENT_TOOL_NAME as w}from"../../../tools/AgentTool/constants.js";import{EXIT_PLAN_MODE_V2_TOOL_NAME as k}from"../../../tools/ExitPlanModeTool/constants.js";import{TEAM_CREATE_TOOL_NAME as I}from"../../../tools/TeamCreateTool/constants.js";import{isAgentSwarmsEnabled as T}from"../../../utils/agentSwarmsEnabled.js";import{calculateContextPercentages as M,getContextWindowForModel as E}from"../../../utils/context.js";import{getExternalEditor as L}from"../../../utils/editor.js";import{getDisplayPath as F}from"../../../utils/file.js";import{toIDEDisplayName as D}from"../../../utils/ide.js";import{logError as N}from"../../../utils/log.js";import{enqueuePendingNotification as U}from"../../../utils/messageQueueManager.js";import{createUserMessage as $}from"../../../utils/messages.js";import{getMainLoopModel as B,getRuntimeMainLoopModel as V}from"../../../utils/model/model.js";import{createPromptRuleContent as X,isClassifierPermissionsEnabled as q,PROMPT_PREFIX as O}from"../../../utils/permissions/bashClassifier.js";import{toExternalPermissionMode as z}from"../../../utils/permissions/PermissionMode.js";import{isAutoModeGateEnabled as K,restoreDangerousPermissions as Q,stripDangerousPermissionsForAutoMode as G}from"../../../utils/permissions/permissionSetup.js";import{getPewterLedgerVariant as H,isPlanModeInterviewPhaseEnabled as J}from"../../../utils/planModeV2.js";import{getPlan as W,getPlanFilePath as Y}from"../../../utils/plans.js";import{editFileInEditor as Z,editPromptInEditor as ee}from"../../../utils/promptEditor.js";import{getCurrentSessionTitle as te,getTranscriptPath as oe,saveAgentName as ne,saveCustomTitle as ae}from"../../../utils/sessionStorage.js";import{getSettings_DEPRECATED as re}from"../../../utils/settings/settings.js";import{Select as ie}from"../../CustomSelect/index.js";import{Markdown as se}from"../../Markdown.js";import{PermissionDialog as le}from"../PermissionDialog.js";import{PermissionRuleExplanation as ce}from"../PermissionRuleExplanation.js";const de=e("TRANSCRIPT_CLASSIFIER")?r("../../../utils/permissions/autoModeState.js"):null;import{maybeResizeAndDownsampleImageBlock as pe}from"../../../utils/imageResizer.js";import{cacheImagePath as me,storeImage as ue}from"../../../utils/imageStore.js";export function buildPermissionUpdates(e,t){const o=[{type:"setMode",mode:z(e),destination:"session"}];return q()&&t&&t.length>0&&o.push({type:"addRules",rules:t.map(e=>({toolName:e.tool,ruleContent:X(e.prompt)})),behavior:"allow",destination:"session"}),o}export function autoNameSessionFromPlan(e,t,o){y()||0===re()?.cleanupPeriodDays||!o&&te(x())||A([$({content:e.slice(0,1e3)})],(new AbortController).signal).then(async e=>{if(!e||te(x()))return;const o=x(),n=oe();await ae(o,e,n,"auto"),await ne(o,e,n,"auto"),t(t=>t.standaloneAgentContext?.name===e?t:{...t,standaloneAgentContext:{...t.standaloneAgentContext,name:e}})}).catch(N)}export function ExitPlanModePermissionRequest({toolUseConfirm:a,onDone:r,onReject:b,workerBadge:x,setStickyFooter:y}){const A=g(e=>e.toolPermissionContext),w=C(),M=f(),{addNotification:E}=u(),[B,V]=m(""),[X,z]=m({}),te=p(0),ne=g(e=>e.settings.showClearContextOnPlanAccept)??!1,ae=g(e=>e.ultraplanSessionUrl),re=g(e=>e.ultraplanLaunching),he=!!e("ULTRAPLAN")&&(!ae&&!re),ge=a.assistantMessage.message.usage,{mode:fe,isAutoModeAvailable:Ce,isBypassPermissionsModeAvailable:be}=A,xe=d(()=>buildPlanApprovalOptions({showClearContext:ne,showUltraplan:he,usedPercent:ne?getContextUsedPercent(ge,fe):null,isAutoModeAvailable:Ce,isBypassPermissionsModeAvailable:be,onFeedbackChange:V}),[ne,he,ge,fe,Ce,be]);function onImagePaste(e,t,o,n,a){const r=te.current++,i={id:r,type:"image",content:e,mediaType:t||"image/png",filename:o||"Pasted image",dimensions:n};me(i),ue(i),z(e=>({...e,[r]:i}))}const ye=s(e=>{z(t=>{const o={...t};return delete o[e],o})},[]),Pe=Object.values(X).filter(e=>"image"===e.type),ve=Pe.length>0,Se=a.tool.name===k,Ae=Se?void 0:a.input.plan,Re=Se?Y():void 0,_e=a.input.allowedPrompts,je=Ae??W(),we=!je||""===je.trim(),[ke]=m(()=>H()??void 0),[Ie,Te]=m(()=>Ae||(je??"No se encontró ningún plan. Por favor, escribe tu plan en el archivo de plan primero.")),[Me,Ee]=m(!1),[Le,Fe]=m(!1);l(()=>{if(Me){const e=setTimeout(Ee,5e3,!1);return()=>clearTimeout(e)}},[Me]);async function handleResponse(t){const o=B.trim(),n=o||void 0;if("ultraplan"===t)return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:"ultraplan",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject("Plan siendo refinado a través de Ultraplan; por favor, espera el resultado."),void R({blurb:"",seedPlan:Ie,getAppState:M.getState,setAppState:M.setState,signal:(new AbortController).signal}).then(e=>U({value:e,mode:"task-notification"})).catch(N);const i=Se&&!Le?{}:{plan:Ie};if(e("TRANSCRIPT_CLASSIFIER")){const e=("yes-resume-auto-mode"===t||"yes-auto-clear-context"===t)&&K(),o=de?.isAutoModeActive()??!1;"no"!==t&&!e&&o&&(de?.setAutoModeActive(!1),v(!0),w(e=>({...e,toolPermissionContext:{...Q(e.toolPermissionContext),prePlanMode:void 0}})))}const s=!!e("TRANSCRIPT_CLASSIFIER")&&"yes-resume-auto-mode"===t,l="yes-accept-edits-keep-context"===t||"yes-default-keep-context"===t||s;if("no"!==t&&autoNameSessionFromPlan(Ie,w,!l),"no"!==t&&!l){let o="default";"yes-bypass-permissions"===t?o="bypassPermissions":"yes-accept-edits"===t?o="acceptEdits":e("TRANSCRIPT_CLASSIFIER")&&"yes-auto-clear-context"===t&&K()&&(o="auto",de?.setAutoModeActive(!0)),h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,clearContext:!0,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n});const i="",s=`\n\nIf you need specific details from before exiting plan mode (like exact code snippets, error messages, or content you generated), read the full transcript at: ${oe()}`,l=T()?`\n\nIf this plan can be broken down into multiple independent tasks, consider using the ${I} tool to create a team and parallelize the work.`:"",c=n?`\n\nUser feedback on this plan: ${n}`:"";return w(e=>({...e,initialMessage:{message:{...$({content:`Implementa el siguiente plan:\n\n${Ie}${i}${s}${l}${c}`}),planContent:Ie},clearContext:!0,mode:o,allowedPrompts:_e}})),P(!0),r(),b(),void a.onReject()}if(e("TRANSCRIPT_CLASSIFIER")&&"yes-resume-auto-mode"===t&&K())return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,clearContext:!1,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n}),P(!0),S(!0),de?.setAutoModeActive(!0),w(e=>({...e,toolPermissionContext:G({...e.toolPermissionContext,mode:"auto",prePlanMode:void 0})})),r(),void a.onAllow(i,[],n);const c={"yes-accept-edits-keep-context":A.isBypassPermissionsModeAvailable?"bypassPermissions":"acceptEdits","yes-default-keep-context":"default",...e("TRANSCRIPT_CLASSIFIER")?{"yes-resume-auto-mode":"default"}:{}}[t];if(c)return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,clearContext:!1,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n}),P(!0),S(!0),r(),void a.onAllow(i,buildPermissionUpdates(c,_e),n);const d={"yes-bypass-permissions":"bypassPermissions","yes-accept-edits":"acceptEdits"}[t];if(d)return h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:t,interviewPhaseEnabled:J(),planStructureVariant:ke,hasFeedback:!!n}),P(!0),S(!0),r(),void a.onAllow(i,buildPermissionUpdates(d,_e),n);if("no"===t){if(!o&&!ve)return;let e;h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),ve&&(e=await Promise.all(Pe.map(async e=>{const t={type:"image",source:{type:"base64",media_type:e.mediaType||"image/png",data:e.content}};return(await pe(t)).block}))),r(),b(),a.onReject(o||(ve?"(See attached image)":void 0),e&&e.length>0?e:void 0)}}const De=L(),Ne=De?D(De):null,Ue=p(handleResponse);Ue.current=handleResponse;const $e=p(void 0);$e.current=()=>{h("tengu_plan_exit",{planLengthChars:Ie.length,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject()};const Be=!we&&!!y;if(c(()=>{if(Be)return y(o(_,{flexDirection:"column",borderStyle:"round",borderColor:"planMode",borderLeft:!1,borderRight:!1,borderBottom:!1,paddingX:1,children:[t(j,{dimColor:!0,children:"¿Deseas continuar?"}),t(_,{marginTop:1,children:t(ie,{options:xe,onChange:e=>{Ue.current(e)},onCancel:()=>$e.current?.(),onImagePaste,pastedContents:X,onRemoveImage:ye})}),Ne&&o(_,{flexDirection:"row",gap:1,marginTop:1,children:[t(j,{dimColor:!0,children:"ctrl-g para editar en "}),t(j,{bold:!0,dimColor:!0,children:Ne}),Se&&Re&&o(j,{dimColor:!0,children:[" · ",F(Re)]}),Me&&o(n,{children:[t(j,{dimColor:!0,children:" · "}),o(j,{color:"success",children:[i.tick,"¡Plan guardado!"]})]})]})]})),()=>y(null)},[Be,y,xe,X,Ne,Se,Re,Me]),we){function handleEmptyPlanResponse(t){if("yes"===t){if(h("tengu_plan_exit",{planLengthChars:0,outcome:"yes-default",interviewPhaseEnabled:J(),planStructureVariant:ke}),e("TRANSCRIPT_CLASSIFIER")){(de?.isAutoModeActive()??!1)&&(de?.setAutoModeActive(!1),v(!0),w(e=>({...e,toolPermissionContext:{...Q(e.toolPermissionContext),prePlanMode:void 0}})))}P(!0),S(!0),r(),a.onAllow({},[{type:"setMode",mode:"default",destination:"session"}])}else h("tengu_plan_exit",{planLengthChars:0,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject()}return t(le,{color:"planMode",title:"¿Salir del modo plan?",workerBadge:x,children:o(_,{flexDirection:"column",paddingX:1,marginTop:1,children:[t(j,{children:"Context quiere salir del modo plan"}),t(_,{marginTop:1,children:t(ie,{options:[{label:"Sí",value:"yes"},{label:"No",value:"no"}],onChange:handleEmptyPlanResponse,onCancel:()=>{h("tengu_plan_exit",{planLengthChars:0,outcome:"no",interviewPhaseEnabled:J(),planStructureVariant:ke}),r(),b(),a.onReject()}})})]})})}return o(_,{flexDirection:"column",tabIndex:0,autoFocus:!0,onKeyDown:e=>e.ctrl&&"g"===e.key?(e.preventDefault(),h("tengu_plan_external_editor_used",{}),void(async()=>{if(Se&&Re){const e=await Z(Re);e.error&&E({key:"external-editor-error",text:e.error,color:"warning",priority:"high"}),null!==e.content&&(e.content!==Ie&&Fe(!0),Te(e.content),Ee(!0))}else{const e=await ee(Ie);e.error&&E({key:"external-editor-error",text:e.error,color:"warning",priority:"high"}),null!==e.content&&e.content!==Ie&&(Te(e.content),Ee(!0))}})()):e.shift&&"tab"===e.key?(e.preventDefault(),void handleResponse(ne?"yes-accept-edits":"yes-accept-edits-keep-context")):void 0,children:[t(le,{color:"planMode",title:"¿Listo para programar?",innerPaddingX:0,workerBadge:x,children:o(_,{flexDirection:"column",marginTop:1,children:[t(_,{paddingX:1,flexDirection:"column",children:t(j,{children:"Aquí está el plan de Context:"})}),t(_,{borderColor:"subtle",borderStyle:"dashed",flexDirection:"column",borderLeft:!1,borderRight:!1,paddingX:1,marginBottom:1,overflow:"hidden",children:t(se,{children:Ie})}),o(_,{flexDirection:"column",paddingX:1,children:[t(ce,{permissionResult:a.permissionResult,toolType:"tool"}),q()&&_e&&_e.length>0&&o(_,{flexDirection:"column",marginBottom:1,children:[t(j,{bold:!0,children:"Permisos solicitados:"}),_e.map((e,t)=>o(j,{dimColor:!0,children:[" ","· ",e.tool,"(",O," ",e.prompt,")"]},t))]}),!Be&&o(n,{children:[t(j,{dimColor:!0,children:"Context ha elaborado un plan y está listo para ejecutarlo. ¿Deseas continuar?"}),t(_,{marginTop:1,children:t(ie,{options:xe,onChange:handleResponse,onCancel:()=>$e.current?.(),onImagePaste,pastedContents:X,onRemoveImage:ye})})]})]})]})}),!Be&&Ne&&o(_,{flexDirection:"row",gap:1,paddingX:1,marginTop:1,children:[o(_,{children:[t(j,{dimColor:!0,children:"ctrl-g para editar en "}),t(j,{bold:!0,dimColor:!0,children:Ne}),Se&&Re&&o(j,{dimColor:!0,children:[" · ",F(Re)]})]}),Me&&o(_,{children:[t(j,{dimColor:!0,children:" · "}),o(j,{color:"success",children:[i.tick,"¡Plan guardado!"]})]})]})]})}export function buildPlanApprovalOptions({showClearContext:t,showUltraplan:o,usedPercent:n,isAutoModeAvailable:a,isBypassPermissionsModeAvailable:r,onFeedbackChange:i}){const s=[],l=null!==n?` (${n}% usado)`:"";return t&&(e("TRANSCRIPT_CLASSIFIER")&&a?s.push({label:`Sí, borrar contexto${l} y usar modo automático`,value:"yes-auto-clear-context"}):r?s.push({label:`Sí, borrar contexto${l} y omitir permisos`,value:"yes-bypass-permissions"}):s.push({label:`Sí, borrar contexto${l} y auto-aceptar ediciones`,value:"yes-accept-edits"})),e("TRANSCRIPT_CLASSIFIER")&&a?s.push({label:"Sí, y usar modo automático",value:"yes-resume-auto-mode"}):r?s.push({label:"Sí, y omitir permisos",value:"yes-accept-edits-keep-context"}):s.push({label:"Sí, auto-aceptar ediciones",value:"yes-accept-edits-keep-context"}),s.push({label:"Sí, aprobar ediciones manualmente",value:"yes-default-keep-context"}),o&&s.push({label:"No, refinar con Ultraplan en Context Code en la web",value:"ultraplan"}),s.push({type:"input",label:"No, seguir planificando",value:"no",placeholder:"Dile a Context qué cambiar",description:"shift+tab para aprobar con este comentario",onChange:i}),s}function getContextUsedPercent(e,t){if(!e)return null;const o=V({permissionMode:t,mainLoopModel:B(),exceeds200kTokens:!1}),n=E(o,b()),{used:a}=M({input_tokens:e.input_tokens,cache_creation_input_tokens:e.cache_creation_input_tokens??0,cache_read_input_tokens:e.cache_read_input_tokens??0},n);return a}
@@ -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)})}}
@@ -1 +1 @@
1
- import{getProviderProfile as e}from"../../../utils/model/providerProfiles.js";import{getSecureStorage as t}from"../../../utils/secureStorage/index.js";const o={claude:"https://api.anthropic.com",openai:"https://api.openai.com/v1",openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic"};function trimTrailingSlash(e){return e.endsWith("/")?e.slice(0,-1):e}function tryParseJson(e){try{return JSON.parse(e)}catch{return null}}function resolveCredential(e,o){if("ollama"===e)return{kind:"none",token:null};const r=function(){try{return t().read()??{}}catch{return{}}}(),n=r.providerProfileApiKeys?.[o];if(n?.trim())return{kind:"api-key",token:n.trim()};const a=r.providerProfileOauth?.[o]?.accessToken;if(a?.trim())return{kind:"oauth",token:a.trim()};const i=r.providerApiKeys?.[e];if(i?.trim())return{kind:"api-key",token:i.trim()};const s="claude"===e?r.claudeAiOauth?.accessToken:"openai"===e?r.openAiOauth?.accessToken:null;return s?.trim()?{kind:"oauth",token:s.trim()}:{kind:"none",token:null}}function buildSystemPrompt(e){const t=e.domain?.domainName??e.task.scopeType,o=e.capabilities.length>0?e.capabilities.join(", "):"sin declarar";return[e.agent.systemPrompt?.trim()||`Eres ${e.agent.name}, agente del equipo ${t}.`,`Rol: ${e.agent.roleKind??"general"}.`,`Capacidades: ${o}.`,"Responde con un reporte ejecutivo y accionable para el orquestador global.","No modifiques archivos. Solo entrega resultado, riesgos y siguientes pasos."].join("\n")}function buildUserPrompt(e){const t=e.domain?.domainName??e.task.scopeType,o=e.members.length>0?e.members.map(e=>`${e.agentId}:${e.duty??"member"}`).join(", "):"sin miembros internos";return[`Objetivo global: ${e.run.goal}`,`Equipo: ${t}`,`Tarea: ${e.task.title}`,`Instrucciones: ${e.task.instructions}`,`Miembros del escuadron: ${o}`,"","Entrega:","1. Resultado del equipo.","2. Decisiones tomadas.","3. Riesgos o bloqueos.","4. Siguientes pasos recomendados."].join("\n")}async function postJson(e,t,o,r=3){let n=null;for(let a=0;a<=r;a++){if(a>0){const e=1e3*Math.pow(2,a)+1e3*Math.random();await new Promise(t=>setTimeout(t,e))}try{const r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",...t},body:JSON.stringify(o)}),a=await r.text(),i=tryParseJson(a)??a;if(!r.ok){if(n={status:r.status,error:"string"==typeof i?i:JSON.stringify(i)},429===r.status||r.status>=500)continue;return{ok:!1,...n}}return{ok:!0,data:i}}catch(e){n={status:0,error:e instanceof Error?e.message:String(e)};continue}}return{ok:!1,...n}}async function executeOpenAICompatible(e,t,o,r){const n={};r.token&&(n.Authorization=`Bearer ${r.token}`),"openrouter"===e.workspace.provider&&(n["HTTP-Referer"]="https://context.iaforged.com",n["X-Title"]="Context Code");const a=await postJson(`${trimTrailingSlash(o)}/chat/completions`,n,{model:t,temperature:.2,messages:[{role:"system",content:buildSystemPrompt(e)},{role:"user",content:buildUserPrompt(e)}]});if(!a.ok)return{ok:!1,error:`HTTP ${a.status}: ${a.error}`};const i=function(e){if(!e||"object"!=typeof e)return null;const t=e,o=t.choices?.[0]?.message?.content??t.choices?.[0]?.text;return"string"==typeof o?o:Array.isArray(o)?o.map(e=>"string"==typeof e?e:"object"==typeof e&&e&&"text"in e?String(e.text??""):"").filter(Boolean).join("\n"):"string"==typeof t.output_text?t.output_text:null}(a.data);return i?.trim()?{ok:!0,output:i}:{ok:!1,error:"El proveedor no devolvio contenido de texto."}}async function executeAnthropicCompatible(e,t,o,r){const n={"anthropic-version":"2023-06-01"};"api-key"===r.kind&&r.token?(n["x-api-key"]=r.token,"minimax"===e.workspace.provider&&(n.Authorization=`Bearer ${r.token}`)):"oauth"===r.kind&&r.token&&(n.Authorization=`Bearer ${r.token}`);const a=await postJson(`${trimTrailingSlash(o)}/v1/messages`,n,{model:t,max_tokens:2048,system:buildSystemPrompt(e),messages:[{role:"user",content:buildUserPrompt(e)}]});if(!a.ok)return{ok:!1,error:`HTTP ${a.status}: ${a.error}`};const i=function(e){if(!e||"object"!=typeof e)return null;const t=e;return t.content?.map(e=>"text"===e.type&&"string"==typeof e.text?e.text:"").filter(Boolean).join("\n")||null}(a.data);return i?.trim()?{ok:!0,output:i}:{ok:!1,error:"El proveedor no devolvio contenido de texto."}}export async function executeAgentDomainTask(t){const r=e(t.agent.profileId),n=t.workspace.provider,a=function(t){const o=e(t.agent.profileId);return t.agent.modelOverride?.trim()||o?.lastModel?.trim()||null}(t);if(!r)return{status:"blocked",summary:`No existe el perfil ${t.agent.profileId} para el agente ${t.agent.name}.`,output:null,provider:n,profileId:t.agent.profileId,model:a,messageType:"task.blocked",blockers:["Perfil del agente no encontrado."],metadata:{reason:"missing-profile"}};if(r.provider!==n)return{status:"blocked",summary:`El perfil ${r.id} pertenece a ${r.provider}, pero el workspace es ${n}.`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.blocked",blockers:["Perfil y workspace no coinciden."],metadata:{reason:"provider-profile-mismatch",profileProvider:r.provider}};if(!a)return{status:"blocked",summary:`El agente ${t.agent.name} no tiene modelo configurado.`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.blocked",blockers:["Modelo no configurado."],metadata:{reason:"missing-model"}};const i=resolveCredential(n,r.id);if("ollama"!==n&&"none"===i.kind)return{status:"blocked",summary:`El perfil ${r.id} no tiene credenciales para ${n}.`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.blocked",blockers:["Credenciales no configuradas."],metadata:{reason:"missing-credentials"}};const s=r.baseUrl||o[n];try{const e="claude"===n||"minimax"===n?await executeAnthropicCompatible(t,a,s,i):await executeOpenAICompatible(t,a,s,i);if(!e.ok)return{status:"failed",summary:`El agente ${t.agent.name} fallo ejecutando ${a}: ${e.error}`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.failed",blockers:[e.error],metadata:{reason:"provider-error",baseUrl:s}};const o=function(e,t=12e3){return e.length>t?`${e.slice(0,t)}\n\n[output truncado a ${t} caracteres]`:e}(e.output.trim());return{status:"completed",summary:o.split("\n").find(e=>e.trim())?.trim()||o,output:o,provider:n,profileId:r.id,model:a,messageType:"task.completed",blockers:[],metadata:{baseUrl:s,credentialKind:i.kind}}}catch(e){const o=function(e){return e instanceof Error?e.message:String(e)}(e);return{status:"failed",summary:`El agente ${t.agent.name} no pudo ejecutar la tarea: ${o}`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.failed",blockers:[o],metadata:{reason:"execution-exception",baseUrl:s}}}}
1
+ import{getProviderProfile as e}from"../../../utils/model/providerProfiles.js";import{getSecureStorage as t}from"../../../utils/secureStorage/index.js";const o={claude:"https://api.anthropic.com",openai:"https://api.openai.com/v1",openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic"};function trimTrailingSlash(e){return e.endsWith("/")?e.slice(0,-1):e}function tryParseJson(e){try{return JSON.parse(e)}catch{return null}}function resolveCredential(e,o){if("ollama"===e)return{kind:"none",token:null};const r=function(){try{return t().read()??{}}catch{return{}}}(),n=r.providerProfileApiKeys?.[o];if(n?.trim())return{kind:"api-key",token:n.trim()};const a=r.providerProfileOauth?.[o]?.accessToken;if(a?.trim())return{kind:"oauth",token:a.trim()};const i=r.providerApiKeys?.[e];if(i?.trim())return{kind:"api-key",token:i.trim()};const s="claude"===e?r.claudeAiOauth?.accessToken:"openai"===e?r.openAiOauth?.accessToken:null;return s?.trim()?{kind:"oauth",token:s.trim()}:{kind:"none",token:null}}function buildSystemPrompt(e){const t=e.domain?.domainName??e.task.scopeType,o=e.capabilities.length>0?e.capabilities.join(", "):"sin declarar";return[e.agent.systemPrompt?.trim()||`Eres ${e.agent.name}, agente del equipo ${t}.`,`Rol: ${e.agent.roleKind??"general"}.`,`Capacidades: ${o}.`,"Responde con un reporte ejecutivo y accionable para el orquestador global.","No modifiques archivos. Solo entrega resultado, riesgos y siguientes pasos."].join("\n")}function buildUserPrompt(e){const t=e.domain?.domainName??e.task.scopeType,o=e.members.length>0?e.members.map(e=>`${e.agentId}:${e.duty??"member"}`).join(", "):"sin miembros internos";return[`Objetivo global: ${e.run.goal}`,`Equipo: ${t}`,`Tarea: ${e.task.title}`,`Instrucciones: ${e.task.instructions}`,`Miembros del escuadron: ${o}`,"","Entrega:","1. Resultado del equipo.","2. Decisiones tomadas.","3. Riesgos o bloqueos.","4. Siguientes pasos recomendados."].join("\n")}async function postJson(e,t,o,r=3){let n=null;for(let a=0;a<=r;a++){if(a>0){const e=1e3*Math.pow(2,a)+1e3*Math.random();await new Promise(t=>setTimeout(t,e))}try{const r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",...t},body:JSON.stringify(o)}),a=await r.text(),i=tryParseJson(a)??a;if(!r.ok){if(n={status:r.status,error:"string"==typeof i?i:JSON.stringify(i)},429===r.status||r.status>=500)continue;return{ok:!1,...n}}return{ok:!0,data:i}}catch(e){n={status:0,error:e instanceof Error?e.message:String(e)};continue}}return{ok:!1,...n}}async function executeOpenAICompatible(e,t,o,r){const n={};r.token&&(n.Authorization=`Bearer ${r.token}`),"openrouter"===e.workspace.provider&&(n["HTTP-Referer"]="https://context.iaforged.com",n["X-Title"]="Context Code");const a=await postJson(`${trimTrailingSlash(o)}/chat/completions`,n,{model:t,temperature:.2,messages:[{role:"system",content:buildSystemPrompt(e)},{role:"user",content:buildUserPrompt(e)}]});if(!a.ok)return{ok:!1,error:`HTTP ${a.status}: ${a.error}`};const i=function(e){if(!e||"object"!=typeof e)return null;const t=e,o=t.choices?.[0]?.message?.content??t.choices?.[0]?.text;return"string"==typeof o?o:Array.isArray(o)?o.map(e=>"string"==typeof e?e:"object"==typeof e&&e&&"text"in e?String(e.text??""):"").filter(Boolean).join("\n"):"string"==typeof t.output_text?t.output_text:null}(a.data);return i?.trim()?{ok:!0,output:i}:{ok:!1,error:"El proveedor no devolvio contenido de texto."}}async function executeAnthropicCompatible(e,t,o,r){const n={"anthropic-version":"2023-06-01"};"api-key"===r.kind&&r.token?(n["x-api-key"]=r.token,"minimax"===e.workspace.provider&&(n.Authorization=`Bearer ${r.token}`)):"oauth"===r.kind&&r.token&&(n.Authorization=`Bearer ${r.token}`);const a=await postJson(`${trimTrailingSlash(o)}/v1/messages`,n,{model:t,max_tokens:2048,system:buildSystemPrompt(e),messages:[{role:"user",content:buildUserPrompt(e)}]});if(!a.ok)return{ok:!1,error:`HTTP ${a.status}: ${a.error}`};const i=function(e){if(!e||"object"!=typeof e)return null;const t=e;return t.content?.map(e=>"text"===e.type&&"string"==typeof e.text?e.text:"").filter(Boolean).join("\n")||null}(a.data);return i?.trim()?{ok:!0,output:i}:{ok:!1,error:"El proveedor no devolvio contenido de texto."}}export async function executeAgentDomainTask(t){const r=e(t.agent.profileId),n=t.workspace.provider,a=function(t){const o=e(t.agent.profileId);return t.agent.modelOverride?.trim()||o?.lastModel?.trim()||null}(t);if(!r)return{status:"blocked",summary:`No existe el perfil ${t.agent.profileId} para el agente ${t.agent.name}.`,output:null,provider:n,profileId:t.agent.profileId,model:a,messageType:"task.blocked",blockers:["Perfil del agente no encontrado."],metadata:{reason:"missing-profile"}};if(r.provider!==n)return{status:"blocked",summary:`El perfil ${r.id} pertenece a ${r.provider}, pero el workspace es ${n}.`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.blocked",blockers:["Perfil y workspace no coinciden."],metadata:{reason:"provider-profile-mismatch",profileProvider:r.provider}};if(!a)return{status:"blocked",summary:`El agente ${t.agent.name} no tiene modelo configurado.`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.blocked",blockers:["Modelo no configurado."],metadata:{reason:"missing-model"}};const i=resolveCredential(n,r.id);if("ollama"!==n&&"none"===i.kind)return{status:"blocked",summary:`El perfil ${r.id} no tiene credenciales para ${n}.`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.blocked",blockers:["Credenciales no configuradas."],metadata:{reason:"missing-credentials"}};const s=r.baseUrl||o[n];try{const e="claude"===n||"minimax"===n?await executeAnthropicCompatible(t,a,s,i):await executeOpenAICompatible(t,a,s,i);if(!e.ok)return{status:"failed",summary:`El agente ${t.agent.name} fallo ejecutando ${a}: ${e.error}`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.failed",blockers:[e.error],metadata:{reason:"provider-error",baseUrl:s}};const o=function(e,t=12e3){return e.length>t?`${e.slice(0,t)}\n\n[output truncado a ${t} caracteres]`:e}(e.output.trim());return{status:"completed",summary:o.split("\n").find(e=>e.trim())?.trim()||o,output:o,provider:n,profileId:r.id,model:a,messageType:"task.completed",blockers:[],metadata:{baseUrl:s,credentialKind:i.kind}}}catch(e){const o=function(e){return e instanceof Error?e.message:String(e)}(e);return{status:"failed",summary:`El agente ${t.agent.name} no pudo ejecutar la tarea: ${o}`,output:null,provider:n,profileId:r.id,model:a,messageType:"task.failed",blockers:[o],metadata:{reason:"execution-exception",baseUrl:s}}}}
@@ -1 +1 @@
1
- import{clearProviderProfileBaseUrl as t,getProviderProfileBaseUrl as i,isProfiledProvider as e,setProviderProfileBaseUrl as a}from"./providerProfiles.js";import{clearStoredProviderBaseUrl as r,getStoredProviderBaseUrl as o,setStoredProviderBaseUrl as n}from"./providerProfilesDb.js";const p={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",nvidia:"https://integrate.api.nvidia.com/v1",deepseek:"https://api.deepseek.com/v1",xai:"https://api.x.ai/v1",gmi:"https://api.gmi-serving.com/v1",novita:"https://api.novita.ai/openai/v1",stepfun:"https://api.stepfun.ai/step_plan/v1",huggingface:"https://router.huggingface.co/v1","opencode-zen":"https://opencode.ai/zen/v1",arcee:"https://api.arcee.ai/api/v1",alibaba:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",kimi:"https://api.moonshot.ai/v1","custom-openai":"https://api.openai.com/v1","custom-anthropic":"https://api.anthropic.com/v1"};function trimTrailingSlash(t){return t.endsWith("/")?t.slice(0,-1):t}export function getDefaultProviderBaseUrl(t){return p[t]}export function getConfiguredProviderBaseUrl(t){const e=i(t)?.trim();if(e)try{return normalizeProviderBaseUrl(t,e)}catch{return e}const a=o(t)?.trim();if(a)try{return normalizeProviderBaseUrl(t,a)}catch{return a}return getDefaultProviderBaseUrl(t)}export function isProviderBaseUrlCustomized(t){return Boolean(i(t)?.trim()||o(t)?.trim())}export function normalizeProviderBaseUrl(t,i){const e=function(t,i){const e=i.trim();if(!e)throw new Error("La base URL no puede estar vacia.");try{return new URL(e)}catch{return new URL(`${"ollama"===t||"ollama-cloud"===t?"http://":"https://"}${e}`)}}(t,i),a=`${e.protocol}//${e.host}${e.pathname}${e.search}${e.hash}`;return"zai"===t||"minimax"===t||"gemini-api"===t||"gemini-google"===t||"nvidia"===t?trimTrailingSlash(a):function(t){const i=trimTrailingSlash(t);return i.endsWith("/v1")?i:`${i}/v1`}(a)}export function setProviderBaseUrl(t,i){const r=normalizeProviderBaseUrl(t,i);return e(t)&&a(t,r),n(t,r),r}export function clearProviderBaseUrl(i){e(i)&&t(i),r(i)}
1
+ import{clearProviderProfileBaseUrl as t,getProviderProfileBaseUrl as i,isProfiledProvider as e,setProviderProfileBaseUrl as a}from"./providerProfiles.js";import{clearStoredProviderBaseUrl as o,getStoredProviderBaseUrl as r,setStoredProviderBaseUrl as n}from"./providerProfilesDb.js";const p={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",nvidia:"https://integrate.api.nvidia.com/v1",deepseek:"https://api.deepseek.com/v1",xai:"https://api.x.ai/v1",gmi:"https://api.gmi-serving.com/v1",novita:"https://api.novita.ai/openai/v1",stepfun:"https://api.stepfun.ai/step_plan/v1",huggingface:"https://router.huggingface.co/v1","opencode-zen":"https://opencode.ai/zen/v1",arcee:"https://api.arcee.ai/api/v1",alibaba:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",kimi:"https://api.moonshot.ai/v1","custom-openai":"https://api.openai.com/v1","custom-anthropic":"https://api.anthropic.com/v1"};function trimTrailingSlash(t){return t.endsWith("/")?t.slice(0,-1):t}export function getDefaultProviderBaseUrl(t){return p[t]}export function getConfiguredProviderBaseUrl(t){const e=i(t)?.trim();if(e)try{return normalizeProviderBaseUrl(t,e)}catch{return e}const a=r(t)?.trim();if(a)try{return normalizeProviderBaseUrl(t,a)}catch{return a}return getDefaultProviderBaseUrl(t)}export function isProviderBaseUrlCustomized(t){return Boolean(i(t)?.trim()||r(t)?.trim())}export function normalizeProviderBaseUrl(t,i){const e=function(t,i){const e=i.trim();if(!e)throw new Error("La base URL no puede estar vacia.");try{return new URL(e)}catch{return new URL(`${"ollama"===t||"ollama-cloud"===t||"lmstudio"===t?"http://":"https://"}${e}`)}}(t,i),a=`${e.protocol}//${e.host}${e.pathname}${e.search}${e.hash}`;return"zai"===t||"minimax"===t||"gemini-api"===t||"gemini-google"===t||"nvidia"===t?trimTrailingSlash(a):function(t){const i=trimTrailingSlash(t);return i.endsWith("/v1")?i:`${i}/v1`}(a)}export function setProviderBaseUrl(t,i){const o=normalizeProviderBaseUrl(t,i);return e(t)&&a(t,o),n(t,o),o}export function clearProviderBaseUrl(i){e(i)&&t(i),o(i)}
@@ -1 +1 @@
1
- export const VISIBLE_PROVIDERS=[{id:"minimax",label:"MiniMax",description:"API key propia. Usa el endpoint Anthropic-compatible y luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de MiniMax.",nextStep:"Despues, elige un modelo MiniMax compatible con Anthropic desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"openrouter",label:"OpenRouter",description:"API key propia. Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de OpenRouter.",nextStep:"Despues, elige un modelo compatible desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"ollama",label:"Ollama",description:"Servidor Ollama compatible. Incluye modelos locales y modelos cloud si hiciste ollama signin.",setup:{kind:"local-server",intro:"Esto solo configura el servidor Ollama; no abre un login OAuth.",nextStep:"Asegurate de tener ollama serve activo. Si usas cloud, ejecuta ollama signin fuera del CLI.",actionLabel:"Continuar con Ollama"},implemented:!0},{id:"ollama-cloud",label:"Ollama Cloud",description:"Modelos cloud desde tu servidor Ollama autenticado con ollama signin.",setup:{kind:"local-server",intro:"Esto usa tu servidor Ollama ya autenticado; no abre un login OAuth.",nextStep:"Ejecuta ollama signin fuera del CLI, usa http://localhost:11434/v1 y despues elige un modelo cloud desde /model.",actionLabel:"Continuar con Ollama Cloud"},implemented:!0},{id:"openai",label:"OpenAI / Codex",description:"OAuth de OpenAI",setup:{kind:"oauth",intro:"Inicia sesion con tu cuenta de OpenAI / Codex.",nextStep:"Despues de iniciar sesion, elige un modelo desde /model.",actionLabel:"Continuar con OpenAI"},implemented:!0},{id:"gemini-google",label:"Gemini Google OAuth",description:"Cuenta Google mediante OAuth compatible con Gemini CLI.",setup:{kind:"oauth",intro:"Inicia sesion con tu cuenta de Google usando el flujo OAuth de Gemini CLI.",nextStep:"Usa /login y elige Gemini Google para abrir el navegador y guardar el token OAuth.",actionLabel:"Continuar con Google"},implemented:!0},{id:"gemini-api",label:"Gemini API",description:"API key de Google AI Studio, usando endpoint OpenAI-compatible.",setup:{kind:"api-key",intro:"Pega tu API key de Gemini / Google AI Studio.",nextStep:"Despues, elige un modelo Gemini desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"zai",label:"Z.AI",description:"API key propia. Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de Z.AI.",nextStep:"Despues, elige un modelo compatible desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"nvidia",label:"NVIDIA API",description:"API key propia de NVIDIA NIM / build.nvidia.com. Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de NVIDIA.",nextStep:"Despues, elige un modelo compatible desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"deepseek",label:"DeepSeek",description:"API key propia de api.deepseek.com (OpenAI-compatible). Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de DeepSeek (sk-...).",nextStep:"Despues, elige un modelo como deepseek-chat o deepseek-reasoner desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"xai",label:"xAI / Grok",description:"API key propia de api.x.ai (OpenAI-compatible). Luego elige un modelo Grok en /model.",setup:{kind:"api-key",intro:"Pega tu API key de xAI (xai-...).",nextStep:"Despues, elige un modelo como grok-4 o grok-code-fast-1 desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"gmi",label:"GMI Cloud",description:"API key de api.gmi-serving.com (OpenAI-compatible, multi-modelo). Luego elige modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de GMI Cloud.",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"novita",label:"NovitaAI",description:"API key de novita.ai (OpenAI-compatible, multi-modelo). Luego elige modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de NovitaAI.",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"stepfun",label:"StepFun",description:"API key de stepfun.ai (OpenAI-compatible). Luego elige un modelo Step en /model.",setup:{kind:"api-key",intro:"Pega tu API key de StepFun.",nextStep:"Despues, elige un modelo como step-3 desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"huggingface",label:"HuggingFace",description:"Token HF en router.huggingface.co (OpenAI-compatible). Luego elige modelo en /model.",setup:{kind:"api-key",intro:"Pega tu token de HuggingFace (HF_TOKEN, hf_...).",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar token"},implemented:!0},{id:"opencode-zen",label:"OpenCode Zen",description:"API key de opencode.ai/zen (OpenAI-compatible). Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de OpenCode Zen.",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"arcee",label:"Arcee AI",description:"API key de api.arcee.ai (OpenAI-compatible). Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de Arcee AI.",nextStep:"Despues, elige un modelo (p.ej. auto) desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"alibaba",label:"Alibaba (Qwen)",description:"API key de DashScope (compatible-mode OpenAI). Luego elige un modelo Qwen en /model.",setup:{kind:"api-key",intro:"Pega tu API key de DashScope / Alibaba Cloud (DASHSCOPE_API_KEY).",nextStep:"Despues, elige un modelo como qwen3-max desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"kimi",label:"Kimi (Moonshot)",description:"API key de api.moonshot.ai (OpenAI-compatible). Luego elige un modelo Kimi en /model.",setup:{kind:"api-key",intro:"Pega tu API key de Kimi / Moonshot (KIMI_API_KEY).",nextStep:"Despues, elige un modelo como kimi-k2-0905-preview desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"claude",label:"Claude (Anthropic)",description:"Suscripcion Claude o Anthropic Console",setup:{kind:"oauth",intro:"Inicia sesion con tu cuenta de Claude o Anthropic Console.",nextStep:"Despues de iniciar sesion, elige un modelo desde /model.",actionLabel:"Continuar con Claude"},implemented:!0},{id:"custom-openai",label:"Custom OpenAI",description:"API key y endpoint personalizado para OpenAI-compatible. Ideal para proxies o servidores propios.",setup:{kind:"api-key",intro:"Wizard paso a paso: API key, endpoint (opcional), modelo (opcional).",nextStep:"Al finalizar, elige un modelo desde /model.",actionLabel:"Configurar Custom OpenAI"},implemented:!0},{id:"custom-anthropic",label:"Custom Anthropic",description:"API key y endpoint personalizado para Anthropic-compatible. Ideal para instalaciones on-premise.",setup:{kind:"api-key",intro:"Wizard paso a paso: API key, endpoint (opcional), modelo (opcional).",nextStep:"Al finalizar, elige un modelo desde /model.",actionLabel:"Configurar Custom Anthropic"},implemented:!0}];export function getVisibleProvider(e){const o=VISIBLE_PROVIDERS.find(o=>o.id===e);if(!o)throw new Error(`Unknown provider: ${e}`);return o}
1
+ export const VISIBLE_PROVIDERS=[{id:"minimax",label:"MiniMax",description:"API key propia. Usa el endpoint Anthropic-compatible y luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de MiniMax.",nextStep:"Despues, elige un modelo MiniMax compatible con Anthropic desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"openrouter",label:"OpenRouter",description:"API key propia. Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de OpenRouter.",nextStep:"Despues, elige un modelo compatible desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"ollama",label:"Ollama",description:"Servidor Ollama compatible. Incluye modelos locales y modelos cloud si hiciste ollama signin.",setup:{kind:"local-server",intro:"Esto solo configura el servidor Ollama; no abre un login OAuth.",nextStep:"Asegurate de tener ollama serve activo. Si usas cloud, ejecuta ollama signin fuera del CLI.",actionLabel:"Continuar con Ollama"},implemented:!0},{id:"ollama-cloud",label:"Ollama Cloud",description:"Modelos cloud desde tu servidor Ollama autenticado con ollama signin.",setup:{kind:"local-server",intro:"Esto usa tu servidor Ollama ya autenticado; no abre un login OAuth.",nextStep:"Ejecuta ollama signin fuera del CLI, usa http://localhost:11434/v1 y despues elige un modelo cloud desde /model.",actionLabel:"Continuar con Ollama Cloud"},implemented:!0},{id:"lmstudio",label:"LM Studio",description:"Servidor local OpenAI-compatible de LM Studio. No requiere API key.",setup:{kind:"local-server",intro:"Esto solo apunta al servidor local de LM Studio; no abre un login OAuth.",nextStep:"Abre LM Studio, ve a la pestaña Developer y pulsa Start Server (puerto 1234 por defecto). Carga un modelo en la pestana Chat y elige su identificador exacto desde /model.",actionLabel:"Continuar con LM Studio"},implemented:!0},{id:"openai",label:"OpenAI / Codex",description:"OAuth de OpenAI",setup:{kind:"oauth",intro:"Inicia sesion con tu cuenta de OpenAI / Codex.",nextStep:"Despues de iniciar sesion, elige un modelo desde /model.",actionLabel:"Continuar con OpenAI"},implemented:!0},{id:"gemini-google",label:"Gemini Google OAuth",description:"Cuenta Google mediante OAuth compatible con Gemini CLI.",setup:{kind:"oauth",intro:"Inicia sesion con tu cuenta de Google usando el flujo OAuth de Gemini CLI.",nextStep:"Usa /login y elige Gemini Google para abrir el navegador y guardar el token OAuth.",actionLabel:"Continuar con Google"},implemented:!0},{id:"gemini-api",label:"Gemini API",description:"API key de Google AI Studio, usando endpoint OpenAI-compatible.",setup:{kind:"api-key",intro:"Pega tu API key de Gemini / Google AI Studio.",nextStep:"Despues, elige un modelo Gemini desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"zai",label:"Z.AI",description:"API key propia. Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de Z.AI.",nextStep:"Despues, elige un modelo compatible desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"nvidia",label:"NVIDIA API",description:"API key propia de NVIDIA NIM / build.nvidia.com. Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de NVIDIA.",nextStep:"Despues, elige un modelo compatible desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"deepseek",label:"DeepSeek",description:"API key propia de api.deepseek.com (OpenAI-compatible). Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de DeepSeek (sk-...).",nextStep:"Despues, elige un modelo como deepseek-chat o deepseek-reasoner desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"xai",label:"xAI / Grok",description:"API key propia de api.x.ai (OpenAI-compatible). Luego elige un modelo Grok en /model.",setup:{kind:"api-key",intro:"Pega tu API key de xAI (xai-...).",nextStep:"Despues, elige un modelo como grok-4 o grok-code-fast-1 desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"gmi",label:"GMI Cloud",description:"API key de api.gmi-serving.com (OpenAI-compatible, multi-modelo). Luego elige modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de GMI Cloud.",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"novita",label:"NovitaAI",description:"API key de novita.ai (OpenAI-compatible, multi-modelo). Luego elige modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de NovitaAI.",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"stepfun",label:"StepFun",description:"API key de stepfun.ai (OpenAI-compatible). Luego elige un modelo Step en /model.",setup:{kind:"api-key",intro:"Pega tu API key de StepFun.",nextStep:"Despues, elige un modelo como step-3 desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"huggingface",label:"HuggingFace",description:"Token HF en router.huggingface.co (OpenAI-compatible). Luego elige modelo en /model.",setup:{kind:"api-key",intro:"Pega tu token de HuggingFace (HF_TOKEN, hf_...).",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar token"},implemented:!0},{id:"opencode-zen",label:"OpenCode Zen",description:"API key de opencode.ai/zen (OpenAI-compatible). Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de OpenCode Zen.",nextStep:"Despues, elige un modelo desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"arcee",label:"Arcee AI",description:"API key de api.arcee.ai (OpenAI-compatible). Luego elige un modelo en /model.",setup:{kind:"api-key",intro:"Pega tu API key de Arcee AI.",nextStep:"Despues, elige un modelo (p.ej. auto) desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"alibaba",label:"Alibaba (Qwen)",description:"API key de DashScope (compatible-mode OpenAI). Luego elige un modelo Qwen en /model.",setup:{kind:"api-key",intro:"Pega tu API key de DashScope / Alibaba Cloud (DASHSCOPE_API_KEY).",nextStep:"Despues, elige un modelo como qwen3-max desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"kimi",label:"Kimi (Moonshot)",description:"API key de api.moonshot.ai (OpenAI-compatible). Luego elige un modelo Kimi en /model.",setup:{kind:"api-key",intro:"Pega tu API key de Kimi / Moonshot (KIMI_API_KEY).",nextStep:"Despues, elige un modelo como kimi-k2-0905-preview desde /model.",actionLabel:"Pegar API key"},implemented:!0},{id:"claude",label:"Claude (Anthropic)",description:"Suscripcion Claude o Anthropic Console",setup:{kind:"oauth",intro:"Inicia sesion con tu cuenta de Claude o Anthropic Console.",nextStep:"Despues de iniciar sesion, elige un modelo desde /model.",actionLabel:"Continuar con Claude"},implemented:!0},{id:"custom-openai",label:"Custom OpenAI",description:"API key y endpoint personalizado para OpenAI-compatible. Ideal para proxies o servidores propios.",setup:{kind:"api-key",intro:"Wizard paso a paso: API key, endpoint (opcional), modelo (opcional).",nextStep:"Al finalizar, elige un modelo desde /model.",actionLabel:"Configurar Custom OpenAI"},implemented:!0},{id:"custom-anthropic",label:"Custom Anthropic",description:"API key y endpoint personalizado para Anthropic-compatible. Ideal para instalaciones on-premise.",setup:{kind:"api-key",intro:"Wizard paso a paso: API key, endpoint (opcional), modelo (opcional).",nextStep:"Al finalizar, elige un modelo desde /model.",actionLabel:"Configurar Custom Anthropic"},implemented:!0}];export function getVisibleProvider(e){const o=VISIBLE_PROVIDERS.find(o=>o.id===e);if(!o)throw new Error(`Unknown provider: ${e}`);return o}
@@ -1 +1 @@
1
- import{getStoredLastModelForProvider as e,getStoredProviderBaseUrl as i,readProviderProfilesState as r,writeProviderProfilesState as o}from"./providerProfilesDb.js";const t=new Set(["claude","openai","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"]),n={claude:"main",openai:"main",openrouter:"main",ollama:"local","ollama-cloud":"main","gemini-api":"main","gemini-google":"main",zai:"main",minimax:"main",nvidia:"main",deepseek:"main",xai:"main",gmi:"main",novita:"main",stepfun:"main",huggingface:"main","opencode-zen":"main",arcee:"main",alibaba:"main",kimi:"main","custom-openai":"main","custom-anthropic":"main"},a={claude:"claude",openai:"openai",openrouter:"openrouter",ollama:"ollama-local","ollama-cloud":"ollama-cloud","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"z-ai",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"},l={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",deepseek:"https://api.deepseek.com/v1",xai:"https://api.x.ai/v1",gmi:"https://api.gmi-serving.com/v1",novita:"https://api.novita.ai/openai/v1",stepfun:"https://api.stepfun.ai/step_plan/v1",huggingface:"https://router.huggingface.co/v1","opencode-zen":"https://opencode.ai/zen/v1",arcee:"https://api.arcee.ai/api/v1",alibaba:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",kimi:"https://api.moonshot.ai/v1"};function sanitizeProfileSegment(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"default"}function buildProfileId(e,i){return`${e}/${sanitizeProfileSegment(i)}`}function buildDefaultAgentName(e,i){const r=a[e],o=sanitizeProfileSegment(i);return o===sanitizeProfileSegment(n[e])?r:`${r}-${o}`}export function getDefaultProfileName(e){return n[e]}export function buildProviderProfileId(e,i){return buildProfileId(e,i)}export function isDefaultProfileId(e,i){return!!i&&i===buildProfileId(e,n[e])}function getState(){const e=r();return{version:1,profiles:e.profiles??{},lastProfileIdByProvider:e.lastProfileIdByProvider??{},activeProfileId:e.activeProfileId}}function saveState(e){const i=e(getState());return o(i),i}function getProfilesMap(){return getState().profiles??{}}function getProfileSeed(r,o){return o?function(r){return{baseUrl:"openrouter"===r||"ollama"===r||"ollama-cloud"===r||"zai"===r||"minimax"===r||"deepseek"===r||"xai"===r||"gmi"===r||"novita"===r||"stepfun"===r||"huggingface"===r||"opencode-zen"===r||"arcee"===r||"alibaba"===r||"kimi"===r?i(r):void 0,lastModel:e(r)??null}}(r):{baseUrl:l[r],lastModel:null}}export function isProfiledProvider(e){return t.has(e)}export function listProviderProfiles(e){const i=Object.values(getProfilesMap());return e?i.filter(i=>i.provider===e):i}export function getProviderProfile(e){return e?getProfilesMap()[e]??null:null}export function getActiveProviderProfile(){return getProviderProfile(getState().activeProfileId)}export function getLastUsedProviderProfile(e){const i=getState(),r=i.lastProfileIdByProvider?.[e];if(r){const e=getProviderProfile(r);if(e)return e}return listProviderProfiles(e)[0]??null}export function createProviderProfile(e){const i=buildProfileId(e.provider,e.name),r=getProviderProfile(i);if(r)return r;const o=(new Date).toISOString(),t={id:i,provider:e.provider,name:e.name.trim()||n[e.provider],agentName:e.agentName?.trim()||buildDefaultAgentName(e.provider,e.name),baseUrl:e.baseUrl,lastModel:e.lastModel??null,createdAt:o,updatedAt:o};return saveState(i=>({...i,activeProfileId:e.activate?t.id:i.activeProfileId,profiles:{...i.profiles??{},[t.id]:t},lastProfileIdByProvider:{...i.lastProfileIdByProvider??{},[e.provider]:t.id}})),t}export function ensureProviderProfile(e,i=n[e]){const r=getProviderProfile(buildProfileId(e,i));if(r)return r;return createProviderProfile({provider:e,name:i,...getProfileSeed(e,0===listProviderProfiles(e).length),activate:!1})}export function resolveProviderProfile(e,i={}){const r=getActiveProviderProfile();if(r?.provider===e)return r;const o=getLastUsedProviderProfile(e);return o||(i.createIfMissing?ensureProviderProfile(e):null)}export function getResolvedProviderProfileId(e){return resolveProviderProfile(e)?.id??null}export function setActiveProviderProfile(e){const i=getProviderProfile(e);return i?(saveState(e=>({...e,activeProfileId:i.id,lastProfileIdByProvider:{...e.lastProfileIdByProvider??{},[i.provider]:i.id}})),i):null}export function setActiveProfileForProvider(e,i){const r=i&&i.trim()?ensureProviderProfile(e,i):resolveProviderProfile(e,{createIfMissing:!0});return setActiveProviderProfile(r.id),r}export function findProviderProfileByName(e,i){return getProviderProfile(buildProfileId(e,i))}export function updateProviderProfile(e,i){let r=null;return saveState(o=>{const t=o.profiles?.[e];return t?(r=i(t),{...o,profiles:{...o.profiles??{},[e]:r},lastProfileIdByProvider:{...o.lastProfileIdByProvider??{},[t.provider]:e}}):o}),r}export function renameProviderProfile(e,i,r){const o=findProviderProfileByName(e,i);if(!o)return null;const t=r.trim();if(!t)throw new Error("Debes indicar un nuevo nombre de perfil.");const n=buildProfileId(e,t);if(n!==o.id&&getProviderProfile(n))throw new Error(`Ya existe un perfil ${e}/${t}.`);const a={...o,id:n,name:t,updatedAt:(new Date).toISOString()};return saveState(i=>{const r={...i.profiles??{}};delete r[o.id],r[n]=a;const t={...i.lastProfileIdByProvider??{},[e]:i.lastProfileIdByProvider?.[e]===o.id?n:i.lastProfileIdByProvider?.[e]};return{...i,activeProfileId:i.activeProfileId===o.id?n:i.activeProfileId,profiles:r,lastProfileIdByProvider:t}}),{previousId:o.id,profile:a}}export function removeProviderProfile(e,i){const r=findProviderProfileByName(e,i);return r?(saveState(i=>{const o={...i.profiles??{}};delete o[r.id];const t=Object.values(o).filter(i=>i.provider===e),n=t[0]?.id;return{...i,activeProfileId:i.activeProfileId===r.id?n:i.activeProfileId,profiles:o,lastProfileIdByProvider:{...i.lastProfileIdByProvider??{},[e]:i.lastProfileIdByProvider?.[e]===r.id?n:i.lastProfileIdByProvider?.[e]}}}),r):null}export function clearAllProviderProfiles(){const e=Object.values(getProfilesMap());return saveState(e=>({version:1,profiles:{},lastProfileIdByProvider:{}})),e}export function setProviderProfileAgentNameByName(e,i,r){const o=findProviderProfileByName(e,i);if(!o)return null;const t=sanitizeProfileSegment(r);if(!t)throw new Error("Debes indicar un agentName valido.");return updateProviderProfile(o.id,e=>({...e,agentName:t,updatedAt:(new Date).toISOString()}))}export function setProviderProfileBaseUrl(e,i){const r=resolveProviderProfile(e,{createIfMissing:!0});return updateProviderProfile(r.id,e=>({...e,baseUrl:i,updatedAt:(new Date).toISOString()}))??r}export function clearProviderProfileBaseUrl(e){const i=resolveProviderProfile(e);return i?updateProviderProfile(i.id,e=>({...e,baseUrl:void 0,updatedAt:(new Date).toISOString()})):null}export function getProviderProfileBaseUrl(e){return resolveProviderProfile(e)?.baseUrl??null}export function setProviderProfileLastModel(e,i){const r=resolveProviderProfile(e);return r?updateProviderProfile(r.id,e=>({...e,lastModel:i,updatedAt:(new Date).toISOString()})):null}export function getProviderProfileLastModel(e){return resolveProviderProfile(e)?.lastModel??null}export function setProviderProfileLastModelByName(e,i,r){const o=findProviderProfileByName(e,i);return o?updateProviderProfile(o.id,e=>({...e,lastModel:r,updatedAt:(new Date).toISOString()})):null}
1
+ import{getStoredLastModelForProvider as e,getStoredProviderBaseUrl as i,readProviderProfilesState as r,writeProviderProfilesState as o}from"./providerProfilesDb.js";const t=new Set(["claude","openai","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"]),n={claude:"main",openai:"main",openrouter:"main",ollama:"local","ollama-cloud":"main",lmstudio:"local","gemini-api":"main","gemini-google":"main",zai:"main",minimax:"main",nvidia:"main",deepseek:"main",xai:"main",gmi:"main",novita:"main",stepfun:"main",huggingface:"main","opencode-zen":"main",arcee:"main",alibaba:"main",kimi:"main","custom-openai":"main","custom-anthropic":"main"},a={claude:"claude",openai:"openai",openrouter:"openrouter",ollama:"ollama-local","ollama-cloud":"ollama-cloud",lmstudio:"lmstudio-local","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"z-ai",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"},l={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",deepseek:"https://api.deepseek.com/v1",xai:"https://api.x.ai/v1",gmi:"https://api.gmi-serving.com/v1",novita:"https://api.novita.ai/openai/v1",stepfun:"https://api.stepfun.ai/step_plan/v1",huggingface:"https://router.huggingface.co/v1","opencode-zen":"https://opencode.ai/zen/v1",arcee:"https://api.arcee.ai/api/v1",alibaba:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",kimi:"https://api.moonshot.ai/v1"};function sanitizeProfileSegment(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"default"}function buildProfileId(e,i){return`${e}/${sanitizeProfileSegment(i)}`}function buildDefaultAgentName(e,i){const r=a[e],o=sanitizeProfileSegment(i);return o===sanitizeProfileSegment(n[e])?r:`${r}-${o}`}export function getDefaultProfileName(e){return n[e]}export function buildProviderProfileId(e,i){return buildProfileId(e,i)}export function isDefaultProfileId(e,i){return!!i&&i===buildProfileId(e,n[e])}function getState(){const e=r();return{version:1,profiles:e.profiles??{},lastProfileIdByProvider:e.lastProfileIdByProvider??{},activeProfileId:e.activeProfileId}}function saveState(e){const i=e(getState());return o(i),i}function getProfilesMap(){return getState().profiles??{}}function getProfileSeed(r,o){return o?function(r){return{baseUrl:"openrouter"===r||"ollama"===r||"ollama-cloud"===r||"zai"===r||"minimax"===r||"deepseek"===r||"xai"===r||"gmi"===r||"novita"===r||"stepfun"===r||"huggingface"===r||"opencode-zen"===r||"arcee"===r||"alibaba"===r||"kimi"===r?i(r):void 0,lastModel:e(r)??null}}(r):{baseUrl:l[r],lastModel:null}}export function isProfiledProvider(e){return t.has(e)}export function listProviderProfiles(e){const i=Object.values(getProfilesMap());return e?i.filter(i=>i.provider===e):i}export function getProviderProfile(e){return e?getProfilesMap()[e]??null:null}export function getActiveProviderProfile(){return getProviderProfile(getState().activeProfileId)}export function getLastUsedProviderProfile(e){const i=getState(),r=i.lastProfileIdByProvider?.[e];if(r){const e=getProviderProfile(r);if(e)return e}return listProviderProfiles(e)[0]??null}export function createProviderProfile(e){const i=buildProfileId(e.provider,e.name),r=getProviderProfile(i);if(r)return r;const o=(new Date).toISOString(),t={id:i,provider:e.provider,name:e.name.trim()||n[e.provider],agentName:e.agentName?.trim()||buildDefaultAgentName(e.provider,e.name),baseUrl:e.baseUrl,lastModel:e.lastModel??null,createdAt:o,updatedAt:o};return saveState(i=>({...i,activeProfileId:e.activate?t.id:i.activeProfileId,profiles:{...i.profiles??{},[t.id]:t},lastProfileIdByProvider:{...i.lastProfileIdByProvider??{},[e.provider]:t.id}})),t}export function ensureProviderProfile(e,i=n[e]){const r=getProviderProfile(buildProfileId(e,i));if(r)return r;return createProviderProfile({provider:e,name:i,...getProfileSeed(e,0===listProviderProfiles(e).length),activate:!1})}export function resolveProviderProfile(e,i={}){const r=getActiveProviderProfile();if(r?.provider===e)return r;const o=getLastUsedProviderProfile(e);return o||(i.createIfMissing?ensureProviderProfile(e):null)}export function getResolvedProviderProfileId(e){return resolveProviderProfile(e)?.id??null}export function setActiveProviderProfile(e){const i=getProviderProfile(e);return i?(saveState(e=>({...e,activeProfileId:i.id,lastProfileIdByProvider:{...e.lastProfileIdByProvider??{},[i.provider]:i.id}})),i):null}export function setActiveProfileForProvider(e,i){const r=i&&i.trim()?ensureProviderProfile(e,i):resolveProviderProfile(e,{createIfMissing:!0});return setActiveProviderProfile(r.id),r}export function findProviderProfileByName(e,i){return getProviderProfile(buildProfileId(e,i))}export function updateProviderProfile(e,i){let r=null;return saveState(o=>{const t=o.profiles?.[e];return t?(r=i(t),{...o,profiles:{...o.profiles??{},[e]:r},lastProfileIdByProvider:{...o.lastProfileIdByProvider??{},[t.provider]:e}}):o}),r}export function renameProviderProfile(e,i,r){const o=findProviderProfileByName(e,i);if(!o)return null;const t=r.trim();if(!t)throw new Error("Debes indicar un nuevo nombre de perfil.");const n=buildProfileId(e,t);if(n!==o.id&&getProviderProfile(n))throw new Error(`Ya existe un perfil ${e}/${t}.`);const a={...o,id:n,name:t,updatedAt:(new Date).toISOString()};return saveState(i=>{const r={...i.profiles??{}};delete r[o.id],r[n]=a;const t={...i.lastProfileIdByProvider??{},[e]:i.lastProfileIdByProvider?.[e]===o.id?n:i.lastProfileIdByProvider?.[e]};return{...i,activeProfileId:i.activeProfileId===o.id?n:i.activeProfileId,profiles:r,lastProfileIdByProvider:t}}),{previousId:o.id,profile:a}}export function removeProviderProfile(e,i){const r=findProviderProfileByName(e,i);return r?(saveState(i=>{const o={...i.profiles??{}};delete o[r.id];const t=Object.values(o).filter(i=>i.provider===e),n=t[0]?.id;return{...i,activeProfileId:i.activeProfileId===r.id?n:i.activeProfileId,profiles:o,lastProfileIdByProvider:{...i.lastProfileIdByProvider??{},[e]:i.lastProfileIdByProvider?.[e]===r.id?n:i.lastProfileIdByProvider?.[e]}}}),r):null}export function clearAllProviderProfiles(){const e=Object.values(getProfilesMap());return saveState(e=>({version:1,profiles:{},lastProfileIdByProvider:{}})),e}export function setProviderProfileAgentNameByName(e,i,r){const o=findProviderProfileByName(e,i);if(!o)return null;const t=sanitizeProfileSegment(r);if(!t)throw new Error("Debes indicar un agentName valido.");return updateProviderProfile(o.id,e=>({...e,agentName:t,updatedAt:(new Date).toISOString()}))}export function setProviderProfileBaseUrl(e,i){const r=resolveProviderProfile(e,{createIfMissing:!0});return updateProviderProfile(r.id,e=>({...e,baseUrl:i,updatedAt:(new Date).toISOString()}))??r}export function clearProviderProfileBaseUrl(e){const i=resolveProviderProfile(e);return i?updateProviderProfile(i.id,e=>({...e,baseUrl:void 0,updatedAt:(new Date).toISOString()})):null}export function getProviderProfileBaseUrl(e){return resolveProviderProfile(e)?.baseUrl??null}export function setProviderProfileLastModel(e,i){const r=resolveProviderProfile(e);return r?updateProviderProfile(r.id,e=>({...e,lastModel:i,updatedAt:(new Date).toISOString()})):null}export function getProviderProfileLastModel(e){return resolveProviderProfile(e)?.lastModel??null}export function setProviderProfileLastModelByName(e,i,r){const o=findProviderProfileByName(e,i);return o?updateProviderProfile(o.id,e=>({...e,lastModel:r,updatedAt:(new Date).toISOString()})):null}
@@ -1 +1 @@
1
- import{createRequire as e}from"module";import{randomUUID as t}from"node:crypto";import{join as n}from"path";import{getGlobalConfig as i,saveGlobalConfig as r}from"../config.js";import{getClaudeConfigHomeDir as a}from"../envUtils.js";import{getFsImplementation as E}from"../fsOperations.js";import{getSecureStorage as o}from"../secureStorage/index.js";function hasStoredCredentialForProvider(e,t){if(!e)return!1;if("openai"===t&&e.openAiOauth?.accessToken)return!0;if("claude"===t&&e.claudeAiOauth?.accessToken)return!0;if(Object.keys(e.providerProfileOauth??{}).some(e=>e.startsWith(`${t}/`)))return!0;if(e.providerApiKeys?.[t])return!0;return Object.keys(e.providerProfileApiKeys??{}).some(e=>e.startsWith(`${t}/`))}const d=e(import.meta.url);let _=null,s=!1,T=!1;const l="active_provider",N="active_profile_id",p=["claude","openai","openrouter","ollama","ollama-cloud","gemini-api","gemini-google","zai","minimax","deepseek"],L={claude:"main",openai:"main",openrouter:"main",ollama:"local","ollama-cloud":"main","gemini-api":"main","gemini-google":"main",zai:"main",minimax:"main",nvidia:"main",deepseek:"main"},c={claude:"claude",openai:"openai",openrouter:"openrouter",ollama:"ollama-local","ollama-cloud":"ollama-cloud","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"z-ai",minimax:"minimax",nvidia:"nvidia",deepseek:"deepseek"},u={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",deepseek:"https://api.deepseek.com/v1"},m={claude:"Claude",openai:"OpenAI",openrouter:"OpenRouter",ollama:"Ollama","ollama-cloud":"Ollama Cloud","gemini-api":"Gemini API","gemini-google":"Gemini Google",zai:"Z.AI",minimax:"MiniMax",nvidia:"NVIDIA NIM",deepseek:"DeepSeek"},O=["openrouter","ollama","ollama-cloud","gemini-api","gemini-google","zai","minimax","deepseek"];function sanitizeProfileSegment(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"default"}function buildProfileId(e,t){return`${e}/${sanitizeProfileSegment(t)}`}function buildDefaultAgentName(e,t){const n=c[e],i=sanitizeProfileSegment(t);return i===sanitizeProfileSegment(L[e])?n:`${n}-${i}`}function tableExists(e,t){const n=e.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(t);return Boolean(n)}function columnExists(e,t,n){return e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)}function migrateTeamUnitsSchema(e){e.exec("PRAGMA foreign_keys = OFF;");try{tableExists(e,"team_domains")&&e.exec("\n INSERT OR IGNORE INTO team_units (\n id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n )\n SELECT id, team_id, domain_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n FROM team_domains;\n "),tableExists(e,"team_domain_members")&&e.exec("\n INSERT OR IGNORE INTO team_unit_members (\n id, team_unit_id, agent_id, duty, priority, created_at, updated_at\n )\n SELECT id, team_domain_id, agent_id, duty, priority, created_at, updated_at\n FROM team_domain_members;\n "),tableExists(e,"orchestration_tasks")&&!columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("ALTER TABLE orchestration_tasks ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n UPDATE orchestration_tasks\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS orchestration_tasks_v8 (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks_v8(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n INSERT OR REPLACE INTO orchestration_tasks_v8 (\n id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n )\n SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n FROM orchestration_tasks;\n\n DROP TABLE orchestration_tasks;\n ALTER TABLE orchestration_tasks_v8 RENAME TO orchestration_tasks;\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n ")}(e),tableExists(e,"orchestration_domain_reports")&&e.exec("\n INSERT OR IGNORE INTO orchestration_team_reports (\n id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n )\n SELECT id, run_id, team_domain_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n FROM orchestration_domain_reports;\n "),tableExists(e,"provider_agent_capability_rankings")&&!columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("ALTER TABLE provider_agent_capability_rankings ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n UPDATE provider_agent_capability_rankings\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings_v8 (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n INSERT OR REPLACE INTO provider_agent_capability_rankings_v8 (\n id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n )\n SELECT id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n FROM provider_agent_capability_rankings;\n\n DROP TABLE provider_agent_capability_rankings;\n ALTER TABLE provider_agent_capability_rankings_v8 RENAME TO provider_agent_capability_rankings;\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n ")}(e),e.exec("\n DROP TABLE IF EXISTS orchestration_domain_reports;\n DROP TABLE IF EXISTS team_domain_members;\n DROP TABLE IF EXISTS team_domains;\n ")}finally{e.exec("PRAGMA foreign_keys = ON;")}tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n "),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n ")}function getDatabasePath(){return n(a(),"provider-state.sqlite3")}function rowToProfile(e){if(!e)return null;const t=e;return{id:t.id,provider:t.provider,name:t.name,agentName:t.agent_name,baseUrl:t.base_url??void 0,lastModel:t.last_model,createdAt:t.created_at,updatedAt:t.updated_at}}function seedLegacyProfiles(){const e=i(),t=e.providerProfiles,n={...t&&"object"==typeof t&&t.profiles?t.profiles:{}},r={...t&&"object"==typeof t&&t.lastProfileIdByProvider?t.lastProfileIdByProvider:{}},a=(()=>{try{return o().read()}catch{return null}})();for(const t of p){const i=Object.values(n).some(e=>e.provider===t),E=e.providerBaseUrls?.[t],o=e.lastModelByProvider?.[t]??null;if(!(i||e.activeProvider===t||Boolean(E)||null!==o||hasStoredCredentialForProvider(a,t))||i)continue;const d=L[t],_=buildProfileId(t,d),s=(new Date).toISOString();n[_]={id:_,provider:t,name:d,agentName:buildDefaultAgentName(t,d),baseUrl:E??u[t],lastModel:o,createdAt:s,updatedAt:s},r[t]=_}return{version:1,activeProfileId:(t&&"object"==typeof t?t.activeProfileId:void 0)??(e.activeProvider&&p.includes(e.activeProvider)?r[e.activeProvider]:void 0),lastProfileIdByProvider:r,profiles:n}}function migrateFromLegacyConfig(e){const t=i(),n=seedLegacyProfiles(),r=e.prepare("\n INSERT OR REPLACE INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n "),a=e.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ON CONFLICT(provider) DO UPDATE SET profile_id = excluded.profile_id\n "),E=e.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n "),o=e.prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n "),d=e.prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ");for(const e of Object.values(n.profiles??{}))r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);for(const[e,t]of Object.entries(n.lastProfileIdByProvider??{}))t&&a.run(e,t);n.activeProfileId&&E.run(N,n.activeProfileId);const _=t.activeProvider??(n.activeProfileId?n.profiles?.[n.activeProfileId]?.provider:void 0);_&&E.run(l,_);const s={claude:t.lastClaudeModel??t.lastModelByProvider?.claude??null,openai:t.lastOpenAIModel??t.lastModelByProvider?.openai??null,openrouter:t.lastOpenRouterModel??t.lastModelByProvider?.openrouter??null,ollama:t.lastModelByProvider?.ollama??null,"ollama-cloud":t.lastModelByProvider?.["ollama-cloud"]??null,"gemini-api":t.lastModelByProvider?.["gemini-api"]??null,"gemini-google":t.lastModelByProvider?.["gemini-google"]??null,zai:t.lastModelByProvider?.zai??null,minimax:t.lastModelByProvider?.minimax??null,deepseek:t.lastModelByProvider?.deepseek??null};for(const e of p)o.run(e,s[e]??null,(new Date).toISOString());for(const e of O){const n=t.providerBaseUrls?.[e];"string"==typeof n&&n.trim()&&d.run(e,n.trim(),(new Date).toISOString())}}export function purgeLegacyProviderStateInConfig(){hasLegacyProviderStateInConfig()&&r(e=>({...e,activeProvider:void 0,lastModelByProvider:{},providerBaseUrls:void 0,lastOpenAIModel:void 0,lastClaudeModel:void 0,lastOpenRouterModel:void 0,providerProfiles:void 0}))}export function finalizeProviderProfilesMigration(){ensureInitialized(),purgeLegacyProviderStateInConfig()}function ensureInitialized(){const e=function(){if(T)throw new Error("SQLite no disponible en este runtime.");if(_)return _;let e;E().mkdirSync(a(),{mode:448});try{e=d("node:sqlite")}catch(e){throw T=!0,e}return _=new e.DatabaseSync(getDatabasePath()),_}();if(s)return e;e.exec("\n PRAGMA journal_mode = WAL;\n PRAGMA foreign_keys = ON;\n PRAGMA synchronous = NORMAL;\n\n CREATE TABLE IF NOT EXISTS provider_profiles (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n name TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n base_url TEXT NULL,\n last_model TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_profile (\n provider TEXT PRIMARY KEY,\n profile_id TEXT NOT NULL,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS provider_runtime_state (\n key TEXT PRIMARY KEY,\n value TEXT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_model (\n provider TEXT PRIMARY KEY,\n last_model TEXT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_base_url (\n provider TEXT PRIMARY KEY,\n base_url TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_workspaces (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL UNIQUE,\n display_name TEXT NOT NULL,\n domain_focus TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_agents (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n profile_id TEXT NOT NULL,\n name TEXT NOT NULL,\n role_kind TEXT NULL,\n system_prompt TEXT NULL,\n model_override TEXT NULL,\n tool_policy TEXT NULL,\n autonomy_level TEXT NULL,\n is_orchestrator INTEGER NOT NULL DEFAULT 0,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE CASCADE,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE,\n UNIQUE (workspace_id, name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agents_workspace_id\n ON provider_agents(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agents_profile_id\n ON provider_agents(profile_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capabilities (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n capability TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (agent_id, capability)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capabilities_agent_id\n ON provider_agent_capabilities(agent_id);\n\n CREATE TABLE IF NOT EXISTS teams (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT NULL,\n global_orchestrator_agent_id TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE TABLE IF NOT EXISTS team_units (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n unit_name TEXT NOT NULL,\n workspace_id TEXT NULL,\n local_orchestrator_agent_id TEXT NULL,\n lead_agent_id TEXT NULL,\n selection_mode TEXT NOT NULL DEFAULT 'manual',\n required INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE SET NULL,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (lead_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (team_id, unit_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_units_team_id\n ON team_units(team_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_workspace_id\n ON team_units(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_local_orchestrator_agent_id\n ON team_units(local_orchestrator_agent_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_lead_agent_id\n ON team_units(lead_agent_id);\n\n CREATE TABLE IF NOT EXISTS team_unit_members (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n duty TEXT NULL,\n priority INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_team_unit_id\n ON team_unit_members(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_agent_id\n ON team_unit_members(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_runs (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n goal TEXT NOT NULL,\n global_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n created_at TEXT NOT NULL,\n started_at TEXT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_team_id\n ON orchestration_runs(team_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_status\n ON orchestration_runs(status);\n\n CREATE TABLE IF NOT EXISTS orchestration_tasks (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_messages (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NULL,\n from_agent_id TEXT NULL,\n to_agent_id TEXT NULL,\n message_type TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (from_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (to_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_run_id\n ON orchestration_messages(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_task_id\n ON orchestration_messages(task_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_task_results (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n agent_id TEXT NULL,\n result_type TEXT NOT NULL,\n status TEXT NOT NULL,\n summary TEXT NULL,\n content TEXT NULL,\n metadata_json TEXT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_run_id\n ON orchestration_task_results(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_task_id\n ON orchestration_task_results(task_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_agent_id\n ON orchestration_task_results(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_team_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n team_unit_id TEXT NOT NULL,\n local_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n blockers TEXT NULL,\n output TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (run_id, team_unit_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_run_id\n ON orchestration_team_reports(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_team_unit_id\n ON orchestration_team_reports(team_unit_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_run_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n output TEXT NULL,\n risks TEXT NULL,\n next_steps TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_run_reports_run_id\n ON orchestration_run_reports(run_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n\n CREATE TABLE IF NOT EXISTS secure_storage (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS projects (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS permission_rules (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n tool_name TEXT NOT NULL,\n behavior TEXT NOT NULL,\n created_at TEXT NOT NULL,\n expires_at TEXT NULL,\n UNIQUE (scope, scope_path, tool_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_permission_rules_scope\n ON permission_rules(scope, scope_path);\n CREATE INDEX IF NOT EXISTS idx_permission_rules_tool_name\n ON permission_rules(tool_name);\n\n CREATE TABLE IF NOT EXISTS permission_mode_config (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n mode TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE (scope, scope_path)\n );\n\n CREATE TABLE IF NOT EXISTS trusted_directories (\n path TEXT PRIMARY KEY,\n trust_level TEXT NOT NULL DEFAULT 'full',\n created_at TEXT NOT NULL\n );\n "),migrateTeamUnitsSchema(e);const n=e.prepare("PRAGMA user_version").get();(n?.user_version??0)<8&&e.exec("PRAGMA user_version = 8"),function(e){const n=(new Date).toISOString(),i=e.prepare("\n INSERT OR IGNORE INTO provider_workspaces (\n id, provider, display_name, domain_focus, is_enabled, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ");for(const e of p)i.run(t(),e,m[e],null,1,n,n)}(e);const i=e.prepare("SELECT COUNT(*) AS count FROM provider_profiles").get();if(0===(i?.count??0))migrateFromLegacyConfig(e);else{const t=e.prepare("SELECT COUNT(*) AS count FROM provider_last_model").get();0===(t?.count??0)&&migrateFromLegacyConfig(e);const n=e.prepare("SELECT COUNT(*) AS count FROM provider_base_url").get();0===(n?.count??0)&&migrateFromLegacyConfig(e)}return purgeLegacyProviderStateInConfig(),s=!0,e}export class ProviderProfilesDb{static instance=null;db;constructor(){this.db=ensureInitialized()}static async get(){return ProviderProfilesDb.instance||(ProviderProfilesDb.instance=new ProviderProfilesDb),ProviderProfilesDb.instance}}export function getProviderProfilesDbPath(){return getDatabasePath()}export function getProviderProfilesStorageBackend(){try{return ensureInitialized(),"sqlite"}catch{return"legacy"}}export function hasLegacyProviderStateInConfig(){try{const e=i();return Boolean(e.activeProvider||e.lastClaudeModel||e.lastOpenAIModel||e.lastOpenRouterModel||Object.keys(e.lastModelByProvider??{}).length>0||Object.keys(e.providerBaseUrls??{}).length>0||e.providerProfiles?.activeProfileId||Object.keys(e.providerProfiles?.profiles??{}).length>0||Object.keys(e.providerProfiles?.lastProfileIdByProvider??{}).length>0)}catch{return!1}}export function getProviderProfilesStorageMode(){return"sqlite"!==getProviderProfilesStorageBackend()?"legacy":hasLegacyProviderStateInConfig()?"sqlite-migration-pending":"sqlite-only"}export function readProviderProfilesState(){let e;try{e=ensureInitialized()}catch{return seedLegacyProfiles()}const t=e.prepare("SELECT id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n FROM provider_profiles\n ORDER BY provider, created_at, id").all().map(rowToProfile).filter(e=>null!==e),n=e.prepare("SELECT provider, profile_id FROM provider_last_profile").all(),i=e.prepare(`SELECT value FROM provider_runtime_state WHERE key = '${N}'`).get();return{version:1,activeProfileId:i?.value,lastProfileIdByProvider:Object.fromEntries(n.map(e=>[e.provider,e.profile_id])),profiles:Object.fromEntries(t.map(e=>[e.id,e]))}}export function writeProviderProfilesState(e){let t;try{t=ensureInitialized()}catch{return}const n=Object.values(e.profiles??{}),i=0===n.length;t.exec("BEGIN");try{t.exec("DELETE FROM provider_last_profile"),t.exec(`DELETE FROM provider_runtime_state WHERE key = '${N}'`),t.exec("DELETE FROM provider_profiles"),i&&(t.exec(`DELETE FROM provider_runtime_state WHERE key = '${l}'`),t.exec("DELETE FROM provider_last_model"),t.exec("DELETE FROM provider_base_url"));const r=t.prepare("\n INSERT INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ");for(const e of n)r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);const a=t.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ");for(const[t,n]of Object.entries(e.lastProfileIdByProvider??{}))n&&a.run(t,n);e.activeProfileId&&t.prepare(`\n INSERT INTO provider_runtime_state (key, value)\n VALUES ('${N}', ?)\n `).run(e.activeProfileId),t.exec("COMMIT")}catch(e){throw t.exec("ROLLBACK"),e}}export function getStoredActiveProviderPreference(){const e=function(e){try{const t=ensureInitialized().prepare("SELECT value FROM provider_runtime_state WHERE key = ?").get(e);return t?.value??null}catch{return null}}(l);return null!==e?e:null}export function setStoredActiveProviderPreference(e){!function(e,t){try{const n=ensureInitialized();if(null===t)return void n.prepare("DELETE FROM provider_runtime_state WHERE key = ?").run(e);n.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n ").run(e,t)}catch{}}(l,e)}export function getStoredLastModelForProvider(e){try{const t=ensureInitialized().prepare("SELECT last_model FROM provider_last_model WHERE provider = ?").get(e);if(t&&Object.prototype.hasOwnProperty.call(t,"last_model"))return t.last_model??null}catch{return}}export function setStoredLastModelForProvider(e,t){!function(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}(e,t)}export function getStoredProviderBaseUrl(e){try{const t=ensureInitialized().prepare("SELECT base_url FROM provider_base_url WHERE provider = ?").get(e);if(t?.base_url?.trim())return t.base_url.trim()}catch{return}}export function setStoredProviderBaseUrl(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}export function clearStoredProviderBaseUrl(e){try{ensureInitialized().prepare("DELETE FROM provider_base_url WHERE provider = ?").run(e)}catch{}}
1
+ import{createRequire as e}from"module";import{randomUUID as t}from"node:crypto";import{join as n}from"path";import{getGlobalConfig as i,saveGlobalConfig as r}from"../config.js";import{getClaudeConfigHomeDir as a}from"../envUtils.js";import{getFsImplementation as E}from"../fsOperations.js";import{getSecureStorage as o}from"../secureStorage/index.js";function hasStoredCredentialForProvider(e,t){if(!e)return!1;if("openai"===t&&e.openAiOauth?.accessToken)return!0;if("claude"===t&&e.claudeAiOauth?.accessToken)return!0;if(Object.keys(e.providerProfileOauth??{}).some(e=>e.startsWith(`${t}/`)))return!0;if(e.providerApiKeys?.[t])return!0;return Object.keys(e.providerProfileApiKeys??{}).some(e=>e.startsWith(`${t}/`))}const d=e(import.meta.url);let _=null,s=!1,T=!1;const l="active_provider",N="active_profile_id",p=["claude","openai","openrouter","ollama","ollama-cloud","lmstudio","gemini-api","gemini-google","zai","minimax","deepseek"],L={claude:"main",openai:"main",openrouter:"main",ollama:"local","ollama-cloud":"main",lmstudio:"local","gemini-api":"main","gemini-google":"main",zai:"main",minimax:"main",nvidia:"main",deepseek:"main"},c={claude:"claude",openai:"openai",openrouter:"openrouter",ollama:"ollama-local","ollama-cloud":"ollama-cloud",lmstudio:"lmstudio-local","gemini-api":"gemini-api","gemini-google":"gemini-google",zai:"z-ai",minimax:"minimax",nvidia:"nvidia",deepseek:"deepseek"},u={openrouter:"https://openrouter.ai/api/v1",ollama:"http://localhost:11434/v1","ollama-cloud":"http://localhost:11434/v1",lmstudio:"http://localhost:1234/v1","gemini-api":"https://generativelanguage.googleapis.com/v1beta/openai","gemini-google":"https://generativelanguage.googleapis.com/v1beta/openai",zai:"https://api.z.ai/api/coding/paas/v4",minimax:"https://api.minimax.io/anthropic",deepseek:"https://api.deepseek.com/v1"},m={claude:"Claude",openai:"OpenAI",openrouter:"OpenRouter",ollama:"Ollama","ollama-cloud":"Ollama Cloud",lmstudio:"LM Studio","gemini-api":"Gemini API","gemini-google":"Gemini Google",zai:"Z.AI",minimax:"MiniMax",nvidia:"NVIDIA NIM",deepseek:"DeepSeek"},O=["openrouter","ollama","ollama-cloud","gemini-api","gemini-google","zai","minimax","deepseek"];function sanitizeProfileSegment(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"default"}function buildProfileId(e,t){return`${e}/${sanitizeProfileSegment(t)}`}function buildDefaultAgentName(e,t){const n=c[e],i=sanitizeProfileSegment(t);return i===sanitizeProfileSegment(L[e])?n:`${n}-${i}`}function tableExists(e,t){const n=e.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(t);return Boolean(n)}function columnExists(e,t,n){return e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)}function migrateTeamUnitsSchema(e){e.exec("PRAGMA foreign_keys = OFF;");try{tableExists(e,"team_domains")&&e.exec("\n INSERT OR IGNORE INTO team_units (\n id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n )\n SELECT id, team_id, domain_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at\n FROM team_domains;\n "),tableExists(e,"team_domain_members")&&e.exec("\n INSERT OR IGNORE INTO team_unit_members (\n id, team_unit_id, agent_id, duty, priority, created_at, updated_at\n )\n SELECT id, team_domain_id, agent_id, duty, priority, created_at, updated_at\n FROM team_domain_members;\n "),tableExists(e,"orchestration_tasks")&&!columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("ALTER TABLE orchestration_tasks ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n UPDATE orchestration_tasks\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS orchestration_tasks_v8 (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks_v8(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n INSERT OR REPLACE INTO orchestration_tasks_v8 (\n id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n )\n SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at\n FROM orchestration_tasks;\n\n DROP TABLE orchestration_tasks;\n ALTER TABLE orchestration_tasks_v8 RENAME TO orchestration_tasks;\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n ")}(e),tableExists(e,"orchestration_domain_reports")&&e.exec("\n INSERT OR IGNORE INTO orchestration_team_reports (\n id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n )\n SELECT id, run_id, team_domain_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at\n FROM orchestration_domain_reports;\n "),tableExists(e,"provider_agent_capability_rankings")&&!columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("ALTER TABLE provider_agent_capability_rankings ADD COLUMN team_unit_id TEXT NULL;"),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n UPDATE provider_agent_capability_rankings\n SET team_unit_id = team_domain_id\n WHERE team_unit_id IS NULL AND team_domain_id IS NOT NULL;\n "),function(e){tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_domain_id")&&e.exec("\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings_v8 (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n INSERT OR REPLACE INTO provider_agent_capability_rankings_v8 (\n id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n )\n SELECT id, team_unit_id, capability, agent_id, score, reason, source, created_at, updated_at\n FROM provider_agent_capability_rankings;\n\n DROP TABLE provider_agent_capability_rankings;\n ALTER TABLE provider_agent_capability_rankings_v8 RENAME TO provider_agent_capability_rankings;\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n ")}(e),e.exec("\n DROP TABLE IF EXISTS orchestration_domain_reports;\n DROP TABLE IF EXISTS team_domain_members;\n DROP TABLE IF EXISTS team_domains;\n ")}finally{e.exec("PRAGMA foreign_keys = ON;")}tableExists(e,"orchestration_tasks")&&columnExists(e,"orchestration_tasks","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_team_unit_id\n ON orchestration_tasks(team_unit_id);\n "),tableExists(e,"provider_agent_capability_rankings")&&columnExists(e,"provider_agent_capability_rankings","team_unit_id")&&e.exec("\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_team_unit\n ON provider_agent_capability_rankings(team_unit_id);\n ")}function getDatabasePath(){return n(a(),"provider-state.sqlite3")}function rowToProfile(e){if(!e)return null;const t=e;return{id:t.id,provider:t.provider,name:t.name,agentName:t.agent_name,baseUrl:t.base_url??void 0,lastModel:t.last_model,createdAt:t.created_at,updatedAt:t.updated_at}}function seedLegacyProfiles(){const e=i(),t=e.providerProfiles,n={...t&&"object"==typeof t&&t.profiles?t.profiles:{}},r={...t&&"object"==typeof t&&t.lastProfileIdByProvider?t.lastProfileIdByProvider:{}},a=(()=>{try{return o().read()}catch{return null}})();for(const t of p){const i=Object.values(n).some(e=>e.provider===t),E=e.providerBaseUrls?.[t],o=e.lastModelByProvider?.[t]??null;if(!(i||e.activeProvider===t||Boolean(E)||null!==o||hasStoredCredentialForProvider(a,t))||i)continue;const d=L[t],_=buildProfileId(t,d),s=(new Date).toISOString();n[_]={id:_,provider:t,name:d,agentName:buildDefaultAgentName(t,d),baseUrl:E??u[t],lastModel:o,createdAt:s,updatedAt:s},r[t]=_}return{version:1,activeProfileId:(t&&"object"==typeof t?t.activeProfileId:void 0)??(e.activeProvider&&p.includes(e.activeProvider)?r[e.activeProvider]:void 0),lastProfileIdByProvider:r,profiles:n}}function migrateFromLegacyConfig(e){const t=i(),n=seedLegacyProfiles(),r=e.prepare("\n INSERT OR REPLACE INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n "),a=e.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ON CONFLICT(provider) DO UPDATE SET profile_id = excluded.profile_id\n "),E=e.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n "),o=e.prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n "),d=e.prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ");for(const e of Object.values(n.profiles??{}))r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);for(const[e,t]of Object.entries(n.lastProfileIdByProvider??{}))t&&a.run(e,t);n.activeProfileId&&E.run(N,n.activeProfileId);const _=t.activeProvider??(n.activeProfileId?n.profiles?.[n.activeProfileId]?.provider:void 0);_&&E.run(l,_);const s={claude:t.lastClaudeModel??t.lastModelByProvider?.claude??null,openai:t.lastOpenAIModel??t.lastModelByProvider?.openai??null,openrouter:t.lastOpenRouterModel??t.lastModelByProvider?.openrouter??null,ollama:t.lastModelByProvider?.ollama??null,"ollama-cloud":t.lastModelByProvider?.["ollama-cloud"]??null,"gemini-api":t.lastModelByProvider?.["gemini-api"]??null,"gemini-google":t.lastModelByProvider?.["gemini-google"]??null,zai:t.lastModelByProvider?.zai??null,minimax:t.lastModelByProvider?.minimax??null,deepseek:t.lastModelByProvider?.deepseek??null};for(const e of p)o.run(e,s[e]??null,(new Date).toISOString());for(const e of O){const n=t.providerBaseUrls?.[e];"string"==typeof n&&n.trim()&&d.run(e,n.trim(),(new Date).toISOString())}}export function purgeLegacyProviderStateInConfig(){hasLegacyProviderStateInConfig()&&r(e=>({...e,activeProvider:void 0,lastModelByProvider:{},providerBaseUrls:void 0,lastOpenAIModel:void 0,lastClaudeModel:void 0,lastOpenRouterModel:void 0,providerProfiles:void 0}))}export function finalizeProviderProfilesMigration(){ensureInitialized(),purgeLegacyProviderStateInConfig()}function ensureInitialized(){const e=function(){if(T)throw new Error("SQLite no disponible en este runtime.");if(_)return _;let e;E().mkdirSync(a(),{mode:448});try{e=d("node:sqlite")}catch(e){throw T=!0,e}return _=new e.DatabaseSync(getDatabasePath()),_}();if(s)return e;e.exec("\n PRAGMA journal_mode = WAL;\n PRAGMA foreign_keys = ON;\n PRAGMA synchronous = NORMAL;\n\n CREATE TABLE IF NOT EXISTS provider_profiles (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n name TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n base_url TEXT NULL,\n last_model TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_profile (\n provider TEXT PRIMARY KEY,\n profile_id TEXT NOT NULL,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS provider_runtime_state (\n key TEXT PRIMARY KEY,\n value TEXT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_last_model (\n provider TEXT PRIMARY KEY,\n last_model TEXT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_base_url (\n provider TEXT PRIMARY KEY,\n base_url TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_workspaces (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL UNIQUE,\n display_name TEXT NOT NULL,\n domain_focus TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS provider_agents (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n profile_id TEXT NOT NULL,\n name TEXT NOT NULL,\n role_kind TEXT NULL,\n system_prompt TEXT NULL,\n model_override TEXT NULL,\n tool_policy TEXT NULL,\n autonomy_level TEXT NULL,\n is_orchestrator INTEGER NOT NULL DEFAULT 0,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE CASCADE,\n FOREIGN KEY (profile_id) REFERENCES provider_profiles(id) ON DELETE CASCADE,\n UNIQUE (workspace_id, name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agents_workspace_id\n ON provider_agents(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_provider_agents_profile_id\n ON provider_agents(profile_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capabilities (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n capability TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (agent_id, capability)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capabilities_agent_id\n ON provider_agent_capabilities(agent_id);\n\n CREATE TABLE IF NOT EXISTS teams (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT NULL,\n global_orchestrator_agent_id TEXT NULL,\n is_enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE TABLE IF NOT EXISTS team_units (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n unit_name TEXT NOT NULL,\n workspace_id TEXT NULL,\n local_orchestrator_agent_id TEXT NULL,\n lead_agent_id TEXT NULL,\n selection_mode TEXT NOT NULL DEFAULT 'manual',\n required INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (workspace_id) REFERENCES provider_workspaces(id) ON DELETE SET NULL,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (lead_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (team_id, unit_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_units_team_id\n ON team_units(team_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_workspace_id\n ON team_units(workspace_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_local_orchestrator_agent_id\n ON team_units(local_orchestrator_agent_id);\n CREATE INDEX IF NOT EXISTS idx_team_units_lead_agent_id\n ON team_units(lead_agent_id);\n\n CREATE TABLE IF NOT EXISTS team_unit_members (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n duty TEXT NULL,\n priority INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_team_unit_id\n ON team_unit_members(team_unit_id);\n CREATE INDEX IF NOT EXISTS idx_team_unit_members_agent_id\n ON team_unit_members(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_runs (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL,\n goal TEXT NOT NULL,\n global_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n created_at TEXT NOT NULL,\n started_at TEXT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,\n FOREIGN KEY (global_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_team_id\n ON orchestration_runs(team_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_runs_status\n ON orchestration_runs(status);\n\n CREATE TABLE IF NOT EXISTS orchestration_tasks (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n parent_task_id TEXT NULL,\n scope_type TEXT NOT NULL,\n team_unit_id TEXT NULL,\n assigned_agent_id TEXT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL,\n status TEXT NOT NULL,\n result_summary TEXT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (parent_task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE SET NULL,\n FOREIGN KEY (assigned_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_run_id\n ON orchestration_tasks(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_tasks_assigned_agent_id\n ON orchestration_tasks(assigned_agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_messages (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NULL,\n from_agent_id TEXT NULL,\n to_agent_id TEXT NULL,\n message_type TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE SET NULL,\n FOREIGN KEY (from_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n FOREIGN KEY (to_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_run_id\n ON orchestration_messages(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_messages_task_id\n ON orchestration_messages(task_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_task_results (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n agent_id TEXT NULL,\n result_type TEXT NOT NULL,\n status TEXT NOT NULL,\n summary TEXT NULL,\n content TEXT NULL,\n metadata_json TEXT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (task_id) REFERENCES orchestration_tasks(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_run_id\n ON orchestration_task_results(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_task_id\n ON orchestration_task_results(task_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_task_results_agent_id\n ON orchestration_task_results(agent_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_team_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n team_unit_id TEXT NOT NULL,\n local_orchestrator_agent_id TEXT NULL,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n blockers TEXT NULL,\n output TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (local_orchestrator_agent_id) REFERENCES provider_agents(id) ON DELETE SET NULL,\n UNIQUE (run_id, team_unit_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_run_id\n ON orchestration_team_reports(run_id);\n CREATE INDEX IF NOT EXISTS idx_orchestration_team_reports_team_unit_id\n ON orchestration_team_reports(team_unit_id);\n\n CREATE TABLE IF NOT EXISTS orchestration_run_reports (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL,\n summary TEXT NOT NULL,\n output TEXT NULL,\n risks TEXT NULL,\n next_steps TEXT NULL,\n metrics_json TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n submitted_at TEXT NULL,\n FOREIGN KEY (run_id) REFERENCES orchestration_runs(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_orchestration_run_reports_run_id\n ON orchestration_run_reports(run_id);\n\n CREATE TABLE IF NOT EXISTS provider_agent_capability_rankings (\n id TEXT PRIMARY KEY,\n team_unit_id TEXT NULL,\n capability TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n score REAL NOT NULL DEFAULT 0,\n reason TEXT NULL,\n source TEXT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (team_unit_id) REFERENCES team_units(id) ON DELETE CASCADE,\n FOREIGN KEY (agent_id) REFERENCES provider_agents(id) ON DELETE CASCADE,\n UNIQUE (team_unit_id, capability, agent_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_capability\n ON provider_agent_capability_rankings(capability);\n CREATE INDEX IF NOT EXISTS idx_provider_agent_capability_rankings_agent\n ON provider_agent_capability_rankings(agent_id);\n\n CREATE TABLE IF NOT EXISTS secure_storage (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS projects (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS permission_rules (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n tool_name TEXT NOT NULL,\n behavior TEXT NOT NULL,\n created_at TEXT NOT NULL,\n expires_at TEXT NULL,\n UNIQUE (scope, scope_path, tool_name)\n );\n\n CREATE INDEX IF NOT EXISTS idx_permission_rules_scope\n ON permission_rules(scope, scope_path);\n CREATE INDEX IF NOT EXISTS idx_permission_rules_tool_name\n ON permission_rules(tool_name);\n\n CREATE TABLE IF NOT EXISTS permission_mode_config (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n scope_path TEXT NULL,\n mode TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE (scope, scope_path)\n );\n\n CREATE TABLE IF NOT EXISTS trusted_directories (\n path TEXT PRIMARY KEY,\n trust_level TEXT NOT NULL DEFAULT 'full',\n created_at TEXT NOT NULL\n );\n "),migrateTeamUnitsSchema(e);const n=e.prepare("PRAGMA user_version").get();(n?.user_version??0)<8&&e.exec("PRAGMA user_version = 8"),function(e){const n=(new Date).toISOString(),i=e.prepare("\n INSERT OR IGNORE INTO provider_workspaces (\n id, provider, display_name, domain_focus, is_enabled, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ");for(const e of p)i.run(t(),e,m[e],null,1,n,n)}(e);const i=e.prepare("SELECT COUNT(*) AS count FROM provider_profiles").get();if(0===(i?.count??0))migrateFromLegacyConfig(e);else{const t=e.prepare("SELECT COUNT(*) AS count FROM provider_last_model").get();0===(t?.count??0)&&migrateFromLegacyConfig(e);const n=e.prepare("SELECT COUNT(*) AS count FROM provider_base_url").get();0===(n?.count??0)&&migrateFromLegacyConfig(e)}return purgeLegacyProviderStateInConfig(),s=!0,e}export class ProviderProfilesDb{static instance=null;db;constructor(){this.db=ensureInitialized()}static async get(){return ProviderProfilesDb.instance||(ProviderProfilesDb.instance=new ProviderProfilesDb),ProviderProfilesDb.instance}}export function getProviderProfilesDbPath(){return getDatabasePath()}export function getProviderProfilesStorageBackend(){try{return ensureInitialized(),"sqlite"}catch{return"legacy"}}export function hasLegacyProviderStateInConfig(){try{const e=i();return Boolean(e.activeProvider||e.lastClaudeModel||e.lastOpenAIModel||e.lastOpenRouterModel||Object.keys(e.lastModelByProvider??{}).length>0||Object.keys(e.providerBaseUrls??{}).length>0||e.providerProfiles?.activeProfileId||Object.keys(e.providerProfiles?.profiles??{}).length>0||Object.keys(e.providerProfiles?.lastProfileIdByProvider??{}).length>0)}catch{return!1}}export function getProviderProfilesStorageMode(){return"sqlite"!==getProviderProfilesStorageBackend()?"legacy":hasLegacyProviderStateInConfig()?"sqlite-migration-pending":"sqlite-only"}export function readProviderProfilesState(){let e;try{e=ensureInitialized()}catch{return seedLegacyProfiles()}const t=e.prepare("SELECT id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n FROM provider_profiles\n ORDER BY provider, created_at, id").all().map(rowToProfile).filter(e=>null!==e),n=e.prepare("SELECT provider, profile_id FROM provider_last_profile").all(),i=e.prepare(`SELECT value FROM provider_runtime_state WHERE key = '${N}'`).get();return{version:1,activeProfileId:i?.value,lastProfileIdByProvider:Object.fromEntries(n.map(e=>[e.provider,e.profile_id])),profiles:Object.fromEntries(t.map(e=>[e.id,e]))}}export function writeProviderProfilesState(e){let t;try{t=ensureInitialized()}catch{return}const n=Object.values(e.profiles??{}),i=0===n.length;t.exec("BEGIN");try{t.exec("DELETE FROM provider_last_profile"),t.exec(`DELETE FROM provider_runtime_state WHERE key = '${N}'`),t.exec("DELETE FROM provider_profiles"),i&&(t.exec(`DELETE FROM provider_runtime_state WHERE key = '${l}'`),t.exec("DELETE FROM provider_last_model"),t.exec("DELETE FROM provider_base_url"));const r=t.prepare("\n INSERT INTO provider_profiles (\n id, provider, name, agent_name, base_url, last_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ");for(const e of n)r.run(e.id,e.provider,e.name,e.agentName,e.baseUrl??null,e.lastModel??null,e.createdAt,e.updatedAt);const a=t.prepare("\n INSERT INTO provider_last_profile (provider, profile_id)\n VALUES (?, ?)\n ");for(const[t,n]of Object.entries(e.lastProfileIdByProvider??{}))n&&a.run(t,n);e.activeProfileId&&t.prepare(`\n INSERT INTO provider_runtime_state (key, value)\n VALUES ('${N}', ?)\n `).run(e.activeProfileId),t.exec("COMMIT")}catch(e){throw t.exec("ROLLBACK"),e}}export function getStoredActiveProviderPreference(){const e=function(e){try{const t=ensureInitialized().prepare("SELECT value FROM provider_runtime_state WHERE key = ?").get(e);return t?.value??null}catch{return null}}(l);return null!==e?e:null}export function setStoredActiveProviderPreference(e){!function(e,t){try{const n=ensureInitialized();if(null===t)return void n.prepare("DELETE FROM provider_runtime_state WHERE key = ?").run(e);n.prepare("\n INSERT INTO provider_runtime_state (key, value)\n VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n ").run(e,t)}catch{}}(l,e)}export function getStoredLastModelForProvider(e){try{const t=ensureInitialized().prepare("SELECT last_model FROM provider_last_model WHERE provider = ?").get(e);if(t&&Object.prototype.hasOwnProperty.call(t,"last_model"))return t.last_model??null}catch{return}}export function setStoredLastModelForProvider(e,t){!function(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_last_model (provider, last_model, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n last_model = excluded.last_model,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}(e,t)}export function getStoredProviderBaseUrl(e){try{const t=ensureInitialized().prepare("SELECT base_url FROM provider_base_url WHERE provider = ?").get(e);if(t?.base_url?.trim())return t.base_url.trim()}catch{return}}export function setStoredProviderBaseUrl(e,t){try{ensureInitialized().prepare("\n INSERT INTO provider_base_url (provider, base_url, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(provider) DO UPDATE SET\n base_url = excluded.base_url,\n updated_at = excluded.updated_at\n ").run(e,t,(new Date).toISOString())}catch{}}export function clearStoredProviderBaseUrl(e){try{ensureInitialized().prepare("DELETE FROM provider_base_url WHERE provider = ?").run(e)}catch{}}
@@ -1 +1 @@
1
- import{jsxs as e}from"react/jsx-runtime";import o from"chalk";import r from"figures";import{color as s,Text as a}from"../ink.js";import{getAccountInformation as n,hasStoredProviderApiKey as l,hasStoredProviderOAuthTokens as t,isClaudeAISubscriber as i}from"./auth.js";import{getLargeMemoryFiles as u,getMemoryFiles as c,MAX_MEMORY_CHARACTER_COUNT as p}from"./claudemd.js";import{getDoctorDiagnostic as d}from"./doctorDiagnostic.js";import{getAWSRegion as m,getDefaultVertexRegion as v,isEnvTruthy as f}from"./envUtils.js";import{getDisplayPath as h}from"./file.js";import{formatNumber as b}from"./format.js";import{getIdeClientName as E,isJetBrainsIde as _,toIDEDisplayName as A}from"./ide.js";import{getClaudeAiUserDefaultModelDescription as C,modelDisplayString as g}from"./model/model.js";import{checkProviderHealth as D}from"./model/providerModels.js";import{getAPIProvider as S,isOllamaCloudProviderConfigured as O,isMiniMaxProviderConfigured as R,isOllamaProviderConfigured as I,isOpenRouterProviderConfigured as L,isZAIProviderConfigured as P}from"./model/providers.js";import{getConfiguredProviderBaseUrl as T}from"./model/providerBaseUrls.js";import{getActiveProviderProfile as U}from"./model/providerProfiles.js";import{getProviderProfilesDbPath as y,getProviderProfilesStorageBackend as j,getProviderProfilesStorageMode as x,getStoredActiveProviderPreference as $}from"./model/providerProfilesDb.js";import{getMTLSConfig as N}from"./mtls.js";import{checkInstall as M}from"./nativeInstaller/index.js";import{getProxyUrl as B}from"./proxy.js";import{SandboxManager as k}from"./sandbox/sandbox-adapter.js";import{getSecureStorage as K}from"./secureStorage/index.js";import{getLegacyCredentialsFilePath as H,getSecureStorageDbPath as z,getSecureStorageKeyPath as X,hasLegacyCredentialsFile as w,isSecureStorageEncrypted as F}from"./secureStorage/sqliteStorage.js";import{getSettingsWithAllErrors as V}from"./settings/allErrors.js";import{getEnabledSettingSources as q,getSettingSourceDisplayNameCapitalized as Y}from"./settings/constants.js";import{getManagedFileSettingsPresence as G,getPolicySettingsOrigin as Q,getSettingsForSource as W}from"./settings/settings.js";export function buildSandboxProperties(){return[{label:"Bash Sandbox",value:k.isSandboxingEnabled()?"Enabled":"Disabled"}]}export function buildIDEProperties(o,n=null,l){const t=o?.find(e=>"ide"===e.name);if(n){const o=A(n.ideType),i=_(n.ideType)?"plugin":"extensión";if(n.error)return[{label:"IDE",value:e(a,{children:[s("error",l)(r.cross)," Error al instalar ",o," ",i,": ",n.error,"\n","Por favor, reinicie su IDE e inténtelo de nuevo."]})}];if(n.installed)return t&&"connected"===t.type?n.installedVersion!==t.serverInfo?.version?[{label:"IDE",value:`Conectado a ${o} (${i}) versión ${n.installedVersion} (versión servidor: ${t.serverInfo?.version})`}]:[{label:"IDE",value:`Conectado a ${o} (${i}) versión ${n.installedVersion}`}]:[{label:"IDE",value:`Instalado ${o} (${i})`}]}else if(t){const e=E(t)??"IDE";return"connected"===t.type?[{label:"IDE",value:`Conectado a la extensión ${e}`}]:[{label:"IDE",value:`${s("error",l)(r.cross)} No conectado a ${e}`}]}return[]}export function buildMcpProperties(e=[],o){const r=e.filter(e=>"ide"!==e.name);if(!r.length)return[];const a={connected:0,pending:0,needsAuth:0,failed:0};for(const e of r)"connected"===e.type?a.connected++:"pending"===e.type?a.pending++:"needs-auth"===e.type?a.needsAuth++:a.failed++;const n=[];return a.connected&&n.push(s("success",o)(`${a.connected} conectados`)),a.needsAuth&&n.push(s("warning",o)(`${a.needsAuth} requieren autenticación`)),a.pending&&n.push(s("inactive",o)(`${a.pending} pendientes`)),a.failed&&n.push(s("error",o)(`${a.failed} fallidos`)),[{label:"Servidores MCP",value:`${n.join(", ")} ${s("inactive",o)("· /mcp")}`}]}export async function buildMemoryDiagnostics(){const e=await c(),o=u(e),r=[];return o.forEach(e=>{const o=h(e.path);r.push(`${o} pesado impactará el rendimiento (${b(e.content.length)} caracteres > ${b(p)})`)}),r}export function buildSettingSourcesProperties(){return[{label:"Fuentes de ajustes",value:q().filter(e=>{const o=W(e);return null!==o&&Object.keys(o).length>0}).map(e=>{if("policySettings"===e){const e=Q();if(null===e)return null;switch(e){case"remote":return"Ajustes corporativos (remoto)";case"plist":return"Ajustes corporativos (plist)";case"hklm":return"Ajustes corporativos (HKLM)";case"file":{const{hasBase:e,hasDropIns:o}=G();return e&&o?"Ajustes corporativos (archivo + complementos)":o?"Ajustes corporativos (complementos)":"Ajustes corporativos (archivo)"}case"hkcu":return"Ajustes corporativos (HKCU)"}}return Y(e)}).filter(e=>null!==e)}]}export async function buildInstallationDiagnostics(){return(await M()).map(e=>e.message)}export async function buildInstallationHealthDiagnostics(){const e=await d(),o=[],{errors:r}=V();if(r.length>0){const e=Array.from(new Set(r.map(e=>e.file))).join(", ");o.push(`Se encontraron archivos de ajustes inválidos: ${e}. Serán ignorados.`)}e.warnings.forEach(e=>{o.push(e.issue)});const s=await async function(){const e=function(){const e=new Set,o=$();L()&&e.add("openrouter");I()&&e.add("ollama");O()&&e.add("ollama-cloud");P()&&e.add("zai");R()&&e.add("minimax");const r=S();"openrouter"!==r&&"openrouter"!==o||e.add("openrouter");"ollama"!==r&&"ollama"!==o||e.add("ollama");"ollama-cloud"!==r&&"ollama-cloud"!==o||e.add("ollama-cloud");"zai"!==r&&"zai"!==o||e.add("zai");"minimax"!==r&&"minimax"!==o||e.add("minimax");return Array.from(e)}();if(0===e.length)return[];return(await Promise.all(e.map(e=>D(e)))).map(formatProviderHealthDiagnostic)}();return o.push(...s),!1===e.hasUpdatePermissions&&o.push("Sin permisos de escritura para auto-actualizaciones (requiere sudo)"),o}function formatProviderHealthDiagnostic(e){switch(e.state){case"healthy":return`${e.label}: OK (${e.message})`;case"needs-setup":case"rate-limited":case"unreachable":return`${e.label}: ${e.message}`}}export function buildAccountProperties(){const e=n();if(!e)return[];const o=[];return e.subscription&&o.push({label:"Cuenta",value:`${e.subscription}`}),e.tokenSource&&o.push({label:"Token",value:e.tokenSource}),e.apiKeySource&&o.push({label:"API Key",value:e.apiKeySource}),e.organization&&!process.env.IS_DEMO&&o.push({label:"Organización",value:e.organization}),e.email&&!process.env.IS_DEMO&&o.push({label:"Correo",value:e.email}),o}export function buildAPIProviderProperties(){const e=S(),o=[],r=j(),s=x();if(o.push({label:"Persistencia providers",value:"sqlite"===r?"sqlite-only"===s?"SQLite-only":"SQLite (migracion pendiente)":"Legacy fallback"}),o.push({label:"Provider DB",value:y()}),o.push({label:"Credenciales providers",value:"sqlite"===K().name?"SQLite (cifrado local)":K().name}),"sqlite"===K().name&&(K().read(),o.push({label:"Credenciales DB",value:z()}),o.push({label:"Clave cifrado",value:X()}),o.push({label:"Estado cifrado credenciales",value:F()?"Cifrado activo":"Sin payload o pendiente"}),o.push({label:"Legacy credentials file",value:w()?`Presente (${H()})`:"No presente"})),"firstParty"!==e){const r={bedrock:"AWS Bedrock",vertex:"Google Vertex AI",foundry:"Microsoft Foundry",openai:"OpenAI / Codex",openrouter:"OpenRouter",ollama:"Ollama","ollama-cloud":"Ollama Cloud",zai:"Z.AI",minimax:"MiniMax"}[e]||e;o.push({label:"Proveedor API",value:r})}if("firstParty"===e){const e=process.env.ANTHROPIC_BASE_URL;e&&o.push({label:"Anthropic base URL",value:e})}else if("bedrock"===e){const e=process.env.BEDROCK_BASE_URL;e&&o.push({label:"Bedrock base URL",value:e}),o.push({label:"AWS region",value:m()}),(f(process.env.CONTEXT_CODE_SKIP_BEDROCK_AUTH)||f(process.env.CLAUDE_CODE_SKIP_BEDROCK_AUTH))&&o.push({value:"AWS auth skipped"})}else if("vertex"===e){const e=process.env.VERTEX_BASE_URL;e&&o.push({label:"Vertex base URL",value:e});const r=process.env.ANTHROPIC_VERTEX_PROJECT_ID;r&&o.push({label:"GCP project",value:r}),o.push({label:"Default region",value:v()}),(f(process.env.CONTEXT_CODE_SKIP_VERTEX_AUTH)||f(process.env.CLAUDE_CODE_SKIP_VERTEX_AUTH))&&o.push({value:"GCP auth skipped"})}else if("foundry"===e){const e=process.env.ANTHROPIC_FOUNDRY_BASE_URL;e&&o.push({label:"Microsoft Foundry base URL",value:e});const r=process.env.ANTHROPIC_FOUNDRY_RESOURCE;r&&o.push({label:"Microsoft Foundry resource",value:r}),(f(process.env.CONTEXT_CODE_SKIP_FOUNDRY_AUTH)||f(process.env.CLAUDE_CODE_SKIP_FOUNDRY_AUTH))&&o.push({value:"Microsoft Foundry auth skipped"})}else if("openai"===e){const e=process.env.OPENAI_BASE_URL;e&&o.push({label:"OpenAI base URL",value:e})}else if("openrouter"===e){const e=process.env.OPENROUTER_BASE_URL||T("openrouter");o.push({label:"OpenRouter base URL",value:e})}else if("ollama"===e){const e=process.env.OLLAMA_BASE_URL||T("ollama");o.push({label:"Ollama base URL",value:e})}else if("ollama-cloud"===e){const e=process.env.OLLAMA_BASE_URL||T("ollama-cloud");o.push({label:"Ollama Cloud base URL",value:e})}else if("zai"===e){const e=process.env.ZAI_BASE_URL||T("zai");o.push({label:"Z.AI base URL",value:e})}else if("minimax"===e){const e=process.env.MINIMAX_BASE_URL||T("minimax");o.push({label:"MiniMax base URL",value:e})}const a=U();if(a&&(a.provider===e||"firstParty"===e&&"claude"===a.provider)&&a){o.push({label:"Perfil activo",value:`${a.name} (${a.agentName})`}),o.push({label:"Modelo guardado",value:a.lastModel||"Sin modelo guardado"});let e="No aplica";"openai"===a.provider?e=t(a.provider,a.id)?"Configuradas":"No configuradas":"openrouter"!==a.provider&&"zai"!==a.provider&&"minimax"!==a.provider||(e=l(a.provider,a.id)?"Configuradas":"No configuradas"),o.push({label:"Credenciales por perfil",value:e})}const n=B();n&&o.push({label:"Proxy",value:n});const i=N();if(process.env.NODE_EXTRA_CA_CERTS&&o.push({label:"Additional CA cert(s)",value:process.env.NODE_EXTRA_CA_CERTS}),i){const e=process.env.CONTEXT_CODE_CLIENT_CERT??process.env.CLAUDE_CODE_CLIENT_CERT;i.cert&&e&&o.push({label:"mTLS client cert",value:e});const r=process.env.CONTEXT_CODE_CLIENT_KEY??process.env.CLAUDE_CODE_CLIENT_KEY;i.key&&r&&o.push({label:"mTLS client key",value:r})}return o}export function getModelDisplayLabel(e){let r=g(e);if(null===e&&i()){const e=C();r=`${o.bold("Default")} ${e}`}return r}
1
+ import{jsxs as e}from"react/jsx-runtime";import o from"chalk";import r from"figures";import{color as s,Text as a}from"../ink.js";import{getAccountInformation as n,hasStoredProviderApiKey as l,hasStoredProviderOAuthTokens as t,isClaudeAISubscriber as i}from"./auth.js";import{getLargeMemoryFiles as u,getMemoryFiles as c,MAX_MEMORY_CHARACTER_COUNT as p}from"./claudemd.js";import{getDoctorDiagnostic as d}from"./doctorDiagnostic.js";import{getAWSRegion as m,getDefaultVertexRegion as v,isEnvTruthy as f}from"./envUtils.js";import{getDisplayPath as b}from"./file.js";import{formatNumber as h}from"./format.js";import{getIdeClientName as E,isJetBrainsIde as _,toIDEDisplayName as A}from"./ide.js";import{getClaudeAiUserDefaultModelDescription as C,modelDisplayString as S}from"./model/model.js";import{checkProviderHealth as D}from"./model/providerModels.js";import{getAPIProvider as g,isOllamaCloudProviderConfigured as R,isMiniMaxProviderConfigured as O,isOllamaProviderConfigured as L,isOpenRouterProviderConfigured as I,isZAIProviderConfigured as U}from"./model/providers.js";import{getConfiguredProviderBaseUrl as T}from"./model/providerBaseUrls.js";import{getActiveProviderProfile as P}from"./model/providerProfiles.js";import{getProviderProfilesDbPath as y,getProviderProfilesStorageBackend as j,getProviderProfilesStorageMode as x,getStoredActiveProviderPreference as $}from"./model/providerProfilesDb.js";import{getMTLSConfig as N}from"./mtls.js";import{checkInstall as M}from"./nativeInstaller/index.js";import{getProxyUrl as B}from"./proxy.js";import{SandboxManager as k}from"./sandbox/sandbox-adapter.js";import{getSecureStorage as K}from"./secureStorage/index.js";import{getLegacyCredentialsFilePath as H,getSecureStorageDbPath as z,getSecureStorageKeyPath as X,hasLegacyCredentialsFile as w,isSecureStorageEncrypted as F}from"./secureStorage/sqliteStorage.js";import{getSettingsWithAllErrors as V}from"./settings/allErrors.js";import{getEnabledSettingSources as q,getSettingSourceDisplayNameCapitalized as Y}from"./settings/constants.js";import{getManagedFileSettingsPresence as G,getPolicySettingsOrigin as Q,getSettingsForSource as W}from"./settings/settings.js";export function buildSandboxProperties(){return[{label:"Bash Sandbox",value:k.isSandboxingEnabled()?"Enabled":"Disabled"}]}export function buildIDEProperties(o,n=null,l){const t=o?.find(e=>"ide"===e.name);if(n){const o=A(n.ideType),i=_(n.ideType)?"plugin":"extensión";if(n.error)return[{label:"IDE",value:e(a,{children:[s("error",l)(r.cross)," Error al instalar ",o," ",i,": ",n.error,"\n","Por favor, reinicie su IDE e inténtelo de nuevo."]})}];if(n.installed)return t&&"connected"===t.type?n.installedVersion!==t.serverInfo?.version?[{label:"IDE",value:`Conectado a ${o} (${i}) versión ${n.installedVersion} (versión servidor: ${t.serverInfo?.version})`}]:[{label:"IDE",value:`Conectado a ${o} (${i}) versión ${n.installedVersion}`}]:[{label:"IDE",value:`Instalado ${o} (${i})`}]}else if(t){const e=E(t)??"IDE";return"connected"===t.type?[{label:"IDE",value:`Conectado a la extensión ${e}`}]:[{label:"IDE",value:`${s("error",l)(r.cross)} No conectado a ${e}`}]}return[]}export function buildMcpProperties(e=[],o){const r=e.filter(e=>"ide"!==e.name);if(!r.length)return[];const a={connected:0,pending:0,needsAuth:0,failed:0};for(const e of r)"connected"===e.type?a.connected++:"pending"===e.type?a.pending++:"needs-auth"===e.type?a.needsAuth++:a.failed++;const n=[];return a.connected&&n.push(s("success",o)(`${a.connected} conectados`)),a.needsAuth&&n.push(s("warning",o)(`${a.needsAuth} requieren autenticación`)),a.pending&&n.push(s("inactive",o)(`${a.pending} pendientes`)),a.failed&&n.push(s("error",o)(`${a.failed} fallidos`)),[{label:"Servidores MCP",value:`${n.join(", ")} ${s("inactive",o)("· /mcp")}`}]}export async function buildMemoryDiagnostics(){const e=await c(),o=u(e),r=[];return o.forEach(e=>{const o=b(e.path);r.push(`${o} pesado impactará el rendimiento (${h(e.content.length)} caracteres > ${h(p)})`)}),r}export function buildSettingSourcesProperties(){return[{label:"Fuentes de ajustes",value:q().filter(e=>{const o=W(e);return null!==o&&Object.keys(o).length>0}).map(e=>{if("policySettings"===e){const e=Q();if(null===e)return null;switch(e){case"remote":return"Ajustes corporativos (remoto)";case"plist":return"Ajustes corporativos (plist)";case"hklm":return"Ajustes corporativos (HKLM)";case"file":{const{hasBase:e,hasDropIns:o}=G();return e&&o?"Ajustes corporativos (archivo + complementos)":o?"Ajustes corporativos (complementos)":"Ajustes corporativos (archivo)"}case"hkcu":return"Ajustes corporativos (HKCU)"}}return Y(e)}).filter(e=>null!==e)}]}export async function buildInstallationDiagnostics(){return(await M()).map(e=>e.message)}export async function buildInstallationHealthDiagnostics(){const e=await d(),o=[],{errors:r}=V();if(r.length>0){const e=Array.from(new Set(r.map(e=>e.file))).join(", ");o.push(`Se encontraron archivos de ajustes inválidos: ${e}. Serán ignorados.`)}e.warnings.forEach(e=>{o.push(e.issue)});const s=await async function(){const e=function(){const e=new Set,o=$();I()&&e.add("openrouter");L()&&e.add("ollama");R()&&e.add("ollama-cloud");U()&&e.add("zai");O()&&e.add("minimax");const r=g();"openrouter"!==r&&"openrouter"!==o||e.add("openrouter");"ollama"!==r&&"ollama"!==o||e.add("ollama");"ollama-cloud"!==r&&"ollama-cloud"!==o||e.add("ollama-cloud");"zai"!==r&&"zai"!==o||e.add("zai");"minimax"!==r&&"minimax"!==o||e.add("minimax");return Array.from(e)}();if(0===e.length)return[];return(await Promise.all(e.map(e=>D(e)))).map(formatProviderHealthDiagnostic)}();return o.push(...s),!1===e.hasUpdatePermissions&&o.push("Sin permisos de escritura para auto-actualizaciones (requiere sudo)"),o}function formatProviderHealthDiagnostic(e){switch(e.state){case"healthy":return`${e.label}: OK (${e.message})`;case"needs-setup":case"rate-limited":case"unreachable":return`${e.label}: ${e.message}`}}export function buildAccountProperties(){const e=n();if(!e)return[];const o=[];return e.subscription&&o.push({label:"Cuenta",value:`${e.subscription}`}),e.tokenSource&&o.push({label:"Token",value:e.tokenSource}),e.apiKeySource&&o.push({label:"API Key",value:e.apiKeySource}),e.organization&&!process.env.IS_DEMO&&o.push({label:"Organización",value:e.organization}),e.email&&!process.env.IS_DEMO&&o.push({label:"Correo",value:e.email}),o}export function buildAPIProviderProperties(){const e=g(),o=[],r=j(),s=x();if(o.push({label:"Persistencia providers",value:"sqlite"===r?"sqlite-only"===s?"SQLite-only":"SQLite (migracion pendiente)":"Legacy fallback"}),o.push({label:"Provider DB",value:y()}),o.push({label:"Credenciales providers",value:"sqlite"===K().name?"SQLite (cifrado local)":K().name}),"sqlite"===K().name&&(K().read(),o.push({label:"Credenciales DB",value:z()}),o.push({label:"Clave cifrado",value:X()}),o.push({label:"Estado cifrado credenciales",value:F()?"Cifrado activo":"Sin payload o pendiente"}),o.push({label:"Legacy credentials file",value:w()?`Presente (${H()})`:"No presente"})),"firstParty"!==e){const r={bedrock:"AWS Bedrock",vertex:"Google Vertex AI",foundry:"Microsoft Foundry",openai:"OpenAI / Codex",openrouter:"OpenRouter",ollama:"Ollama","ollama-cloud":"Ollama Cloud",zai:"Z.AI",minimax:"MiniMax"}[e]||e;o.push({label:"Proveedor API",value:r})}if("firstParty"===e){const e=process.env.ANTHROPIC_BASE_URL;e&&o.push({label:"Anthropic base URL",value:e})}else if("bedrock"===e){const e=process.env.BEDROCK_BASE_URL;e&&o.push({label:"Bedrock base URL",value:e}),o.push({label:"AWS region",value:m()}),(f(process.env.CONTEXT_CODE_SKIP_BEDROCK_AUTH)||f(process.env.CLAUDE_CODE_SKIP_BEDROCK_AUTH))&&o.push({value:"AWS auth skipped"})}else if("vertex"===e){const e=process.env.VERTEX_BASE_URL;e&&o.push({label:"Vertex base URL",value:e});const r=process.env.ANTHROPIC_VERTEX_PROJECT_ID;r&&o.push({label:"GCP project",value:r}),o.push({label:"Default region",value:v()}),(f(process.env.CONTEXT_CODE_SKIP_VERTEX_AUTH)||f(process.env.CLAUDE_CODE_SKIP_VERTEX_AUTH))&&o.push({value:"GCP auth skipped"})}else if("foundry"===e){const e=process.env.ANTHROPIC_FOUNDRY_BASE_URL;e&&o.push({label:"Microsoft Foundry base URL",value:e});const r=process.env.ANTHROPIC_FOUNDRY_RESOURCE;r&&o.push({label:"Microsoft Foundry resource",value:r}),(f(process.env.CONTEXT_CODE_SKIP_FOUNDRY_AUTH)||f(process.env.CLAUDE_CODE_SKIP_FOUNDRY_AUTH))&&o.push({value:"Microsoft Foundry auth skipped"})}else if("openai"===e){const e=process.env.OPENAI_BASE_URL;e&&o.push({label:"OpenAI base URL",value:e})}else if("openrouter"===e){const e=process.env.OPENROUTER_BASE_URL||T("openrouter");o.push({label:"OpenRouter base URL",value:e})}else if("ollama"===e){const e=process.env.OLLAMA_BASE_URL||T("ollama");o.push({label:"Ollama base URL",value:e})}else if("ollama-cloud"===e){const e=process.env.OLLAMA_BASE_URL||T("ollama-cloud");o.push({label:"Ollama Cloud base URL",value:e})}else if("lmstudio"===e){const e=process.env.LMSTUDIO_BASE_URL||process.env.LM_STUDIO_BASE_URL||T("lmstudio");o.push({label:"LM Studio base URL",value:e})}else if("zai"===e){const e=process.env.ZAI_BASE_URL||T("zai");o.push({label:"Z.AI base URL",value:e})}else if("minimax"===e){const e=process.env.MINIMAX_BASE_URL||T("minimax");o.push({label:"MiniMax base URL",value:e})}const a=P();if(a&&(a.provider===e||"firstParty"===e&&"claude"===a.provider)&&a){o.push({label:"Perfil activo",value:`${a.name} (${a.agentName})`}),o.push({label:"Modelo guardado",value:a.lastModel||"Sin modelo guardado"});let e="No aplica";"openai"===a.provider?e=t(a.provider,a.id)?"Configuradas":"No configuradas":"openrouter"!==a.provider&&"zai"!==a.provider&&"minimax"!==a.provider||(e=l(a.provider,a.id)?"Configuradas":"No configuradas"),o.push({label:"Credenciales por perfil",value:e})}const n=B();n&&o.push({label:"Proxy",value:n});const i=N();if(process.env.NODE_EXTRA_CA_CERTS&&o.push({label:"Additional CA cert(s)",value:process.env.NODE_EXTRA_CA_CERTS}),i){const e=process.env.CONTEXT_CODE_CLIENT_CERT??process.env.CLAUDE_CODE_CLIENT_CERT;i.cert&&e&&o.push({label:"mTLS client cert",value:e});const r=process.env.CONTEXT_CODE_CLIENT_KEY??process.env.CLAUDE_CODE_CLIENT_KEY;i.key&&r&&o.push({label:"mTLS client key",value:r})}return o}export function getModelDisplayLabel(e){let r=S(e);if(null===e&&i()){const e=C();r=`${o.bold("Default")} ${e}`}return r}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "configVersion": 1,
3
- "timestamp": 1781073650057,
3
+ "timestamp": 1781124616766,
4
4
  "index": "./index.html",
5
5
  "assetGroups": [
6
6
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iaforged/context-code",
3
- "version": "2.3.5",
3
+ "version": "2.3.7",
4
4
  "description": "Context Code es un asistente de desarrollo para la terminal. Puede revisar tu proyecto, editar archivos, ejecutar comandos y apoyarte en tareas reales de programacion.",
5
5
  "author": "Context AI",
6
6
  "license": "MIT",