mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-26 20:45:37 +02:00
feat(runner): support OAuth providers (claude-code, openai-codex)
- Add provider alias mapping (claude-code -> anthropic) - Resolve API key from OAuth credentials for claude-code and codex - Add default models for each provider Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { SessionManager } from "./session/session-manager.js";
|
||||
import { ProfileManager } from "./profile/index.js";
|
||||
import { SkillManager } from "./skills/index.js";
|
||||
import { credentialManager, getCredentialsPath } from "./credentials.js";
|
||||
import { resolveProviderConfig } from "./credentials/providers.js";
|
||||
import {
|
||||
checkContextWindow,
|
||||
DEFAULT_CONTEXT_TOKENS,
|
||||
@@ -16,10 +17,24 @@ import { mergeToolsConfig, type ToolsConfig } from "./tools/policy.js";
|
||||
|
||||
/**
|
||||
* Get API Key based on provider.
|
||||
* Priority: explicit key > provider-specific env var > generic env var format.
|
||||
* Priority: explicit key > OAuth credentials > credentials.json5 config.
|
||||
*
|
||||
* Supports OAuth providers like "claude-code" and "openai-codex" by
|
||||
* reading credentials from their respective CLI tools.
|
||||
*/
|
||||
function resolveApiKey(provider: string, explicitKey?: string): string | undefined {
|
||||
if (explicitKey) return explicitKey;
|
||||
|
||||
// Try OAuth providers first (claude-code, openai-codex)
|
||||
const providerConfig = resolveProviderConfig(provider);
|
||||
if (providerConfig?.apiKey) {
|
||||
return providerConfig.apiKey;
|
||||
}
|
||||
if (providerConfig?.accessToken) {
|
||||
return providerConfig.accessToken;
|
||||
}
|
||||
|
||||
// Fall back to credentials.json5
|
||||
return credentialManager.getLlmProviderConfig(provider)?.apiKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,52 @@ import { createWebFetchTool, createWebSearchTool } from "./tools/web/index.js";
|
||||
import { createMemoryTools } from "./tools/memory/index.js";
|
||||
import { filterTools } from "./tools/policy.js";
|
||||
|
||||
/**
|
||||
* Provider alias mapping for OAuth providers.
|
||||
* Maps friendly names to actual pi-ai provider names.
|
||||
*/
|
||||
const PROVIDER_ALIAS: Record<string, string> = {
|
||||
"claude-code": "anthropic", // Claude Code OAuth uses anthropic API
|
||||
};
|
||||
|
||||
/**
|
||||
* Default models for each provider.
|
||||
*/
|
||||
const DEFAULT_MODELS: Record<string, string> = {
|
||||
"anthropic": "claude-sonnet-4-20250514",
|
||||
"claude-code": "claude-sonnet-4-20250514",
|
||||
"openai": "gpt-4o",
|
||||
"openai-codex": "gpt-5.1",
|
||||
"kimi-coding": "kimi-k2-thinking",
|
||||
"google": "gemini-2.0-flash",
|
||||
"groq": "llama-3.3-70b-versatile",
|
||||
"mistral": "mistral-large-latest",
|
||||
};
|
||||
|
||||
export function resolveModel(options: AgentOptions) {
|
||||
if (options.provider && options.model) {
|
||||
// Map provider alias (e.g., claude-code -> anthropic)
|
||||
const actualProvider = PROVIDER_ALIAS[options.provider] ?? options.provider;
|
||||
|
||||
// Type assertion needed because provider/model come from dynamic user config
|
||||
return (getModel as (p: string, m: string) => ReturnType<typeof getModel>)(
|
||||
options.provider,
|
||||
actualProvider,
|
||||
options.model,
|
||||
);
|
||||
}
|
||||
|
||||
// If only provider specified, use default model for that provider
|
||||
if (options.provider) {
|
||||
const actualProvider = PROVIDER_ALIAS[options.provider] ?? options.provider;
|
||||
const defaultModel = DEFAULT_MODELS[options.provider] ?? DEFAULT_MODELS[actualProvider];
|
||||
if (defaultModel) {
|
||||
return (getModel as (p: string, m: string) => ReturnType<typeof getModel>)(
|
||||
actualProvider,
|
||||
defaultModel,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return getModel("kimi-coding", "kimi-k2-thinking");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user