feat(agent): support Responses steering and project-aware tools

Use the dedicated TJWATER_AGENT_URL and Responses stream protocol. Keep running
turns active while users steer or queue follow-ups and edit pending delivery.
Refresh the model catalog before generation and preserve approval mode selection.

Integrate scoped investigation messaging/presentation, geographic place selection,
current Agent composer styles and supporting workbench contracts.

Validation: 77 focused Vitest checks, 21 browser cases, lint, typecheck and
production build. Preserve direct Server/Agent routing and project authentication.
This commit is contained in:
2026-10-19 18:46:58 +08:00
parent 2c5bf15cce
commit ec23d44b02
131 changed files with 6663 additions and 1204 deletions
@@ -1,6 +1,31 @@
import { expect, test, type Locator, type Page } from "@playwright/test";
import { mockFlatWorkOrder } from "./support/mock-hierarchical-work-order";
test("keeps the open scheduled report when the rolling history refreshes", async ({ page }) => {
await page.clock.install({ time: new Date("2026-09-24T09:20:53Z") });
await page.goto("/", { waitUntil: "domcontentloaded" });
await openConditionFeed(page);
const panel = page.getByRole("region", { name: "工况任务", exact: true });
await panel.getByRole("button", { name: "展开工况任务" }).click();
const rows = panel.getByTestId("scheduled-condition-timeline").locator("button[aria-pressed]");
const oldestReport = rows.last();
const reportTitle = await oldestReport.textContent();
expect(reportTitle).toContain("11:20SCADA 数据诊断");
await oldestReport.click();
await expect(oldestReport).toHaveAttribute("aria-pressed", "true");
await page.clock.runFor(12_000);
await expect(rows.filter({ hasText: reportTitle ?? "" })).toHaveAttribute("aria-pressed", "true");
await expect(panel.getByTestId("scheduled-condition-detail-scroll"))
.toContainText("11:20 的SCADA 数据诊断");
await panel.getByRole("button", { name: /预约任务/ }).click();
await panel.getByRole("button", { name: /定时任务/ }).click();
await expect(rows.filter({ hasText: reportTitle ?? "" })).toHaveCount(0);
});
test("scheduled conditions keep acrylic blur outside transformed ancestors", async ({ page }) => {
await page.goto("/", { waitUntil: "domcontentloaded" });
await openConditionFeed(page);