148 lines · 4.7 KB · TypeScript
RawDownload
import { assert, it } from "@effect/vitest";import {  ContextTransferId,  MessageId,  type ModelSelection,  type OrchestrationV2AppThread,  type OrchestrationV2Run,  type OrchestrationV2ThreadProjection,  ProjectId,  ProviderInstanceId,  ProviderThreadId,  RunId,  ThreadId,} from "@t3tools/contracts";import * as DateTime from "effect/DateTime";import * as Effect from "effect/Effect"; import { layer, ThreadForkServiceV2 } from "./ThreadForkService.ts"; const sourceThreadId = ThreadId.make("thread:fork-snoozed-source");const targetThreadId = ThreadId.make("thread:fork-awake-target");const sourceRunId = RunId.make("run:fork-snoozed-source");const providerInstanceId = ProviderInstanceId.make("codex");const modelSelection = {  instanceId: providerInstanceId,  model: "gpt-5.4",} satisfies ModelSelection;const sourceCreatedAt = DateTime.makeUnsafe("2026-07-24T09:00:00.000Z");const snoozedAt = DateTime.makeUnsafe("2026-07-24T09:05:00.000Z");const snoozedUntil = DateTime.makeUnsafe("2026-07-25T09:00:00.000Z");const forkCreatedAt = DateTime.makeUnsafe("2026-07-24T09:10:00.000Z"); function makeSourceThread(): OrchestrationV2AppThread {  return {    createdBy: "user",    creationSource: "web",    id: sourceThreadId,    projectId: ProjectId.make("project:fork-snooze"),    title: "Snoozed source",    providerInstanceId,    modelSelection,    runtimeMode: "full-access",    interactionMode: "plan",    branch: "feature/source",    worktreePath: "/tmp/source-worktree",    activeProviderThreadId: ProviderThreadId.make("provider-thread:fork-snoozed-source"),    lineage: {      parentThreadId: null,      relationshipToParent: null,      rootThreadId: sourceThreadId,    },    forkedFrom: null,    createdAt: sourceCreatedAt,    updatedAt: snoozedAt,    archivedAt: null,    settledOverride: null,    settledAt: null,    lastVisitedAt: null,    snoozedUntil,    snoozedAt,    deletedAt: null,  };} function makeCompletedSourceRun(): OrchestrationV2Run {  return {    id: sourceRunId,    threadId: sourceThreadId,    ordinal: 1,    providerInstanceId,    modelSelection,    providerThreadId: ProviderThreadId.make("provider-thread:fork-snoozed-source"),    userMessageId: MessageId.make("message:fork-snoozed-source"),    rootNodeId: null,    activeAttemptId: null,    status: "completed",    queuePosition: null,    requestedAt: sourceCreatedAt,    startedAt: sourceCreatedAt,    completedAt: snoozedAt,    checkpointId: null,    contextHandoffId: null,  };} it.effect("keeps a fork awake when its source thread is snoozed", () =>  Effect.gen(function* () {    const sourceThread = makeSourceThread();    const sourceRun = makeCompletedSourceRun();    const sourceProjection: OrchestrationV2ThreadProjection = {      thread: sourceThread,      runs: [sourceRun],      attempts: [],      nodes: [],      subagents: [],      providerSessions: [],      providerThreads: [],      providerTurns: [],      runtimeRequests: [],      messages: [],      plans: [],      turnItems: [],      checkpointScopes: [],      checkpoints: [],      contextHandoffs: [],      contextTransfers: [],      visibleTurnItems: [],      updatedAt: snoozedAt,    };    const service = yield* ThreadForkServiceV2;    const result = yield* service.plan({      sourceProjection,      sourceRun,      sourceProviderThread: undefined,      canonicalSourcePoint: {        threadId: sourceThreadId,        runId: sourceRunId,      },      transferId: ContextTransferId.make("context-transfer:fork-snoozed-source"),      targetThreadId,      title: "Awake fork",      createdBy: "user",      creationSource: "mobile",      createdAt: forkCreatedAt,    });     assert.isNull(result.targetThread.snoozedUntil);    assert.isNull(result.targetThread.snoozedAt);    assert.equal(result.targetThread.projectId, sourceThread.projectId);    assert.equal(result.targetThread.providerInstanceId, sourceThread.providerInstanceId);    assert.deepEqual(result.targetThread.modelSelection, sourceThread.modelSelection);    assert.equal(result.targetThread.runtimeMode, sourceThread.runtimeMode);    assert.equal(result.targetThread.interactionMode, sourceThread.interactionMode);    assert.equal(result.targetThread.branch, sourceThread.branch);    assert.equal(result.targetThread.worktreePath, sourceThread.worktreePath);    assert.isNull(result.targetThread.activeProviderThreadId);    assert.deepEqual(result.targetThread.lineage, {      parentThreadId: sourceThreadId,      relationshipToParent: "fork",      rootThreadId: sourceThreadId,    });    assert.deepEqual(result.targetThread.forkedFrom, {      type: "run",      threadId: sourceThreadId,      runId: sourceRunId,    });  }).pipe(Effect.provide(layer)),);