mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 23:04:32 +00:00
fix(models): preserve implicit vision models
This commit is contained in:
@@ -487,9 +487,14 @@ describe("models config", () => {
|
|||||||
const modelPath = path.join(resolveClawdbotAgentDir(), "models.json");
|
const modelPath = path.join(resolveClawdbotAgentDir(), "models.json");
|
||||||
const raw = await fs.readFile(modelPath, "utf8");
|
const raw = await fs.readFile(modelPath, "utf8");
|
||||||
const parsed = JSON.parse(raw) as {
|
const parsed = JSON.parse(raw) as {
|
||||||
providers: Record<string, { apiKey?: string }>;
|
providers: Record<
|
||||||
|
string,
|
||||||
|
{ apiKey?: string; models?: Array<{ id: string }> }
|
||||||
|
>;
|
||||||
};
|
};
|
||||||
expect(parsed.providers.minimax?.apiKey).toBe("MINIMAX_API_KEY");
|
expect(parsed.providers.minimax?.apiKey).toBe("MINIMAX_API_KEY");
|
||||||
|
const ids = parsed.providers.minimax?.models?.map((model) => model.id);
|
||||||
|
expect(ids).toContain("MiniMax-VL-01");
|
||||||
} finally {
|
} finally {
|
||||||
if (prevKey === undefined) delete process.env.MINIMAX_API_KEY;
|
if (prevKey === undefined) delete process.env.MINIMAX_API_KEY;
|
||||||
else process.env.MINIMAX_API_KEY = prevKey;
|
else process.env.MINIMAX_API_KEY = prevKey;
|
||||||
|
|||||||
@@ -25,6 +25,57 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|||||||
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mergeProviderModels(
|
||||||
|
implicit: ProviderConfig,
|
||||||
|
explicit: ProviderConfig,
|
||||||
|
): ProviderConfig {
|
||||||
|
const implicitModels = Array.isArray(implicit.models) ? implicit.models : [];
|
||||||
|
const explicitModels = Array.isArray(explicit.models) ? explicit.models : [];
|
||||||
|
if (implicitModels.length === 0) return { ...implicit, ...explicit };
|
||||||
|
|
||||||
|
const getId = (model: unknown): string => {
|
||||||
|
if (!model || typeof model !== "object") return "";
|
||||||
|
const id = (model as { id?: unknown }).id;
|
||||||
|
return typeof id === "string" ? id.trim() : "";
|
||||||
|
};
|
||||||
|
const seen = new Set(explicitModels.map(getId).filter(Boolean));
|
||||||
|
|
||||||
|
const mergedModels = [
|
||||||
|
...explicitModels,
|
||||||
|
...implicitModels.filter((model) => {
|
||||||
|
const id = getId(model);
|
||||||
|
if (!id) return false;
|
||||||
|
if (seen.has(id)) return false;
|
||||||
|
seen.add(id);
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...implicit,
|
||||||
|
...explicit,
|
||||||
|
models: mergedModels,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeProviders(params: {
|
||||||
|
implicit?: Record<string, ProviderConfig> | null;
|
||||||
|
explicit?: Record<string, ProviderConfig> | null;
|
||||||
|
}): Record<string, ProviderConfig> {
|
||||||
|
const out: Record<string, ProviderConfig> = params.implicit
|
||||||
|
? { ...params.implicit }
|
||||||
|
: {};
|
||||||
|
for (const [key, explicit] of Object.entries(params.explicit ?? {})) {
|
||||||
|
const providerKey = key.trim();
|
||||||
|
if (!providerKey) continue;
|
||||||
|
const implicit = out[providerKey];
|
||||||
|
out[providerKey] = implicit
|
||||||
|
? mergeProviderModels(implicit, explicit)
|
||||||
|
: explicit;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
async function readJson(pathname: string): Promise<unknown> {
|
async function readJson(pathname: string): Promise<unknown> {
|
||||||
try {
|
try {
|
||||||
const raw = await fs.readFile(pathname, "utf8");
|
const raw = await fs.readFile(pathname, "utf8");
|
||||||
@@ -101,12 +152,15 @@ export async function ensureClawdbotModelsJson(
|
|||||||
? agentDirOverride.trim()
|
? agentDirOverride.trim()
|
||||||
: resolveClawdbotAgentDir();
|
: resolveClawdbotAgentDir();
|
||||||
|
|
||||||
const explicitProviders = cfg.models?.providers ?? {};
|
const explicitProviders = (cfg.models?.providers ?? {}) as Record<
|
||||||
|
string,
|
||||||
|
ProviderConfig
|
||||||
|
>;
|
||||||
const implicitProviders = resolveImplicitProviders({ agentDir });
|
const implicitProviders = resolveImplicitProviders({ agentDir });
|
||||||
const providers: Record<string, ProviderConfig> = {
|
const providers: Record<string, ProviderConfig> = mergeProviders({
|
||||||
...implicitProviders,
|
implicit: implicitProviders,
|
||||||
...explicitProviders,
|
explicit: explicitProviders,
|
||||||
};
|
});
|
||||||
const implicitCopilot = await maybeBuildCopilotProvider({ agentDir });
|
const implicitCopilot = await maybeBuildCopilotProvider({ agentDir });
|
||||||
if (implicitCopilot && !providers["github-copilot"]) {
|
if (implicitCopilot && !providers["github-copilot"]) {
|
||||||
providers["github-copilot"] = implicitCopilot;
|
providers["github-copilot"] = implicitCopilot;
|
||||||
|
|||||||
Reference in New Issue
Block a user