Summary
When a user steers an Agent Mode run while an agent_run.wait caller is blocked, RepoPrompt wakes the wait as interrupted_by_steering but does not include the user's steered message in that interrupt/wake payload. The UI looks correct because the user bubble is appended immediately, but the provider/agent can resume before the underlying harness has delivered the actual user text.
This is especially visible with Codex: the interrupt fires, the waiting harness wakes, and the model may go back to waiting because it did not yet see the user's steered message.
Expected behavior
Visually, steering should appear exactly the same to the user. Internally, the interrupt/wake that reaches the waiting agent should include the user's steered message directly, instead of relying on a later harness follow-up to pass the message.
Actual behavior
agent_run.wait wakes with result: "interrupted_by_steering" and guidance to call agent_run.wait again.
- The wake result does not carry the steered message.
- Provider-specific message delivery remains separate from the wake/interrupt path.
- If the interrupt is observed before the harness delivers the user text, the model can continue as if no user input arrived and return to waiting.
Relevant code surfaces
MCP wait wake/result plumbing:
Sources/RepoPrompt/Infrastructure/MCP/Agent/AgentRunSessionStore.swift
WakeReason.steeringRequested
wakeCurrentWaiters(...)
Sources/RepoPrompt/Infrastructure/MCP/Agent/AgentRunMCPToolService.swift
interrupted_by_steering single-wait and multi-wait result shaping
_meta.wake_reason = steering_requested
Agent Mode steering dispatch:
Sources/RepoPrompt/Features/AgentMode/ViewModels/AgentModeViewModel.swift
- active MCP dispatch planning for Claude/ACP/Codex
wakeMCPWaitersForActiveDispatch(...)
- queued Claude/ACP interrupt handling
Sources/RepoPrompt/Features/AgentMode/Runtime/AgentModeRunService.swift
- queued steering drain around MCP wait scopes
Provider-specific surfaces:
Sources/RepoPrompt/Features/AgentMode/Runtime/Claude/ClaudeAgentModeCoordinator.swift
Sources/RepoPrompt/Infrastructure/AI/Providers/ClaudeCode/SDK/ClaudeNativeProcessSessionController.swift
Sources/RepoPrompt/Features/AgentMode/Runtime/Codex/CodexAgentModeCoordinator.swift
Sources/RepoPrompt/Infrastructure/AI/Providers/Codex/AppServer/CodexNativeSessionController.swift
- Codex
turn/steer carries user text, while turn/interrupt and thread/resume do not carry a pending user message today.
Acceptance criteria
- A run blocked in
agent_run.wait receives an interrupt/wake payload that includes the user's steering message.
- The visible Agent Mode UI remains unchanged: the optimistic user bubble and interaction flow should look the same.
- Claude/ACP/Codex do not double-deliver the same steering message if the interrupt payload carries it.
- Codex active
turn/steer ACK-gated behavior remains intact.
- Tests cover single-wait and multi-wait steering interruption payloads, plus provider-specific duplicate-delivery prevention.
Suggested regression coverage
Existing nearby tests to extend or mirror:
Tests/RepoPromptTests/MCP/AgentRunMCPToolServiceWaitTests.swift
Tests/RepoPromptTests/MCP/AgentRunMCPToolServiceWaitAnyTests.swift
Tests/RepoPromptTests/MCP/AgentRunWaitDrainIntegrationTests.swift
Tests/RepoPromptTests/AgentMode/Codex/CodexAgentModeCoordinatorLivenessTests.swift
Tests/RepoPromptTests/AgentMode/Codex/CodexSteerAckTrackerTests.swift
Tests/RepoPromptTests/AgentMode/Codex/CodexFallbackFIFOTests.swift
Risks / implementation notes
- Avoid duplicate delivery if both the interrupt payload and the existing follow-up prompt path include the same message.
- Be careful with privacy/logging: the steering text would become part of the MCP wait payload, so diagnostics should avoid unnecessary raw-text logging.
- Preserve provider-specific semantics. Codex, Claude-compatible, and ACP steering paths do not currently share identical interrupt/message-delivery mechanics.
Related issues
No direct duplicate found. Related but broader lifecycle/wait issues include:
Summary
When a user steers an Agent Mode run while an
agent_run.waitcaller is blocked, RepoPrompt wakes the wait asinterrupted_by_steeringbut does not include the user's steered message in that interrupt/wake payload. The UI looks correct because the user bubble is appended immediately, but the provider/agent can resume before the underlying harness has delivered the actual user text.This is especially visible with Codex: the interrupt fires, the waiting harness wakes, and the model may go back to waiting because it did not yet see the user's steered message.
Expected behavior
Visually, steering should appear exactly the same to the user. Internally, the interrupt/wake that reaches the waiting agent should include the user's steered message directly, instead of relying on a later harness follow-up to pass the message.
Actual behavior
agent_run.waitwakes withresult: "interrupted_by_steering"and guidance to callagent_run.waitagain.Relevant code surfaces
MCP wait wake/result plumbing:
Sources/RepoPrompt/Infrastructure/MCP/Agent/AgentRunSessionStore.swiftWakeReason.steeringRequestedwakeCurrentWaiters(...)Sources/RepoPrompt/Infrastructure/MCP/Agent/AgentRunMCPToolService.swiftinterrupted_by_steeringsingle-wait and multi-wait result shaping_meta.wake_reason = steering_requestedAgent Mode steering dispatch:
Sources/RepoPrompt/Features/AgentMode/ViewModels/AgentModeViewModel.swiftwakeMCPWaitersForActiveDispatch(...)Sources/RepoPrompt/Features/AgentMode/Runtime/AgentModeRunService.swiftProvider-specific surfaces:
Sources/RepoPrompt/Features/AgentMode/Runtime/Claude/ClaudeAgentModeCoordinator.swiftSources/RepoPrompt/Infrastructure/AI/Providers/ClaudeCode/SDK/ClaudeNativeProcessSessionController.swiftSources/RepoPrompt/Features/AgentMode/Runtime/Codex/CodexAgentModeCoordinator.swiftSources/RepoPrompt/Infrastructure/AI/Providers/Codex/AppServer/CodexNativeSessionController.swiftturn/steercarries user text, whileturn/interruptandthread/resumedo not carry a pending user message today.Acceptance criteria
agent_run.waitreceives an interrupt/wake payload that includes the user's steering message.turn/steerACK-gated behavior remains intact.Suggested regression coverage
Existing nearby tests to extend or mirror:
Tests/RepoPromptTests/MCP/AgentRunMCPToolServiceWaitTests.swiftTests/RepoPromptTests/MCP/AgentRunMCPToolServiceWaitAnyTests.swiftTests/RepoPromptTests/MCP/AgentRunWaitDrainIntegrationTests.swiftTests/RepoPromptTests/AgentMode/Codex/CodexAgentModeCoordinatorLivenessTests.swiftTests/RepoPromptTests/AgentMode/Codex/CodexSteerAckTrackerTests.swiftTests/RepoPromptTests/AgentMode/Codex/CodexFallbackFIFOTests.swiftRisks / implementation notes
Related issues
No direct duplicate found. Related but broader lifecycle/wait issues include: