murashit_codex-panel/tests/features/chat/app-server/thread-reference-resolver.test.ts

81 lines
2.8 KiB
TypeScript
Raw Normal View History

import { describe, expect, it, vi } from "vitest";
import type { AppServerClient } from "../../../../src/app-server/connection/client";
import type { CodexInput } from "../../../../src/domain/chat/input";
import { createThreadReferenceResolver } from "../../../../src/features/chat/app-server/thread-reference-resolver";
const textInput = (text: string): CodexInput => [{ type: "text", text }];
describe("thread reference resolver", () => {
it("reads referenced history and prepares one bundled input", async () => {
const request = vi.fn().mockResolvedValue({
data: [
{
id: "turn",
itemsView: "full",
status: "completed",
error: null,
startedAt: null,
completedAt: null,
durationMs: null,
items: [
{ type: "userMessage", id: "u1", clientId: null, content: [{ type: "text", text: "元の依頼", text_elements: [] }] },
{ type: "agentMessage", id: "a1", text: "回答", phase: "final_answer", memoryCitation: null },
],
},
],
nextCursor: null,
});
const client = { request } as unknown as AppServerClient;
const setStatus = vi.fn();
const inputSnapshot = { sourcePath: "snapshot.md" } as never;
const prepareInput = vi.fn((text: string) => ({ text, input: textInput(text) }));
const resolver = createThreadReferenceResolver({
currentClient: () => client,
prepareInput,
addSystemMessage: vi.fn(),
setStatus,
});
const result = await resolver.referThread(
{
id: "019abcde-0000-7000-8000-000000000001",
preview: "",
name: "Other",
createdAt: 1,
updatedAt: 1,
archived: false,
provenance: { kind: "interactive" },
},
"summarize",
inputSnapshot,
);
expect(request).toHaveBeenCalledWith("thread/turns/list", {
threadId: "019abcde-0000-7000-8000-000000000001",
cursor: null,
limit: 20,
sortDirection: "desc",
itemsView: "full",
});
expect(result?.input[0]).toEqual({ type: "text", text: "summarize" });
expect(result?.input[1]).toMatchObject({
type: "additionalContext",
kind: "untrusted",
value: expect.stringContaining("Referenced thread context for the current user input:"),
attachment: {
kind: "referencedThread",
threadId: "019abcde-0000-7000-8000-000000000001",
includedTurns: 1,
turnLimit: 20,
omittedTurns: 0,
truncated: false,
},
});
expect(result?.text).toBe("summarize");
expect(prepareInput).toHaveBeenCalledWith("summarize", inputSnapshot);
expect(result?.referencedThread).toMatchObject({ title: "Other", includedTurns: 1, turnLimit: 20 });
expect(setStatus).toHaveBeenCalledWith("Referencing 019abcde (1/20 turns).");
});
});