Onboarding: preserve provider rewrites
This commit is contained in:
parent
d6daa108e3
commit
181031856d
@ -0,0 +1,97 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { SYNTHETIC_DEFAULT_MODEL_ID } from "../agents/synthetic-models.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ModelDefinitionConfig } from "../config/types.models.js";
|
||||
import {
|
||||
applyModelStudioProviderConfig,
|
||||
applySyntheticProviderConfig,
|
||||
applyZaiProviderConfig,
|
||||
} from "./onboard-auth.config-core.js";
|
||||
|
||||
function makeModel(id: string): ModelDefinitionConfig {
|
||||
return {
|
||||
id,
|
||||
name: id,
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 4096,
|
||||
maxTokens: 1024,
|
||||
};
|
||||
}
|
||||
|
||||
describe("core onboarding provider rewriters", () => {
|
||||
const secretRef = {
|
||||
source: "env" as const,
|
||||
provider: "default",
|
||||
id: "TEST_API_KEY",
|
||||
};
|
||||
|
||||
it("rewrites aliased ZAI providers to the canonical key and preserves secret refs", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"z-ai": {
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://zai-preview.example/v1",
|
||||
apiKey: secretRef,
|
||||
models: [makeModel("legacy-zai-model")],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = applyZaiProviderConfig(cfg);
|
||||
|
||||
expect(Object.keys(result.models?.providers ?? {})).toEqual(["zai"]);
|
||||
expect(result.models?.providers?.zai?.baseUrl).toBe("https://zai-preview.example/v1");
|
||||
expect(result.models?.providers?.zai?.apiKey).toEqual(secretRef);
|
||||
expect(result.models?.providers?.zai?.models?.map((model) => model.id)).toEqual(
|
||||
expect.arrayContaining(["legacy-zai-model", "glm-5"]),
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves secret-ref api keys when rewriting Synthetic", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
synthetic: {
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://synthetic-legacy.example/v1",
|
||||
apiKey: secretRef,
|
||||
models: [makeModel("legacy-synthetic-model")],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = applySyntheticProviderConfig(cfg);
|
||||
|
||||
expect(result.models?.providers?.synthetic?.apiKey).toEqual(secretRef);
|
||||
expect(result.models?.providers?.synthetic?.models?.map((model) => model.id)).toEqual(
|
||||
expect.arrayContaining(["legacy-synthetic-model", SYNTHETIC_DEFAULT_MODEL_ID]),
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves secret-ref api keys when rewriting Model Studio", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
modelstudio: {
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://modelstudio-legacy.example/v1",
|
||||
apiKey: secretRef,
|
||||
models: [makeModel("legacy-modelstudio-model")],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = applyModelStudioProviderConfig(cfg);
|
||||
|
||||
expect(result.models?.providers?.modelstudio?.apiKey).toEqual(secretRef);
|
||||
expect(result.models?.providers?.modelstudio?.models?.map((model) => model.id)).toEqual(
|
||||
expect.arrayContaining(["legacy-modelstudio-model", "qwen3.5-plus"]),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -15,6 +15,7 @@ import { findNormalizedProviderValue } from "../agents/provider-id.js";
|
||||
import {
|
||||
buildSyntheticModelDefinition,
|
||||
SYNTHETIC_BASE_URL,
|
||||
SYNTHETIC_DEFAULT_MODEL_ID,
|
||||
SYNTHETIC_DEFAULT_MODEL_REF,
|
||||
SYNTHETIC_MODEL_CATALOG,
|
||||
} from "../agents/synthetic-models.js";
|
||||
@ -57,7 +58,6 @@ export {
|
||||
} from "./onboard-auth.config-litellm.js";
|
||||
import {
|
||||
applyAgentDefaultModelPrimary,
|
||||
applyOnboardAuthAgentModelsAndProviders,
|
||||
applyProviderConfigWithDefaultModel,
|
||||
applyProviderConfigWithDefaultModels,
|
||||
applyProviderConfigWithModelCatalog,
|
||||
@ -91,29 +91,6 @@ import {
|
||||
} from "./onboard-auth.models.js";
|
||||
export { applyAuthProfileConfig } from "./auth-profile-config.js";
|
||||
|
||||
function mergeProviderModels<T extends { id: string }>(
|
||||
existingProvider: Record<string, unknown> | undefined,
|
||||
defaultModels: T[],
|
||||
): T[] {
|
||||
const existingModels = Array.isArray(existingProvider?.models)
|
||||
? (existingProvider.models as T[])
|
||||
: [];
|
||||
const mergedModels = [...existingModels];
|
||||
const seen = new Set(existingModels.map((model) => model.id));
|
||||
for (const model of defaultModels) {
|
||||
if (!seen.has(model.id)) {
|
||||
mergedModels.push(model);
|
||||
seen.add(model.id);
|
||||
}
|
||||
}
|
||||
return mergedModels;
|
||||
}
|
||||
|
||||
function getNormalizedProviderApiKey(existingProvider: Record<string, unknown> | undefined) {
|
||||
const { apiKey } = (existingProvider ?? {}) as { apiKey?: string };
|
||||
return typeof apiKey === "string" ? apiKey.trim() || undefined : undefined;
|
||||
}
|
||||
|
||||
export function applyZaiProviderConfig(
|
||||
cfg: OpenClawConfig,
|
||||
params?: { endpoint?: string; modelId?: string },
|
||||
@ -126,9 +103,7 @@ export function applyZaiProviderConfig(
|
||||
...models[modelRef],
|
||||
alias: models[modelRef]?.alias ?? "GLM",
|
||||
};
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers.zai;
|
||||
const existingProvider = findNormalizedProviderValue(cfg.models?.providers, "zai");
|
||||
|
||||
const defaultModels = [
|
||||
buildZaiModelDefinition({ id: "glm-5" }),
|
||||
@ -138,28 +113,19 @@ export function applyZaiProviderConfig(
|
||||
buildZaiModelDefinition({ id: "glm-4.7-flashx" }),
|
||||
];
|
||||
|
||||
const mergedModels = mergeProviderModels(existingProvider, defaultModels);
|
||||
|
||||
const { apiKey: _existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const normalizedApiKey = getNormalizedProviderApiKey(existingProvider);
|
||||
|
||||
const baseUrl = params?.endpoint
|
||||
? resolveZaiBaseUrl(params.endpoint)
|
||||
: (typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl : "") ||
|
||||
resolveZaiBaseUrl();
|
||||
|
||||
providers.zai = {
|
||||
...existingProviderRest,
|
||||
baseUrl,
|
||||
return applyProviderConfigWithDefaultModels(cfg, {
|
||||
agentModels: models,
|
||||
providerId: "zai",
|
||||
api: "openai-completions",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : defaultModels,
|
||||
};
|
||||
|
||||
return applyOnboardAuthAgentModelsAndProviders(cfg, { agentModels: models, providers });
|
||||
baseUrl,
|
||||
defaultModels,
|
||||
defaultModelId: modelId,
|
||||
});
|
||||
}
|
||||
|
||||
export function applyZaiConfig(
|
||||
@ -267,30 +233,16 @@ export function applySyntheticProviderConfig(cfg: OpenClawConfig): OpenClawConfi
|
||||
alias: models[SYNTHETIC_DEFAULT_MODEL_REF]?.alias ?? "MiniMax M2.5",
|
||||
};
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers.synthetic;
|
||||
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
|
||||
const syntheticModels = SYNTHETIC_MODEL_CATALOG.map(buildSyntheticModelDefinition);
|
||||
const mergedModels = [
|
||||
...existingModels,
|
||||
...syntheticModels.filter(
|
||||
(model) => !existingModels.some((existing) => existing.id === model.id),
|
||||
),
|
||||
];
|
||||
const { apiKey: _existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const normalizedApiKey = getNormalizedProviderApiKey(existingProvider);
|
||||
providers.synthetic = {
|
||||
...existingProviderRest,
|
||||
baseUrl: SYNTHETIC_BASE_URL,
|
||||
api: "anthropic-messages",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : syntheticModels,
|
||||
};
|
||||
|
||||
return applyOnboardAuthAgentModelsAndProviders(cfg, { agentModels: models, providers });
|
||||
return applyProviderConfigWithDefaultModels(cfg, {
|
||||
agentModels: models,
|
||||
providerId: "synthetic",
|
||||
api: "anthropic-messages",
|
||||
baseUrl: SYNTHETIC_BASE_URL,
|
||||
defaultModels: syntheticModels,
|
||||
defaultModelId: SYNTHETIC_DEFAULT_MODEL_ID,
|
||||
});
|
||||
}
|
||||
|
||||
export function applySyntheticConfig(cfg: OpenClawConfig): OpenClawConfig {
|
||||
@ -590,9 +542,6 @@ function applyModelStudioProviderConfigWithBaseUrl(
|
||||
alias: models[MODELSTUDIO_DEFAULT_MODEL_REF]?.alias ?? "Qwen",
|
||||
};
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers.modelstudio;
|
||||
|
||||
const defaultModels = [
|
||||
buildModelStudioModelDefinition({ id: "qwen3.5-plus" }),
|
||||
buildModelStudioModelDefinition({ id: "qwen3-max-2026-01-23" }),
|
||||
@ -604,23 +553,14 @@ function applyModelStudioProviderConfigWithBaseUrl(
|
||||
buildModelStudioModelDefinition({ id: "kimi-k2.5" }),
|
||||
];
|
||||
|
||||
const mergedModels = mergeProviderModels(existingProvider, defaultModels);
|
||||
|
||||
const { apiKey: _existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const normalizedApiKey = getNormalizedProviderApiKey(existingProvider);
|
||||
|
||||
providers.modelstudio = {
|
||||
...existingProviderRest,
|
||||
baseUrl,
|
||||
return applyProviderConfigWithDefaultModels(cfg, {
|
||||
agentModels: models,
|
||||
providerId: "modelstudio",
|
||||
api: "openai-completions",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : defaultModels,
|
||||
};
|
||||
|
||||
return applyOnboardAuthAgentModelsAndProviders(cfg, { agentModels: models, providers });
|
||||
baseUrl,
|
||||
defaultModels,
|
||||
defaultModelId: "qwen3.5-plus",
|
||||
});
|
||||
}
|
||||
|
||||
export function applyModelStudioProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user