Skip to content

TEMP local-only: keep finished agents out of the Running section (safe to delete once upstream fixes this) - #8

Merged
VincentBailly merged 3 commits into
mainfrom
local/agents-view-done-in-running
Sep 2, 2026
Merged

TEMP local-only: keep finished agents out of the Running section (safe to delete once upstream fixes this)#8
VincentBailly merged 3 commits into
mainfrom
local/agents-view-done-in-running

Conversation

@VincentBailly

@VincentBailly VincentBailly commented Sep 2, 2026

Copy link
Copy Markdown
Owner

This PR is temporary and meant to be deleted

It is a local-only workaround for a fork of PrimeIntellect-ai/prime-agent.
Nothing here belongs upstream. A future rebase should drop it as soon as the
upstream code classifies finished agents correctly on its own.

Every line to remove is marked:

git grep "LOCAL PATCH(agents-view-done-in-running)"

Two hits: the guard in packages/coding-agent/src/modes/agents-view/agents-view-state.ts,
and packages/coding-agent/test/agents-view-done-in-running.test.ts, which is a local
file in its entirety.

How to prove it is safe to delete

  1. Delete the guard block in agents-view-state.ts (keep the test file for now).
  2. Run npx vitest --run packages/coding-agent/test/agents-view-done-in-running.test.ts.
  3. If it still passes, upstream classifies finished agents correctly. Delete the test
    file too and drop this branch.
  4. If it fails, upstream has not fixed it. Keep the guard.

Full revert in one command:

git apply -R /tmp/agents-view-regression/fix.patch

The bug

In the agents view, finished top-level agents stay in the Running section with the
label classifying.

classifyAgentsViewSession trusts summary.rosterStatus. The supervisor ledger only
re-publishes a roster row when a summarizer verdict text changes. When the summary
model returns an empty verdict every time, nothing changes, no flush happens, and the
row keeps activity: "working" and rosterStatus: "running" forever. On this machine
all 102,076 agent_status entries across 400 transcripts have an empty recap, so every
finished top-level agent gets stuck.

Introduced upstream on 2026-09-01 by 8d5722e (PR 1897, which dropped the
refreshWorkerSummaries pass in handleList) and 1d2e91d (PR 1900, which deleted the
one-second poll that used to re-derive activity from live state, and made classification
prefer rosterStatus).

The change

Do not trust rosterStatus === "running" when no live busy signal backs it. The row
still stays Running when it is queued, has an armed heartbeat, is actually active, has
running RLM children, or has no activeSessionId. Otherwise it is idle.

11 lines of code plus comments, in one function, plus a separate test file.

Upstream status

Not reported upstream for the agents view. Nothing merged upstream fixes it. Related
but unmerged: discussion 1873 (completed RLM worker stays active in the status APIs),
PR 1872 (auto-closed 13 seconds after opening because the contributor was unvouched),
and open PR 1967, which reports the same shape of bug for heartbeat sessions and edits
the same classifiers.

Rebase note for PR 1967: git apply --3way of this change onto its head (4ab2af3)
applies cleanly, because PR 1967 leaves the body of classifyAgentsViewSession byte for
byte the same. If PR 1967 lands, delete the hasActiveHeartbeat !== true line from the
guard and the matching test assertion, since PR 1967 removes the heartbeat to running rule.

Validation

Run in a scratch worktree through prime-agent-isolate, live daemon untouched:

  • npx tsgo --noEmit: clean.
  • npx biome check --error-on-warnings on both files: clean.
  • npx vitest --run on 12 files (agents-view, agent-roster, daemon-agent-roster,
    daemon-session-list, daemon-protocol, subagent-summary-line,
    daemon-supervisor-lazy-subagents): 246 passed, 1 failed.
  • That one failure ("arms the saved-search fetch once...") reproduces at clean HEAD in a
    separate worktree, so it is pre-existing and unrelated.

What this does not fix

Stuck queued-child rows, heartbeat ancestor promotion, the other surfaces (list,
list_agents, the subagents bar), the 25-second re-summarize loop, and the stale
classifying label that the row still shows after it moves to Idle.

Vincent Bailly added 2 commits September 2, 2026 13:05
… section

Fork-local workaround. Do not merge upstream. Delete it once upstream
classifies finished agents correctly.

Finished agents stay in the agents-view Running section forever. The
supervisor ledger only re-publishes a roster row when the summarizer
verdict text changes, so a finished agent keeps activity "working"
(label "classifying") and a frozen rosterStatus "running". This guard
trusts "running" only when a hard busy signal still backs it.

Greppable marker sites (both carry the marker LOCAL PATCH(agents-view-done-in-running)):
  packages/coding-agent/src/modes/agents-view/agents-view-state.ts
  packages/coding-agent/test/agents-view-done-in-running.test.ts

Drop test, one command: delete the guard block in agents-view-state.ts, then run

  npx vitest --run packages/coding-agent/test/agents-view-done-in-running.test.ts

If it still passes without the guard, upstream fixed the bug: delete the
guard block AND the whole test file.

Upstream refs: PrimeIntellect-ai#1873, PrimeIntellect-ai#1872, PrimeIntellect-ai#1967.
Caused by 8d5722e / 1d2e91d.
…iew Running section

Fork-local workaround. Do not merge upstream. Delete it once upstream puts
a session with a busy descendant in the Running section by itself.

A session that is idle itself but has a streaming, tool-running, or queued
descendant renders under Idle today. A parent only learns about its subtree
through summary.hasRunningRlmChildren, a snapshot taken when its own roster
row was last flushed, and AgentSession.hasRunningRlmChildren() only counts
child runs still "running" or "queued". The agents view already holds one
live row per descendant, so this patch classifies an ancestor from those
rows: any Idle ancestor of a Running row becomes Running. Inactive
ancestors are left alone.

Greppable marker sites (all carry the marker LOCAL PATCH(agents-view-active-ancestors)):
  packages/coding-agent/src/modes/agents-view/agents-view-state.ts (call site + helper)
  packages/coding-agent/test/agents-view-active-ancestors.test.ts

Drop test, one command: delete the LOCAL PATCH helper and its call site in
agents-view-state.ts, then run

  npx vitest --run packages/coding-agent/test/agents-view-active-ancestors.test.ts

If it still passes, upstream does this natively and the workaround is dead:
delete both blocks and the whole test file.
…estors

TEMP local-only: show sessions with busy descendants in the Running section (safe to delete once upstream does this)
@VincentBailly
VincentBailly merged commit 1b7ebdf into main Sep 2, 2026
10 of 13 checks passed
sethkarten pushed a commit to PrimeIntellect-ai/prime-agent that referenced this pull request Sep 3, 2026
)

A finished top-level agent stayed in the agents view Running section as
"classifying" forever: the roster's activity axis holds an idle session
at "working" until its summarizer verdict is current, but the summarizer
only notified (and thereby scheduled a roster flush) when the verdict
TEXT or task state changed. A settle that produced the same text at a
new message count updated the verdict's currency without ever
republishing the row, freezing rosterStatus at "running" with the
"classifying" label.

The change gate now treats an idle settle that refreshes
basedOnMessageCount as a status change; working refreshes with unchanged
text stay quiet. The dead agentStatusChanged export duplicated the old
two-field predicate (with no production caller) and is deleted.

Diagnosis credit: Vincent Bailly (VincentBailly#8), whose
consumer-side workaround this producer fix supersedes.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant