diff --git a/apps/open-swe/src/utils/llms/model-manager.ts b/apps/open-swe/src/utils/llms/model-manager.ts index b8503d8fb..64d966ab9 100644 --- a/apps/open-swe/src/utils/llms/model-manager.ts +++ b/apps/open-swe/src/utils/llms/model-manager.ts @@ -23,6 +23,13 @@ export interface CircuitBreakerState { openedAt?: number; } +export interface ApiKeyRotationState { + keys: string[]; + currentIndex: number; + lastUsedTime: number; + cooldownUntil: number; +} + interface ModelLoadConfig { provider: Provider; modelName: string; @@ -47,6 +54,7 @@ export const PROVIDER_FALLBACK_ORDER = [ "openai", "anthropic", "google-genai", + "openrouter", ] as const; export type Provider = (typeof PROVIDER_FALLBACK_ORDER)[number]; @@ -82,6 +90,8 @@ const providerToApiKey = ( return apiKeys.anthropicApiKey; case "google-genai": return apiKeys.googleApiKey; + case "openrouter": + return apiKeys.openrouterApiKey; default: throw new Error(`Unknown provider: ${providerName}`); } @@ -90,6 +100,9 @@ const providerToApiKey = ( export class ModelManager { private config: ModelManagerConfig; private circuitBreakers: Map = new Map(); + private apiKeys: Map = new Map(); + // Store the last reset time for daily rotation + private lastDailyReset: Map = new Map(); constructor(config: Partial = {}) { this.config = { ...DEFAULT_MODEL_MANAGER_CONFIG, ...config }; diff --git a/apps/web/src/lib/api-keys.ts b/apps/web/src/lib/api-keys.ts index d2f0b6a3d..ab94684dc 100644 --- a/apps/web/src/lib/api-keys.ts +++ b/apps/web/src/lib/api-keys.ts @@ -16,7 +16,8 @@ export function hasApiKeySet(config: Record) { if ( (enabledProviders.includes("anthropic") && !apiKeys.anthropicApiKey) || (enabledProviders.includes("openai") && !apiKeys.openaiApiKey) || - (enabledProviders.includes("google-genai") && !apiKeys.googleApiKey) + (enabledProviders.includes("google-genai") && !apiKeys.googleApiKey) || + (enabledProviders.includes("openrouter") && !apiKeys.openrouterApiKey) ) { return false; }