feat(backend): read Pi enabled model scope
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { loadPiEnabledModels } from "../src/pi/enabled-models.js";
|
||||
|
||||
function fixture(globalValue: unknown, projectValue?: unknown) {
|
||||
const root = mkdtempSync(join(tmpdir(), "tht-enabled-models-"));
|
||||
const agentDir = join(root, "agent");
|
||||
const harnessDir = join(root, "harness");
|
||||
mkdirSync(agentDir, { recursive: true });
|
||||
mkdirSync(join(harnessDir, ".pi"), { recursive: true });
|
||||
writeFileSync(join(agentDir, "settings.json"), JSON.stringify(globalValue));
|
||||
if (projectValue !== undefined) {
|
||||
writeFileSync(join(harnessDir, ".pi", "settings.json"), JSON.stringify(projectValue));
|
||||
}
|
||||
return { root, agentDir, harnessDir };
|
||||
}
|
||||
|
||||
test("loads exact global enabledModels in configured order", () => {
|
||||
const f = fixture({ enabledModels: [
|
||||
"zai/glm-5.2",
|
||||
"deepseek/deepseek-v4-flash",
|
||||
"local-qwen/qwen3.6-35b-a3b",
|
||||
] });
|
||||
try {
|
||||
expect(loadPiEnabledModels(f)).toMatchObject({
|
||||
ids: [
|
||||
"zai/glm-5.2",
|
||||
"deepseek/deepseek-v4-flash",
|
||||
"local-qwen/qwen3.6-35b-a3b",
|
||||
],
|
||||
warnings: [],
|
||||
});
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test("project enabledModels overrides global enabledModels", () => {
|
||||
const f = fixture(
|
||||
{ enabledModels: ["zai/glm-5.2", "zai/glm-5v-turbo"] },
|
||||
{ enabledModels: ["local-qwen/qwen3.6-35b-a3b"] },
|
||||
);
|
||||
try {
|
||||
expect(loadPiEnabledModels(f).ids).toEqual(["local-qwen/qwen3.6-35b-a3b"]);
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test("project settings without enabledModels fall back to global settings", () => {
|
||||
const f = fixture({ enabledModels: ["zai/glm-5.2"] }, { theme: "thothii-mono" });
|
||||
try {
|
||||
expect(loadPiEnabledModels(f).ids).toEqual(["zai/glm-5.2"]);
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test("invalid entries are ignored, deduplicated, and reported without their content", () => {
|
||||
const f = fixture({ enabledModels: [
|
||||
"zai/glm-5.2", "zai/glm-5.2", "glm-5.2", "zai/*", "zai/glm-5.2:high", 7,
|
||||
] });
|
||||
try {
|
||||
const result = loadPiEnabledModels(f);
|
||||
expect(result.ids).toEqual(["zai/glm-5.2"]);
|
||||
expect(result.warnings).toHaveLength(4);
|
||||
expect(result.warnings.join(" ")).not.toContain("glm-5.2:high");
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test.each([
|
||||
["missing field", {}],
|
||||
["empty field", { enabledModels: [] }],
|
||||
["wrong type", { enabledModels: "zai/glm-5.2" }],
|
||||
])("%s fails closed", (_name, settings) => {
|
||||
const f = fixture(settings);
|
||||
try {
|
||||
const result = loadPiEnabledModels(f);
|
||||
expect(result.ids).toEqual([]);
|
||||
expect(result.warnings.length).toBeGreaterThan(0);
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test("malformed project settings fail closed instead of exposing global models", () => {
|
||||
const f = fixture({ enabledModels: ["zai/glm-5.2"] });
|
||||
writeFileSync(join(f.harnessDir, ".pi", "settings.json"), "{");
|
||||
try {
|
||||
const result = loadPiEnabledModels(f);
|
||||
expect(result.ids).toEqual([]);
|
||||
expect(result.warnings).toHaveLength(1);
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test("missing global settings fail closed", () => {
|
||||
const f = fixture({ enabledModels: ["zai/glm-5.2"] });
|
||||
rmSync(join(f.agentDir, "settings.json"));
|
||||
try {
|
||||
const result = loadPiEnabledModels(f);
|
||||
expect(result.ids).toEqual([]);
|
||||
expect(result.warnings).toHaveLength(1);
|
||||
} finally { rmSync(f.root, { recursive: true, force: true }); }
|
||||
});
|
||||
Reference in New Issue
Block a user