fix(ai): refresh model options after adding config
This commit is contained in:
1 parent
22ccdef594
commit
e6224ec0b0
3 files changed
+74
-14
No files matched your search
@@ -0,0 +1,54 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getAiConfigModelIds, isAiConfigModelCandidate } from "@/lib/ai/aiConfigCandidates";
|
||||
import type { AiConfig } from "@/types/ai";
|
||||
|
||||
function config(overrides: Partial<AiConfig> = {}): AiConfig {
|
||||
return {
|
||||
provider: "openai",
|
||||
apiKey: "secret",
|
||||
authMethod: "bearer",
|
||||
endpoint: "https://api.example.com/v1",
|
||||
model: "gpt-default",
|
||||
apiStyle: "completions",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("isAiConfigModelCandidate", () => {
|
||||
it("accepts discovered models when the default model is empty", () => {
|
||||
expect(isAiConfigModelCandidate(config({ model: "", models: [{ name: "gpt-new" }] }), true)).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps endpoint and required API key validation", () => {
|
||||
expect(isAiConfigModelCandidate(config({ endpoint: "" }), true)).toBe(false);
|
||||
expect(isAiConfigModelCandidate(config({ apiKey: "" }), true)).toBe(false);
|
||||
});
|
||||
|
||||
it.each(["codex-cli", "claude-code-cli"] as const)("keeps %s configs eligible without endpoint, API key, or model metadata", (provider) => {
|
||||
expect(
|
||||
isAiConfigModelCandidate(
|
||||
config({
|
||||
provider,
|
||||
endpoint: "",
|
||||
apiKey: "",
|
||||
model: "",
|
||||
models: [],
|
||||
}),
|
||||
false,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAiConfigModelIds", () => {
|
||||
it("includes the default model once while preserving configured model order", () => {
|
||||
expect(
|
||||
getAiConfigModelIds(
|
||||
config({
|
||||
model: "gpt-default",
|
||||
models: [{ name: "gpt-fast" }, { name: "gpt-default" }, { name: "gpt-default" }],
|
||||
}),
|
||||
),
|
||||
).toEqual(["gpt-fast", "gpt-default"]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { AiConfig } from "@/types/ai";
|
||||
|
||||
const CLI_PROVIDERS = new Set<AiConfig["provider"]>(["codex-cli", "claude-code-cli"]);
|
||||
|
||||
export function getAiConfigModelIds(config: Pick<AiConfig, "model" | "models">): string[] {
|
||||
const configuredModels = [...new Set(config.models?.map((model) => model.name) ?? [])];
|
||||
return config.model && !configuredModels.includes(config.model) ? [config.model, ...configuredModels] : configuredModels;
|
||||
}
|
||||
|
||||
export function isAiConfigModelCandidate(config: AiConfig, requiresApiKey: boolean): boolean {
|
||||
// CLI providers resolve their model and credentials externally, so keep the existing eligibility bypass.
|
||||
if (CLI_PROVIDERS.has(config.provider)) return true;
|
||||
if (!config.endpoint?.trim() || (requiresApiKey && !config.apiKey?.trim())) return false;
|
||||
|
||||
// A discovered model list is sufficient even before the user chooses a default model.
|
||||
return getAiConfigModelIds(config).some((model) => !!model.trim());
|
||||
}
|
||||
Reference in new issue
Block a user