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
@@ -0,0 +1,23 @@
import { describe, expect, it } from "vitest";
import { collectRecentAgentActivities } from "./use-agent-prompt-suggestions";
import type { AgentChatSessionSummary } from "@/features/agent";
describe("recent activities for Agent suggestions", () => {
it("uses updated ordinary conversations, excludes stale/private task sessions, and preserves real versus demo origins", () => {
const now = Date.parse("2026-10-09T08:00:00Z");
const session = (id: string, updatedAt: number, purpose: AgentChatSessionSummary["purpose"]): AgentChatSessionSummary => ({
id, title: id, purpose, createdAt: now - 10 * 24 * 60 * 60_000, updatedAt,
});
const activities = collectRecentAgentActivities({
alerts: [
{ id: "demo", title: "演示压力告警", description: "演示", time: "15:00", occurredAt: "2026-10-09T07:00:00Z" },
{ id: "operational-task-notification:real", title: "现场核查待办", description: "真实后台任务", time: "15:05", occurredAt: "2026-10-09T07:05:00Z" },
],
alertDataSource: "mock", conditions: [], runtimeDataSource: "mock", artifact: null,
sessions: [session("updated-old-conversation", now - 60_000, "ordinary_chat"), session("stale", now - 8 * 24 * 60 * 60_000, "ordinary_chat"), session("task-private", now, "task_collaboration")],
}, now);
expect(activities.find((item) => item.id === "alert:demo")?.origin).toBe("demo");
expect(activities.find((item) => item.id === "alert:operational-task-notification:real")?.origin).toBe("backend");
expect(activities.filter((item) => item.kind === "session").map((item) => item.title)).toEqual(["updated-old-conversation"]);
});
});