All pages
On this page

Turns and the queue

A turn is one round of work: you send a prompt, the agent works on it, and it answers. A conversation is a series of turns, one after another. When you send a message while a turn is still running, OAR holds it in a queue until the turn is over. When a turn stops making progress, OAR notices, puts it back in the queue or ends it with a note, and does not leave it spinning.

Steering a running turn and the Stop button are on While a turn runs. Restarts are on Restarts and resume.

The states of a turn #

State What you see
Queued Your message is in the transcript with a Cancel button under it.
Running The reply bubble fills as the agent works, with its tool activity and a Stop button. The conversation shows as busy in the list.
Waiting on a question A question card says Waiting for your answer. The turn goes on when you answer.
Finished The reply is complete.
Failed The reply is a short system note that says what happened. See When a turn fails.
Stopped You pressed Stop.

A turn that waits on a question card is never treated as stuck. See ask_user for the card itself.

Sending while a turn runs #

What the send button reads during a turn tells you what will happen to the message:

  • Steer: the message goes into the running turn. This is available on Claude, DeepSeek and Copilot's SDK engine.
  • Queue: the message waits behind the turn and starts as the next one. The button reads Queue on every other provider, and also on Claude, DeepSeek and the SDK engine while the turn waits on a question card or a plan approval, or while it is compacting, and on the SDK engine while a tool call is running. There the message waits as a queued message and goes into the turn once the card is answered, the compaction has ended or the tool call has finished.

Queued messages run in the order they were sent, oldest first.

If your device is offline when you press send, the browser keeps the message and shows You are offline. Message queued — it will send when the connection returns. That is a different queue: it is on your device and empties itself when the connection is back.

Cancelling one queued message #

A queued message has a Cancel button until the agent picks it up. Pressing it removes the message from the queue and shows Queued message cancelled. If the agent has started on the message in the meantime, the relay says Message is already being processed. Use Stop on the thinking bubble instead.

Empty queue #

The ⋯ menu of a conversation has a Queue line. It shows the counts of the whole relay, not of this conversation:

pending=1, processing=1, parked=0

Pending messages wait for their turn. Processing ones are running. Parked ones are held back, for example while the relay restarts.

🚮 Empty queue next to it drops all of them, in every conversation, including the message of a turn that is running right now. A confirmation asks first:

Drop all queue rows in pending, processing, and parked states?
This is a local maintenance action and cannot be undone.

Afterwards a notice reads Queue emptied: dropped 3 rows., or Queue is already empty. when there was nothing to drop. Added in 0.9.11 Any signed-in browser can use it: it needs the access token and nothing else (see Endpoints only the relay's machine may use). If the relay refuses it, Failed to empty queue names the reason. The action only removes the messages from the queue. It does not tell a running agent to stop; use Stop for that. To get rid of one message, use Cancel on it instead.

Requeueing #

A turn that went wrong is not always lost. The relay puts it back in the queue and tries again when:

  • the turn was stuck (see below),
  • the session's worker process died while it was running,
  • the worker reported a failure that is worth another attempt.

Each requeue counts as an attempt. The limit is 5 attempts per message (maxRequeueRetries in the config file, read at start-up), so the fifth failure is final. The wait before the next attempt depends on the cause:

Cause Wait
A turn that was stuck 30 seconds (2 seconds while the relay considers its agent connection offline)
The session's worker process died 2 seconds
The worker reported a failure 1, 2, 4, then 8 minutes after the first, second, third and fourth failure
The worker reported a failure within 15 seconds of the start, before any activity or reply text 10, 20, 40, then 80 seconds

At the limit the message fails for good, with a note (see below).

Two kinds of turn are not replayed. A message that was already folded into a running turn would be answered twice, so it fails with a note instead. A background task's own continuation reply has no prompt to send again, so it is dropped.

When a turn is stuck #

A turn can be slow, or it can be stuck. OAR cannot tell by looking at the answer, so it watches for signs of life. There are three kinds of watch: the relay watches the worker, each worker watches its agent, and two limits bound background work and question cards.

Timer Default Where you change it What you see when it fires
Inactivity: no sign of life from the session's worker 10 min (45 s while the relay considers its agent connection offline) processingTimeoutMs in the config file, in milliseconds; restart the relay after editing The turn goes back to the queue and starts again after 30 seconds.
Max turn duration: one turn's total time 60 min, 0 to 10 h in 5-minute steps; 0 means no limit Settings → General → Max turn duration The same: back in the queue. On Grok the turn fails with a note instead.
Silence from a Copilot (SDK engine), Cursor or Grok runtime: nothing in flight 120 s OAR_TURN_STALL_IDLE_MS in the relay's environment; 0 turns the watch off The turn fails with a system note.
The same, while a model request is running 300 s OAR_TURN_STALL_MODEL_MS; 0 means no limit The turn fails with a system note.
The same, while a tool call is running 30 min OAR_TURN_STALL_TOOL_MS; 0 means no limit The turn fails with a system note.
Background task timeout: background work alone keeps a session running after its reply 4 h, 0 to 10 h in 5-minute steps; 0 means no limit Settings → General → Background task timeout The relay stops the tasks. On Claude Cloud the turn ends instead. See By provider.
Question card wait 8 h; 2 h on Copilot's extension engine Not adjustable The agent is told nobody answered and goes on according to the conversation's mode.

The three OAR_TURN_STALL_* variables on Linux and macOS

Where sessions run under tmux, a variable set for the relay is not handed on to the agents' processes, and these three may then have no effect. See which variables reach the agents.

How they work together:

  • The relay watches the worker. The worker reports every 10 seconds which message it is working on. As long as it does, the turn is alive, however long it runs. If the reports stop for the inactivity window, the relay puts the turn back in the queue. It checks every 15 seconds.
  • Max turn duration is the hard stop. It catches a worker that hangs but keeps reporting. A turn is over the limit when the later of two moments is older than the setting: the start of the turn, and the last question card you answered. So an interview that waited hours for your answers is not cut off right after the last answer. There is one catch. When the check requeues any turn, it requeues every running turn whose start is older than the limit, and it does not look at your answers for those. A turn you answered a card in recently can therefore go back to the queue together with another turn that hit a limit in the same check (every 15 seconds). If a long turn is requeued without an apparent reason, raise this setting or set it to 0.
  • Each worker also watches its agent. For Copilot's SDK engine, Cursor and Grok, a turn with no event at all from the runtime for longer than its window fails. The window depends on what the runtime is doing: a command that prints nothing can be quiet for a long time, a model that is writing is not. That is why the three windows differ. When only the idle window is set, the other two scale with it.
  • A waiting turn is never stuck. A turn that waits on a question card stops both relay guards and the worker's silence watch. (The Grok cap and the extension engine's 2-hour limit do not pause for it.) A compaction and a relay_tool call hold the silence watch as well. Max turn duration does not know about a long relay_tool wait, so a wait close to its maximum with the default 60 minutes can be cut short by it.
  • Background tasks are separate. The task timeout only counts after the reply, when background tasks alone keep the session going. It does not limit a turn. Claude Cloud is the exception, see below.

