fix(server): task_status reports how long a running delegated task has been silent#23898
Problem
A delegated Codex child can sit in Working with no provider events at all. Neither the parent agent (task_status) nor the user can tell it apart from a turn that is doing work. This is the silent post-tool case in #17503. Below is the notification sequence @juliusmarminge asked for, from the last tool result through the end of each silence.
Versions: T3 Code Nightly 0.1.1-nightly.20261020.3411 (macOS), codex-cli 0.163.0 over codex app-server, model gpt-6.1-sol via a Responses-compatible CLIProxyAPI on loopback. Codex stream settings are defaults.
Silence 1: a hung request after a tool result (15m35s, never answered)
| UTC | Dir | Method | Key fields |
|---|---|---|---|
| 21:39:28.953 | in | item/started | commandExecution |
| 21:39:28.960 | in | item/completed | commandExecution failed, exitCode 1 (the command's real exit) |
| 21:39:29.008 | in | thread/tokenUsage/updated | last notification |
| 21:39:29 – 21:55:04 | silence | no thread/status/changed, error, willRetry, deltas, or turn/completed. The Codex rollout is also empty. | |
| 21:55:04.228 | out | turn/interrupt | manual restart by the parent agent |
| 21:55:04.376 | in | thread/status/changed / turn/completed | idle / interrupted, error: null |
Silence 2: the same thread after the restart (5m13s before first output, then normal)
| UTC | Dir | Method | Key fields |
|---|---|---|---|
| 21:55:04.767 | in | thread/status/changed / turn/started | active |
| 21:55:04.782 | in | item/completed | userMessage |
| 21:55:04 – 22:00:18 | silence | the same: no status change, error, retry, or reasoning | |
| 22:00:18.085 | in | item/started | agentMessage (first model output) |
The proxy logged 499 | 15m35s for the first request when the client closed it, and 200 | 5m15s for the second. It logged no retries. These are slow or hung upstream requests that never return response headers, not a 429 retry sequence. Codex's stream idle timeout never fires, so it emits nothing and T3 has no signal to act on. A 5-minute silence can also be healthy, as the second one was, so this PR reports idleness and does not time anything out.
Change
task_status(contract, server, tool description, docs) now returns three fields for running tasks:lastActivityAt: the last recorded change to the child thread.idleForMs: time since then.hasRunningItem: whether an open item belongs to the run's active attempt. Items left open by an attempt that a restart superseded don't count.
A long
idleForMswithworkState: working,hasRunningItem: falseand no pending request points to a stalled provider. The parent can then restart or cancel the task. All three are null/false for queued and finished tasks.Web Working row: after 3 minutes without item activity, with nothing in progress and no pending request, the row adds a quiet "· No activity for N" hint. A pure helper in
TimelineWorkGroupRows.logic.tsderives this from data the client already has.Not included:
- Timeouts and auto-fail.
- Adapter changes.
- Mobile. Its working indicator is separate and would be a follow-up.
- Streaming items with no output. An open text or reasoning item still counts as in progress, because reasoning can legitimately be silent. Codex's stream idle timeout covers a hang in the middle of a stream.
Scope and approval
This addresses #17503, specifically its "no no-progress signal on an active turn" gap. The reporter also asked for that state to be "visible … to parent agents through task_status for delegated tasks". The PR stays informational (no new timeouts or retries) so that it fits the problem the issue already establishes. It does not address the issue's systemError recovery or 429 backoff parts.
Before / after
MessagesTimeline rendered on its own with a running turn whose last activity was 15 minutes ago. Upstream ignores the idle input, and the two "before" captures are byte-identical.
| Before (upstream) | After |
|---|---|
| External image | External image |
Fixture-driven component captures, not a live stuck provider. The desktop and mobile shells were not exercised. Full sanitized notification sequence.
Verification
OrchestratorMcpService.activity.test.ts(usingTestClock) covers:idleForMsgrowing as time advances;- open items from a superseded attempt vs. the active attempt;
- an open item with no provider turn (workspace preparation);
- completed items and items from inactive runs;
- finished tasks returning nulls.
TimelineWorkGroupRows.logic.test.tscovers:- the 3-minute threshold;
- suppression while an item is in progress;
- the restart baseline;
- ignoring items from other runs;
- missing attempt or start returning null;
- formatting.
- The new tests fail on upstream, where the fields and helper don't exist.
vp test runon the MCP service, activity and toolkit integration tests (44 passed) and the web logic tests (6 passed).vp run check:changed upstream/mainpassed: format, lint, knip, typecheck for 29 packages, and 191 tests.- Three independent review rounds, none blocking. Their wording, query-cost, item-filter, render-flash and test-gap findings were fixed, including tests that fail when the lazy-loading guard is removed.
- Not checked: a live stalled provider end to end, Electron, mobile.
Done by Claude Opus 5.5 in Claude Code, running in T3 Code.
🤖 Generated with Claude Code
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- SuccessfulCheckGitHub
- Skipped
- Skipped
- SkippedRustGitHub
- Skipped
- SuccessfulRelease SmokeGitHub
- SuccessfulBuild and TypecheckGitHub
- SuccessfulTestGitHub
- SuccessfulTest WebGitHub
- SkippedEAS PreviewGitHub
- SuccessfulLabel PR 23898GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- Skipped
- Skipped
- Successful
- Successful
- SuccessfulCollect PR targetsGitHub
- SuccessfulPrepare PR size configGitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulTest Server 5GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 8GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulChangesGitHub
- SuccessfulTest Server 7GitHub
- SuccessfulNative fingerprint diffGitHub
- SuccessfulLintGitHub
Added 1 commit
- fix(server): task_status reports how long a running delegated task has been silent50acc35
Approvability
Verdict: Approved at 50acc35
Macroscope's review found this PR approvable — This is a focused observability fix that adds backward-compatible task liveness fields and a minor desktop idle-status hint. It does not add timeouts, retries, workflow gating, breaking schema changes, or other material side effects.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: main
- File: .coderabbit.config.ts
- Commit: e78297d
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Advanced
- Run ID:
9e21f972-f740-4095-be46-38ab3ca2dc64
📥 Commits
Reviewing files that changed from the base of the PR and between e78297d89133eb69a375750974c88aa744dae7c7 and 50acc3565a7462fb943ec9cb13863496330f8075.
📒 Files selected for processing: 13
apps/server/src/mcp/OrchestratorMcpService.activity.test.tsapps/server/src/mcp/OrchestratorMcpService.test.tsapps/server/src/mcp/OrchestratorMcpService.tsapps/server/src/mcp/toolkits/orchestrator/tools.tsapps/web/src/components/ChatView.tsxapps/web/src/components/chat/MessagesTimeline.tsxapps/web/src/components/chat/TimelineWorkGroupRows.logic.test.tsapps/web/src/components/chat/TimelineWorkGroupRows.logic.tsapps/web/src/components/chat/TimelineWorkGroupRows.tsxapps/web/src/components/chat/timelineRowContext.tsdocs/orchestration-v2/orchestrator-mcp-server.mdpackages/contracts/src/orchestratorMcp.test.tspackages/contracts/src/orchestratorMcp.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
📝 Walkthrough
Delegated-task status now includes child-thread activity time, elapsed idle time, and active-attempt item state. The chat timeline derives activity for active work and displays an idle hint after three minutes.
Changes: Delegated task activity
Layer / File(s) Summary Task activity status and contract
packages/contracts/src/orchestratorMcp.ts,apps/server/src/mcp/OrchestratorMcpService.ts,apps/server/src/mcp/toolkits/orchestrator/tools.ts,docs/orchestration-v2/orchestrator-mcp-server.md,packages/contracts/src/orchestratorMcp.test.ts,apps/server/src/mcp/OrchestratorMcpService.test.ts,apps/server/src/mcp/OrchestratorMcpService.activity.test.tsTask status reports the child thread’s last activity, elapsed idle time, and whether an in-progress item belongs to an active run attempt. The service queries activity for running or waiting tasks. Tests cover attempt filtering, query conditions, and terminal-task values. Timeline activity and idle hint
apps/web/src/components/chat/TimelineWorkGroupRows.logic.ts,apps/web/src/components/chat/timelineRowContext.ts,apps/web/src/components/ChatView.tsx,apps/web/src/components/chat/MessagesTimeline.tsx,apps/web/src/components/chat/TimelineWorkGroupRows.tsx,apps/web/src/components/chat/TimelineWorkGroupRows.logic.test.tsThe timeline derives the latest eligible activity for the active attempt and returns no timestamp when an item remains in progress. It displays a formatted idle hint after three minutes when the row is not awaiting input or shimmering. Priority: ➖ Normal
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Feature
Possibly related issues
pingdotgg/t3codeissue 18877: The change filters items from superseded attempts when determining active work and reports activity for delegated tasks.pingdotgg/t3codeissue 22651: The added idle and running-item status fields expose delegated tasks that remain running without active work; the change does not complete or time out those tasks.
Suggested reviewers:
juliusmarminge,t3dotgg
Merge Risk: ⚪ Minimal · up to 50acc
The delegated-task activity fields and idle hint have no identified merge-blocking issue. The change is ready for normal merge checks.
Pre-merge checks: Passed 4
Check name Status Explanation Description check Passed The description includes all required sections. It clearly explains the problem, implementation, scope and approval basis, verification results, screenshots, limitations, and agent attribution. Title check Passed The title is concise and accurately describes the main change: reporting the idle duration of a running delegated task through task_status. Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.