mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-03 23:21:38 +00:00
174 lines
5.5 KiB
TypeScript
174 lines
5.5 KiB
TypeScript
import { mkdir } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { expect, it } from "vitest";
|
|
import { createChatFlowE2eSuite, installMockGateway } from "./chat-flow.test-support.ts";
|
|
|
|
const suite = createChatFlowE2eSuite();
|
|
|
|
const models = [
|
|
{
|
|
id: "claude-opus-4-8",
|
|
name: "Opus 4.8",
|
|
alias: "opus",
|
|
provider: "anthropic",
|
|
},
|
|
{
|
|
id: "claude-sonnet-5",
|
|
name: "Sonnet 5",
|
|
alias: "sonnet",
|
|
provider: "anthropic",
|
|
},
|
|
{
|
|
id: "moonshotai/kimi-k2.5",
|
|
name: "Kimi K2.5",
|
|
alias: "Kimi K2.5 (NVIDIA)",
|
|
provider: "nvidia",
|
|
},
|
|
];
|
|
|
|
const proofDir =
|
|
process.env.OPENCLAW_CAPTURE_UI_PROOF === "1"
|
|
? path.join(process.cwd(), ".artifacts", "control-ui-e2e", "model-alias-display")
|
|
: null;
|
|
|
|
async function createProofContext() {
|
|
if (proofDir) {
|
|
await mkdir(proofDir, { recursive: true });
|
|
}
|
|
return suite.newBrowserContext({
|
|
locale: "en-US",
|
|
serviceWorkers: "block",
|
|
viewport: { height: 900, width: 1280 },
|
|
...(proofDir
|
|
? {
|
|
recordVideo: {
|
|
dir: proofDir,
|
|
size: { height: 900, width: 1280 },
|
|
},
|
|
}
|
|
: {}),
|
|
});
|
|
}
|
|
|
|
suite.define(() => {
|
|
it("keeps model versions and custom aliases visible in the chat picker", async () => {
|
|
const context = await createProofContext();
|
|
const page = await context.newPage();
|
|
const gateway = await installMockGateway(page, {
|
|
models,
|
|
sessionKey: "agent:main:main",
|
|
});
|
|
|
|
try {
|
|
await page.goto(`${suite.server.baseUrl}chat`);
|
|
const main = page.getByRole("main");
|
|
const picker = main.locator('[data-chat-model-select="true"]').first();
|
|
await picker.waitFor({ state: "visible", timeout: 10_000 });
|
|
await picker.click();
|
|
await main.locator('[data-chat-model-provider="anthropic"]').click();
|
|
|
|
const opus = main.locator(
|
|
'[data-chat-model-option="anthropic/claude-opus-4-8"] .chat-controls__model-option-name',
|
|
);
|
|
const sonnet = main.locator(
|
|
'[data-chat-model-option="anthropic/claude-sonnet-5"] .chat-controls__model-option-name',
|
|
);
|
|
await expect.poll(() => opus.textContent()).toBe("Opus 4.8 · opus");
|
|
await expect.poll(() => sonnet.textContent()).toBe("Sonnet 5 · sonnet");
|
|
|
|
if (proofDir) {
|
|
await page.screenshot({
|
|
fullPage: true,
|
|
path: path.join(proofDir, "anthropic-versioned-model-aliases.png"),
|
|
});
|
|
}
|
|
|
|
await main.locator('[data-chat-model-provider="nvidia"]').click();
|
|
const nvidia = main.locator(
|
|
'[data-chat-model-option="nvidia/moonshotai/kimi-k2.5"] .chat-controls__model-option-name',
|
|
);
|
|
await expect.poll(() => nvidia.textContent()).toBe("Kimi K2.5 (NVIDIA)");
|
|
expect(await gateway.getRequests("sessions.patch")).toHaveLength(0);
|
|
|
|
if (proofDir) {
|
|
await page.screenshot({
|
|
fullPage: true,
|
|
path: path.join(proofDir, "preserved-nvidia-model-alias.png"),
|
|
});
|
|
}
|
|
} finally {
|
|
await suite.closeBrowserContext(context);
|
|
}
|
|
});
|
|
|
|
it("uses the same versioned catalog labels in the Agents model picker", async () => {
|
|
const context = await createProofContext();
|
|
const page = await context.newPage();
|
|
const config = {
|
|
agents: {
|
|
defaults: {
|
|
model: { primary: "anthropic/claude-opus-4-8" },
|
|
models: {
|
|
"anthropic/claude-opus-4-8": { alias: "opus" },
|
|
"anthropic/claude-sonnet-5": { alias: "sonnet" },
|
|
"nvidia/moonshotai/kimi-k2.5": { alias: "Kimi K2.5 (NVIDIA)" },
|
|
},
|
|
},
|
|
list: [{ id: "main" }],
|
|
},
|
|
};
|
|
const gateway = await installMockGateway(page, {
|
|
defaultAgentId: "main",
|
|
models,
|
|
methodResponses: {
|
|
"agents.list": {
|
|
agents: [{ id: "main", identity: { name: "Main" }, name: "Main" }],
|
|
defaultId: "main",
|
|
mainKey: "main",
|
|
scope: "agent",
|
|
},
|
|
"config.get": {
|
|
config,
|
|
sourceConfig: config,
|
|
hash: "versioned-model-aliases",
|
|
issues: [],
|
|
raw: JSON.stringify(config),
|
|
valid: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
try {
|
|
const response = await page.goto(`${suite.server.baseUrl}settings/agents/main/overview`);
|
|
expect(response?.status()).toBe(200);
|
|
await gateway.waitForRequest("agents.list");
|
|
await gateway.waitForRequest("config.get");
|
|
const modelRequest = await gateway.waitForRequest("chat.metadata");
|
|
expect(modelRequest.params).toEqual({ agentId: "main" });
|
|
expect(await gateway.getRequests("models.list")).toHaveLength(0);
|
|
|
|
const select = page.locator("select.settings-select").first();
|
|
await select.waitFor({ state: "visible", timeout: 10_000 });
|
|
await expect
|
|
.poll(() => select.locator('option[value="anthropic/claude-opus-4-8"]').textContent())
|
|
.toContain("Opus 4.8 · opus");
|
|
await expect
|
|
.poll(() => select.locator('option[value="anthropic/claude-sonnet-5"]').textContent())
|
|
.toContain("Sonnet 5 · sonnet");
|
|
await expect
|
|
.poll(() => select.locator('option[value="nvidia/moonshotai/kimi-k2.5"]').textContent())
|
|
.toContain("Kimi K2.5 (NVIDIA)");
|
|
expect(await gateway.getRequests("config.set")).toHaveLength(0);
|
|
|
|
if (proofDir) {
|
|
await page.screenshot({
|
|
fullPage: true,
|
|
path: path.join(proofDir, "agents-versioned-model-aliases.png"),
|
|
});
|
|
}
|
|
} finally {
|
|
await suite.closeBrowserContext(context);
|
|
}
|
|
});
|
|
});
|