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
+5 -13
View File
@@ -173,6 +173,7 @@ test("assigned desktop panels avoid native form controls and horizontal overflow
const devPanel = page.getByRole("complementary", { name: "地图开发面板" });
await expectContained(devPanel, 1280);
await expect(devPanel.locator("select")).toHaveCount(0);
await devPanel.locator("summary").filter({ hasText: "图层样式" }).click();
const layerGroup = devPanel.getByRole("combobox", { name: "业务图层组" });
await layerGroup.focus();
await layerGroup.press("Enter");
@@ -199,18 +200,9 @@ for (const width of [375, 320]) {
await page.getByRole("button", { name: "打开 Agent 面板" }).click();
const agentSheet = page.getByRole("region", { name: "Agent 工作台抽屉" });
await expectContained(agentSheet, width);
const welcomeTitle = agentSheet.getByRole("heading", { name: "我已就绪,请描述任务" });
await expect(welcomeTitle).toBeVisible();
const [welcomeBox, conversationBox] = await Promise.all([
welcomeTitle.boundingBox(),
agentSheet.getByRole("log").boundingBox()
]);
expect(welcomeBox).not.toBeNull();
expect(conversationBox).not.toBeNull();
expect(welcomeBox!.y).toBeGreaterThanOrEqual(conversationBox!.y);
expect(welcomeBox!.y + welcomeBox!.height).toBeLessThanOrEqual(
conversationBox!.y + conversationBox!.height
);
await expect(agentSheet.getByRole("heading", { name: "我已就绪,请描述任务" })).toHaveCount(0);
await expect(agentSheet.getByRole("log")).toBeVisible();
await expect(agentSheet.getByRole("textbox")).toBeVisible();
await expect(page.locator("[data-sonner-toast]")).toHaveCount(0, { timeout: 15_000 });
await page.screenshot({
path: `test-results/non-map-panels/${width}-agent.png`,
@@ -364,7 +356,7 @@ async function prepareWorkbench(page: Page) {
TJWATER_MAP_URL: "https://non-map-panels.invalid/geoserver",
TJWATER_GEOSERVER_WORKSPACE: "tjwater_next",
TJWATER_SERVER_API_BASE_URL: "https://tjwater-api.invalid",
TJWATER_AGENT_API_BASE_URL: "http://127.0.0.1:8787",
TJWATER_AGENT_URL: "http://127.0.0.1:8787",
TJWATER_ENABLE_DEV_PANEL: "true",
TJWATER_ENABLE_MSW: "false"
})}`