[Bug]: Grok subagents do not show correctly in the Agents panel
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Start T3 Code with Grok Build authenticated (
grok login) and Grok CLI on PATH. - Create a new thread on the Grok provider, model
grok-4.6. - Send a prompt that causes the parent to call
spawn_subagentat least twice, for example:Use spawn_subagent to launch two independent explore subagents, each inspecting a different part of this repo, then summarize what they found. - While the children are running, open the thread's Agents panel.
- Wait until the parent turn settles (
end_turn) while the subagents are still working, and look at the Agents panel and composer again.
Expected behavior
Each Grok spawn_subagent child should appear in the Agents panel as a live roster row (title/role, status, activity, tokens), the same way Claude Task and Codex collab children already do via task.started / task.progress / task.completed.
The panel empty-state copy already promises this:
When this thread spawns subagents or runs a workflow, they show up here with live status, activity, and token usage.
After the parent turn ends, in-process Grok children that are still running should keep their rows in a running/idle state instead of making the thread look finished.
spawn_subagent should not be the only (and bulky) representation of that work in the parent transcript.
Actual behavior
Grok children run, but they never show correctly in the Agents panel:
- The parent transcript only gets a fat
spawn_subagenttool row (plus laterget_command_or_subagent_outputpolls). - The Agents panel stays empty (
No agents yet), even while several children are in flight. - Child ACP session updates are dropped, so there is no live child status, model, or token usage in the roster.
- The parent Grok turn often ends (
end_turn) while those children keep running inside the Grok process. T3 then looks idle even though work is still happening.
This is reproducible on current main with Grok CLI 1.0.13 / grok-4.6. I hit it on ordinary multi-agent turns, not a one-off.
Impact
Major degradation or frequent failure
Version or commit
T3 Code (Alpha) 0.0.38; main @ 9cb40178a53cca279c67a9079afab3cddf6b6ddb
Environment
macOS 26.5.1 (arm64), T3 Code (Alpha) 0.0.38 desktop, Grok CLI 1.0.13 (5e9a58528b76) [stable], provider Grok Build, model grok-4.6
Logs or stack traces
# Current main has no Grok task.* mapping and no spawn_subagent detector:
$ rg -n 'type: "task\\.' apps/server/src/provider/Layers/GrokAdapter.ts
# (no matches)
$ rg -n 'spawn_subagent|subagent_spawned|GROK_SUBAGENT' apps/server/src/provider -g '*.ts'
# (no matches)
On main @ 9cb40178:
GrokAdapterconsumes ACPsession/updateas generic tool-call / content / plan events only.ToolCallUpdatedis forwarded withmakeAcpToolCallEventand is not classified as a subagent task, sospawn_subagentrenders as an ordinary tool row (apps/server/src/provider/Layers/GrokAdapter.tsaround theToolCallUpdatedbranch).- The only registered xAI extension methods are
_x.ai/ask_user_question,_x.ai/exit_plan_mode, and_x.ai/session/prompt_complete. There is no handler for_x.ai/session/updatekindssubagent_spawned/subagent_progress/subagent_finished(orworkflow_updated). - One ACP runtime projects one root session and intentionally drops child-session updates so they are never flattened into the parent stream:
// apps/server/src/provider/acp/AcpSessionRuntime.ts
// One runtime projects one root ACP session. Child-session updates need
// explicit lineage routing and must never be flattened into this stream.
if (
startState._tag !== "Started" ||
notification.sessionId !== startState.result.sessionId
) {
return;
}
That drop is covered by drops session updates emitted for a child ACP session in AcpJsonRpcConnection.test.ts (V1 choice from #3156). It is correct for not merging child transcripts into the parent timeline, but it means Grok children stay invisible unless the adapter emits task.* itself.
- The Agents panel roster is populated only from persisted
task.*activities (packages/client-runtime/src/state/subagentRuntime.ts). Claude, Codex, and Antigravity adapters emittask.started; GrokAdapter does not. - Because Grok's parent turn can
end_turnwhilespawn_subagent/monitorwork continues in-process, the missingtask.*stream also leaves the thread looking idle after the parent settles.
Workaround
Watch the parent-transcript spawn_subagent / get_command_or_subagent_output tool rows. There is no Agents-panel workaround; the roster never receives those children.
Additional context
Not a duplicate of the closed Grok feature tickets — those never landed.
| Item | State | Why it is not this bug |
|---|---|---|
| #6468 / discussion #6983 | closed as completed / transferred | Feature request for grok-4.6 Agents-panel support. Closed during the issues→discussions move. The implementation PRs were not merged. |
| #5420 / discussion #7019 | closed issue; discussion still open | Earlier mapping request (spawn_subagent → task.*). Same gap, filed as a feature, never shipped. |
| #6410, #5503, #7070, #5425 | closed, unmerged | Adapter PRs that would have emitted task.* / hidden the bulky tool row. |
| #8412 | open PR, no linked issue | feat(grok): show Grok subagents in the Agents panel — maps subagent_* / workflow_updated onto task.*. |
| #9139 | open PR, no linked issue | fix(grok): emit task lifecycle for background subagents and monitors — maps spawn_subagent / monitor / poll / kill onto task.* so the thread stays live after parent end_turn. |
| #8499 | open, Codex | Codex-only Agents panel miss. |
| #5952 | open, OpenCode | OpenCode native Task tool. |
| #7281 | open | Wrong parent model/effort labels on rows that do appear (Claude). Grok never gets the rows. |
| #5479 | closed | CLI-delegated children (codex exec / opencode run) from another provider, not Grok-native spawn_subagent. |
Please treat this as a bug against current main, not as a duplicate of the closed/transferred feature requests. The UI contract already exists; Grok is the provider that does not feed it.
Smallest useful scope is still Grok-adapter-only:
- Emit
task.started/task.progress/task.completedfrom Grok's subagent lifecycle (subagent_spawned/subagent_finishedand/or thespawn_subagenttool identity). - Keep child transcripts out of the parent timeline (the existing child-session drop can stay).
- Prefer a roster row over the bulky
spawn_subagenttool row. - Keep unique event stamps and per-taskId dedupe so polls / late finishes do not clone rows.
#8412 and #9139 already point at that mapping. This issue exists so that work has a current, non-duplicate bug to close against, instead of the completed-but-unshipped feature tickets.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/server/src/provider/Layers/GrokAdapter.ts at the ToolCallUpdated branch, then compare its event handling with the task.* lifecycle emitted by other adapters. Read apps/server/src/provider/acp/AcpSessionRuntime.ts and packages/client-runtime/src/state/subagentRuntime.ts to preserve child-session isolation while feeding the roster. Done means Grok children produce deduplicated task.started, task.progress, and task.completed events, avoid a bulky parent tool row, and keep the thread active until background work finishes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 30/100