* Build auth env vars for a coding agent based on its type and config. * @param {string} agent - 'claude-code', 'pi-coding-agent', 'gemini-cli', 'codex-cli', 'opencode' * @returns {{ env: string[], backendApi: string }} Environment variable strings and resolved backend
(agent)
| 308 | * @returns {{ env: string[], backendApi: string }} Environment variable strings and resolved backend |
| 309 | */ |
| 310 | function buildAgentAuthEnv(agent) { |
| 311 | const env = []; |
| 312 | let backendApi = 'anthropic'; |
| 313 | |
| 314 | if (agent === 'claude-code') { |
| 315 | backendApi = getConfig('CODING_AGENT_CLAUDE_CODE_BACKEND') || 'anthropic'; |
| 316 | |
| 317 | if (backendApi === 'anthropic') { |
| 318 | // Native Anthropic auth — OAuth or API Key |
| 319 | const authMode = getConfig('CODING_AGENT_CLAUDE_CODE_AUTH') || 'oauth'; |
| 320 | if (authMode === 'oauth') { |
| 321 | const token = getConfig('CLAUDE_CODE_OAUTH_TOKEN'); |
| 322 | if (token) env.push(`CLAUDE_CODE_OAUTH_TOKEN=${token}`); |
| 323 | } else { |
| 324 | const key = getConfig('ANTHROPIC_API_KEY'); |
| 325 | if (key) env.push(`ANTHROPIC_API_KEY=${key}`); |
| 326 | } |
| 327 | const model = getConfig('CODING_AGENT_CLAUDE_CODE_MODEL'); |
| 328 | if (model) env.push(`LLM_MODEL=${model}`); |
| 329 | } else { |
| 330 | const provider = BUILTIN_PROVIDERS[backendApi]; |
| 331 | if (provider?.anthropicEndpoint) { |
| 332 | // Native Anthropic-compatible endpoint (DeepSeek, MiniMax, Kimi, OpenRouter) |
| 333 | const apiKey = getConfig(provider.credentials[0].key); |
| 334 | if (apiKey) env.push(`ANTHROPIC_AUTH_TOKEN=${apiKey}`); |
| 335 | env.push(`ANTHROPIC_BASE_URL=${provider.anthropicEndpoint}`); |
| 336 | const model = getConfig('CODING_AGENT_CLAUDE_CODE_MODEL'); |
| 337 | if (model) env.push(`ANTHROPIC_MODEL=${model}`); |
| 338 | } else if (provider?.litellmProxy) { |
| 339 | // Builtin OpenAI-only provider → route through LiteLLM sidecar |
| 340 | const apiKey = getConfig(provider.credentials[0].key); |
| 341 | if (apiKey) env.push(`ANTHROPIC_AUTH_TOKEN=${apiKey}`); |
| 342 | env.push(`ANTHROPIC_BASE_URL=http://litellm:4000`); |
| 343 | const model = getConfig('CODING_AGENT_CLAUDE_CODE_MODEL'); |
| 344 | if (model) env.push(`ANTHROPIC_MODEL=${provider.litellmPrefix}/${model}`); |
| 345 | } else if (!provider) { |
| 346 | // Custom provider → also route through LiteLLM |
| 347 | const custom = getCustomProvider(backendApi); |
| 348 | if (custom) { |
| 349 | env.push(`ANTHROPIC_AUTH_TOKEN=${custom.apiKey || 'not-needed'}`); |
| 350 | env.push(`ANTHROPIC_BASE_URL=http://litellm:4000`); |
| 351 | const model = getConfig('CODING_AGENT_CLAUDE_CODE_MODEL'); |
| 352 | if (model) env.push(`ANTHROPIC_MODEL=${backendApi}/${model}`); |
| 353 | } |
| 354 | } |
| 355 | } |
| 356 | } else if (agent === 'pi-coding-agent' || agent === 'opencode' || agent === 'kimi-cli') { |
| 357 | // Pi, OpenCode, and Kimi share the same multi-provider auth pattern |
| 358 | const configPrefix = agent === 'opencode' ? 'CODING_AGENT_OPENCODE' : agent === 'kimi-cli' ? 'CODING_AGENT_KIMI_CLI' : 'CODING_AGENT_PI'; |
| 359 | const provider = getConfig(`${configPrefix}_PROVIDER`) || 'anthropic'; |
| 360 | backendApi = provider; |
| 361 | const model = getConfig(`${configPrefix}_MODEL`); |
| 362 | if (model) env.push(`LLM_MODEL=${model}`); |
| 363 | |
| 364 | const builtinKeyMap = { anthropic: 'ANTHROPIC_API_KEY', openai: 'OPENAI_API_KEY', google: 'GOOGLE_API_KEY', deepseek: 'DEEPSEEK_API_KEY', minimax: 'MINIMAX_API_KEY', mistral: 'MISTRAL_API_KEY', xai: 'XAI_API_KEY', openrouter: 'OPENROUTER_API_KEY', nvidia: 'NVIDIA_API_KEY' }; |
| 365 | if (builtinKeyMap[provider]) { |
| 366 | const key = getConfig(builtinKeyMap[provider]); |
| 367 | if (key) env.push(`${builtinKeyMap[provider]}=${key}`); |
no test coverage detected