| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import { describe, expect, it } from "vitest";
- import {
- AutomationModeSchema,
- InteractionIntentTypeSchema,
- ExecutionStatusSchema,
- InteractionSessionSchema,
- bindActiveBook,
- clearPendingDecision,
- isTerminalExecutionStatus,
- appendInteractionMessage,
- appendInteractionEvent,
- } from "../index.js";
- describe("interaction models", () => {
- it("parses supported automation modes", () => {
- expect(AutomationModeSchema.parse("auto")).toBe("auto");
- expect(AutomationModeSchema.parse("semi")).toBe("semi");
- expect(AutomationModeSchema.parse("manual")).toBe("manual");
- });
- it("parses supported interaction intents", () => {
- expect(InteractionIntentTypeSchema.parse("create_book")).toBe("create_book");
- expect(InteractionIntentTypeSchema.parse("write_next")).toBe("write_next");
- expect(InteractionIntentTypeSchema.parse("rewrite_chapter")).toBe("rewrite_chapter");
- expect(InteractionIntentTypeSchema.parse("explain_failure")).toBe("explain_failure");
- });
- it("recognizes terminal execution statuses", () => {
- expect(isTerminalExecutionStatus(ExecutionStatusSchema.parse("completed"))).toBe(true);
- expect(isTerminalExecutionStatus(ExecutionStatusSchema.parse("failed"))).toBe(true);
- expect(isTerminalExecutionStatus(ExecutionStatusSchema.parse("idle"))).toBe(false);
- expect(isTerminalExecutionStatus(ExecutionStatusSchema.parse("writing"))).toBe(false);
- });
- it("binds the active book without disturbing unrelated session fields", () => {
- const session = InteractionSessionSchema.parse({
- sessionId: "session-1",
- projectRoot: "/tmp/project",
- automationMode: "semi",
- messages: [],
- pendingDecision: {
- kind: "approve-chapter",
- bookId: "book-a",
- chapterNumber: 3,
- summary: "Chapter 3 is waiting for review.",
- },
- currentExecution: {
- status: "waiting_human",
- bookId: "book-a",
- chapterNumber: 3,
- stageLabel: "waiting for approval",
- },
- });
- expect(bindActiveBook(session, "book-b")).toEqual({
- ...session,
- activeBookId: "book-b",
- });
- });
- it("clears pending decisions while keeping the rest of the session intact", () => {
- const session = InteractionSessionSchema.parse({
- sessionId: "session-2",
- projectRoot: "/tmp/project",
- activeBookId: "book-a",
- automationMode: "auto",
- messages: [],
- pendingDecision: {
- kind: "choose-repair-mode",
- bookId: "book-a",
- chapterNumber: 8,
- summary: "Choose whether to local-fix or rewrite chapter 8.",
- },
- });
- expect(clearPendingDecision(session)).toEqual({
- ...session,
- pendingDecision: undefined,
- });
- });
- it("appends interaction messages in timestamp order", () => {
- const session = InteractionSessionSchema.parse({
- sessionId: "session-3",
- projectRoot: "/tmp/project",
- automationMode: "semi",
- messages: [],
- });
- const next = appendInteractionMessage(session, {
- role: "user",
- content: "continue",
- timestamp: 1,
- });
- expect(next.messages).toEqual([{
- role: "user",
- content: "continue",
- timestamp: 1,
- }]);
- });
- it("appends interaction events in timestamp order", () => {
- const session = InteractionSessionSchema.parse({
- sessionId: "session-4",
- projectRoot: "/tmp/project",
- automationMode: "semi",
- messages: [],
- events: [],
- });
- const next = appendInteractionEvent(session, {
- kind: "task.completed",
- timestamp: 2,
- status: "completed",
- bookId: "harbor",
- detail: "Completed write_next for harbor.",
- });
- expect(next.events).toEqual([{
- kind: "task.completed",
- timestamp: 2,
- status: "completed",
- bookId: "harbor",
- detail: "Completed write_next for harbor.",
- }]);
- });
- });
|