Files
fusion/packages/engine/src/__tests__/agent-user-comments.test.ts
gsxdsm cb57093d03 refactor: domain folder layout (types, API, core, engine) (#2398)
## Summary

Wave 17 organizes Fusion into **domain folders** (stacks on #2397).

### Layout
- **core/types/** — board, task, agents, settings, merge, workflow,
mesh, …
- **core/src/** — agents, ai, async-stores, workflows, tasks, config,
db, …
- **dashboard/app/api/** — client, tasks, agents, git, missions,
planning, …
- **engine/src/** — agents, auth, execution, merge, missions, overseer,
worktree, …

Root keepers retained for large entrypoints (`store.ts`, `executor.ts`,
`merger.ts`, …).

Public barrels (`@fusion/core`, `@fusion/engine`, `app/api.ts` → legacy)
stay stable.

## Test plan
- [x] `@fusion/core` typecheck
- [x] `@fusion/engine` typecheck (pre-existing playwright-core noise
only)
- [ ] CI merge gate

**Stack:** #2394 → #2397 → **this PR**
2026-08-03 00:20:53 -07:00

137 lines
5.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { TaskComment } from "@fusion/core";
import { buildUserCommentsPromptSection, selectUserCommentsForAgentContext } from "../agents/agent-user-comments.js";
function comment(overrides: Partial<TaskComment>): TaskComment {
return {
id: overrides.id ?? "c1",
text: overrides.text ?? "Please keep the old API export",
author: overrides.author ?? "user",
createdAt: overrides.createdAt ?? "2026-06-21T10:00:00.000Z",
updatedAt: overrides.updatedAt,
};
}
describe("agent user comments prompt helper", () => {
it("returns no comments and no section for undefined comments", () => {
const selected = selectUserCommentsForAgentContext({});
expect(selected).toEqual([]);
expect(buildUserCommentsPromptSection(selected)).toBe("");
});
it("returns no comments and no section for an empty comment array", () => {
const selected = selectUserCommentsForAgentContext({ comments: [] });
expect(selected).toEqual([]);
expect(buildUserCommentsPromptSection(selected)).toBe("");
});
it("filters out agent-authored comments", () => {
const selected = selectUserCommentsForAgentContext({
comments: [comment({ id: "agent-1", author: "agent", text: "internal note" })],
});
expect(selected).toEqual([]);
expect(buildUserCommentsPromptSection(selected)).toBe("");
});
it("formats populated user comments with author, timestamp, and text", () => {
const selected = selectUserCommentsForAgentContext({
comments: [comment({ id: "user-1", text: "Please keep the old API export", createdAt: "2026-06-21T12:34:00.000Z" })],
});
const section = buildUserCommentsPromptSection(selected);
expect(section).toContain("## User Comments");
expect(section).toContain("**user** — 2026-06-21T12:34:00.000Z");
expect(section).toContain("> Please keep the old API export");
});
it("selects user-authored legacy steering comments alongside unified comments", () => {
const selected = selectUserCommentsForAgentContext({
comments: [comment({ id: "c-user", text: "Unified user requirement", createdAt: "2026-06-21T10:00:00.000Z" })],
steeringComments: [
{ id: "s-user", text: "Legacy steering requirement", author: "user", createdAt: "2026-06-21T10:05:00.000Z" },
{ id: "s-agent", text: "agent-only steering", author: "agent", createdAt: "2026-06-21T10:06:00.000Z" },
],
});
expect(selected.map((c) => c.id)).toEqual(["c-user", "s-user"]);
const section = buildUserCommentsPromptSection(selected);
expect(section).toContain("Unified user requirement");
expect(section).toContain("Legacy steering requirement");
expect(section).not.toContain("agent-only steering");
});
it("dedupes duplicate ids across unified comments and legacy steering comments", () => {
const selected = selectUserCommentsForAgentContext({
comments: [comment({ id: "dup", text: "unified duplicate", createdAt: "2026-06-21T10:00:00.000Z" })],
steeringComments: [
{ id: "dup", text: "steering duplicate wins", author: "user", createdAt: "2026-06-21T11:00:00.000Z" },
],
});
const section = buildUserCommentsPromptSection(selected);
expect(selected).toHaveLength(1);
expect(section).toContain("steering duplicate wins");
expect(section).not.toContain("unified duplicate");
});
it("preserves multiline text when formatting selected comments and steering", () => {
const selected = selectUserCommentsForAgentContext({
steeringComments: [
{ id: "s-multiline", text: "Line one\nLine two", author: "user", createdAt: "2026-06-21T10:00:00.000Z" },
],
});
expect(buildUserCommentsPromptSection(selected)).toContain("> Line one\n> Line two");
});
it("caps a large mixed history to the requested newest comments in chronological order", () => {
const comments = Array.from({ length: 15 }, (_, index) => comment({
id: `user-${index}`,
text: `comment ${index}`,
createdAt: `2026-06-21T10:${String(index).padStart(2, "0")}:00.000Z`,
}));
const steeringComments = Array.from({ length: 15 }, (_, index) => ({
id: `steer-${index}`,
text: `steering ${index}`,
author: "user" as const,
createdAt: `2026-06-21T11:${String(index).padStart(2, "0")}:00.000Z`,
}));
const selected = selectUserCommentsForAgentContext({ comments, steeringComments }, { limit: 3 });
const section = buildUserCommentsPromptSection(selected);
expect(selected.map((c) => c.id)).toEqual(["steer-12", "steer-13", "steer-14"]);
expect(section).not.toContain("steering 11");
expect(section.indexOf("steering 12")).toBeLessThan(section.indexOf("steering 13"));
expect(section.indexOf("steering 13")).toBeLessThan(section.indexOf("steering 14"));
});
it("returns all user comments and steering entries when reviewer callers request uncapped context", () => {
const comments = Array.from({ length: 15 }, (_, index) => comment({
id: `user-${index}`,
text: `comment ${index}`,
createdAt: `2026-06-21T10:${String(index).padStart(2, "0")}:00.000Z`,
}));
const steeringComments = Array.from({ length: 15 }, (_, index) => ({
id: `steer-${index}`,
text: `steering ${index}`,
author: "user" as const,
createdAt: `2026-06-21T11:${String(index).padStart(2, "0")}:00.000Z`,
}));
const selected = selectUserCommentsForAgentContext({ comments, steeringComments }, { limit: null });
const section = buildUserCommentsPromptSection(selected);
expect(selected).toHaveLength(30);
expect(selected[0]?.id).toBe("user-0");
expect(selected.at(-1)?.id).toBe("steer-14");
expect(section).toContain("comment 0");
expect(section).toContain("steering 14");
});
});