feat: complete TASK-WP3-02 runtime recommendation

This commit is contained in:
suyx
2026-08-03 03:00:12 +08:00
parent d79ac74fdd
commit 827ae912e0
12 changed files with 627 additions and 203 deletions
+42
View File
@@ -53,6 +53,18 @@ function configuration(version = 1) {
};
}
function runtimeConfiguration() {
const result = configuration();
result.recommended_model_id = "gemini-3-pro-image-preview";
result.models[0].contract_validation_status = "verified";
result.models[1].contract_validation_status = "verified";
result.models[2].contract_validation_status = "verified";
result.models[0].runtime_availability = { available_for_new_jobs: false, checked_at: "2026-08-02T15:00:00.000Z", reason: "gateway_balance_insufficient" };
result.models[1].runtime_availability = { available_for_new_jobs: true, checked_at: "2026-08-02T15:00:00.000Z", reason: "available" };
result.models[2].runtime_availability = { available_for_new_jobs: false, checked_at: "2026-08-02T15:00:00.000Z", reason: "worker_degraded" };
return result;
}
async function routeBase(page: Page) {
await page.route("**/api/v1/admin-auth/session", (route) => route.fulfill({ body: JSON.stringify(adminSession), contentType: "application/json", status: 200 }));
}
@@ -109,3 +121,33 @@ test("TDD-WP3-MDL-002-cas-conflict blocks saving until the complete set is refre
await expect(page.getByRole("button", { name: "保存完整配置集合" })).toBeDisabled();
await expect(page.getByRole("button", { name: "刷新最新配置" })).toBeVisible();
});
test("TDD-WP3-MDL-003 keeps configured default, runtime and recommendation independent", async ({ page }) => {
await routeBase(page);
let recovered = false;
await page.route("**/api/v1/models", (route) => route.fulfill({ body: JSON.stringify(recovered ? {
...runtimeConfiguration(),
recommended_model_id: "gemini-3.1-flash-image-preview",
models: runtimeConfiguration().models.map((model) => ({ ...model, runtime_availability: { available_for_new_jobs: true, checked_at: "2026-08-02T15:01:00.000Z", reason: "available" } })),
} : runtimeConfiguration()), contentType: "application/json", status: 200 }));
await page.goto(`${webUrl}/admin/models`);
await expect(page.getByText("配置默认").locator("..").getByText("gemini-3.1-flash-image-preview", { exact: true })).toBeVisible();
await expect(page.getByText("当前推荐").locator("..").getByText("gemini-3-pro-image-preview", { exact: true })).toBeVisible();
await expect(page.getByText("不可用 · gateway_balance_insufficient")).toBeVisible();
await expect(page.getByText("可用于新任务")).toBeVisible();
await expect(page.locator("tbody tr").nth(1).getByText("是", { exact: true })).toBeVisible();
const evidenceRoot = process.env.DADA_EVIDENCE_DIR_RUNTIME;
if (evidenceRoot) {
const directory = resolve(evidenceRoot, "TDD-WP3-MDL-003-runtime-recommendation", "screenshots");
mkdirSync(directory, { recursive: true });
await page.screenshot({ fullPage: true, path: resolve(directory, "model-states.png") });
}
recovered = true;
await page.reload();
await expect(page.locator(".admin-models-summary").getByText("gemini-3.1-flash-image-preview", { exact: true }).last()).toBeVisible();
if (evidenceRoot) {
const directory = resolve(evidenceRoot, "TDD-WP3-BAL-001-confirmed-recovery", "screenshots");
mkdirSync(directory, { recursive: true });
await page.screenshot({ fullPage: true, path: resolve(directory, "recovery.png") });
}
});