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.
34 lines
2.1 KiB
TypeScript
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();
|
|
});
|