A requeue is not shown as an error. The message goes back to queued and runs again. Only when the attempts run out does the turn fail.

When a turn fails #

A failed turn ends with a reply from the relay, in plain text. It says what happened, ends with an error code, and tells you what to do next. A turn that the silence watch ended reads, for example:

System note: the Copilot runtime sent nothing for 300s while a model request was running, so the relay ended the turn.

When the tool was the one running, the note names it: while a tool was running (build). A runtime that no longer answers when the relay asks reads the Copilot runtime stopped answering … (nothing for 120s, no reply when asked), so the relay ended the turn.

A message that ran out of attempts fails with one of these:

Relay timeout after 5 attempts. Message was skipped to keep the queue moving. Retry the message.
Relay recovery limit reached after 5 attempts (stale-recovery). The worker kept dying before completing this turn, so the message was failed to keep the queue moving. Send it again to retry.

Most failures end with the advice to send the message again. Two things help:

  • Send it again. Paste or retype the message, or press Resend where the transcript offers it. Resend appears on a message that was steered into a turn which then failed or was stopped. Its marker reads Steered into the turn above, which failed — not answered. or Stopped with the turn — not answered. After you press it, the button reads Resent on every device.
  • Use the button on the reply. Some failures name a fix the relay can do for you, and the failed reply carries a button for it. A Claude account problem shows Claude settings. Added in 0.9.17 A DeepSeek turn refused because the balance is used up shows Top up DeepSeek and DeepSeek settings; one refused for the API key shows DeepSeek settings (see DeepSeek errors). A Grok turn that could not start shows Install Grok CLI and Grok settings, or Sign in to Grok and Grok settings when it was not signed in.

A conversation whose session worker stopped for a launch problem shows a Retry button on the note, which starts the worker again.

A conversation that seems wedged can be freed with ☠️ Kill session in the ⋯ menu, which stops its worker. Then send the message again.

By provider #

The queue, Cancel, Empty queue, the inactivity window and Max turn duration are the same on every provider. What differs is the watch on the agent itself.

Provider Silence watch Steer or Queue
GitHub Copilot and OpenAI, SDK engine Yes: 120 s, 300 s and 30 min. Once per idle window the worker asks the runtime whether it is still there, with 5 seconds to answer; a runtime that does not answer ends the turn at once. Steer
GitHub Copilot, extension engine No silence watch. A turn is limited to 2 hours in all; when that runs out, the turn goes back to the queue and counts as a failed attempt, with the waits above. With the default 60 minutes, Max turn duration normally acts first. A question card waits 2 hours. Queue
Claude Observes only. A turn the CLI has not spoken in for 10 minutes (30 with a tool open) is written to the worker's log and left running, because ending it would kill the CLI and its background tasks. Steer
DeepSeek Added in 0.9.17 As Claude: a DeepSeek chat runs Claude Code, with the same observe-only watch. Steer
Claude Cloud No silence watch on the agent. The worker watches its connection: a stream with no data for 120 s is reopened, and a stream that stays away for 5 minutes hands the message back to the queue, where the next attempt follows the same turn instead of sending it again. A cloud turn that is quiet while its connection is alive keeps running. When the agent ends its turn while background work still runs, the turn stays open for Background task timeout (60 minutes if that is 0). Then it ends with an activity line telling you to send a message to see how the work went. Queue
Cursor Yes, with the same three windows. There is no idle phase while a run is going: it counts as a model request unless a tool call is open. Queue
Grok Yes, with the same three windows; a pending relay_tool call is asked about first. An OAR_TURN_STALL_IDLE_MS of 0 does not turn it off here. The turn is also capped at Max turn duration, counted from the start of the turn without a restart for answered questions, and a card you leave unanswered counts too. A Grok turn that reaches the cap fails with System note: the Grok turn stalled and was stopped (grok turn exceeded the 60-minute turn ceiling). Send a new message to retry. (or the number you set). Queue

Background task timeout applies to Claude, Claude API, DeepSeek, Copilot's SDK engine and Claude Cloud. On Claude, Claude API and DeepSeek it stops the background tasks. On Copilot's SDK engine the relay cancels them. On Claude Cloud it only sets how long the turn waits for them. It does not apply to the other providers.