diff --git a/extensions/litellm/onboard.test.ts b/extensions/litellm/onboard.test.ts index d0283a7ea03..37ac2527fc1 100644 --- a/extensions/litellm/onboard.test.ts +++ b/extensions/litellm/onboard.test.ts @@ -1,26 +1,21 @@ import { describe, expect, it } from "vitest"; -import { createLegacyProviderConfig } from "../../test/helpers/plugins/onboard-config.js"; +import { expectProviderOnboardMergedLegacyConfig } from "../../test/helpers/plugins/provider-onboard.js"; import { applyLitellmProviderConfig } from "./onboard.js"; describe("litellm onboard", () => { it("preserves existing baseUrl and api key while adding the default model", () => { - const cfg = applyLitellmProviderConfig( - createLegacyProviderConfig({ - providerId: "litellm", - api: "anthropic-messages", - modelId: "custom-model", - modelName: "Custom", - baseUrl: "https://litellm.example/v1", - apiKey: " old-key ", - }), - ); + const provider = expectProviderOnboardMergedLegacyConfig({ + applyProviderConfig: applyLitellmProviderConfig, + providerId: "litellm", + providerApi: "openai-completions", + baseUrl: "https://litellm.example/v1", + legacyApi: "anthropic-messages", + legacyModelId: "custom-model", + legacyModelName: "Custom", + legacyBaseUrl: "https://litellm.example/v1", + legacyApiKey: " old-key ", + }); - expect(cfg.models?.providers?.litellm?.baseUrl).toBe("https://litellm.example/v1"); - expect(cfg.models?.providers?.litellm?.api).toBe("openai-completions"); - expect(cfg.models?.providers?.litellm?.apiKey).toBe("old-key"); - expect(cfg.models?.providers?.litellm?.models.map((m) => m.id)).toEqual([ - "custom-model", - "claude-opus-4-6", - ]); + expect(provider?.models.map((m) => m.id)).toEqual(["custom-model", "claude-opus-4-6"]); }); }); diff --git a/extensions/synthetic/onboard.test.ts b/extensions/synthetic/onboard.test.ts index 1172567e231..f71ffa9fbbe 100644 --- a/extensions/synthetic/onboard.test.ts +++ b/extensions/synthetic/onboard.test.ts @@ -1,6 +1,6 @@ import { resolveAgentModelPrimaryValue } from "openclaw/plugin-sdk/provider-onboard"; import { describe, expect, it } from "vitest"; -import { createLegacyProviderConfig } from "../../test/helpers/plugins/onboard-config.js"; +import { expectProviderOnboardMergedLegacyConfig } from "../../test/helpers/plugins/provider-onboard.js"; import { SYNTHETIC_DEFAULT_MODEL_REF as SYNTHETIC_DEFAULT_MODEL_REF_PUBLIC } from "./api.js"; import { applySyntheticConfig, @@ -21,16 +21,14 @@ describe("synthetic onboard", () => { }); it("merges existing synthetic provider models", () => { - const cfg = applySyntheticProviderConfig( - createLegacyProviderConfig({ - providerId: "synthetic", - api: "openai-completions", - }), - ); - expect(cfg.models?.providers?.synthetic?.baseUrl).toBe("https://api.synthetic.new/anthropic"); - expect(cfg.models?.providers?.synthetic?.api).toBe("anthropic-messages"); - expect(cfg.models?.providers?.synthetic?.apiKey).toBe("old-key"); - const ids = cfg.models?.providers?.synthetic?.models.map((m) => m.id); + const provider = expectProviderOnboardMergedLegacyConfig({ + applyProviderConfig: applySyntheticProviderConfig, + providerId: "synthetic", + providerApi: "anthropic-messages", + baseUrl: "https://api.synthetic.new/anthropic", + legacyApi: "openai-completions", + }); + const ids = provider?.models.map((m) => m.id); expect(ids).toContain("old-model"); expect(ids).toContain(SYNTHETIC_DEFAULT_MODEL_REF.replace(/^synthetic\//, "")); }); diff --git a/extensions/xiaomi/onboard.test.ts b/extensions/xiaomi/onboard.test.ts index 89f8529592f..f45af114055 100644 --- a/extensions/xiaomi/onboard.test.ts +++ b/extensions/xiaomi/onboard.test.ts @@ -1,6 +1,6 @@ import { resolveAgentModelPrimaryValue } from "openclaw/plugin-sdk/provider-onboard"; import { describe, expect, it } from "vitest"; -import { createLegacyProviderConfig } from "../../test/helpers/plugins/onboard-config.js"; +import { expectProviderOnboardMergedLegacyConfig } from "../../test/helpers/plugins/provider-onboard.js"; import { applyXiaomiConfig, applyXiaomiProviderConfig } from "./onboard.js"; describe("xiaomi onboard", () => { @@ -19,19 +19,16 @@ describe("xiaomi onboard", () => { }); it("merges Xiaomi models and keeps existing provider overrides", () => { - const cfg = applyXiaomiProviderConfig( - createLegacyProviderConfig({ - providerId: "xiaomi", - api: "openai-completions", - modelId: "custom-model", - modelName: "Custom", - }), - ); - - expect(cfg.models?.providers?.xiaomi?.baseUrl).toBe("https://api.xiaomimimo.com/v1"); - expect(cfg.models?.providers?.xiaomi?.api).toBe("openai-completions"); - expect(cfg.models?.providers?.xiaomi?.apiKey).toBe("old-key"); - expect(cfg.models?.providers?.xiaomi?.models.map((m) => m.id)).toEqual([ + const provider = expectProviderOnboardMergedLegacyConfig({ + applyProviderConfig: applyXiaomiProviderConfig, + providerId: "xiaomi", + providerApi: "openai-completions", + baseUrl: "https://api.xiaomimimo.com/v1", + legacyApi: "openai-completions", + legacyModelId: "custom-model", + legacyModelName: "Custom", + }); + expect(provider?.models.map((m) => m.id)).toEqual([ "custom-model", "mimo-v2-flash", "mimo-v2-pro", diff --git a/test/helpers/plugins/provider-onboard.ts b/test/helpers/plugins/provider-onboard.ts index befd5a62b6c..22ce672eb3a 100644 --- a/test/helpers/plugins/provider-onboard.ts +++ b/test/helpers/plugins/provider-onboard.ts @@ -4,7 +4,11 @@ import { } from "openclaw/plugin-sdk/provider-onboard"; import { expect } from "vitest"; import type { OpenClawConfig } from "../../../src/config/config.js"; -import { createConfigWithFallbacks, EXPECTED_FALLBACKS } from "./onboard-config.js"; +import { + createConfigWithFallbacks, + createLegacyProviderConfig, + EXPECTED_FALLBACKS, +} from "./onboard-config.js"; export function expectProviderOnboardAllowlistAlias(params: { applyProviderConfig: (config: OpenClawConfig) => OpenClawConfig; @@ -38,3 +42,38 @@ export function expectProviderOnboardPrimaryAndFallbacks(params: { ...EXPECTED_FALLBACKS, ]); } + +export function expectProviderOnboardMergedLegacyConfig(params: { + applyProviderConfig: (config: OpenClawConfig) => OpenClawConfig; + providerId: string; + providerApi: OpenClawConfig["models"] extends { providers?: infer P } + ? P extends Record + ? Provider extends { api?: infer Api } + ? Api + : never + : never + : never; + baseUrl: string; + legacyApi: Parameters[0]["api"]; + legacyModelId?: string; + legacyModelName?: string; + legacyBaseUrl?: string; + legacyApiKey?: string; +}) { + const cfg = params.applyProviderConfig( + createLegacyProviderConfig({ + providerId: params.providerId, + api: params.legacyApi, + modelId: params.legacyModelId, + modelName: params.legacyModelName, + baseUrl: params.legacyBaseUrl, + apiKey: params.legacyApiKey, + }), + ); + + const provider = cfg.models?.providers?.[params.providerId]; + expect(provider?.baseUrl).toBe(params.baseUrl); + expect(provider?.api).toBe(params.providerApi); + expect(provider?.apiKey).toBe((params.legacyApiKey ?? "old-key").trim()); + return provider; +}