feat: add project-aware agent workspace
Generic Container CI/CD / test-build-publish (push) Successful in 2m9s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 2m39s

This commit is contained in:
2026-10-22 18:52:18 +08:00
parent c6a0e74e72
commit 2d8506fea0
191 changed files with 12373 additions and 3556 deletions
+34 -3
View File
@@ -2,16 +2,45 @@ import { afterEach, describe, expect, it, vi } from "vitest";
import { createAgentApiClient } from "./client";
describe("Agent prompt suggestions", () => {
it("uses owned topic endpoints and retains full-text hits from another topic", async () => {
const topic = { id: "topic-a", name: "城南压力问题", createdAt: "2026-10-22T01:00:00Z", updatedAt: "2026-10-22T01:00:00Z" };
const fetchMock = vi.fn()
.mockResolvedValueOnce(Response.json({ topics: [topic] }))
.mockResolvedValueOnce(Response.json({ sessions: [{ id: "session-b", title: "另一段对话", topic_id: "topic-b", topic_name: "检修事件", search_snippet: "正文中的南桥阀门", purpose: "task_collaboration" }], has_more: false }))
.mockResolvedValueOnce(Response.json({ session_id: "session-b", topic_id: "topic-a" }))
.mockResolvedValueOnce(new Response(null, { status: 204 }));
vi.stubGlobal("fetch", fetchMock);
const client = createAgentApiClient("http://agent.local", { getAccessToken: async () => "token", getProjectId: async () => "project-a" });
expect(await client.listTopics()).toEqual([topic]);
const result = await client.listSessionPage({ q: "南桥阀门", includeCollaboration: true });
expect(result.sessions[0]).toMatchObject({ title: "另一段对话", topicId: "topic-b", topicName: "检修事件", searchSnippet: "正文中的南桥阀门", purpose: "task_collaboration" });
const query = new URL(String(fetchMock.mock.calls[1]?.[0])).searchParams;
expect(query.get("q")).toBe("南桥阀门");
expect(query.has("topic_id")).toBe(false);
expect(query.get("include_collaboration")).toBe("true");
await client.moveSessionToTopic("session-b", "topic-a");
expect(JSON.parse(String(fetchMock.mock.calls[2]?.[1]?.body))).toEqual({ topic_id: "topic-a" });
await client.deleteTopic("topic-a");
expect(String(fetchMock.mock.calls[3]?.[0])).toContain("/topics/topic-a");
for (const [, init] of fetchMock.mock.calls) {
expect(new Headers(init?.headers).get("Authorization")).toBe("Bearer token");
expect(new Headers(init?.headers).get("X-Project-Id")).toBe("project-a");
}
});
it("submits and edits pending input through the scoped Responses and session endpoints", async () => {
const input = { id: `msg_${"1".repeat(32)}`, text: "补充压力测点", delivery: "steer", status: "pending" };
const fetchMock = vi.fn().mockResolvedValueOnce(Response.json(input)).mockResolvedValueOnce(Response.json({ items: [input] }))
.mockResolvedValueOnce(Response.json({ ...input, delivery: "queue" }));
.mockResolvedValueOnce(Response.json({ ...input, delivery: "queue" }))
.mockResolvedValueOnce(Response.json({ ...input, status: "cancelled" }));
vi.stubGlobal("fetch", fetchMock);
const client = createAgentApiClient("http://agent.local", { getAccessToken: async () => "token", getProjectId: async () => "project" });
await expect(client.submitResponseInput("session-1", input.text, "steer", input.id)).resolves.toEqual(input);
expect(JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body))).toEqual({ input: input.text, conversation: "session-1", stream: false, tjwater: { delivery: "steer", input_id: input.id } });
await expect(client.listResponseInputs("session-1")).resolves.toEqual([input]);
await expect(client.updateResponseInput("session-1", input.id, "queue")).resolves.toEqual({ ...input, delivery: "queue" });
await expect(client.cancelResponseInput("session-1", input.id)).resolves.toEqual({ ...input, status: "cancelled" });
expect(fetchMock.mock.calls[3]?.[1]?.method).toBe("DELETE");
expect(String(fetchMock.mock.calls[0]?.[0])).toBe("http://agent.local/api/v1/responses");
expect(String(fetchMock.mock.calls[2]?.[0])).toContain(`/api/v1/session/session-1/inputs/${input.id}`);
for (const [, request] of fetchMock.mock.calls) {
@@ -83,7 +112,8 @@ describe("Agent API client sessions", () => {
runStatus: "running",
purpose: "ordinary_chat",
taskId: undefined,
trigger: undefined
trigger: undefined,
topicId: null, topicName: undefined, searchSnippet: undefined
},
{
id: "old",
@@ -96,7 +126,8 @@ describe("Agent API client sessions", () => {
runStatus: undefined,
purpose: "ordinary_chat",
taskId: undefined,
trigger: undefined
trigger: undefined,
topicId: null, topicName: undefined, searchSnippet: undefined
}
]);
});