diff --git a/extensions/mistral/api.ts b/extensions/mistral/api.ts index f671e7a7e35..440f4601ad7 100644 --- a/extensions/mistral/api.ts +++ b/extensions/mistral/api.ts @@ -1,4 +1,4 @@ -export { applyMistralConfig, applyMistralProviderConfig, MISTRAL_DEFAULT_MODEL_REF } from "./onboard.js"; +export { applyMistralConfig, applyMistralProviderConfig } from "./onboard.js"; export { buildMistralCatalogModels, buildMistralModelDefinition, diff --git a/extensions/mistral/onboard.test.ts b/extensions/mistral/onboard.test.ts index f327001e31c..f32eca3a1d5 100644 --- a/extensions/mistral/onboard.test.ts +++ b/extensions/mistral/onboard.test.ts @@ -54,7 +54,9 @@ describe("mistral onboard", () => { it("uses the bundled mistral default model definition", () => { const bundled = buildBundledMistralModelDefinition(); const cfg = applyMistralProviderConfig({}); - const defaultModel = cfg.models?.providers?.mistral?.models.find((model) => model.id === bundled.id); + const defaultModel = cfg.models?.providers?.mistral?.models.find( + (model) => model.id === bundled.id, + ); expect(defaultModel).toMatchObject({ id: bundled.id, diff --git a/extensions/modelstudio/model-definitions.ts b/extensions/modelstudio/model-definitions.ts index df82fa20712..b820bf1b495 100644 --- a/extensions/modelstudio/model-definitions.ts +++ b/extensions/modelstudio/model-definitions.ts @@ -31,8 +31,7 @@ export function buildModelStudioModelDefinition(params: { name: params.name ?? catalog?.name ?? params.id, reasoning: params.reasoning ?? catalog?.reasoning ?? false, input: - (params.input as ("text" | "image")[]) ?? - (catalog?.input ? [...catalog.input] : ["text"]), + (params.input as ("text" | "image")[]) ?? (catalog?.input ? [...catalog.input] : ["text"]), cost: params.cost ?? catalog?.cost ?? MODELSTUDIO_DEFAULT_COST, contextWindow: params.contextWindow ?? catalog?.contextWindow ?? 262_144, maxTokens: params.maxTokens ?? catalog?.maxTokens ?? 65_536, diff --git a/extensions/moonshot/api.ts b/extensions/moonshot/api.ts index f7c5068dda4..355343763d4 100644 --- a/extensions/moonshot/api.ts +++ b/extensions/moonshot/api.ts @@ -1,2 +1,6 @@ -export { buildMoonshotProvider, MOONSHOT_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID } from "./provider-catalog.js"; +export { + buildMoonshotProvider, + MOONSHOT_BASE_URL, + MOONSHOT_DEFAULT_MODEL_ID, +} from "./provider-catalog.js"; export { MOONSHOT_CN_BASE_URL, MOONSHOT_DEFAULT_MODEL_REF } from "./onboard.js"; diff --git a/src/agents/models-config.providers.moonshot.test.ts b/src/agents/models-config.providers.moonshot.test.ts index 0c3acc565b2..588666208c0 100644 --- a/src/agents/models-config.providers.moonshot.test.ts +++ b/src/agents/models-config.providers.moonshot.test.ts @@ -2,7 +2,10 @@ import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; -import { MOONSHOT_BASE_URL as MOONSHOT_AI_BASE_URL, MOONSHOT_CN_BASE_URL } from "../../extensions/moonshot/api.js"; +import { + MOONSHOT_BASE_URL as MOONSHOT_AI_BASE_URL, + MOONSHOT_CN_BASE_URL, +} from "../../extensions/moonshot/api.js"; import { captureEnv } from "../test-utils/env.js"; import { resolveImplicitProvidersForTest } from "./models-config.e2e-harness.js"; import { applyNativeStreamingUsageCompat } from "./models-config.providers.js"; diff --git a/src/commands/auth-choice.test.ts b/src/commands/auth-choice.test.ts index 62b56a03873..5eb5b9c3524 100644 --- a/src/commands/auth-choice.test.ts +++ b/src/commands/auth-choice.test.ts @@ -1,16 +1,14 @@ import fs from "node:fs/promises"; import type { OAuthCredentials } from "@mariozechner/pi-ai"; import { afterEach, describe, expect, it, vi } from "vitest"; +import { MINIMAX_CN_API_BASE_URL } from "../../extensions/minimax/api.js"; +import { ZAI_CODING_CN_BASE_URL, ZAI_CODING_GLOBAL_BASE_URL } from "../../extensions/zai/api.js"; import { resolveAgentDir } from "../agents/agent-scope.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveAgentModelPrimaryValue } from "../config/model-input.js"; import type { ModelProviderConfig } from "../config/types.models.js"; import { createProviderApiKeyAuthMethod } from "../plugins/provider-api-key-auth.js"; import { providerApiKeyAuthRuntime } from "../plugins/provider-api-key-auth.runtime.js"; -import { - MINIMAX_CN_API_BASE_URL, -} from "../../extensions/minimax/api.js"; -import { ZAI_CODING_CN_BASE_URL, ZAI_CODING_GLOBAL_BASE_URL } from "../../extensions/zai/api.js"; import type { ProviderAuthMethod, ProviderPlugin } from "../plugins/types.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import { applyAuthChoice, resolvePreferredProviderForAuthChoice } from "./auth-choice.js"; diff --git a/src/commands/onboard-non-interactive.provider-auth.test.ts b/src/commands/onboard-non-interactive.provider-auth.test.ts index 0749757b0c4..73f9d68dc7e 100644 --- a/src/commands/onboard-non-interactive.provider-auth.test.ts +++ b/src/commands/onboard-non-interactive.provider-auth.test.ts @@ -2,10 +2,7 @@ import fs from "node:fs/promises"; import path from "node:path"; import { setTimeout as delay } from "node:timers/promises"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { - MINIMAX_API_BASE_URL, - MINIMAX_CN_API_BASE_URL, -} from "../../extensions/minimax/api.js"; +import { MINIMAX_API_BASE_URL, MINIMAX_CN_API_BASE_URL } from "../../extensions/minimax/api.js"; import { ZAI_CODING_CN_BASE_URL, ZAI_CODING_GLOBAL_BASE_URL, diff --git a/src/plugins/provider-auth-storage.ts b/src/plugins/provider-auth-storage.ts index 93fb0c05600..04076286e21 100644 --- a/src/plugins/provider-auth-storage.ts +++ b/src/plugins/provider-auth-storage.ts @@ -18,6 +18,12 @@ import { KILOCODE_DEFAULT_MODEL_REF } from "./provider-model-kilocode.js"; const resolveAuthAgentDir = (agentDir?: string) => agentDir ?? resolveOpenClawAgentDir(); +type ProviderApiKeySetter = ( + key: SecretInput, + agentDir?: string, + options?: ApiKeyStorageOptions, +) => Promise | void; + function upsertProviderApiKeyProfile(params: { provider: string; key: SecretInput; @@ -33,6 +39,20 @@ function upsertProviderApiKeyProfile(params: { }); } +function createProviderApiKeySetter( + provider: string, + resolveKey: (key: SecretInput) => SecretInput = (key) => key, +): ProviderApiKeySetter { + return async (key, agentDir, options) => { + upsertProviderApiKeyProfile({ + provider, + key: resolveKey(key), + agentDir, + options, + }); + }; +} + export { HUGGINGFACE_DEFAULT_MODEL_REF, KILOCODE_DEFAULT_MODEL_REF, @@ -50,29 +70,9 @@ export { type WriteOAuthCredentialsOptions, }; -export async function setAnthropicApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "anthropic", key, agentDir, options }); -} - -export async function setOpenaiApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "openai", key, agentDir, options }); -} - -export async function setGeminiApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "google", key, agentDir, options }); -} +export const setAnthropicApiKey = createProviderApiKeySetter("anthropic"); +export const setOpenaiApiKey = createProviderApiKeySetter("openai"); +export const setGeminiApiKey = createProviderApiKeySetter("google"); export async function setMinimaxApiKey( key: SecretInput, @@ -84,90 +84,17 @@ export async function setMinimaxApiKey( upsertProviderApiKeyProfile({ provider, key, agentDir, options, profileId }); } -export async function setMoonshotApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "moonshot", key, agentDir, options }); -} - -export async function setKimiCodingApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "kimi", key, agentDir, options }); -} - -export async function setVolcengineApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "volcengine", key, agentDir, options }); -} - -export async function setByteplusApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "byteplus", key, agentDir, options }); -} - -export async function setSyntheticApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "synthetic", key, agentDir, options }); -} - -export async function setVeniceApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "venice", key, agentDir, options }); -} - -export async function setZaiApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertAuthProfile({ - profileId: "zai:default", - credential: buildApiKeyCredential("zai", key, undefined, options), - agentDir: resolveAuthAgentDir(agentDir), - }); -} - -export async function setXiaomiApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertAuthProfile({ - profileId: "xiaomi:default", - credential: buildApiKeyCredential("xiaomi", key, undefined, options), - agentDir: resolveAuthAgentDir(agentDir), - }); -} - -export async function setOpenrouterApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - const safeKey = typeof key === "string" && key === "undefined" ? "" : key; - upsertAuthProfile({ - profileId: "openrouter:default", - credential: buildApiKeyCredential("openrouter", safeKey, undefined, options), - agentDir: resolveAuthAgentDir(agentDir), - }); -} +export const setMoonshotApiKey = createProviderApiKeySetter("moonshot"); +export const setKimiCodingApiKey = createProviderApiKeySetter("kimi"); +export const setVolcengineApiKey = createProviderApiKeySetter("volcengine"); +export const setByteplusApiKey = createProviderApiKeySetter("byteplus"); +export const setSyntheticApiKey = createProviderApiKeySetter("synthetic"); +export const setVeniceApiKey = createProviderApiKeySetter("venice"); +export const setZaiApiKey = createProviderApiKeySetter("zai"); +export const setXiaomiApiKey = createProviderApiKeySetter("xiaomi"); +export const setOpenrouterApiKey = createProviderApiKeySetter("openrouter", (key) => + typeof key === "string" && key === "undefined" ? "" : key, +); export async function setCloudflareAiGatewayConfig( accountId: string, @@ -190,21 +117,8 @@ export async function setCloudflareAiGatewayConfig( }); } -export async function setLitellmApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "litellm", key, agentDir, options }); -} - -export async function setVercelAiGatewayApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "vercel-ai-gateway", key, agentDir, options }); -} +export const setLitellmApiKey = createProviderApiKeySetter("litellm"); +export const setVercelAiGatewayApiKey = createProviderApiKeySetter("vercel-ai-gateway"); export async function setOpencodeZenApiKey( key: SecretInput, @@ -232,54 +146,10 @@ async function setSharedOpencodeApiKey( } } -export async function setTogetherApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "together", key, agentDir, options }); -} - -export async function setHuggingfaceApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "huggingface", key, agentDir, options }); -} - -export function setQianfanApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "qianfan", key, agentDir, options }); -} - -export function setModelStudioApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "modelstudio", key, agentDir, options }); -} - -export function setXaiApiKey(key: SecretInput, agentDir?: string, options?: ApiKeyStorageOptions) { - upsertProviderApiKeyProfile({ provider: "xai", key, agentDir, options }); -} - -export async function setMistralApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "mistral", key, agentDir, options }); -} - -export async function setKilocodeApiKey( - key: SecretInput, - agentDir?: string, - options?: ApiKeyStorageOptions, -) { - upsertProviderApiKeyProfile({ provider: "kilocode", key, agentDir, options }); -} +export const setTogetherApiKey = createProviderApiKeySetter("together"); +export const setHuggingfaceApiKey = createProviderApiKeySetter("huggingface"); +export const setQianfanApiKey = createProviderApiKeySetter("qianfan"); +export const setModelStudioApiKey = createProviderApiKeySetter("modelstudio"); +export const setXaiApiKey = createProviderApiKeySetter("xai"); +export const setMistralApiKey = createProviderApiKeySetter("mistral"); +export const setKilocodeApiKey = createProviderApiKeySetter("kilocode"); diff --git a/src/plugins/provider-zai-endpoint.ts b/src/plugins/provider-zai-endpoint.ts index f2a0d903213..0eca8076f86 100644 --- a/src/plugins/provider-zai-endpoint.ts +++ b/src/plugins/provider-zai-endpoint.ts @@ -1,10 +1,10 @@ -import { fetchWithTimeout } from "../utils/fetch-timeout.js"; import { ZAI_CN_BASE_URL, ZAI_CODING_CN_BASE_URL, ZAI_CODING_GLOBAL_BASE_URL, ZAI_GLOBAL_BASE_URL, } from "../../extensions/zai/api.js"; +import { fetchWithTimeout } from "../utils/fetch-timeout.js"; export type ZaiEndpointId = "global" | "cn" | "coding-global" | "coding-cn";