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 raw = await fs.readFile(modelPath, "utf8");
|
||||
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");
|
||||
const ids = parsed.providers.minimax?.models?.map((model) => model.id);
|
||||
expect(ids).toContain("MiniMax-VL-01");
|
||||
} finally {
|
||||
if (prevKey === undefined) delete process.env.MINIMAX_API_KEY;
|
||||
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));
|
||||
}
|
||||
|
||||
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> {
|
||||
try {
|
||||
const raw = await fs.readFile(pathname, "utf8");
|
||||
@@ -101,12 +152,15 @@ export async function ensureClawdbotModelsJson(
|
||||
? agentDirOverride.trim()
|
||||
: resolveClawdbotAgentDir();
|
||||
|
||||
const explicitProviders = cfg.models?.providers ?? {};
|
||||
const explicitProviders = (cfg.models?.providers ?? {}) as Record<
|
||||
string,
|
||||
ProviderConfig
|
||||
>;
|
||||
const implicitProviders = resolveImplicitProviders({ agentDir });
|
||||
const providers: Record<string, ProviderConfig> = {
|
||||
...implicitProviders,
|
||||
...explicitProviders,
|
||||
};
|
||||
const providers: Record<string, ProviderConfig> = mergeProviders({
|
||||
implicit: implicitProviders,
|
||||
explicit: explicitProviders,
|
||||
});
|
||||
const implicitCopilot = await maybeBuildCopilotProvider({ agentDir });
|
||||
if (implicitCopilot && !providers["github-copilot"]) {
|
||||
providers["github-copilot"] = implicitCopilot;
|
||||
|
||||
Reference in New Issue
Block a user