DEV Community

Solon Framework
Solon Framework

Posted on

When a Coding Agent Is Already Working: Steer the Current Task and Queue the Next One in SolonCode

A coding agent is most useful when it is doing real work. It is also most frustrating when a new fact arrives halfway through that work.

You may notice a missed constraint, discover that the requested change is too broad, or simply remember the next task while the current one is still reading files. The old workflow was to wait, stop the agent, or keep the next instruction in your head.

SolonCode Web offers two different ways to handle that moment: steer the active run with a text-only follow-up, or put a later task into the task queue. They look similar from the input box, but they have different semantics.

The short version

  • Steer is for information that belongs to the active run.
  • Queue is for work that should happen after the active run.
  • A steer message is not a hard interrupt. It is injected at a safe reasoning boundary; it does not forcibly stop a model stream or an in-flight tool call.
  • The Web task queue is a browser-managed FIFO queue with persistence. It is not a server-side scheduler that keeps executing after the browser disappears.

That distinction is the feature. It lets the developer choose between changing the current context and preparing the next unit of work.

Two paths from the same input box

While a session is streaming, the Web input gives the user a useful hint: Enter to steer now / Tab to queue. The two paths eventually produce different state transitions.

Steer: add context to the active run

A plain text message submitted while the task is running is sent to the session's steer endpoint. The server accepts it into a small, session-scoped mailbox. It does not rewrite the system prompt and it does not interrupt an already-running tool call.

At the next eligible reasoning boundary, the pending text is drained in submission order and added to working memory as a user message. Internally, the injected message carries a source=steer marker and a visible prefix identifying it as a real-time user addition.

There are two important safeguards:

  1. The first reasoning turn is protected, so a late input cannot rewrite the original prompt before the run has established its context.
  2. If the last assistant message contains an open tool call, the steer waits. This avoids breaking the tool-use/tool-result pair.

In other words, “steer now” means “make this information available to the current run at the next safe point,” not “take over the model immediately.”

Once the server confirms that the text has been accepted, the UI keeps it in a pending state. It is not immediately rendered as a normal user turn. When the system.steer_applied event arrives, the message is shown as a steer note inside the current assistant bubble when possible. That placement makes the timeline honest: the note belongs to the run that was already in progress.

The steer endpoint also has explicit fallback cases. If the session is no longer running, the message is sent normally. If the run changed or the steer mailbox is full, the message is moved to the ordinary task queue. A single steer message is limited to 4,096 characters and the mailbox holds at most five pending messages.

Queue: prepare a later run

A queued message is different. It is not additional context for the current reasoning loop. It is a follow-up task waiting for the active session to become idle.

The browser stores queue items in FIFO order. Each item can retain text plus selected run metadata such as the model, reasoning effort, thinking mode, and selected agent. When the session is idle, the queue drainer takes the head item and sends it through the normal message path.

The queue has a maximum of ten items. The Queue Dock shows the total of ordinary queued items and pending steer items, while pending steers are displayed first with a Pending badge. Ordinary queue entries can be edited or cancelled; a pending steer cannot be individually cancelled through the current UI because the server mailbox does not expose per-message removal.

What the queue does—and does not—promise

The queue is persisted through the Web client. The browser sends the queue to /web/chat/queue, and the server stores it as a JSON cache, preferring queue-tasks.json while retaining compatibility with the older queue.json name.

This persistence is useful, but it needs to be described precisely:

  • A page reload can hydrate the waiting text and its metadata.
  • Hydration does not automatically send the restored tasks; the user must continue by pressing Enter.
  • File attachments are not persisted as binary data. An attachment-only item is not written to disk, and a text item retains only an attachment marker after restoration.
  • The server endpoint reads and writes the queue cache; it does not run a background scheduler.
  • A queue can help a session survive a refresh, but it is not a durable job system for a closed browser.

That last point is easy to miss. “Queued” means “waiting in the Web session's follow-up queue,” not “guaranteed to execute on a remote worker.”

A practical decision rule

Use a steer when the new message changes how the current task should think:

  • “Keep this read-only.”
  • “Do not touch the generated files.”
  • “The compatibility requirement is Java 8.”
  • “Prioritize the security issue you just found.”

Use the task queue when the message describes work that should begin later:

  • “After the analysis, draft a remediation plan.”
  • “Then update the documentation.”
  • “Finally, run the tests and report failures.”

The distinction is similar to adding a note to the current work versus adding the next card to a workflow. A steer refines the active run. A queue item waits for its own normal turn.

Interruption is not rollback

Steering and stopping should not be confused with rollback.

Stopping a task does not automatically restore every file, undo every tool side effect, or recreate a previous workspace. If an agent has already written a file, inspect the diff and the working tree. If a tool call is in progress, wait for the UI to report the resulting state rather than assuming that the stop button means the operation was reversed.

Likewise, seeing a follow-up message in the Queue Dock proves that the message is waiting; it does not prove that it has run. For a trustworthy workflow, check:

  • which task is active;
  • which messages are pending or queued;
  • whether the active run actually ended;
  • whether the next item started once the session became idle;
  • what files and Git state changed.

A small experiment worth repeating

For a safe demonstration, use a temporary or read-only workspace and start a bounded analysis. While it is running:

  1. Submit a short constraint with Enter.
  2. Watch for the pending and applied steer states.
  3. Add a separate follow-up task with Tab.
  4. Confirm that the follow-up remains visible rather than being treated as current-run context.
  5. Let the first run finish and observe whether the queue head is sent.
  6. Repeat after a refresh and verify that restored items wait for explicit continuation.

This experiment tests the user-visible contract without claiming that the queue is a distributed scheduler. It also reveals the most important operational fact: the developer can see whether a message is changing the current run or waiting for the next one.

The useful mental model

Think in terms of two lanes:

Active run
  ├── steer message → pending → applied at a safe reasoning boundary
  └── stop          → run ends; inspect side effects

Follow-up lane
  └── queued task → FIFO waiting → normal send when the session is idle
Enter fullscreen mode Exit fullscreen mode

This is a small interaction design choice, but it changes the rhythm of agent-assisted development. You do not have to interrupt every time a new thought appears, and you do not have to wait for every later task before recording it.

The important habit is to choose the lane deliberately: steer the current run when the new information belongs to it; queue the next task when it does not.

Final checklist

Before relying on either path in a real repository:

  • bound the task and state whether edits are allowed;
  • use steer for current-run constraints, not for unrelated future work;
  • use queue for explicit follow-up work;
  • do not treat accepted input as completed execution;
  • do not treat stopping as rollback;
  • inspect file and Git changes after interruption;
  • verify queue order and the next task's start;
  • remember that restored queue items require explicit continuation;
  • avoid attachments when you need the queued item to survive a refresh;
  • test the exact SolonCode version and client you plan to use.

SolonCode's “steer” and task queue are not competing versions of the same button. One preserves control inside the current reasoning loop; the other preserves intent for the next run. Together, they make a running coding agent feel less like a black box and more like a workflow you can actively shape.

Tested with SolonCode Web. The implementation details described here are based on the Web client and CLI source available in the SolonCode repository; other clients may expose different controls or wording.

Repository: https://github.com/opensolon/soloncode
Documentation: https://solon.noear.org/article/soloncode

Top comments (0)