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:
@@ -1,3 +1,4 @@
|
||||
import { responsesFixture } from "./support/responses-fixture";
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { mockAgentApi } from "./support/mock-agent-api";
|
||||
import { mockWorkbenchContext } from "./support/mock-workbench-context";
|
||||
@@ -99,7 +100,7 @@ for (const width of [1440, 375, 320]) {
|
||||
data: { content: "仍需用户补充现场核验资料。", ui_block_ids: ["pressure"] }
|
||||
}
|
||||
];
|
||||
await page.route("**/api/v1/agent/chat/session/browser-session-1", async (route) => {
|
||||
await page.route("**/api/v1/session/browser-session-1", async (route) => {
|
||||
if (route.request().method() !== "GET") return route.fallback();
|
||||
await route.fulfill({
|
||||
headers: { "Access-Control-Allow-Origin": "*" },
|
||||
@@ -121,16 +122,16 @@ for (const width of [1440, 375, 320]) {
|
||||
});
|
||||
});
|
||||
const prompts: string[] = [];
|
||||
await page.route("**/api/v1/agent/chat/stream", async (route) => {
|
||||
await page.route("**/api/v1/responses", async (route) => {
|
||||
if (route.request().method() === "OPTIONS") return route.fallback();
|
||||
const body = route.request().postDataJSON() as {
|
||||
messages: Array<{ role: string; parts: Array<{ type: string; text?: string }> }>;
|
||||
input: Array<{ role: string; content: Array<{ type: string; text?: string }> }>;
|
||||
};
|
||||
const text =
|
||||
body.messages
|
||||
body.input
|
||||
.filter((m) => m.role === "user")
|
||||
.at(-1)
|
||||
?.parts.filter((p) => p.type === "text")
|
||||
?.content.filter((p) => p.type === "input_text")
|
||||
.map((p) => p.text)
|
||||
.join("") ?? "";
|
||||
prompts.push(text);
|
||||
@@ -160,9 +161,9 @@ for (const width of [1440, 375, 320]) {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Content-Type": "text/event-stream",
|
||||
"X-Vercel-AI-UI-Message-Stream": "v1"
|
||||
"Cache-Control": "no-cache"
|
||||
},
|
||||
body: chunks.map((chunk) => `data: ${JSON.stringify(chunk)}\n\n`).join("")
|
||||
body: responsesFixture(chunks)
|
||||
});
|
||||
});
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
|
||||
Reference in New Issue
Block a user