OpenProgram / Web / Conversation input

Queue and active-turn steering

Each message typed during a run picks its destination when it is sent. Enter and the send button steer: the text is added to the exact active execution at a supported safe point. Cmd/Ctrl+Enter queues: the conversation sends it as one follow-up after the preceding turn ends. Neither queue action cancels the active execution; cancellation belongs to the separate Stop control.

Reference and compatibility

Codex prompting separates queued follow-ups from active-turn input. Codex App Server binds steering to the expected active turn and does not accept runtime-setting overrides. OpenProgram uses its existing execution command service and safe points instead of adding a second session inbox or provider-specific steering transport.

Delivery

Queued text → execution identity and current version → durable execution.steer command → next safe point → persisted steering user message

The queue retains an entry until a matching applied receipt confirms that its user message is persisted. Accepted or applying commands are checked automatically with the same envelope. The command carries only the message, exact execution identity, version and an idempotency key. It does not change permissions, models, tools or the current running program. Unsupported or ended executions leave the entry queued; idle reconciliation drains normal follow-ups in FIFO order.

Before posting, the client retains the immutable command envelope. A lost acknowledgement leaves delivery unconfirmed: the row remains visible, normal drain cannot send it again, and automatic confirmation retries reuse the same envelope. Confirmation uses one timer per queued row, starting at 1.5 seconds and backing off to at most 30 seconds after transport failures. A definitive receipt clears retry state; uncertain delivery never becomes an ordinary duplicate send. A confirmed stale-version rejection permits one new envelope against a fresh snapshot of the same execution. Errors are visible; injected flags are always released after transport failure.

Ownership and UI

The active session and its running execution determine the target. Another session or related sub-Agent is never selected opportunistically. There is no standing queue-or-steer preference; the key chosen at send time decides. Queued messages show as one raised card docked above the input box. The heading counts the rows and how many are being added to this turn, and collapses the card. Each row is one line: a tag (This turn while its steer is in flight, Next turn while it waits, Not sent or Unconfirmed after a failure), the first line of text, and actions shown on hover or keyboard focus. The actions are a non-cancelling add-to-this-turn, retry, edit and removal when delivery is not uncertain. Clicking the text expands the full message and its attachments. Clear all removes every row in one write except rows being delivered or edited, so clearing never drains a row that was about to be removed. Attachments retain their existing draft behavior; steering accepts text within the canonical command size limit.

Normal follow-up admission resolves its predecessor from the durable session head before updating the server conversation mirror. It includes the preceding assistant reply, tool results and delivered steering inputs; explicit branch predecessors remain unchanged.

Cancelled and interrupted assistant turns retain their partial content and display their terminal status, including empty replies. A cancellation notice does not infer who initiated the cancellation.

Storage boundary

Ordinary queue entries remain in renderer memory. Pending text steering receipts and stopped or ended steering drafts use same-window session storage. Pending steering entries cannot be drained as ordinary messages until a definitive acknowledgement resolves the command. Canonical acceptance persists the command on the server; application persists the user message. When an execution finishes, undelivered steering commands are rejected and their rows can resume ordinary queuing. A completed tool batch is never skipped merely because a steering message arrives. This change does not replace ordinary chat transport with a new message broker.

Acceptance

Implementation status

The implementation uses canonical execution commands and non-cancelling queue controls. Agent command application confirms persisted user input in the active reply branch; safe-point admission alone remains applying. Owner expiry cannot authorize a late input write. Execution closure resolves undelivered commands even when the execution awaits effect reconciliation. Acceptance uses the default App and real request handling; static checks do not replace that runtime acceptance.

Automatic receipt confirmation and terminal assistant status notices are implemented. The expanded lifecycle audit passes independent specification and quality review and its complete verification manifest.

Function retry acknowledgement

Each retry carries a request identity echoed by its dispatch acknowledgement or rejection. The acceptance timer ends when dispatch is accepted, not when the function finishes. A rejection or disconnected send restores only the corresponding pending card and reports the actual cause once. Missing acknowledgements remain uncertain and are not automatically resubmitted. History and surface validation remain authoritative.

Steering lifecycle audit contract

Steering binds to the execution selected when the user requests it. A version retry can refresh that execution's version but cannot select a replacement execution. Stop retains an in-flight instruction as an unsent draft even when admission has not yet completed. An uncertain command remains immutable until the server provides a definitive receipt; Stop must not erase it or permit duplicate ordinary dispatch.

The renderer retains text-only steering commands and stopped or ended steering drafts in same-window session storage. Refresh restores them without replaying ordinary chat. After authoritative session hydration, unresolved commands are confirmed using their original identity. Ordinary unsent queues and attachments remain memory-only. Storage is best-effort when browser storage is unavailable; it is not a second server command log.

Acceptance covers Stop during snapshot retrieval and version retry; replacement executions; replay after accepted or lost acknowledgements and refresh; multiple accepted inputs; provider text, reasoning and silent waits; tools, pause and continuation; cancellation and cold history; unsupported targets, attachment and length limits, and cross-session authorization. The command service remains authoritative for receipt order and execution ownership. No provider-specific transport or new permission mechanism is introduced.

The lifecycle repair passes independent specification and quality review. The combined verification manifest reports 3,279 Python tests passed, two existing skips, 964 Web tests passed and eight browser tests passed. Static checks, TypeScript and documentation links pass. The local release ledger records the exact reviewed implementation and installed-App acceptance separately.

Audit coverage

BoundaryObservable behaviorRegression evidence
Input preparationExpanded paste, attachments, 4,096 Unicode code pointssubmit-reliability.test.mjs
Target ownershipSession identity; snapshot replacement; same-execution version retrysubmit-reliability.test.mjs; execution_cursor_auth_audit
Duplicate and uncertain commandsSame-envelope retry; one confirmation timer; bounded transport backoffsubmit-reliability.test.mjs
Stop before admissionSnapshot and version-rejection races retain the draftsubmit-reliability.test.mjs
Refresh and storageAccepted, lost ACK and stopped commands; exact replay; storage denialtest_queue_steer.py; submit-reliability.test.mjs
StreamingText, reasoning and silent provider wait interrupt; partial content survivestest_streaming_steer.py
Tools and pauseWhole tool batch completes; paused inputs enter continuationtest_safe_points.py; test_continue_step_steer.py
Durable commandsAccepted order, idempotency, checkpoint rollback, owner expirytest_safe_points.py; test_continue_step_steer.py
HistoryCancelled partial reply; explicit next-turn predecessor; no head rewindtest_streaming_steer.py; test_queue_steer.py