fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(client-runtime): stop counting the workflow coordinator as a working agent - #5808

Closed
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count
Closed

fix(client-runtime): stop counting the workflow coordinator as a working agent#5808
artieeg wants to merge 1 commit into
pingdotgg:mainfrom
artieeg:fix/workflow-coordinator-live-count

Conversation

@artieeg

@artieegartieeg commented Aug 9, 2026

Copy link
Copy Markdown

Closes#5807

What changed

deriveAgentPanelModel counted the workflow coordinator as one of the agents doing work. A workflow running a single member reported two:

  • composer banner: "2 agents working in the background"
  • Agents panel footer: "2 working · 1 settled"
  • inline spawn card: "Spine · 1 working" ← the only correct one

The tally loop in packages/client-runtime/src/state/subagentRuntime.ts iterated every roster entry, including the coordinator (kind === "workflow"), which stays running for the whole run. So liveCount = runningCount + waitingCount was always one higher than the number of agents actually working.

liveCount now applies the same coordinator-exclusion rule the totalTokens sum four lines below already used: skip a coordinator that has members. A memberless coordinator still counts, so a workflow that has not spawned its first member — or is between phases — does not read as zero agents.

runningCount / waitingCount still count every roster entry, preserving the existing bucket-sum invariant (idle + running + waiting + settled === roster.length). AgentsPanel's footer switches to liveCount so both surfaces agree with the inline card.

Why it should exist

The banner is the only visible Stop affordance for background work, so its count is what a user reads to decide whether anything is still running. It disagreed with the two other surfaces in the same view. With N concurrent workflows the banner is off by N, and a workflow whose members have all settled between phases reads "1 agent working" when zero are.

Note the inline card is unaffected and stays correct: "Kicked off 2 subagents" is the batch size (how many were spawned), not a live count.

Before / after

Identical fixture, one member running and one settled. Only the two counts differ.

BannerPanel footer
Before2 agents working in the background● 2 working · 1 settled
After1 agent working in the background● 1 working · 1 settled

Unchanged in both: inline card Kicked off 2 subagents · ride-shelf-v2 — Spine · 1 working, panel header 1/2 settled, RECON 1 done, SPINE 1 active · 0 done.

Before:
image

After:
image

Tests

Two cases added to subagentRuntime.test.ts:

  • coordinator excluded — liveCount is 1 while runningCount is 2
  • memberless coordinator still counts as 1, so a mid-spawn workflow does not read as zero

Verified red/green: with the source change reverted the first test fails expected 2 to be 1; with it applied 48/48 pass. vp lint and tsgo --noEmit clean for both packages.

Scope

3 files, +35 / −5. No behavior change outside the two count readouts.

🤖 Generated with Claude Code


Note

Low Risk
UI-only count logic in client-runtime with targeted tests; no auth, data, or server behavior changes.

Overview
liveCount no longer treats workflow coordinators as working agents when they already have member rows, so the composer banner, panel footer, and inline cards agree (e.g. one running member reads as 1 working, not 2).

In deriveAgentPanelModel, liveCount is computed in the roster loop instead of runningCount + waitingCount. Live agents (running, pending, waiting) count toward liveCount unless they are a workflow coordinator with members—the same rule already used for totalTokens. A coordinator with no members still counts, so mid-spawn or between-phase runs do not show zero.

The Agents panel footer now displays model.liveCount directly. runningCount / waitingCount are unchanged and still sum to roster size with idle and settled.

Tests cover coordinator exclusion vs runningCount, and memberless coordinators still contributing liveCount of 1.

Reviewed by Cursor Bugbot for commit 17a1a6f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix liveCount in deriveAgentPanelModel to exclude workflow coordinators that have members

  • liveCount previously equaled runningCount + waitingCount, which included workflow coordinators even when they duplicate work already counted via their members.
  • deriveAgentPanelModel now computes liveCount independently: non-workflow agents count if running, pending, or waiting; coordinators only count when they have no members.
  • The AgentsPanel footer now uses model.liveCount directly instead of summing runningCount + waitingCount.
  • Behavioral Change: the working-agents count shown in the UI will be lower in workflows where coordinators have active members.

Macroscope summarized 17a1a6f.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cdc43c0-17c7-4470-a9e9-120cebd9b728

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved be6bf47

A straightforward bug fix that corrects an inflated agent count in the UI by excluding workflow coordinators from the "working" tally. The change follows an existing pattern in the same file, is well-documented in code comments, and includes comprehensive unit tests.

You can customize Macroscope's approvability policy. Learn more.

…ing agent
deriveAgentPanelModel tallied liveCount over every agent in the roster,
including the workflow coordinator. A workflow running a single member
therefore reported two live agents: the composer banner read "2 agents
working in the background" and the Agents panel footer read "2 working",
while the inline spawn card — which counts members only — correctly read
"1 working".
liveCount now applies the same coordinator-exclusion rule the totalTokens
sum two lines below already used: skip a coordinator that has members. A
memberless coordinator still counts, so a workflow that has not spawned
its first member (or is between phases) does not read as zero agents.
runningCount/waitingCount keep counting every roster entry, preserving
the bucket-sum invariant; AgentsPanel's footer switches to liveCount so
both surfaces agree.
@juliusmarminge
juliusmarmingeforce-pushed the fix/workflow-coordinator-live-count branch from be6bf47 to 17a1a6fCompareAugust 15, 2026 10:51
@juliusmarminge
juliusmarminge enabled auto-merge (squash) August 15, 2026 11:31
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as superseded by #6672, which merged and fixes the same underlying issue (#5807).

Both PRs patch deriveAgentPanelModel's coordinator double-count. #6672's fix is a strict superset of this one: it hoists a single continue that excludes a workflow coordinator (when it has members) from the whole status tally loop — runningCount, waitingCount, idleCount, settledCount, liveCount, and totalTokens — whereas this PR only corrects liveCount and left runningCount/waitingCount still counting the coordinator (relying on the panel switching to liveCount for display).

Rebasing this branch onto current main produces a real conflict in subagentRuntime.ts/subagentRuntime.test.ts against #6672's already-merged fix — confirming the overlap. Thanks for the report and the fix here; #6672 covers it. 🙏

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

Labels

size:S10-29 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Background-work banner counts the workflow coordinator as a working agent

2 participants

@artieeg@juliusmarminge