From f91c1356fdee5dd228b304016910d8602af8caa2 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:51:12 -0700 Subject: [PATCH] test(server): remove skipped, duplicate, and constant-restating V2 tests Drops tests that never run, repeat coverage that a replay fixture or a stronger sibling test already provides, or only restate a constant or a fake's call log. Moves the one assertion unique to the removed OpenCode clean-EOF test (threadDisposition "broken") into the surviving one. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../Adapters/ClaudeAdapterV2.test.ts | 72 --- .../Adapters/ClaudeAdapterV2.testkit.ts | 13 - .../Adapters/CodexAdapterV2.test.ts | 10 - .../Adapters/CursorAdapterV2.test.ts | 15 - .../Adapters/OpenCodeAdapterV2.test.ts | 46 +- .../CheckpointRollbackService.test.ts | 46 +- .../src/orchestration-v2/EffectWorker.test.ts | 52 +- .../ThreadLaunchService.test.ts | 18 - .../src/orchestration-v2/runtimeLayer.test.ts | 31 - .../ClaudeReplayFixtures.integration.test.ts | 95 --- .../testkit/ThreadFork.integration.test.ts | 573 ------------------ .../src/provider/acp/XAiAcpExtension.test.ts | 15 - 12 files changed, 3 insertions(+), 983 deletions(-) diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts index 48b64dbd5d66..796bae795a99 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts @@ -794,16 +794,6 @@ describe("ClaudeAdapterV2 native protocol logging", () => { }), ); - it("does not install a protocol logger when native logging is unavailable", () => { - const protocolLogger = makeClaudeAgentSdkProtocolLogger({ - nativeEventLogger: undefined, - threadId: ThreadId.make("thread-1"), - providerSessionId: ProviderSessionId.make("provider-session-1"), - }); - - assert.equal(protocolLogger, undefined); - }); - it("logs query options without leaking environment values or callback functions", () => { const options: ClaudeAgentSdkQueryOptions = { model: "claude-sonnet-4-6", @@ -1398,11 +1388,6 @@ describe("ClaudeAdapterV2 attachments", () => { }); describe("ClaudeAdapterV2 native fork", () => { - it("advertises Claude Agent SDK session forks", () => { - assert.equal(ClaudeProviderCapabilitiesV2.threads.canForkThread, true); - assert.equal(ClaudeProviderCapabilitiesV2.threads.canForkFromTurn, true); - }); - it.effect("forks at the source assistant cursor and resumes the forked session", () => Effect.scoped( Effect.gen(function* () { @@ -4257,63 +4242,6 @@ describe("ClaudeAdapterV2 background wake turns", () => { ), ); - it.effect("clears the pending task when the wake notification carries no summary", () => - Effect.scoped( - Effect.gen(function* () { - const harness = yield* makeWakeHarness; - const now = yield* DateTime.now; - - yield* harness.runtime.startTurn( - makeClaudeTestTurnInput({ - threadId: harness.threadId, - providerThread: harness.providerThread, - now, - attemptId: RunAttemptId.make("attempt-claude-wake-5a"), - text: "Run the build in the background.", - attachments: [], - }), - ); - yield* Queue.offer(harness.sdkMessages, wakeTaskStarted); - yield* Queue.offer(harness.sdkMessages, turnOneResult); - yield* awaitUntil(() => harness.terminalEvents().length === 1, "first turn terminal"); - - yield* Queue.offer( - harness.sdkMessages, - claudeSdkFrame({ - type: "system", - subtype: "task_notification", - task_id: WAKE_TASK_ID, - status: "completed", - output_file: "/tmp/task-wake-build.log", - summary: null, - uuid: "00000000-0000-4000-8000-000000000106", - session_id: WAKE_NATIVE_SESSION, - }), - ); - yield* Queue.offer(harness.sdkMessages, wakeResult); - yield* awaitUntil(() => harness.continuationRequests.length === 1, "continuation request"); - assert.isNull(harness.continuationRequests[0]?.detail); - - yield* harness.runtime.startTurn( - makeClaudeTestTurnInput({ - threadId: harness.threadId, - providerThread: harness.providerThread, - now, - attemptId: RunAttemptId.make("attempt-claude-wake-5b"), - text: "Background task completed.", - attachments: [], - providerTurnOrdinal: 2, - messageCreatedBy: "agent", - messageCreationSource: "provider", - }), - ); - yield* awaitUntil(() => harness.terminalEvents().length === 2, "continuation terminal"); - assert.equal(harness.terminalEvents()[1]?.status, "completed"); - assert.isFalse(yield* harness.hasPendingBackgroundWork); - }).pipe(Effect.provide(Layer.merge(idAllocatorLayer, NodeServices.layer))), - ), - ); - it.effect("settles a continuation turn immediately when no wake output is buffered", () => Effect.scoped( Effect.gen(function* () { diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.testkit.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.testkit.ts index 8ecc86dcb445..05a76a0a3ebd 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.testkit.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.testkit.ts @@ -900,19 +900,6 @@ function makeClaudeProviderAdapterRegistryReplayLayer( ); } -export async function replayClaudeAgentSdkTranscript(input: { - readonly transcript: ClaudeAgentSdkReplayTranscript; - readonly prompts: ReadonlyArray; - readonly modelSelection: ModelSelection; - readonly cwd?: string; -}): Promise> { - return input.transcript.entries.flatMap((entry) => - entry.type === "emit_inbound" && isClaudeSdkReplayMessage(entry.frame) - ? [sdkMessageFromReplayFrame(entry.frame)] - : [], - ); -} - function serializeReplayError(error: unknown, scenario?: string): unknown { return error instanceof Error ? { diff --git a/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts index 9392ae4047d6..aaddd176ea96 100644 --- a/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts @@ -984,16 +984,6 @@ describe("CodexAdapterV2 native protocol logging", () => { assert.nestedPropertyVal(writes[0], "event.payload.params.turnId", "native-turn"); }), ); - - it("does not install a protocol logger when native logging is unavailable", () => { - const protocolLogger = makeCodexAppServerProtocolLogger({ - nativeEventLogger: undefined, - threadId: ThreadId.make("thread-1"), - providerSessionId: ProviderSessionId.make("provider-session-1"), - }); - - assert.equal(protocolLogger, undefined); - }); }); describe("CodexAdapterV2 rollback mapping", () => { diff --git a/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.test.ts index b58cadfb5341..e9fce01d24ff 100644 --- a/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.test.ts @@ -27,7 +27,6 @@ import * as McpProviderSession from "../../mcp/McpProviderSession.ts"; import { IdAllocatorV2, layer as idAllocatorLayer } from "../IdAllocator.ts"; import { ProviderAdapterV2RuntimePolicy } from "../ProviderAdapter.ts"; import { - CursorProviderCapabilitiesV2, cursorMcpServers, cursorRuntimeAgentPolicy, cursorSdkModelSelection, @@ -846,20 +845,6 @@ describe("CursorAdapterV2", () => { ); }); - it("advertises only capabilities exposed by the official SDK adapter", () => { - assert.isTrue(CursorProviderCapabilitiesV2.threads.canReadThreadSnapshot); - assert.isFalse(CursorProviderCapabilitiesV2.threads.canForkThread); - assert.isFalse(CursorProviderCapabilitiesV2.threads.canRollbackThread); - assert.isTrue(CursorProviderCapabilitiesV2.turns.supportsInterrupt); - assert.isFalse(CursorProviderCapabilitiesV2.turns.supportsActiveSteering); - assert.isTrue(CursorProviderCapabilitiesV2.turns.supportsSteeringByInterruptRestart); - assert.isTrue(CursorProviderCapabilitiesV2.tools.supportsMcpTools); - assert.isTrue(CursorProviderCapabilitiesV2.subagents.supportsSubagents); - assert.isFalse(CursorProviderCapabilitiesV2.subagents.exposesSubagentThreadIds); - assert.equal(CursorProviderCapabilitiesV2.identity.nativeItemIds, "weak"); - assert.isFalse(CursorProviderCapabilitiesV2.approvals.supportsCommandApproval); - }); - it("injects thread-scoped MCP credentials without logging them", () => { const threadId = ThreadId.make("thread-cursor-mcp"); McpProviderSession.setMcpProviderSession({ diff --git a/apps/server/src/orchestration-v2/Adapters/OpenCodeAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/OpenCodeAdapterV2.test.ts index 216847d04e6a..acceadce0268 100644 --- a/apps/server/src/orchestration-v2/Adapters/OpenCodeAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/OpenCodeAdapterV2.test.ts @@ -46,7 +46,6 @@ import { makeOpenCodeProtocolLogger, makeOpenCodeAdapterV2, OPENCODE_PROVIDER, - OpenCodeProviderCapabilitiesV2, reconcileOpenCodePromptAdmissionStatus, } from "./OpenCodeAdapterV2.ts"; import { ProviderAdapterV2RuntimePolicy } from "../ProviderAdapter.ts"; @@ -456,39 +455,6 @@ describe("OpenCodeAdapterV2", () => { ); } - it.effect("fails an active turn when the event stream reaches unexpected clean EOF", () => - Effect.gen(function* () { - const nativeEvents = asyncEventStream(); - const harness = yield* makeOpenCodeRuntimeHarness("eof", "root", { - event: { subscribe: async () => ({ stream: nativeEvents.stream }) }, - session: { - create: async () => ({ data: { id: "root", time: { created: 1, updated: 1 } } }), - promptAsync: async () => ({ data: true }), - abort: async () => ({ data: true }), - children: async () => ({ data: [] }), - }, - }); - yield* harness.startTurn(); - const received = yield* harness.runtime.events.pipe( - Stream.takeUntil((event) => event.type === "turn.terminal"), - Stream.runCollect, - Effect.forkScoped, - ); - nativeEvents.close(); - const events = yield* Fiber.join(received); - assert.isTrue( - events.some( - (event) => - event.type === "provider_session.updated" && event.providerSession.status === "error", - ), - ); - const terminal = events.find((event) => event.type === "turn.terminal"); - assert.equal(terminal?.status, "failed"); - assert.equal(terminal?.failure?.class, "transport_error"); - assert.equal(terminal?.threadDisposition, "broken"); - }).pipe(Effect.provide(idAllocatorLayer), Effect.scoped), - ); - it.effect("aborts external root and descendants before closing the event stream", () => Effect.gen(function* () { const scope = yield* Scope.make(); @@ -1497,6 +1463,7 @@ describe("OpenCodeAdapterV2", () => { const terminal = received.find((event) => event.type === "turn.terminal"); assert.equal(terminal?.status, "failed"); assert.equal(terminal?.failure?.class, "transport_error"); + assert.equal(terminal?.threadDisposition, "broken"); assert.equal((yield* Effect.exit(harness.startTurn()))._tag, "Failure"); }).pipe(Effect.provide(idAllocatorLayer), Effect.scoped), ); @@ -2084,17 +2051,6 @@ describe("OpenCodeAdapterV2", () => { ), ); - it("advertises the identity strengths exposed by the SDK boundary", () => { - assert.equal(OpenCodeProviderCapabilitiesV2.identity.nativeThreadIds, "strong"); - assert.equal(OpenCodeProviderCapabilitiesV2.identity.nativeTurnIds, "weak"); - assert.equal(OpenCodeProviderCapabilitiesV2.identity.nativeItemIds, "strong"); - assert.equal(OpenCodeProviderCapabilitiesV2.identity.nativeRequestIds, "strong"); - assert.isTrue(OpenCodeProviderCapabilitiesV2.threads.canForkFromTurn); - assert.isTrue(OpenCodeProviderCapabilitiesV2.turns.supportsActiveSteering); - assert.equal(OpenCodeProviderCapabilitiesV2.turns.terminalStatusQuality, "strong"); - assert.isFalse(OpenCodeProviderCapabilitiesV2.subagents.canCloseSubagents); - }); - it("maps native permission families to orchestration request kinds", () => { assert.equal(openCodePermissionRequestKind("bash"), "command"); assert.equal(openCodePermissionRequestKind("read"), "file-read"); diff --git a/apps/server/src/orchestration-v2/CheckpointRollbackService.test.ts b/apps/server/src/orchestration-v2/CheckpointRollbackService.test.ts index f2894fdebb20..54722a44c860 100644 --- a/apps/server/src/orchestration-v2/CheckpointRollbackService.test.ts +++ b/apps/server/src/orchestration-v2/CheckpointRollbackService.test.ts @@ -24,7 +24,7 @@ import { } from "./CheckpointRollbackService.ts"; import { EventSinkV2 } from "./EventSink.ts"; import { layer as idAllocatorLayer } from "./IdAllocator.ts"; -import { ProjectionStoreReadError, ProjectionStoreV2 } from "./ProjectionStore.ts"; +import { ProjectionStoreV2 } from "./ProjectionStore.ts"; import type { ProviderAdapterV2RollbackThreadInput } from "./ProviderAdapter.ts"; import { ProviderSessionManagerV2 } from "./ProviderSessionManager.ts"; import { RuntimePolicyV2 } from "./RuntimePolicy.ts"; @@ -328,50 +328,6 @@ it.effect("reports a missing provider turn as a structured rollback failure", () }).pipe(Effect.provide(testLayer)); }); -it.effect("wraps underlying failures with an unexpected-failure reason and cause", () => { - const threadId = ThreadId.make("thread:rollback-unexpected-failure"); - const providerThreadId = ProviderThreadId.make("provider-thread:rollback-unexpected-failure"); - const checkpointId = CheckpointId.make("checkpoint:rollback-unexpected-failure"); - const scopeId = CheckpointScopeId.make("checkpoint-scope:rollback-unexpected-failure"); - const projectionError = new ProjectionStoreReadError({ - threadId, - cause: new Error("database read failed"), - }); - const testLayer = checkpointRollbackServiceLayer.pipe( - Layer.provide( - Layer.mergeAll( - Layer.mock(CheckpointServiceV2)({}), - Layer.mock(EventSinkV2)({}), - idAllocatorLayer, - Layer.mock(ProjectionStoreV2)({ - getThreadRecords: () => Effect.fail(projectionError), - }), - Layer.mock(ProviderSessionManagerV2)({}), - Layer.mock(RuntimePolicyV2)({}), - ), - ), - ); - - return Effect.gen(function* () { - const service = yield* CheckpointRollbackServiceV2; - const error = yield* service - .execute({ - threadId, - providerThreadId, - checkpointId, - scopeId, - }) - .pipe(Effect.flip); - - assert.equal(error.reason, "unexpected-failure"); - assert.equal( - error.message, - `Failed to execute rollback target ${checkpointId} on provider thread ${providerThreadId} for thread ${threadId}.`, - ); - assert.strictEqual(error.cause, projectionError); - }).pipe(Effect.provide(testLayer)); -}); - it.effect.each([ { restoreFiles: true, shared: "none" }, { restoreFiles: false, shared: "root" }, diff --git a/apps/server/src/orchestration-v2/EffectWorker.test.ts b/apps/server/src/orchestration-v2/EffectWorker.test.ts index 3e8e609d46b6..c082ed35b6eb 100644 --- a/apps/server/src/orchestration-v2/EffectWorker.test.ts +++ b/apps/server/src/orchestration-v2/EffectWorker.test.ts @@ -1,7 +1,6 @@ import { assert, it } from "@effect/vitest"; import { CommandId, - MessageId, ProviderSessionId, ProviderThreadId, ProviderTurnId, @@ -149,9 +148,7 @@ function makeExecutorLayer(input: { ), Layer.succeed( ThreadTitleRegenerationService, - ThreadTitleRegenerationService.of({ - execute: ({ requestId, kind }) => record(`title:${kind.type}:${requestId}`), - }), + ThreadTitleRegenerationService.of({ execute: () => Effect.void }), ), ); return executorLayer.pipe( @@ -722,53 +719,6 @@ it.effect("backs off briefly when a due deadline loses a claim race", () => }).pipe(Effect.provide(TestClock.layer())), ); -it.effect("detaches a handed-off session only after the old turn terminalizes", () => - Effect.gen(function* () { - const now = yield* DateTime.now; - const events = yield* Ref.make>([]); - - yield* Effect.gen(function* () { - const executor = yield* OrchestrationEffectExecutorV2; - yield* executor.execute(restartEffect(now, { type: "detach" })); - }).pipe(Effect.provide(makeExecutorLayer({ events }))); - - assert.deepEqual(yield* Ref.get(events), ["interrupt", "detach", "start"]); - }), -); - -it.effect("executes durable thread title generation effects", () => - Effect.gen(function* () { - const now = DateTime.formatIso(yield* DateTime.now); - const events = yield* Ref.make>([]); - const commandId = CommandId.make("command:title-generation"); - const effect: OrchestrationEffectV2 = { - id: "effect:title-generation", - commandId, - threadId, - request: { - type: "thread-title.generate", - kind: { type: "initial", messageId: MessageId.make("message:title-generation") }, - }, - status: "running", - attemptCount: 1, - availableAt: now, - leaseOwner: "test-worker", - leaseExpiresAt: now, - createdAt: now, - updatedAt: now, - completedAt: null, - lastError: null, - }; - - yield* Effect.gen(function* () { - const executor = yield* OrchestrationEffectExecutorV2; - yield* executor.execute(effect); - }).pipe(Effect.provide(makeExecutorLayer({ events }))); - - assert.deepEqual(yield* Ref.get(events), [`title:initial:${commandId}`]); - }), -); - it.effect("safely retries after replacement cleanup succeeds and start fails", () => Effect.gen(function* () { const now = yield* DateTime.now; diff --git a/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts b/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts index f2365689177a..fa9642bab1fe 100644 --- a/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts +++ b/apps/server/src/orchestration-v2/ThreadLaunchService.test.ts @@ -36,7 +36,6 @@ import * as Option from "effect/Option"; import * as Ref from "effect/Ref"; import * as Stream from "effect/Stream"; import * as Schema from "effect/Schema"; -import * as SqlClient from "effect/unstable/sql/SqlClient"; import * as TestClock from "effect/testing/TestClock"; import * as GitWorkflow from "../git/GitWorkflowService.ts"; @@ -1676,23 +1675,6 @@ it.effect("creates a strong provider-thread mapping for an imported native sessi }).pipe(Effect.provide(harness.layer)); }); -it.effect("does not depend on the legacy launch workflow table", () => { - const harness = makeHarness(); - return Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; - const launches = yield* ThreadLaunch.ThreadLaunchService; - yield* sql`DROP TABLE orchestration_v2_thread_launch_workflows`; - const launched = yield* launches.launch( - launchInput({ - command: "command:launch:no-workflow-table", - thread: "thread:launch:no-workflow-table", - message: "No private workflow state", - }), - ); - assert.equal(launched.projection.messages[0]?.text, "No private workflow state"); - }).pipe(Effect.provide(harness.layer)); -}); - it.effect("shared intake preserves durable attachment bytes after a lost launch result", () => { const harness = makeHarness(); const files = ServerConfig.layerTest(process.cwd(), { prefix: "t3-message-intake-" }).pipe( diff --git a/apps/server/src/orchestration-v2/runtimeLayer.test.ts b/apps/server/src/orchestration-v2/runtimeLayer.test.ts index 60f5fc91c4cd..df6572c90244 100644 --- a/apps/server/src/orchestration-v2/runtimeLayer.test.ts +++ b/apps/server/src/orchestration-v2/runtimeLayer.test.ts @@ -362,37 +362,6 @@ const SharedApplicationDataPlaneTestLayer = Layer.merge( ); it.layer(TestLayer)("OrchestrationV2LayerLive", (it) => { - it.effect("creates and reads a thread through the production V2 composition", () => - Effect.gen(function* () { - const orchestrator = yield* OrchestratorV2; - const threadId = ThreadId.make("runtime-layer-thread"); - const projectId = ProjectId.make("runtime-layer-project"); - - const result = yield* orchestrator.dispatch({ - type: "thread.create", - createdBy: "user", - creationSource: "web", - commandId: CommandId.make("runtime-layer-create"), - threadId, - projectId, - title: "Runtime layer thread", - modelSelection: modelSelection, - runtimeMode: "full-access", - interactionMode: "default", - branch: null, - worktreePath: null, - }); - - const projection = yield* orchestrator.getThreadProjection(threadId); - - assert.equal(result.sequence, 1); - assert.equal(projection.thread.id, threadId); - assert.equal(projection.thread.projectId, projectId); - assert.equal(projection.thread.providerInstanceId, "codex"); - assert.deepEqual(projection.runs, []); - }), - ); - it.effect("emits model updates separately from provider switches", () => Effect.gen(function* () { const orchestrator = yield* OrchestratorV2; diff --git a/apps/server/src/orchestration-v2/testkit/ClaudeReplayFixtures.integration.test.ts b/apps/server/src/orchestration-v2/testkit/ClaudeReplayFixtures.integration.test.ts index 79710bb0c57b..b5e51ba123fa 100644 --- a/apps/server/src/orchestration-v2/testkit/ClaudeReplayFixtures.integration.test.ts +++ b/apps/server/src/orchestration-v2/testkit/ClaudeReplayFixtures.integration.test.ts @@ -4,16 +4,8 @@ import type { ProviderReplayTranscript } from "@t3tools/contracts"; import * as Effect from "effect/Effect"; import { classifyClaudeNativeTool } from "../Adapters/ClaudeAdapterV2.ts"; -import { - ClaudeOrchestratorReplayHarness, - recordClaudeAgentSdkReplayTranscript, - replayClaudeAgentSdkTranscript, -} from "../Adapters/ClaudeAdapterV2.testkit.ts"; import { ORCHESTRATOR_REPLAY_FIXTURES } from "./fixtures/index.ts"; import { - MULTI_TURN_FIRST_PROMPT, - MULTI_TURN_SECOND_PROMPT, - SIMPLE_PROMPT, THREAD_FORK_NATIVE_CONTINUE_FORK_MARKER, THREAD_FORK_NATIVE_CONTINUE_RECALL, THREAD_FORK_NATIVE_CONTINUE_SOURCE_MARKER, @@ -25,22 +17,12 @@ import { THREAD_MERGE_BACK_SIBLINGS_SOURCE_MARKER, THREAD_MERGE_BACK_SOURCE_MARKER, } from "./fixtures/shared.ts"; -import { checkpointWorkspace } from "./ReplayFixtureWorkspace.ts"; import { readProviderReplayTranscript } from "./ReplayTranscriptNdjson.ts"; const readTranscript = Effect.fn("readClaudeReplayFixture")(function* (file: URL) { return yield* readProviderReplayTranscript(file); }, Effect.provide(NodeServices.layer)); -function claudeFixture(name: string) { - const fixture = ORCHESTRATOR_REPLAY_FIXTURES.find((entry) => entry.name === name); - const provider = fixture?.providers.find((entry) => entry.driver === "claudeAgent"); - if (fixture === undefined || provider === undefined) { - throw new Error(`Missing ${name}/claudeAgent replay fixture.`); - } - return { fixture, provider }; -} - function readClaudeTranscriptFixture(path: string) { return readTranscript(new URL(`./fixtures/${path}/claude_transcript.ndjson`, import.meta.url)); } @@ -316,81 +298,4 @@ describe("Claude Agent SDK replay fixtures", () => { assert.notInclude(forkLocalRollbackFinalText, "fork local second"); }), ); - - it.effect.skipIf(process.env.T3_RECORD_CLAUDE_AGENT_SDK_FIXTURE !== "1")( - "records simple from real Claude Code query() output", - () => - Effect.scoped( - Effect.gen(function* () { - const { fixture, provider } = claudeFixture("simple"); - - const workspace = yield* checkpointWorkspace("claude-simple-record"); - const transcript = yield* Effect.promise(() => - recordClaudeAgentSdkReplayTranscript({ - scenario: fixture.name, - prompts: [SIMPLE_PROMPT], - modelSelection: provider.modelSelection, - cwd: workspace, - }), - ); - - assert.equal(transcript.provider, "claudeAgent"); - assert.equal(transcript.protocol, "claude-agent-sdk.query"); - assert.isAtLeast(transcript.entries.length, 3); - }), - ), - ); - - it.effect("replays simple as typed Claude Agent SDK query messages", () => - Effect.gen(function* () { - const { provider } = claudeFixture("simple"); - - const rawTranscript = yield* readTranscript(provider.transcriptFile); - const transcript = yield* ClaudeOrchestratorReplayHarness.decodeTranscript(rawTranscript); - - const messages = yield* Effect.promise(() => - replayClaudeAgentSdkTranscript({ - transcript, - prompts: [SIMPLE_PROMPT], - modelSelection: provider.modelSelection, - }), - ); - - assert.include( - messages - .filter((message) => message.type === "assistant") - .flatMap((message) => - message.message.content.flatMap((part) => (part.type === "text" ? [part.text] : [])), - ) - .join(""), - "fixture simple ok", - ); - }), - ); - - it.effect("replays multi_turn as typed Claude Agent SDK query messages", () => - Effect.gen(function* () { - const { provider } = claudeFixture("multi_turn"); - - const rawTranscript = yield* readTranscript(provider.transcriptFile); - const transcript = yield* ClaudeOrchestratorReplayHarness.decodeTranscript(rawTranscript); - - const messages = yield* Effect.promise(() => - replayClaudeAgentSdkTranscript({ - transcript, - prompts: [MULTI_TURN_FIRST_PROMPT, MULTI_TURN_SECOND_PROMPT], - modelSelection: provider.modelSelection, - }), - ); - - const assistantText = messages - .filter((message) => message.type === "assistant") - .flatMap((message) => - message.message.content.flatMap((part) => (part.type === "text" ? [part.text] : [])), - ) - .join("\n"); - assert.include(assistantText, "first fixture turn complete"); - assert.include(assistantText, "second fixture turn complete"); - }), - ); }); diff --git a/apps/server/src/orchestration-v2/testkit/ThreadFork.integration.test.ts b/apps/server/src/orchestration-v2/testkit/ThreadFork.integration.test.ts index 041168b6ff13..2d751847a9f3 100644 --- a/apps/server/src/orchestration-v2/testkit/ThreadFork.integration.test.ts +++ b/apps/server/src/orchestration-v2/testkit/ThreadFork.integration.test.ts @@ -6,7 +6,6 @@ import { type OrchestrationV2Command, type OrchestrationV2ThreadProjection, ProviderInstanceId, - type ProviderReplayEntry, type ProviderReplayTranscript, ThreadId, } from "@t3tools/contracts"; @@ -139,264 +138,6 @@ function userAndAssistantText( .join("\n"); } -function compactExpectedText(text: string, maxLength = 240): string { - const compacted = text.replace(/\s+/g, " ").trim(); - if (compacted.length <= maxLength) { - return compacted; - } - return `${compacted.slice(0, maxLength - 3)}...`; -} - -function findCompletedAgentMessageText(input: { - readonly transcript: ProviderReplayTranscript; - readonly threadId: string; - readonly turnId: string; -}): string { - for (const entry of input.transcript.entries) { - if (entry.type !== "emit_inbound") { - continue; - } - const frame = entry.frame as { - readonly method?: unknown; - readonly params?: { - readonly threadId?: unknown; - readonly turnId?: unknown; - readonly item?: { - readonly type?: unknown; - readonly text?: unknown; - }; - }; - }; - if ( - frame.method === "item/completed" && - frame.params?.threadId === input.threadId && - frame.params.turnId === input.turnId && - frame.params.item?.type === "agentMessage" && - typeof frame.params.item.text === "string" - ) { - return frame.params.item.text; - } - } - throw new Error(`No completed agent message found for ${input.threadId}/${input.turnId}`); -} - -function makeExpectedForkDeltaSummary(input: { - readonly sourceThreadId: string; - readonly targetThreadId: string; - readonly forkUserText: string; - readonly forkAssistantText: string; -}): string { - return [ - "Merge-back context from forked conversation.", - `Source thread: ${input.sourceThreadId}`, - `Target thread: ${input.targetThreadId}`, - "Covered fork runs: 1-1", - "", - "Fork delta:", - `- User: ${compactExpectedText(input.forkUserText)}`, - `- Assistant: ${compactExpectedText(input.forkAssistantText)}`, - "- Checkpoint: 0 files", - ].join("\n"); -} - -function transcriptWithMergeBackContinuation(input: { - readonly transcript: ProviderReplayTranscript; - readonly providerMessageText: string; - readonly projectedUserText: string; - readonly assistantText: string; -}): ProviderReplayTranscript { - const sourceNativeThreadId = "019dd6ba-2681-7bf0-b051-141b0cbcbb27"; - const mergeBackNativeTurnId = "019dd6ba-5000-7000-8000-000000000001"; - const mergeBackUserItemId = "merge-back-user-message"; - const mergeBackAgentItemId = "merge-back-agent-message"; - const entriesWithoutExit = input.transcript.entries.filter( - (entry) => entry.type !== "runtime_exit", - ); - const continuation = [ - { - type: "expect_outbound", - label: "turn/start/merge-back-source", - frame: { - id: 9, - method: "turn/start", - params: { - threadId: sourceNativeThreadId, - input: [{ type: "text", text: input.providerMessageText }], - approvalPolicy: "never", - sandboxPolicy: { - type: "readOnly", - access: { type: "fullAccess" }, - networkAccess: false, - }, - }, - }, - }, - { - type: "emit_inbound", - label: "turn/start/merge-back-source", - frame: { - id: 9, - result: { - turn: { - id: mergeBackNativeTurnId, - items: [], - status: "inProgress", - error: null, - startedAt: 1777424041, - completedAt: null, - durationMs: null, - }, - }, - }, - }, - { - type: "emit_inbound", - label: "thread/status/changed/merge-back-source", - frame: { - method: "thread/status/changed", - params: { - threadId: sourceNativeThreadId, - status: { type: "active", activeFlags: [] }, - }, - }, - }, - { - type: "emit_inbound", - label: "turn/started/merge-back-source", - frame: { - method: "turn/started", - params: { - threadId: sourceNativeThreadId, - turn: { - id: mergeBackNativeTurnId, - items: [], - status: "inProgress", - error: null, - startedAt: 1777424041, - completedAt: null, - durationMs: null, - }, - }, - }, - }, - { - type: "emit_inbound", - label: "item/userMessage/started/merge-back-source", - frame: { - method: "item/started", - params: { - item: { - type: "userMessage", - id: mergeBackUserItemId, - content: [{ type: "text", text: input.projectedUserText, text_elements: [] }], - }, - threadId: sourceNativeThreadId, - turnId: mergeBackNativeTurnId, - }, - }, - }, - { - type: "emit_inbound", - label: "item/userMessage/completed/merge-back-source", - frame: { - method: "item/completed", - params: { - item: { - type: "userMessage", - id: mergeBackUserItemId, - content: [{ type: "text", text: input.projectedUserText, text_elements: [] }], - }, - threadId: sourceNativeThreadId, - turnId: mergeBackNativeTurnId, - }, - }, - }, - { - type: "emit_inbound", - label: "item/agentMessage/started/merge-back-source", - frame: { - method: "item/started", - params: { - item: { - type: "agentMessage", - id: mergeBackAgentItemId, - text: "", - phase: "final_answer", - memoryCitation: null, - }, - threadId: sourceNativeThreadId, - turnId: mergeBackNativeTurnId, - }, - }, - }, - { - type: "emit_inbound", - label: "item/agentMessage/delta/merge-back-source", - frame: { - method: "item/agentMessage/delta", - params: { - threadId: sourceNativeThreadId, - turnId: mergeBackNativeTurnId, - itemId: mergeBackAgentItemId, - delta: input.assistantText, - }, - }, - }, - { - type: "emit_inbound", - label: "item/agentMessage/completed/merge-back-source", - frame: { - method: "item/completed", - params: { - item: { - type: "agentMessage", - id: mergeBackAgentItemId, - text: input.assistantText, - phase: "final_answer", - memoryCitation: null, - }, - threadId: sourceNativeThreadId, - turnId: mergeBackNativeTurnId, - }, - }, - }, - { - type: "emit_inbound", - label: "thread/status/changed/merge-back-source", - frame: { - method: "thread/status/changed", - params: { threadId: sourceNativeThreadId, status: { type: "idle" } }, - }, - }, - { - type: "emit_inbound", - label: "turn/completed/merge-back-source", - frame: { - method: "turn/completed", - params: { - threadId: sourceNativeThreadId, - turn: { - id: mergeBackNativeTurnId, - items: [], - status: "completed", - error: null, - startedAt: 1777424041, - completedAt: 1777424042, - durationMs: 1000, - }, - }, - }, - }, - { type: "runtime_exit", status: "success" }, - ] satisfies ReadonlyArray; - - return { - ...input.transcript, - scenario: `${input.transcript.scenario}_merge_back`, - entries: [...entriesWithoutExit, ...continuation], - }; -} - describe("orchestration V2 thread fork", () => { it.effect( "creates an idle app fork and resolves it with Codex native thread/fork on first dispatch", @@ -1456,318 +1197,4 @@ describe("orchestration V2 thread fork", () => { ); }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), ); - - // Covered with recorded Codex and Claude provider transcripts in ThreadMergeBack.integration. - it.effect.skip("merges a fork delta back into the source thread through context handoff", () => - Effect.gen(function* () { - const rawTranscript = yield* readTranscript(PRIOR_TURN_TRANSCRIPT_PATH); - const forkNativeThreadId = "019dd6ba-47b7-7092-8688-9cf7fe5f6498"; - const sourceNativeThreadId = "019dd6ba-2681-7bf0-b051-141b0cbcbb27"; - const forkRepeatNativeTurnId = "019dd6ba-47eb-7041-ad45-5abe752c28c9"; - const forkPrompt = THREAD_FORK_NATIVE_PRIOR_TURN_REPEAT_PROMPT; - const mergeBackPrompt = "Acknowledge the fork context with exactly: merge back acknowledged"; - const mergeBackAssistantText = "merge back acknowledged"; - const materialized = yield* Effect.gen(function* () { - const ids = yield* IdAllocatorV2; - const projectId = yield* ids.allocate.project({ - fixtureName: "thread-fork-native-prior-turn", - }); - const sourceThreadId = yield* ids.allocate.thread({ - fixtureName: "thread-fork-native-prior-turn-source", - projectId, - }); - const targetThreadId = ThreadId.make("thread-fork-native-prior-turn-target"); - const firstRunId = ids.derive.run({ threadId: sourceThreadId, ordinal: 1 }); - const forkRunId = ids.derive.run({ threadId: targetThreadId, ordinal: 1 }); - - const commands = [ - { - type: "thread.create", - createdBy: "user", - creationSource: "web", - commandId: yield* ids.allocate.command({ - fixtureName: "thread-fork-native-prior-turn", - commandName: "thread-create-source", - }), - threadId: sourceThreadId, - projectId, - title: "Source thread", - modelSelection: CODEX_MODEL_SELECTION, - runtimeMode: "full-access", - interactionMode: "default", - branch: null, - worktreePath: null, - }, - { - type: "message.dispatch", - createdBy: "user", - creationSource: "web", - commandId: yield* ids.allocate.command({ - fixtureName: "thread-fork-native-prior-turn", - commandName: "source-message-alpha", - }), - threadId: sourceThreadId, - messageId: MessageId.make("message-thread-fork-native-prior-turn-alpha"), - text: THREAD_FORK_NATIVE_PRIOR_TURN_ALPHA_PROMPT, - attachments: [], - modelSelection: CODEX_MODEL_SELECTION, - dispatchMode: { type: "start_immediately" }, - }, - { - type: "message.dispatch", - createdBy: "user", - creationSource: "web", - commandId: yield* ids.allocate.command({ - fixtureName: "thread-fork-native-prior-turn", - commandName: "source-message-beta", - }), - threadId: sourceThreadId, - messageId: MessageId.make("message-thread-fork-native-prior-turn-beta"), - text: THREAD_FORK_NATIVE_PRIOR_TURN_BETA_PROMPT, - attachments: [], - modelSelection: CODEX_MODEL_SELECTION, - dispatchMode: { type: "start_immediately" }, - }, - { - type: "thread.fork", - createdBy: "user", - creationSource: "web", - commandId: CommandId.make("command-thread-fork-native-prior-turn"), - sourceThreadId, - targetThreadId, - sourcePoint: { type: "run", runId: firstRunId }, - title: "Forked from first response", - }, - { - type: "message.dispatch", - createdBy: "user", - creationSource: "web", - commandId: yield* ids.allocate.command({ - fixtureName: "thread-fork-native-prior-turn", - commandName: "target-message-repeat", - }), - threadId: targetThreadId, - messageId: MessageId.make("message-thread-fork-native-prior-turn-repeat"), - text: forkPrompt, - attachments: [], - modelSelection: CODEX_MODEL_SELECTION, - dispatchMode: { type: "start_immediately" }, - }, - { - type: "thread.merge_back", - createdBy: "user", - creationSource: "web", - commandId: CommandId.make("command-thread-merge-back-native-prior-turn-stale"), - sourceThreadId: targetThreadId, - targetThreadId: sourceThreadId, - sourcePoint: { type: "run", runId: forkRunId }, - }, - { - type: "thread.merge_back", - createdBy: "user", - creationSource: "web", - commandId: CommandId.make("command-thread-merge-back-native-prior-turn"), - sourceThreadId: targetThreadId, - targetThreadId: sourceThreadId, - sourcePoint: { type: "run", runId: forkRunId }, - }, - { - type: "message.dispatch", - createdBy: "user", - creationSource: "web", - commandId: yield* ids.allocate.command({ - fixtureName: "thread-fork-native-prior-turn", - commandName: "source-message-merge-back", - }), - threadId: sourceThreadId, - messageId: MessageId.make("message-thread-fork-native-prior-turn-merge-back"), - text: mergeBackPrompt, - attachments: [], - modelSelection: CODEX_MODEL_SELECTION, - dispatchMode: { type: "start_immediately" }, - }, - ] satisfies ReadonlyArray; - - return { - sourceThreadId, - targetThreadId, - firstRunId, - forkRunId, - commands, - }; - }).pipe(Effect.provide(idAllocatorLayer), provideDeterministicTestRuntime); - const expectedSummary = makeExpectedForkDeltaSummary({ - sourceThreadId: materialized.targetThreadId, - targetThreadId: materialized.sourceThreadId, - forkUserText: forkPrompt, - forkAssistantText: findCompletedAgentMessageText({ - transcript: rawTranscript, - threadId: forkNativeThreadId, - turnId: forkRepeatNativeTurnId, - }), - }); - const providerMessageText = [ - "Context handoff (merge_back / fork_delta_summary):", - expectedSummary, - "", - "User message:", - mergeBackPrompt, - ].join("\n"); - const transcript = yield* CodexOrchestratorReplayHarness.decodeTranscript( - transcriptWithMergeBackContinuation({ - transcript: rawTranscript, - providerMessageText, - projectedUserText: mergeBackPrompt, - assistantText: mergeBackAssistantText, - }), - ); - const cwd = yield* Effect.acquireRelease(makeCheckpointWorkspace, (directory) => - Effect.service(FileSystem.FileSystem).pipe( - Effect.flatMap((fs) => fs.remove(directory, { recursive: true, force: true })), - Effect.orDie, - ), - ); - - const result = yield* runOrchestratorV2ProviderReplayScenario( - { - name: "thread_fork_native_prior_turn_merge_back/codex", - transcript, - commands: materialized.commands, - steps: [ - { type: "dispatch", command: materialized.commands[0]!, await: true }, - { type: "advance_clock", duration: "1 millis" }, - { type: "dispatch", command: materialized.commands[1]!, await: true }, - { type: "await_thread_idle", threadId: materialized.sourceThreadId }, - { type: "dispatch", command: materialized.commands[2]!, await: true }, - { type: "await_thread_idle", threadId: materialized.sourceThreadId }, - { type: "dispatch", command: materialized.commands[3]!, await: true }, - { type: "dispatch", command: materialized.commands[4]!, await: true }, - { type: "await_thread_idle", threadId: materialized.targetThreadId }, - { type: "dispatch", command: materialized.commands[5]!, await: true }, - { type: "dispatch", command: materialized.commands[6]!, await: true }, - { type: "dispatch", command: materialized.commands[7]!, await: true }, - { type: "await_thread_idle", threadId: materialized.sourceThreadId }, - ], - projectionThreadIds: [materialized.sourceThreadId, materialized.targetThreadId], - runtimePolicyOverride: { cwd, ...CODEX_READ_ONLY_NEVER_POLICY }, - }, - CodexOrchestratorReplayHarness, - ).pipe(provideDeterministicTestRuntime); - - const sourceProjection = result.projections.get(materialized.sourceThreadId); - const forkProjection = result.projections.get(materialized.targetThreadId); - assert.isDefined(sourceProjection); - assert.isDefined(forkProjection); - - assert.equal( - sourceProjection.providerThreads[0]?.nativeThreadRef?.nativeId, - sourceNativeThreadId, - "merge-back should continue the original source provider thread", - ); - assert.lengthOf(sourceProjection.runs, 3); - assert.equal( - sourceProjection.runs[2]?.contextHandoffId, - sourceProjection.contextHandoffs[0]?.id, - ); - assert.lengthOf(sourceProjection.contextHandoffs, 1); - const handoff = sourceProjection.contextHandoffs[0]!; - assert.equal(handoff.strategy, "fork_delta_summary"); - assert.equal(handoff.status, "ready"); - assert.equal(handoff.threadId, materialized.sourceThreadId); - assert.equal(handoff.targetRunId, sourceProjection.runs[2]?.id); - assert.deepEqual(handoff.coveredRunOrdinals, { from: 1, to: 1 }); - assert.include(handoff.summaryText, "Merge-back context from forked conversation."); - assert.include(handoff.summaryText, "Repeat the user-visible conversation"); - assert.notInclude( - handoff.summaryText, - "fork boundary beta", - "merge-back context should summarize only fork-local delta after the source point", - ); - assert.equal(handoff.summaryText, expectedSummary); - - const mergeBackTransfers = sourceProjection.contextTransfers.filter( - (transfer) => transfer.type === "merge_back", - ); - assert.lengthOf(mergeBackTransfers, 2); - const supersededTransfer = mergeBackTransfers.find( - (transfer) => transfer.status === "superseded", - ); - const mergeBackTransfer = mergeBackTransfers.find( - (transfer) => transfer.status === "consumed", - ); - assert.isDefined(supersededTransfer); - assert.isDefined(mergeBackTransfer); - assert.include( - supersededTransfer.error ?? "", - mergeBackTransfer.id, - "newer merge-back preparation should supersede the previous pending transfer", - ); - assert.equal(mergeBackTransfer.sourceThreadId, materialized.targetThreadId); - assert.equal(mergeBackTransfer.targetThreadId, materialized.sourceThreadId); - assert.equal(mergeBackTransfer.sourcePoint.runId, materialized.forkRunId); - assert.equal(mergeBackTransfer.basePoint?.runId, materialized.firstRunId); - assert.equal(mergeBackTransfer.status, "consumed"); - assert.equal(mergeBackTransfer.targetRunId, sourceProjection.runs[2]?.id); - assert.equal(mergeBackTransfer.resolution?.strategy, "fork_delta_context"); - assert.equal( - mergeBackTransfer.resolution?.strategy === "fork_delta_context" - ? mergeBackTransfer.resolution.contextHandoffId - : null, - handoff.id, - ); - - const mergeBackRunItems = sourceProjection.turnItems.filter( - (item) => item.runId === sourceProjection.runs[2]?.id, - ); - assert.deepEqual( - mergeBackRunItems.map((item) => item.type), - ["handoff", "user_message", "assistant_message", "checkpoint"], - ); - const handoffItem = mergeBackRunItems[0]; - assert.equal(handoffItem?.type, "handoff"); - assert.equal( - handoffItem?.type === "handoff" ? handoffItem.contextHandoffId : null, - handoff.id, - ); - assert.equal(handoffItem?.ordinal, 299); - const mergeUserItem = mergeBackRunItems.find((item) => item.type === "user_message"); - assert.equal( - mergeUserItem?.type === "user_message" ? mergeUserItem.text : null, - mergeBackPrompt, - ); - assert.notInclude( - sourceProjection.turnItems - .filter((item) => item.type === "user_message") - .map((item) => item.text) - .join("\n"), - "Context handoff", - "context handoff text should be provider input only, not projected user-visible message text", - ); - assert.include( - sourceProjection.turnItems - .filter((item) => item.type === "assistant_message") - .map((item) => item.text) - .join("\n"), - mergeBackAssistantText, - ); - - const visibleTypes = sourceProjection.visibleTurnItems.map((row) => row.item.type); - assert.includeMembers(visibleTypes, ["handoff", "user_message", "assistant_message"]); - const sourceShell = result.shellSnapshot.threads.find( - (thread) => thread.id === materialized.sourceThreadId, - ); - assert.isDefined(sourceShell); - assert.equal(sourceShell.visibleItemCount, sourceProjection.visibleTurnItems.length); - - assert.include( - forkProjection.turnItems - .filter((item) => item.type === "user_message") - .map((item) => item.text) - .join("\n"), - forkPrompt, - "merge-back should not remove fork-local history", - ); - assert.equal(forkProjection.contextTransfers[0]?.resolution?.strategy, "native_fork"); - }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), - ); }); diff --git a/apps/server/src/provider/acp/XAiAcpExtension.test.ts b/apps/server/src/provider/acp/XAiAcpExtension.test.ts index 31ccac4a0597..8181c1e4e54c 100644 --- a/apps/server/src/provider/acp/XAiAcpExtension.test.ts +++ b/apps/server/src/provider/acp/XAiAcpExtension.test.ts @@ -10,7 +10,6 @@ import { describe, expect } from "vite-plus/test"; import { XAiExitPlanModeRequest, XAI_EMPTY_PLAN_MARKDOWN, - makeXAiExitPlanModeCapturedResponse, isGrokPlanMarkdownPath, extractXAiExitPlanMarkdown, extractGrokPlanMarkdownFromToolCallData, @@ -24,7 +23,6 @@ import { isGenericAcpToolTitle, isXAiMonitorTool, isXAiPersistentMonitor, - makeXAiAskUserQuestionCancelledResponse, makeXAiAskUserQuestionResponse, makeXAiPromptCompletionRuntime, normalizeXAiAcpToolCallState, @@ -1270,12 +1268,6 @@ describe("XAiAcpExtension", () => { }); }); - it("encodes interrupted dialogs as xAI cancelled responses", () => { - expect(makeXAiAskUserQuestionCancelledResponse()).toEqual({ - outcome: "cancelled", - }); - }); - it("does not echo preview annotations for multi-select answers", () => { const response = makeXAiAskUserQuestionResponse( { @@ -1730,13 +1722,6 @@ describe("Grok exit_plan_mode capture (#8358)", () => { expect(extractXAiExitPlanMarkdown(wrapped, "")).toBe(XAI_EMPTY_PLAN_MARKDOWN); expect(extractXAiExitPlanMarkdown(wrapped)).toBe(XAI_EMPTY_PLAN_MARKDOWN); }); - it("builds an abandoned exit_plan_mode response that captures the plan", () => { - expect(makeXAiExitPlanModeCapturedResponse()).toEqual({ - outcome: "abandoned", - feedback: - "The client captured your proposed plan. Stop here and wait for the user's feedback or implementation request in a later turn.", - }); - }); it("identifies Grok plan.md paths and extracts markdown from tool call data", () => { const linuxHost = { platform: "linux" as const, environment: {} }; const windowsHost = { platform: "win32" as const, environment: {} };