Skip to content

feat(web): steer a queued message (SDK harnesses) - #2022

Merged
serena-ruan merged 3 commits into
mainfrom
feat/queue-steer-message
Jul 6, 2026
Merged

feat(web): steer a queued message (SDK harnesses)#2022
serena-ruan merged 3 commits into
mainfrom
feat/queue-steer-message

Conversation

@serena-ruan

Copy link
Copy Markdown
Collaborator

Related issue

N/A

Summary

  • Adds a per-row steer (send-now) button to the composer's "Queued" strip.
    Clicking it POSTs that message immediately instead of waiting for the idle
    flush. On an SDK harness the server live-injects it into the running turn (no
    interrupt — it folds in at the agent's next breakpoint); the optimistic bubble
    promotes on POST.
  • It sends to the agent captured at enqueue time and can jump ahead of earlier
    queued messages (steer = "this one, now").
  • Scoped to SDK harnesses. Native terminals buffer & drain rather than
    inject mid-turn, so the steer button is hidden there
    (isNativeTerminalSession) until that path lands — tracked in
    docs/QUEUE_STEER_DESIGN.md.
  • Fourth step of the queue+steer design; native steer + reorder still to come.

Test Plan

  • Unit (web, vitest): chatStore.test.ts covers steerMessage (sends the
    chosen message now, to its enqueue-time agent, out of FIFO order; no-op on a
    missing id). QueuedMessagesStrip.test.tsx covers the steer button appearing
    only when onSteer is provided and invoking it with the row's queueId. 255
    passing.
  • Gates: npm run type-check, tests, prettier all pass.

Demo

Type of change

  • Bug fix
  • Feature
  • UI / frontend change
  • Refactor / chore
  • Docs
  • Test / CI
  • Breaking change

Test coverage

  • Unit tests added / updated
  • Integration tests added / updated
  • E2E tests added / updated
  • Manual verification completed
  • Existing tests cover this change
  • Not applicable

Coverage notes

steerMessage and the strip's steer button (presence + queueId wiring) are
covered by unit tests; the mid-turn delivery reuses the server's existing
live-injection path (send() while streaming), already exercised elsewhere.

This pull request and its description were written by Isaac.

Adds a per-row steer (send-now) button to the composer's queued strip:
clicking it POSTs that message immediately instead of waiting for the idle
flush. On an SDK harness the server live-injects it into the running turn;
the optimistic bubble promotes on POST. It sends to the agent captured at
enqueue time and can jump ahead of earlier queued messages.

Gated to non-native sessions: native terminals buffer & drain rather than
inject mid-turn, so no steer button is shown there until that path lands
(tracked in docs/QUEUE_STEER_DESIGN.md).

Co-authored-by: Isaac
@github-actions github-actions Bot added the size/M Pull request size: M label Jul 6, 2026
@omnigent-ci

omnigent-ci Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Polly AI Review

Review: feat(web): steer a queued message (SDK harnesses)

1. Blocking issues

None. The change is small, additive, and the core steerMessage reducer is correct: it resolves the agent (target.agentId ?? boundAgentId), no-ops safely when the id is missing or no agent is available, and removes the message from the queue before the async send() so a concurrent maybeFlushQueuedHead can't double-send it. The onSteer prop is optional and correctly gated off for native-terminal sessions.

2. Security vulnerabilities

None. No new network surface, auth boundary, deserialization, or injection path — steerMessage reuses the existing send() flow, which already handles the streaming/live-inject case. No dependency or lockfile changes.

3. Non-blocking notes

  • Destination is the current conversation, not the message's captured one. steerMessage forwards the enqueue-time agentId, but send() pins its destination to get().conversationId (submitConversationId), not target.conversationId. In practice the strip filters rows to the active conversation (QueuedMessagesStrip messages={queuedMessages.filter(... === conversationId)}), so a steered row's conversationId always equals the current one and this is safe today. Still, steerMessage itself has no conversation guard, so a future non-UI caller passing a cross-conversation queueId would send that text into the wrong session. A cheap guard (skip/relocate when target.conversationId !== get().conversationId) would make the reducer robust independent of the caller. Worth a one-line comment at minimum.
  • No failure feedback on the steer path. void s.send(...) fire-and-forgets; the message is already removed from the queue optimistically. If the POST fails, send()'s own catch rolls back the pending bubble and surfaces an error block, so the user isn't left silent — but the message is not returned to the queue, so a failed steer is lost from the strip. This matches the existing maybeFlushQueuedHead behavior, so it's consistent, not a regression; flagging only as an edge case.
  • Test coverage is solid for what changed (out-of-FIFO send to enqueue-time agent, missing-id no-op, button presence gated on onSteer, queueId wiring). The mid-turn live-injection itself isn't covered here, but it reuses the already-exercised streaming send() path, as the description notes.
  • Demo is a TODO placeholder. Per repo PR conventions this is a UI change, so a short clip is expected before merge — worth resolving the <!-- TODO --> in the description.

4. Summary

A clean, well-scoped fourth step in the queue+steer series. The reducer correctly captures the enqueue-time agent, removes-before-send to avoid a double-flush race, and cleanly gates the button off for native terminals. No correctness, contract, or security problems in the diff. The only substantive design note is that steerMessage relies on the UI filter rather than its own guard to keep steering within the active conversation — safe today, worth hardening. Approvable once the demo placeholder is addressed per repo PR conventions.


Automated review by Polly · workflow run

Replace the icon-only steer button with a labeled '↳ Steer' (corner-down-
right arrow + text) and remove the redundant 'Queued' tag — the strip's
position above the composer already signals queued state.

Co-authored-by: Isaac
Drives the SPA against a spawned server: a first message is acked but
never gets a session.status event, so the session stays busy; a follow-up
queues in the docked strip; clicking Steer POSTs it immediately — which
can only happen via steer, since the session never went idle to trigger
the auto-flush. Asserts the steered message POSTs and leaves the queue.

Co-authored-by: Isaac
@github-actions github-actions Bot added size/L Pull request size: L and removed size/M Pull request size: M labels Jul 6, 2026
def _worker() -> None:
try:
asyncio.run(coro)
except BaseException as exc:
@serena-ruan
serena-ruan merged commit 687db94 into main Jul 6, 2026
33 checks passed
@serena-ruan
serena-ruan deleted the feat/queue-steer-message branch July 6, 2026 10:04
@github-actions github-actions Bot added the needs-doc-update Merged PR needs a user-facing docs update label Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🏷️ Doc impact: needs-doc-update

Adds a user-facing "Steer" button to queued messages in the web chat UI (send-now mid-turn), a new interaction that changes how users manage the client-side message queue and should be reflected in web UI docs.

Drafting a docs PR to omnigent-ai/omnigent-site (staged on 0.5-docs until release)…

Auto-classified on merge. Set the label manually before merging to override. · run

serena-ruan added a commit to omnigent-ai/omnigent-site that referenced this pull request Jul 8, 2026
* docs: document omnigent-ai/omnigent#2022

* docs: add steering gif and simplify message queue section

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>
dhruv0811 added a commit to omnigent-ai/omnigent-site that referenced this pull request Jul 10, 2026
* docs: document omnigent-ai/omnigent#1722 (#261)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2018 (#265)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1386 (#272)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2156 (#278)

* docs: document omnigent-ai/omnigent#2156

* Apply suggestion from @serena-ruan

* Apply suggestions from code review

Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2022 (#268)

* docs: document omnigent-ai/omnigent#2022

* docs: add steering gif and simplify message queue section

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@3c7a558 (#274)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#526 (#279)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: rename hindsight extra to memory (omnigent[memory]) (#282)

The memory tools ship under the `memory` extra (omnigent[memory]), not
`hindsight`. Update the install instruction and extra name to match.
The Hindsight product name and the hindsight_* tool names are unchanged.

* docs: document default base branch for new worktrees (#284)

* docs: document default base branch for new worktrees

* docs: condense worktree branches section and add setting demo gif

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@7fb779f (#281)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* chore(api): sync openapi.json from omnigent@60e775a (#288)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2152 (#280)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1859 (#277)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2135 (#276)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>
Co-authored-by: Pat Sukprasert <pattara.sk127@gmail.com>
Co-authored-by: Dhruv Gupta <dhruv.gupta@databricks.com>
yours-aditya pushed a commit to yours-aditya/omnigent that referenced this pull request Jul 16, 2026
* feat(web): steer a queued message (SDK harnesses)

Adds a per-row steer (send-now) button to the composer's queued strip:
clicking it POSTs that message immediately instead of waiting for the idle
flush. On an SDK harness the server live-injects it into the running turn;
the optimistic bubble promotes on POST. It sends to the agent captured at
enqueue time and can jump ahead of earlier queued messages.

Gated to non-native sessions: native terminals buffer & drain rather than
inject mid-turn, so no steer button is shown there until that path lands
(tracked in docs/QUEUE_STEER_DESIGN.md).

Co-authored-by: Isaac

* fix(web): label steer action and drop the Queued tag

Replace the icon-only steer button with a labeled '↳ Steer' (corner-down-
right arrow + text) and remove the redundant 'Queued' tag — the strip's
position above the composer already signals queued state.

Co-authored-by: Isaac

* test(e2e_ui): steer a queued message sends it mid-turn

Drives the SPA against a spawned server: a first message is acked but
never gets a session.status event, so the session stays busy; a follow-up
queues in the docked strip; clicking Steer POSTs it immediately — which
can only happen via steer, since the session never went idle to trigger
the auto-flush. Asserts the steered message POSTs and leaves the queue.

Co-authored-by: Isaac
Signed-off-by: Aditya Devarapalli <adityareddyd2@gmail.com>
daniellok-db added a commit to omnigent-ai/omnigent-site that referenced this pull request Jul 17, 2026
* docs: document omnigent-ai/omnigent#1722 (#261)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2018 (#265)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1386 (#272)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2156 (#278)

* docs: document omnigent-ai/omnigent#2156

* Apply suggestion from @serena-ruan

* Apply suggestions from code review

Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2022 (#268)

* docs: document omnigent-ai/omnigent#2022

* docs: add steering gif and simplify message queue section

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@3c7a558 (#274)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#526 (#279)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: rename hindsight extra to memory (omnigent[memory]) (#282)

The memory tools ship under the `memory` extra (omnigent[memory]), not
`hindsight`. Update the install instruction and extra name to match.
The Hindsight product name and the hindsight_* tool names are unchanged.

* docs: document default base branch for new worktrees (#284)

* docs: document default base branch for new worktrees

* docs: condense worktree branches section and add setting demo gif

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@7fb779f (#281)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* chore(api): sync openapi.json from omnigent@60e775a (#288)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2152 (#280)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1859 (#277)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2135 (#276)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document official kubernetes server image variant (#285)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>
Co-authored-by: Pat Sukprasert <pattara.sk127@gmail.com>
Co-authored-by: Dhruv Gupta <dhruv.gupta@databricks.com>
Co-authored-by: Daniel Lok <daniel.lok@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-doc-update Merged PR needs a user-facing docs update size/L Pull request size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant