Skip to content

fix(mobile): fold subagent lifecycle rows into one batch per spawn - #10211

Merged
juliusmarminge merged 2 commits into
t3code/mobile-work-row-expand-only-with-extrafrom
t3code/mobile-subagent-spawn-batches
Sep 5, 2026
Merged

juliusmarminge merged 2 commits into
t3code/mobile-work-row-expand-only-with-extrafrom
t3code/mobile-subagent-spawn-batches

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 5, 2026 •

Copy link
Copy Markdown
Member

Stacked on #10210.

Problem

Each subagent's progress and completion rendered as its own timeline row on mobile (three agents → three "Running …" rows plus their completions), while web folds a turn's spawns into one "Kicked off N subagents" row via collapseDerivedWorkLogEntries in session-logic.ts.

Fix

Mirror web's batching in the mobile work log:

  • Same spawn-group keys (wf:<coordinator> for workflows, direct:<turn> for direct spawns), decided at the first row seen per taskId so later rows under synthetic turns cannot splinter the batch.
  • Agent lifecycle rows pass the agent-internal filter even when bypassed or owned by another agent, as on web; that is how Codex children (all bypassed) and Claude workflow members reach the batch row.
  • The batch row keeps the anchor's identity so it renders where the run launched.
  • Background tasks (agentKind !== "agent") keep one row per task, as before.
  • Web reads live agent state from its Agents panel; mobile has no such surface, so the row carries each member's latest lifecycle state, derives its own lifecycle from them (live while any member is, then the worst terminal state), and lists the members when opened. A Codex child's idle turn end counts as finished, and a finished coordinator settles members that never reported their own end. That lifecycle feeds the group summary and shimmer from fix(mobile): restore live tool shimmer and add a Thinking row #10173 unchanged.

Verification

  • vp test run apps/mobile/src/lib/threadActivity.test.ts — 98 passed, including new tests that fold two direct spawns into one row and track it through running → one done → one failed, fold bypassed workflow members into the coordinator's batch and settle them with it, and finish a Codex child on idle; plus updated expectations for the resumed-agent and Antigravity batch cases.
  • tsc --noEmit for apps/mobile, targeted lint and format.
  • Simulator, same seeded turn (three agents: two running, one finished) on main and this branch.

Before: three separate subagent rows. After: one "Kicked off 3 subagents · 1 working" row.

Implemented by Claude Fable 5 in the Claude Code harness.

Note

Fold subagent lifecycle rows into one batch row per spawn in mobile threadActivity

  • Replaces one-row-per-agent-task rendering with one aggregated row per workflow or direct-spawn batch in the mobile work log; shell, monitor, and plan tasks remain ordinary per-task rows.
  • Agent task rows that were previously filtered as internal now reach feed derivation so they can be grouped by workflow, turn, or task ID into spawn batches.
  • Adds helpers for batch lifecycle precedence (in-progress > failed > stopped > completed), member merging by task ID, label generation with live/failed/stopped member counts, and expanded-body formatting listing each member's title, status, and detail.
  • Workflow coordinators are excluded from displayed member counts and details; a terminal coordinator settles unfinished workflow members to its own terminal state.
  • Updates tests in threadActivity.test.ts to assert batch-row grouping, anchor identity, member counts, terminal states, and idle-as-completed behavior.
  • Behavioral Change: isAgentInternalActivity now retains agent task rows with task IDs (including bypassed rows) for batch folding instead of filtering them; consumers of collapseDerivedWorkLogEntries will see fewer rows and new structured spawn metadata on WorkLogEntry.

Macroscope summarized a83379d.

Each subagent's progress and completion rendered as its own timeline row
on mobile, while web folds a turn's spawns into one "Kicked off N
subagents" row. Use the same spawn-group keys as web's session-logic,
keep the batch anchored where the run launched, derive its lifecycle
from the members, and list the members with their states when the row
is opened.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 13.6 KiB — 15.1 KiB ✅
Codex Thread snapshot wire — 7.0 KiB — 7.3 KiB ✅
Codex Live turn WebSocket wire — 6.6 KiB — 7.8 KiB ✅
Codex Live turn WebSocket decoded — 57.1 KiB — 66.4 KiB ✅
Codex Live turn messages — 10 — 21 ✅
Claude Total thread wire — 13.5 KiB — 15.1 KiB ✅
Claude Thread snapshot wire — 7.0 KiB — 7.3 KiB ✅
Claude Live turn WebSocket wire — 6.5 KiB — 7.8 KiB ✅
Claude Live turn WebSocket decoded — 57.8 KiB — 66.4 KiB ✅
Claude Live turn messages — 9 — 21 ✅

Baseline: unavailable · PR result: a83379d · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Comment thread apps/mobile/src/lib/threadActivity.ts
Comment thread apps/mobile/src/lib/threadActivity.ts
Comment thread apps/mobile/src/lib/threadActivity.ts
@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR changes the existing mobile work-log behavior by replacing individual agent lifecycle rows with stateful batches across direct spawns and workflows. The implementation spans filtering, aggregation, lifecycle derivation, and expanded rendering, making the change broader than a straightforward isolated fix.

You can add or adjust custom eligibility rules. Learn more.

