From 1c411db2a5f7ea2a12601d25d9a954ec6c91ce6d Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Sat, 17 Oct 2026 13:12:26 -0700 Subject: [PATCH] fix(native-chat): a refused steer leaves its turn as the chat's latest request (#29907) A steer Codex answered into a turn that then ended without taking it is rejected and moved to the thread, so the sidebar verdict and the completion feed treated it as a refused request of its own and reported it in place of the turn it joined. --- .../structured-agent-session-latest-request.test.ts | 8 ++++++-- src/shared/structured-agent-session-latest-request.ts | 7 ++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/shared/structured-agent-session-latest-request.test.ts b/src/shared/structured-agent-session-latest-request.test.ts index 6f73d8ecb82..443d5ba9441 100644 --- a/src/shared/structured-agent-session-latest-request.test.ts +++ b/src/shared/structured-agent-session-latest-request.test.ts @@ -191,11 +191,15 @@ const ROWS: Row[] = [ items: [ userEntry('m1', 1), turn('t1', 2, { state: 'completed', outcome: 'success', completedAt: 50 }), - userEntry('steer', 3, 't1') + userEntry('steer', 3) ], submissions: [ sent('m1', { dispatchState: 'accepted' }), - rejected('steer', 'no active turn to steer', 30) + sent('steer', { + dispatchState: 'rejected', + reason: 'no active turn to steer', + answeredInTurn: { turnItemId: 'codex:turn:t1', via: 'steer' } + }) ], outcome: 'success', listed: true diff --git a/src/shared/structured-agent-session-latest-request.ts b/src/shared/structured-agent-session-latest-request.ts index be8bd69ddc4..fbefd134bd2 100644 --- a/src/shared/structured-agent-session-latest-request.ts +++ b/src/shared/structured-agent-session-latest-request.ts @@ -82,7 +82,12 @@ export function latestStructuredAgentSessionRequest( } } const submission = rejected.get(item.itemId) - if (submission && classifyDispatchRejection(submission).verdict === 'failure') { + // Rejection relocates a refused steer to the thread, but its turn remains the request. + if ( + submission && + submission.answeredInTurn?.via !== 'steer' && + classifyDispatchRejection(submission).verdict === 'failure' + ) { return { kind: 'refused-send', id: item.itemId,