Test: cover z.ai normalization
This commit is contained in:
committed by
Peter Steinberger
parent
0ddfbf5534
commit
8954f7719c
@@ -73,9 +73,37 @@ describe("resolveConfiguredModelRef", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("still resolves legacy agent.model string", () => {
|
it("normalizes z.ai provider in agent.model", () => {
|
||||||
const cfg = {
|
const cfg = {
|
||||||
agent: { model: "openai/gpt-4.1-mini" },
|
agent: { model: "z.ai/glm-4.7" },
|
||||||
|
} satisfies ClawdbotConfig;
|
||||||
|
|
||||||
|
const resolved = resolveConfiguredModelRef({
|
||||||
|
cfg,
|
||||||
|
defaultProvider: DEFAULT_PROVIDER,
|
||||||
|
defaultModel: DEFAULT_MODEL,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resolved).toEqual({ provider: "zai", model: "glm-4.7" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes z-ai provider in agent.model", () => {
|
||||||
|
const cfg = {
|
||||||
|
agent: { model: "z-ai/glm-4.7" },
|
||||||
|
} satisfies ClawdbotConfig;
|
||||||
|
|
||||||
|
const resolved = resolveConfiguredModelRef({
|
||||||
|
cfg,
|
||||||
|
defaultProvider: DEFAULT_PROVIDER,
|
||||||
|
defaultModel: DEFAULT_MODEL,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resolved).toEqual({ provider: "zai", model: "glm-4.7" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes provider casing in agent.model", () => {
|
||||||
|
const cfg = {
|
||||||
|
agent: { model: "OpenAI/gpt-4.1-mini" },
|
||||||
} satisfies ClawdbotConfig;
|
} satisfies ClawdbotConfig;
|
||||||
|
|
||||||
const resolved = resolveConfiguredModelRef({
|
const resolved = resolveConfiguredModelRef({
|
||||||
@@ -86,4 +114,18 @@ describe("resolveConfiguredModelRef", () => {
|
|||||||
|
|
||||||
expect(resolved).toEqual({ provider: "openai", model: "gpt-4.1-mini" });
|
expect(resolved).toEqual({ provider: "openai", model: "gpt-4.1-mini" });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("normalizes z.ai casing in agent.model", () => {
|
||||||
|
const cfg = {
|
||||||
|
agent: { model: "Z.AI/glm-4.7" },
|
||||||
|
} satisfies ClawdbotConfig;
|
||||||
|
|
||||||
|
const resolved = resolveConfiguredModelRef({
|
||||||
|
cfg,
|
||||||
|
defaultProvider: DEFAULT_PROVIDER,
|
||||||
|
defaultModel: DEFAULT_MODEL,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resolved).toEqual({ provider: "zai", model: "glm-4.7" });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
159
src/commands/models.list.test.ts
Normal file
159
src/commands/models.list.test.ts
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
const loadConfig = vi.fn();
|
||||||
|
const ensureClawdbotModelsJson = vi.fn().mockResolvedValue(undefined);
|
||||||
|
const resolveClawdbotAgentDir = vi.fn().mockReturnValue("/tmp/clawdbot-agent");
|
||||||
|
const ensureAuthProfileStore = vi.fn().mockReturnValue({});
|
||||||
|
const listProfilesForProvider = vi.fn().mockReturnValue([]);
|
||||||
|
const resolveEnvApiKey = vi.fn().mockReturnValue(undefined);
|
||||||
|
const getCustomProviderApiKey = vi.fn().mockReturnValue(undefined);
|
||||||
|
const discoverAuthStorage = vi.fn().mockReturnValue({});
|
||||||
|
const discoverModels = vi.fn();
|
||||||
|
|
||||||
|
vi.mock("../config/config.js", () => ({
|
||||||
|
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
|
||||||
|
loadConfig,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../agents/models-config.js", () => ({
|
||||||
|
ensureClawdbotModelsJson,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../agents/agent-paths.js", () => ({
|
||||||
|
resolveClawdbotAgentDir,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../agents/auth-profiles.js", () => ({
|
||||||
|
ensureAuthProfileStore,
|
||||||
|
listProfilesForProvider,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../agents/model-auth.js", () => ({
|
||||||
|
resolveEnvApiKey,
|
||||||
|
getCustomProviderApiKey,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("@mariozechner/pi-coding-agent", () => ({
|
||||||
|
discoverAuthStorage,
|
||||||
|
discoverModels,
|
||||||
|
}));
|
||||||
|
|
||||||
|
function makeRuntime() {
|
||||||
|
return {
|
||||||
|
log: vi.fn(),
|
||||||
|
error: vi.fn(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("models list/status", () => {
|
||||||
|
it("models status resolves z.ai alias to canonical zai", async () => {
|
||||||
|
loadConfig.mockReturnValue({ agent: { model: "z.ai/glm-4.7" } });
|
||||||
|
const runtime = makeRuntime();
|
||||||
|
|
||||||
|
const { modelsStatusCommand } = await import("./models/list.js");
|
||||||
|
await modelsStatusCommand({ json: true }, runtime);
|
||||||
|
|
||||||
|
expect(runtime.log).toHaveBeenCalledTimes(1);
|
||||||
|
const payload = JSON.parse(String(runtime.log.mock.calls[0]?.[0]));
|
||||||
|
expect(payload.resolvedDefault).toBe("zai/glm-4.7");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("models status plain outputs canonical zai model", async () => {
|
||||||
|
loadConfig.mockReturnValue({ agent: { model: "z.ai/glm-4.7" } });
|
||||||
|
const runtime = makeRuntime();
|
||||||
|
|
||||||
|
const { modelsStatusCommand } = await import("./models/list.js");
|
||||||
|
await modelsStatusCommand({ plain: true }, runtime);
|
||||||
|
|
||||||
|
expect(runtime.log).toHaveBeenCalledTimes(1);
|
||||||
|
expect(runtime.log.mock.calls[0]?.[0]).toBe("zai/glm-4.7");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("models list outputs canonical zai key for configured z.ai model", async () => {
|
||||||
|
loadConfig.mockReturnValue({ agent: { model: "z.ai/glm-4.7" } });
|
||||||
|
const runtime = makeRuntime();
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
provider: "zai",
|
||||||
|
id: "glm-4.7",
|
||||||
|
name: "GLM-4.7",
|
||||||
|
input: ["text"],
|
||||||
|
baseUrl: "https://api.z.ai/v1",
|
||||||
|
contextWindow: 128000,
|
||||||
|
};
|
||||||
|
|
||||||
|
discoverModels.mockReturnValue({
|
||||||
|
getAll: () => [model],
|
||||||
|
getAvailable: () => [model],
|
||||||
|
});
|
||||||
|
|
||||||
|
const { modelsListCommand } = await import("./models/list.js");
|
||||||
|
await modelsListCommand({ json: true }, runtime);
|
||||||
|
|
||||||
|
expect(runtime.log).toHaveBeenCalledTimes(1);
|
||||||
|
const payload = JSON.parse(String(runtime.log.mock.calls[0]?.[0]));
|
||||||
|
expect(payload.models[0]?.key).toBe("zai/glm-4.7");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("models list plain outputs canonical zai key", async () => {
|
||||||
|
loadConfig.mockReturnValue({ agent: { model: "z.ai/glm-4.7" } });
|
||||||
|
const runtime = makeRuntime();
|
||||||
|
|
||||||
|
const model = {
|
||||||
|
provider: "zai",
|
||||||
|
id: "glm-4.7",
|
||||||
|
name: "GLM-4.7",
|
||||||
|
input: ["text"],
|
||||||
|
baseUrl: "https://api.z.ai/v1",
|
||||||
|
contextWindow: 128000,
|
||||||
|
};
|
||||||
|
|
||||||
|
discoverModels.mockReturnValue({
|
||||||
|
getAll: () => [model],
|
||||||
|
getAvailable: () => [model],
|
||||||
|
});
|
||||||
|
|
||||||
|
const { modelsListCommand } = await import("./models/list.js");
|
||||||
|
await modelsListCommand({ plain: true }, runtime);
|
||||||
|
|
||||||
|
expect(runtime.log).toHaveBeenCalledTimes(1);
|
||||||
|
expect(runtime.log.mock.calls[0]?.[0]).toBe("zai/glm-4.7");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("models list provider filter normalizes z.ai alias", async () => {
|
||||||
|
loadConfig.mockReturnValue({ agent: { model: "z.ai/glm-4.7" } });
|
||||||
|
const runtime = makeRuntime();
|
||||||
|
|
||||||
|
const models = [
|
||||||
|
{
|
||||||
|
provider: "zai",
|
||||||
|
id: "glm-4.7",
|
||||||
|
name: "GLM-4.7",
|
||||||
|
input: ["text"],
|
||||||
|
baseUrl: "https://api.z.ai/v1",
|
||||||
|
contextWindow: 128000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: "openai",
|
||||||
|
id: "gpt-4.1-mini",
|
||||||
|
name: "GPT-4.1 mini",
|
||||||
|
input: ["text"],
|
||||||
|
baseUrl: "https://api.openai.com/v1",
|
||||||
|
contextWindow: 128000,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
discoverModels.mockReturnValue({
|
||||||
|
getAll: () => models,
|
||||||
|
getAvailable: () => models,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { modelsListCommand } = await import("./models/list.js");
|
||||||
|
await modelsListCommand({ all: true, provider: "z.ai", json: true }, runtime);
|
||||||
|
|
||||||
|
expect(runtime.log).toHaveBeenCalledTimes(1);
|
||||||
|
const payload = JSON.parse(String(runtime.log.mock.calls[0]?.[0]));
|
||||||
|
expect(payload.count).toBe(1);
|
||||||
|
expect(payload.models[0]?.key).toBe("zai/glm-4.7");
|
||||||
|
});
|
||||||
|
});
|
||||||
103
src/commands/models.set.test.ts
Normal file
103
src/commands/models.set.test.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
const readConfigFileSnapshot = vi.fn();
|
||||||
|
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
|
||||||
|
const loadConfig = vi.fn().mockReturnValue({});
|
||||||
|
|
||||||
|
vi.mock("../config/config.js", () => ({
|
||||||
|
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
|
||||||
|
readConfigFileSnapshot,
|
||||||
|
writeConfigFile,
|
||||||
|
loadConfig,
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("models set + fallbacks", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
readConfigFileSnapshot.mockReset();
|
||||||
|
writeConfigFile.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes z.ai provider in models set", async () => {
|
||||||
|
readConfigFileSnapshot.mockResolvedValue({
|
||||||
|
path: "/tmp/clawdbot.json",
|
||||||
|
exists: true,
|
||||||
|
raw: "{}",
|
||||||
|
parsed: {},
|
||||||
|
valid: true,
|
||||||
|
config: {},
|
||||||
|
issues: [],
|
||||||
|
legacyIssues: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const runtime = { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
|
||||||
|
const { modelsSetCommand } = await import("./models/set.js");
|
||||||
|
|
||||||
|
await modelsSetCommand("z.ai/glm-4.7", runtime);
|
||||||
|
|
||||||
|
expect(writeConfigFile).toHaveBeenCalledTimes(1);
|
||||||
|
const written = writeConfigFile.mock.calls[0]?.[0] as Record<
|
||||||
|
string,
|
||||||
|
unknown
|
||||||
|
>;
|
||||||
|
expect(written.agent).toEqual({
|
||||||
|
model: { primary: "zai/glm-4.7" },
|
||||||
|
models: { "zai/glm-4.7": {} },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes z-ai provider in models fallbacks add", async () => {
|
||||||
|
readConfigFileSnapshot.mockResolvedValue({
|
||||||
|
path: "/tmp/clawdbot.json",
|
||||||
|
exists: true,
|
||||||
|
raw: "{}",
|
||||||
|
parsed: {},
|
||||||
|
valid: true,
|
||||||
|
config: { agent: { model: { fallbacks: [] } } },
|
||||||
|
issues: [],
|
||||||
|
legacyIssues: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const runtime = { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
|
||||||
|
const { modelsFallbacksAddCommand } = await import("./models/fallbacks.js");
|
||||||
|
|
||||||
|
await modelsFallbacksAddCommand("z-ai/glm-4.7", runtime);
|
||||||
|
|
||||||
|
expect(writeConfigFile).toHaveBeenCalledTimes(1);
|
||||||
|
const written = writeConfigFile.mock.calls[0]?.[0] as Record<
|
||||||
|
string,
|
||||||
|
unknown
|
||||||
|
>;
|
||||||
|
expect(written.agent).toEqual({
|
||||||
|
model: { fallbacks: ["zai/glm-4.7"] },
|
||||||
|
models: { "zai/glm-4.7": {} },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes provider casing in models set", async () => {
|
||||||
|
readConfigFileSnapshot.mockResolvedValue({
|
||||||
|
path: "/tmp/clawdbot.json",
|
||||||
|
exists: true,
|
||||||
|
raw: "{}",
|
||||||
|
parsed: {},
|
||||||
|
valid: true,
|
||||||
|
config: {},
|
||||||
|
issues: [],
|
||||||
|
legacyIssues: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const runtime = { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
|
||||||
|
const { modelsSetCommand } = await import("./models/set.js");
|
||||||
|
|
||||||
|
await modelsSetCommand("Z.AI/glm-4.7", runtime);
|
||||||
|
|
||||||
|
expect(writeConfigFile).toHaveBeenCalledTimes(1);
|
||||||
|
const written = writeConfigFile.mock.calls[0]?.[0] as Record<
|
||||||
|
string,
|
||||||
|
unknown
|
||||||
|
>;
|
||||||
|
expect(written.agent).toEqual({
|
||||||
|
model: { primary: "zai/glm-4.7" },
|
||||||
|
models: { "zai/glm-4.7": {} },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user