Skip to content

[bug] Navigating back loses 'working on it' — the run is still going and the API already reports it #252

Description

@serge-ivo

The symptom

Start work, navigate away, come back — "working on it" is gone. The agent may still be working; the
console simply stops claiming so. There is no way to tell a finished run from a running one.

It is entirely client-side, and the data already exists

The thinking indicator is local React state. pages/InstanceDetail.tsx:

:80    const [thinking, setThinking] = useState(false);
:327   setThinking(true);      // on send
:352   setThinking(false);     // when the reply lands

Never seeded from the server. Unmount discards it; remount starts at false.

The loop watcher only knows about loops this tab started. pollLoop opens with:

if (!id || !loopRunIdRef.current) return;

loopRunIdRef is set when you press Loop in that tab. After a remount it is null, so the
watcher returns immediately every tick — even with a run active.

But the server can answer this already:

Source What it gives
GET /v1/instances/:id/loop (routes/tools.ts:457listLoopRuns) every run for the instance, with status + iteration
GET /v1/instances/:id/loop/:runId (:460) one run
WS broadcast already emits {type:"status", status:"thinking"}
AgentDO state records status: "thinking" (readable via /state)

Nothing needs building on the backend. The Assistant tab just never asks on mount.

And the one UI that does show runs is in the wrong place

LoopRunsSection — the component that lists loop runs — is rendered only in
SettingsTab.tsx:1145. So the answer to "is my agent working?" lives in Settings, several clicks
from the Assistant tab where the work was started and where the user is looking.

Proposal

  • On mount, call GET /v1/instances/:id/loop; if a run is running, adopt its id into
    loopRunIdRef and resume the existing watcher. The polling machinery already works — it is only
    missing its starting value.
  • Show a persistent indicator on the Assistant tab whenever a run is active, with the iteration
    count that pollLoop already reads.
  • For a plain chat turn, seed the thinking state from the DO's own status rather than assuming
    idle. Note ensureStateDefaults (agent-do-prompt.ts:63) resets thinking/erroridle
    when the DO reloads, which is a sensible self-heal but means status is only trustworthy while
    the object is warm — so treat it as a hint, and let [bug] A chat turn is bound to the request — navigating away can lose the reply while its tool side effects persist #251 decide what "in flight" should durably
    mean for chat.
  • Consider surfacing LoopRunsSection (or a compact form of it) where work happens, not only in
    Settings.

Verification

  • Start a loop, navigate to another agent and back: the indicator and iteration count return
    without a page reload.
  • Two tabs open on the same instance both show the run — neither "owns" it.
  • A finished run clears on return rather than showing stale "working".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions