Skip to content

fix(subagents): correct duration display showing 5-6x inflated runtime#57739

Merged
frankekn merged 3 commits into
openclaw:mainfrom
samzong:fix/subagent-duration-display
Mar 30, 2026
Merged

fix(subagents): correct duration display showing 5-6x inflated runtime#57739
frankekn merged 3 commits into
openclaw:mainfrom
samzong:fix/subagent-duration-display

Conversation

@samzong

@samzong samzong commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Subagent interim status shows runtime inflated ~5-6x (e.g. 30s displayed as "1m")
  • Why it matters: Users cannot trust /subagents list runtime during active runs
  • What changed: Replaced buggy duplicate formatDurationCompact in src/shared/subagents-format.ts with a re-export of the canonical implementation from src/infra/format-time/format-duration.ts; added ?? "n/a" fallback at two call sites
  • What did NOT change (scope boundary): The canonical formatter, final completion stats, or any other display path

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • UI / DX

Linked Issue/PR

Root Cause / Regression History (if applicable)

  • Root cause: A duplicate formatDurationCompact in src/shared/subagents-format.ts divides ms by 60,000 (jumping to minutes) instead of 1,000 (seconds). Math.max(1, Math.round(ms / 60_000)) rounds anything under 60s up to "1m".
  • Missing detection / guardrail: The duplicate was never tested against short durations (<60s); existing test cases only covered minute+ ranges.
  • Prior context: The canonical implementation in src/infra/format-time/format-duration.ts already handles second-level granularity correctly with full test coverage.
  • Why this regressed now: The duplicate likely predates the canonical formatter; never caught because final completion stats use a different code path.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
  • Target test or file: src/shared/subagents-format.test.ts
  • Scenario the test should lock in: formatDurationCompact(30_000) returns "30s" (not "1m"), and formatDurationCompact(90_000) returns "1m30s"
  • Why this is the smallest reliable guardrail: Directly tests the re-exported formatter at the module boundary where callers import it
  • Existing test that already covers this (if any): src/infra/format-time/format-time.test.ts covers the canonical implementation

User-visible / Behavior Changes

  • /subagents list and /subagents info now show seconds-level granularity (e.g. 45s instead of 1m)
  • Short-running subagents no longer show inflated runtimes

Diagram (if applicable)

N/A

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 24 / Bun

Steps

  1. Spawn a subagent with a short task (~30s)
  2. Run /subagents list during execution
  3. Observe runtime display

Expected

  • Runtime shows 30s

Actual

  • Runtime shows 1m (before fix)

Evidence

  • Failing test/log before + passing after
    • Before: formatDurationCompact(30_000)"1m"
    • After: formatDurationCompact(30_000)"30s"

Human Verification (required)

  • Verified scenarios: subagents-format.test.ts (5/5), subagent-control.test.ts + reply-plumbing.test.ts + format-time.test.ts (104/104 all passed)
  • Edge cases checked: undefined input, sub-second input, boundary values (59s, 60s, 3599s, 3600s)
  • What you did not verify: Live subagent run with real model (test-only verification)

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

None. The canonical formatter is already used by other callers (bash-tools.process.ts, sandbox-display.ts, usage-render-*.ts); this change aligns the remaining three callers to the same implementation.


Credit: Root cause originally identified by @jackjin1997 in #45009 comments and #45700. This PR corrects the test expectations that were missed in the prior attempt.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS labels Mar 30, 2026
@greptile-apps

greptile-apps Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a longstanding display bug where the formatDurationCompact in src/shared/subagents-format.ts was a duplicate that incorrectly divided milliseconds by 60,000 instead of 1,000, causing short runtimes (e.g. 30 s) to be shown as "1m" in /subagents list and /subagents info. The fix replaces the duplicate with a re-export of the canonical implementation in src/infra/format-time/format-duration.ts, adds ?? "n/a" fallbacks at the two affected call sites to handle the changed return type (string | undefined vs. the old string), and updates the test to verify second-level granularity.

  • All three callers that import from subagents-format.js (subagent-control.ts, commands-subagents/shared.ts, commands-subagents/action-info.ts) correctly handle the undefined return with ?? "n/a"
  • The canonical formatter already had full test coverage and is used by other display paths (bash-tools.process.ts, sandbox-display.ts, usage-render-*.ts)
  • Test expectations correctly updated: formatDurationCompact() now toBeUndefined() (consistent with the canonical API), and the key regression case formatDurationCompact(30_000) === "30s" is now locked in

Confidence Score: 5/5

Safe to merge — the fix is minimal, correct, and all affected call sites are properly updated.

No P0 or P1 issues found. The change replaces a clearly broken duplicate function with a re-export of the well-tested canonical implementation, adds ?? "n/a" at every affected call site, and updates the test expectations to match. The canonical formatter has existing test coverage and is already used by other display paths in the codebase.

No files require special attention.

Important Files Changed

Filename Overview
src/shared/subagents-format.ts Buggy duplicate removed; replaced with a one-line re-export of the canonical formatDurationCompact from src/infra/format-time/format-duration.ts.
src/agents/subagent-control.ts Added ?? "n/a" fallback to handle the canonical function's undefined return for invalid/missing runtime values.
src/auto-reply/reply/commands-subagents/shared.ts Added ?? "n/a" fallback at the formatDurationCompact call site, mirroring the change in subagent-control.ts.
src/shared/subagents-format.test.ts Test updated to assert toBeUndefined() for no-arg call, and to lock in 30s / 1m30s regression cases that the old duplicate would have failed.

Reviews (1): Last reviewed commit: "fix(subagents): correct duration display..." | Re-trigger Greptile

@frankekn frankekn self-assigned this Mar 30, 2026
samzong and others added 3 commits March 30, 2026 23:32
Replace buggy duplicate formatDurationCompact (ms/60000, minutes-only)
with re-export of canonical implementation (ms/1000, second-level).
Add ?? "n/a" fallback at two call sites for undefined return.

Closes openclaw#45009

Signed-off-by: samzong <[email protected]>
@frankekn
frankekn force-pushed the fix/subagent-duration-display branch from 9a77c51 to 018bbbc Compare March 30, 2026 15:44
@frankekn
frankekn merged commit 09bb93c into openclaw:main Mar 30, 2026
9 checks passed
@frankekn

Copy link
Copy Markdown
Contributor

Merged via squash.

Thanks @samzong!

pgondhi987 pushed a commit to pgondhi987/openclaw that referenced this pull request Mar 31, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
pgondhi987 pushed a commit to pgondhi987/openclaw that referenced this pull request Mar 31, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
Tardisyuan pushed a commit to Tardisyuan/openclaw that referenced this pull request Apr 30, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
Nachx639 pushed a commit to Nachx639/clawdbot that referenced this pull request Jun 17, 2026
openclaw#57739)

Merged via squash.

Prepared head SHA: 018bbbc
Co-authored-by: samzong <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Subagent runtime display shows incorrect duration (5-6x actual time)

2 participants