Bypassed workflow member rows were dropped before batching, so a
workflow batch only ever held its coordinator, and a Codex child's
idle turn end left the batch working forever. Let agent lifecycle rows
through the internal filter the way web does, treat idle as a finished
member, and settle members that never reported their own end when the
coordinator finishes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@juliusmarminge
juliusmarminge merged commit 579a775 into main Sep 5, 2026
26 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/mobile-subagent-spawn-batches branch September 5, 2026 22:57
incognitojam added a commit to incognitojam/styal that referenced this pull request Sep 24, 2026
When the PR selected for `early` does not apply at the reconciled
upstream boundary, the command stopped with a single line that gave
nothing to act on:

```console
$ node scripts/upstream-queue.ts early 11784 --through upstream/main
Selected pingdotgg#11784 cannot be applied at the upstream boundary.
```

That happens when the PR builds on upstream work the fork has not taken
in yet, and the planner only looks for dependencies in the changes it
replays after a successful apply.

The command now reports which of the PR's files conflict at the boundary
and which earlier pending upstream PRs and direct commits change those
files, in upstream order. Text output lists the first 20 and says how
many remain; `--json` includes every source with its SHA, PR, and title.
A plan that succeeds prints as before. The intake runbook's `early`
paragraph describes the report.

## Validation

- A new test in `scripts/upstream-early.test.ts` checks which sources
the report lists: pending sources after the boundary and before the
blocked PR whose files overlap the conflicting paths, including direct
commits and directory prefixes, and not recorded or later sources.
- `scripts/upstream-early.test.ts` and `scripts/upstream-queue.test.ts`
pass (21 tests); lint, formatting, and the scripts typecheck are clean.
- Against fetched fork `main` (`495b7cfd5`) and upstream `main`
(`b2b43bef7`), the same command now prints:

  ```console
  $ node scripts/upstream-queue.ts early 11784 --through upstream/main
  Fork 495b7cf; reconciled through d28077e
pingdotgg#11784 does not apply at the reconciled boundary. 16 of its files
conflict there:
    apps/mobile/src/features/threads/ThreadFeed.tsx
    apps/mobile/src/features/threads/thread-work-log.tsx
    apps/mobile/src/lib/threadActivity.ts
    apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts
    apps/server/src/orchestration/decider.ts
    apps/server/src/provider/Layers/ClaudeAdapter.test.ts
    apps/server/src/provider/Layers/ClaudeAdapter.ts
    apps/server/src/textGeneration/ThreadTitleContext.test.ts
    apps/server/src/textGeneration/ThreadTitleContext.ts
    apps/server/src/ws.ts
    apps/web/src/components/chat/MessagesTimeline.logic.ts
    apps/web/src/components/chat/MessagesTimeline.tsx
    apps/web/src/components/settings/SettingsPanels.tsx
    packages/client-runtime/src/state/environmentHttpAuth.test.ts
    packages/client-runtime/src/state/threadSnapshotHttp.ts
    packages/contracts/src/orchestration.ts
Earlier pending upstream changes to those files: 110 PRs. Take them in
first, or add their PRs to this plan.
pingdotgg#9594 fix(connect): refresh HTTP credentials without reconnecting
(pingdotgg#9594)
    pingdotgg#9894 fix(chat): show hours for long runs (pingdotgg#9894)
pingdotgg#9933 fix(settings): share restart continuation across environments
(pingdotgg#9933)
    pingdotgg#10092 fix(web): scale agent spawn rows with interface font (pingdotgg#10092)
pingdotgg#9965 fix(web): keep the composer expanded until the thread can scroll
(pingdotgg#9965)
pingdotgg#9935 fix(web): align tool disclosure chevrons with expanded state
(pingdotgg#9935)
pingdotgg#10199 fix(mobile): size a chat image's frame before its bytes arrive
(pingdotgg#10199)
pingdotgg#10200 fix(web): size the chat image slot from server-reported
dimensions (pingdotgg#10200)
pingdotgg#10167 refactor(client-runtime): remove unused runtime exports and
helpers (pingdotgg#10167)
pingdotgg#10173 fix(mobile): restore live tool shimmer and add a Thinking row
(pingdotgg#10173)
pingdotgg#10210 fix(mobile): only make work rows expandable when the body adds
something (pingdotgg#10210)
pingdotgg#10211 fix(mobile): fold subagent lifecycle rows into one batch per
spawn (pingdotgg#10211)
    pingdotgg#10212 fix(mobile): stop clipping expanded tool groups (pingdotgg#10212)
    pingdotgg#9875 feat: show provider usage limits with /usage-limits (pingdotgg#9875)
pingdotgg#9561 fix(ui): unify loading and refresh feedback across clients (pingdotgg#9561)
pingdotgg#10226 refactor(web): keep feature component helpers private (pingdotgg#10226)
pingdotgg#9754 feat(settings): add shared project defaults and scoped overrides
(pingdotgg#9754)
pingdotgg#9895 feat(connections): balance new threads across connected machines
(pingdotgg#9895)
pingdotgg#10273 fix(mobile): stop the work log flickering during subagent runs
and failing calls (pingdotgg#10273)
    pingdotgg#10271 fix(mobile): save linked media from chat (pingdotgg#10271)
    ... 90 more; --json lists every source.
  ```

`--json` returns the same 16 paths and all 110 sources. `early 5521
--through upstream/main`, which plans successfully, prints the same
summary as before.

---
Written by an agent (Claude Code, claude-opus-5-5).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant