diff --git a/apps/frontend/src/main/agent/agent-queue.ts b/apps/frontend/src/main/agent/agent-queue.ts index 7ee53f84..93f716aa 100644 --- a/apps/frontend/src/main/agent/agent-queue.ts +++ b/apps/frontend/src/main/agent/agent-queue.ts @@ -7,7 +7,6 @@ import { AgentEvents } from './agent-events'; import { AgentProcessManager } from './agent-process'; import { RoadmapConfig } from './types'; import type { IdeationConfig, Idea } from '../../shared/types'; -import { MODEL_ID_MAP } from '../../shared/constants'; import { detectRateLimit, createSDKRateLimitInfo, getProfileEnv } from '../rate-limit-detector'; import { getAPIProfileEnv } from '../services/profile'; import { getOAuthModeClearVars } from './env-utils'; @@ -96,9 +95,9 @@ export class AgentQueueManager { } // Add model and thinking level from config + // Pass shorthand (opus/sonnet/haiku) - backend resolves using API profile env vars if (config?.model) { - const modelId = MODEL_ID_MAP[config.model] || MODEL_ID_MAP['opus']; - args.push('--model', modelId); + args.push('--model', config.model); } if (config?.thinkingLevel) { args.push('--thinking-level', config.thinkingLevel); @@ -172,9 +171,9 @@ export class AgentQueueManager { } // Add model and thinking level from config + // Pass shorthand (opus/sonnet/haiku) - backend resolves using API profile env vars if (config.model) { - const modelId = MODEL_ID_MAP[config.model] || MODEL_ID_MAP['opus']; - args.push('--model', modelId); + args.push('--model', config.model); } if (config.thinkingLevel) { args.push('--thinking-level', config.thinkingLevel); diff --git a/apps/frontend/src/renderer/components/EnvConfigModal.tsx b/apps/frontend/src/renderer/components/EnvConfigModal.tsx index f7c95bff..f35138b8 100644 --- a/apps/frontend/src/renderer/components/EnvConfigModal.tsx +++ b/apps/frontend/src/renderer/components/EnvConfigModal.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { AlertCircle, Key, @@ -13,6 +13,7 @@ import { ChevronDown, ChevronRight } from 'lucide-react'; +import { useSettingsStore } from '../stores/settings-store'; import { Dialog, DialogContent, @@ -592,35 +593,51 @@ export function EnvConfigModal({ /** * Hook to check if the Claude token is configured * Returns { hasToken, isLoading, checkToken } + * + * This combines two sources of authentication: + * 1. OAuth token from source .env (checked via checkSourceToken) + * 2. Active API profile (custom Anthropic-compatible endpoint) */ export function useClaudeTokenCheck() { const [hasToken, setHasToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); - const checkToken = async () => { + // Get active API profile from settings store + const activeProfileId = useSettingsStore((state) => state.activeProfileId); + + const checkToken = useCallback(async () => { setIsLoading(true); setError(null); + // Compute once - activeProfileId is captured from closure + const hasAPIProfile = !!activeProfileId; + try { const result = await window.electronAPI.checkSourceToken(); - if (result.success && result.data) { - setHasToken(result.data.hasToken); - } else { - setHasToken(false); + const hasSourceOAuthToken = result.success && result.data?.hasToken; + + // Auth is valid if either OAuth token OR API profile exists + setHasToken(hasSourceOAuthToken || hasAPIProfile); + + // Set error if OAuth check failed and no API profile fallback + if (!result.success && !hasAPIProfile) { setError(result.error || 'Failed to check token'); } } catch (err) { - setHasToken(false); - setError(err instanceof Error ? err.message : 'Unknown error'); + // Even if OAuth check fails, API profile is still valid auth + setHasToken(hasAPIProfile); + if (!hasAPIProfile) { + setError(err instanceof Error ? err.message : 'Unknown error'); + } } finally { setIsLoading(false); } - }; + }, [activeProfileId]); useEffect(() => { checkToken(); - }, []); + }, [checkToken]); // Re-check when checkToken changes (i.e., when activeProfileId changes) return { hasToken, isLoading, error, checkToken }; }