import { expect, it } from "@effect/vitest"; import { CommandId, NodeId, type OrchestrationV2Command, ProjectId, ProviderInstanceId, RunId, ThreadId, } from "@t3tools/contracts"; import { existingThreadIdsForCommand, withCreationProvenance } from "./ThreadManagementService.ts"; it("stamps authoritative provenance on commands that create threads or messages", () => { const command: OrchestrationV2Command = { type: "thread.create", createdBy: "agent", creationSource: "mcp", commandId: CommandId.make("command:thread-management:create"), threadId: ThreadId.make("thread:thread-management:create"), projectId: ProjectId.make("project:thread-management"), title: "Thread management", modelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, }; expect( withCreationProvenance(command, { createdBy: "user", creationSource: "web", }), ).toMatchObject({ createdBy: "user", creationSource: "web", }); }); it("leaves commands that do not create durable authored content unchanged", () => { const command: OrchestrationV2Command = { type: "run.interrupt", commandId: CommandId.make("command:thread-management:interrupt"), threadId: ThreadId.make("thread:thread-management:interrupt"), runId: RunId.make("run:thread-management:interrupt"), }; expect( withCreationProvenance(command, { createdBy: "user", creationSource: "web", }), ).toBe(command); }); it("identifies every existing thread that must be hydrated before dispatch", () => { const sourceThreadId = ThreadId.make("thread:thread-management:source"); const targetThreadId = ThreadId.make("thread:thread-management:target"); const parentThreadId = ThreadId.make("thread:thread-management:parent"); expect( existingThreadIdsForCommand({ type: "thread.create", createdBy: "user", creationSource: "web", commandId: CommandId.make("command:thread-management:create"), threadId: targetThreadId, projectId: ProjectId.make("project:thread-management"), title: "Created thread", modelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, }), ).toEqual([]); expect( existingThreadIdsForCommand({ type: "thread.archive", commandId: CommandId.make("command:thread-management:archive"), threadId: targetThreadId, }), ).toEqual([targetThreadId]); expect( existingThreadIdsForCommand({ type: "thread.fork", createdBy: "user", creationSource: "web", commandId: CommandId.make("command:thread-management:fork"), sourceThreadId, targetThreadId, sourcePoint: { type: "run", runId: RunId.make("run:thread-management:source"), }, }), ).toEqual([sourceThreadId]); expect( existingThreadIdsForCommand({ type: "thread.merge_back", createdBy: "user", creationSource: "web", commandId: CommandId.make("command:thread-management:merge"), sourceThreadId, targetThreadId, sourcePoint: { type: "run", runId: RunId.make("run:thread-management:source"), }, }), ).toEqual([sourceThreadId, targetThreadId]); expect( existingThreadIdsForCommand({ type: "delegated_task.request", createdBy: "agent", creationSource: "provider", commandId: CommandId.make("command:thread-management:delegate"), parentThreadId, parentRunId: RunId.make("run:thread-management:parent"), parentNodeId: NodeId.make("node:thread-management:parent"), task: "Inspect the migration", modelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, runtimeMode: "full-access", interactionMode: "default", }), ).toEqual([parentThreadId]); expect( existingThreadIdsForCommand({ type: "delegated_task.wake-policy", commandId: CommandId.make("command:thread-management:wake-policy"), parentThreadId, taskId: NodeId.make("node:thread-management:delegated"), completionWake: "always", }), ).toEqual([parentThreadId]); expect( existingThreadIdsForCommand({ type: "thread.created.record", commandId: CommandId.make("command:thread-management:record"), parentThreadId, parentRunId: RunId.make("run:thread-management:parent"), parentNodeId: NodeId.make("node:thread-management:parent"), targetThreadId, targetRunId: null, }), ).toEqual([parentThreadId, targetThreadId]); });