Files
next-tjwater-frontend/src/features/agent/api/agent-messages.test.ts
T
jiang ec23d44b02 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.
2026-10-19 18:46:58 +08:00

34 lines
2.1 KiB
TypeScript

import { afterEach, expect, it, vi } from "vitest";
import { createAgentApiClient } from "./client";
afterEach(() => vi.unstubAllGlobals());
it("reads mailbox pages without sending or consuming messages and validates the contract", async () => {
const message = { message_id: "m1", task_id: "t1", run_id: "r1", source_session_id: "task-session", target_session_id: "chat-session", direction: "to_chat", text: "现场记录已核对", status: "pending", in_reply_to: null, created_at: "2026-10-13T00:00:00Z", source_owner_id: "private-owner" };
const fetchMock = vi.fn().mockResolvedValue(Response.json({ items: [message], next_cursor: "m1" }));
vi.stubGlobal("fetch", fetchMock);
const client = createAgentApiClient("http://agent.local", { getAccessToken: async () => "token", getProjectId: async () => "p1" });
const page = await client.listAgentMessages("chat-session", { cursor: "previous" });
expect(page.items[0]).not.toHaveProperty("source_owner_id");
const [url, init] = fetchMock.mock.calls[0];
expect(url).toBe("http://agent.local/api/v1/session/chat-session/agent-messages?limit=50&cursor=previous");
expect(init.method).toBeUndefined();
expect(init.body).toBeUndefined();
expect(new Headers(init.headers).get("X-Project-Id")).toBe("p1");
fetchMock.mockResolvedValue(Response.json({ items: [{ ...message, target_session_id: null, direction: "to_task" }], next_cursor: null }));
expect((await client.listAgentMessages("chat-session")).items[0].target_session_id).toBeNull();
fetchMock.mockResolvedValue(Response.json({ items: [{ ...message, status: "invented" }], next_cursor: null }));
await expect(client.listAgentMessages("chat-session")).rejects.toThrow();
});
it("accepts inbox notifications only for the subscribed session", async () => {
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(new Response([
'event: agent_message\ndata: {"session_id":"other"}\n\n',
'event: agent_message\ndata: {"session_id":"main"}\n\n',
': heartbeat\n\n'
].join(""))));
const onMessage = vi.fn();
await createAgentApiClient("http://agent.local").streamAgentMessages("main", { onMessage });
expect(onMessage).toHaveBeenCalledOnce();
});