diff --git a/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.ts index df0f4043cb09..20a6b5280b4c 100644 --- a/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.ts @@ -1165,12 +1165,16 @@ export function makeCursorAdapterV2( const emitToolArtifacts = Effect.fnUntraced(function* (input: { readonly active: ActiveCursorToolCall; readonly completed: boolean; + /** Terminal status for a tool the turn ended before Cursor completed it. */ + readonly unfinishedStatus?: "interrupted" | "failed" | "cancelled"; }) { const { active } = input; const toolCall = active.toolCall; const now = yield* DateTime.now; const failed = input.completed && cursorToolFailed(toolCall); - const status = input.completed ? (failed ? "failed" : "completed") : "running"; + const status = !input.completed + ? "running" + : (input.unfinishedStatus ?? (failed ? "failed" : "completed")); const nodeId = idAllocator.derive.nodeFromProviderItem({ driver: CURSOR_PROVIDER, nativeItemId: active.callId, @@ -1968,8 +1972,14 @@ export function makeCursorAdapterV2( } input.context.finalized = true; const completedAt = yield* DateTime.now; + // Tools still here never got a tool-call-completed. A stopped or + // failed turn cut them short, so they end with the turn's status. for (const tool of input.context.tools.values()) { - yield* emitToolArtifacts({ active: tool, completed: true }); + yield* emitToolArtifacts({ + active: tool, + completed: true, + ...(input.status === "completed" ? {} : { unfinishedStatus: input.status }), + }); } input.context.tools.clear(); // This interaction stops delivering updates at finalization. Tasks diff --git a/apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/cursor_output.ts b/apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/cursor_output.ts index becc6006a970..ad4d01018d5d 100644 --- a/apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/cursor_output.ts +++ b/apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/cursor_output.ts @@ -63,6 +63,7 @@ export function assertTurnInterruptMidToolCursorOutput( assert.isDefined(interruptRequest); assert.isDefined(interruptResult); assert.include(commandItem.input, "node -e"); + assert.equal(commandItem.status, "interrupted"); assert.equal(interruptRequest.status, "completed"); assert.equal(interruptResult.status, "interrupted"); assert.equal(interruptResult.parentItemId, interruptRequest.id);