feat(models): add auth profile cooldown for api key pools

This commit is contained in:
William Valentin
2026-02-19 11:45:55 -08:00
parent baa53f91d9
commit 6b56d9e223
9 changed files with 175 additions and 22 deletions
+11
View File
@@ -58,6 +58,17 @@ describe('createClientFromConfig', () => {
expect(client.constructor.name).toBe('RotatingModelClient');
});
it('supports auth_profile_cooldown_ms with api_keys pools', async () => {
const { createClientFromConfig } = await loadFactory();
const client = createClientFromConfig({
provider: 'openai',
model: 'gpt-4o',
api_keys: ['sk-1', 'sk-2'],
auth_profile_cooldown_ms: 30_000,
});
expect(client.constructor.name).toBe('RotatingModelClient');
});
it('creates OllamaClient for ollama provider', async () => {
const { createClientFromConfig } = await loadFactory();
const client = createClientFromConfig({
+13 -9
View File
@@ -50,11 +50,15 @@ function resolveApiKeyPool(cfg: ModelConfig, envVar?: string): string[] {
function createApiKeyClient(
keys: string[],
build: (apiKey: string) => ModelClient,
options?: { cooldownMs?: number },
): ModelClient {
if (keys.length === 1) {
return build(keys[0]);
}
return new RotatingModelClient(keys.map((key) => build(key)));
return new RotatingModelClient(
keys.map((key) => build(key)),
{ cooldownMs: options?.cooldownMs ?? 0 },
);
}
function resolveZaiCredential(cfg: ModelConfig): string {
@@ -113,7 +117,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
return createApiKeyClient(allKeys, (apiKey) => new AnthropicClient({
model: cfg.model,
apiKey,
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
// auto: prefer API keys, then token
@@ -126,7 +130,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
return createApiKeyClient(allKeys, (apiKey) => new AnthropicClient({
model: cfg.model,
apiKey,
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
const token = cfg.auth_token ?? getAnthropicAuthToken();
@@ -176,7 +180,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
return createApiKeyClient(allKeys, (apiKey) => new OpenAIClient({
model: cfg.model,
apiKey,
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
// auto: prefer API keys, then OAuth
@@ -189,7 +193,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
return createApiKeyClient(allKeys, (apiKey) => new OpenAIClient({
model: cfg.model,
apiKey,
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
const existing = loadStoredOpenAIAuth();
@@ -235,7 +239,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
model: cfg.model,
apiKey,
baseURL: cfg.endpoint ?? 'https://openrouter.ai/api/v1',
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
case 'vercel':
return new OpenAIClient({
@@ -261,7 +265,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
model: cfg.model,
apiKey,
baseURL: cfg.endpoint ?? 'https://api.x.ai/v1',
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
case 'minimax':
{
@@ -275,7 +279,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
model: cfg.model,
apiKey,
baseURL: cfg.endpoint ?? 'https://api.minimax.io/v1',
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
case 'moonshot':
{
@@ -289,7 +293,7 @@ export function createClientFromConfig(cfg: ModelConfig): ModelClient {
model: cfg.model,
apiKey,
baseURL: cfg.endpoint ?? 'https://api.moonshot.cn/v1',
}));
}), { cooldownMs: cfg.auth_profile_cooldown_ms });
}
case 'bedrock':
return new BedrockClient({