refactor: consolidate requests and finalize agent tool states

Share project JSON transport, interaction replies and report selectors.
Settle tool progress consistently for direct streams, reconnects and history, preserving failure reasons and stopped state.
This commit is contained in:
2026-11-09 17:55:00 +08:00
parent ad1f7ca7a9
commit 692bbf609c
38 changed files with 605 additions and 280 deletions
@@ -0,0 +1,25 @@
import { expect, it, vi } from "vitest";
import type { AgentQuestionRequest } from "@/features/agent";
import { createAgentInteractionReplies } from "./agent-interaction-replies";
import type { AgentSessionRuntime } from "./agent-session-runtime";
import { WorkbenchSessionResources } from "./workbench-session-resources";
it("keeps a reply bound to its original session when the user switches conversations", async () => {
let resolve: () => void = () => {};
const request = vi.fn(() => new Promise<void>((done) => { resolve = done; }));
const original = { sessionId: "original", client: { replyQuestion: request }, questionOverrides: {} } as unknown as AgentSessionRuntime;
const next = { sessionId: "next", questionOverrides: {} } as AgentSessionRuntime;
const resources = new WorkbenchSessionResources(); resources.activeAgent = original;
const setters = { permission: vi.fn(), question: vi.fn() };
const replies = createAgentInteractionReplies(resources, setters);
const question = { sessionId: "original", requestId: "question" } as AgentQuestionRequest;
const submitted = replies.replyQuestion(question, [["A"]]);
expect(original.questionOverrides.question.status).toBe("submitting");
resources.activeAgent = next; setters.question.mockClear();
resolve(); await submitted;
expect(original.questionOverrides.question).toEqual({ status: "answered", answers: [["A"]] });
expect(next.questionOverrides).toEqual({});
expect(setters.question).not.toHaveBeenCalled();
await replies.replyQuestion(question, [["B"]]);
expect(request).toHaveBeenCalledTimes(1);
});