fix: subagent announce shows correct runtime, tokens, and output
Three fixes for subagent announce displaying "runtime 0s", "tokens n/a", and "(no output)" even when the sub-agent completed successfully: 1. formatDurationShort: allow 0ms as valid (sub-second tasks are real), display as "<1s" instead of treating as invalid 2. waitForSessionUsage: increase polling from 4×200ms (800ms) to 10×500ms (5s) so token data has time to persist 3. readLatestAssistantReply: add retry loop (5×500ms) for transcript readback when session data hasn't flushed yet Fixes both copies of formatDurationShort (subagent-announce.ts and subagents-utils.ts) for consistency. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
da71eaebd2
commit
cf8c66d675
@ -23,8 +23,10 @@ import { type AnnounceQueueItem, enqueueAnnounce } from "./subagent-announce-que
|
||||
import { readLatestAssistantReply } from "./tools/agent-step.js";
|
||||
|
||||
function formatDurationShort(valueMs?: number) {
|
||||
if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) return undefined;
|
||||
if (valueMs === undefined || valueMs === null || !Number.isFinite(valueMs) || valueMs < 0)
|
||||
return undefined;
|
||||
const totalSeconds = Math.round(valueMs / 1000);
|
||||
if (totalSeconds === 0) return "<1s";
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
@ -79,8 +81,8 @@ async function waitForSessionUsage(params: { sessionKey: string }) {
|
||||
typeof entry.inputTokens === "number" ||
|
||||
typeof entry.outputTokens === "number");
|
||||
if (hasTokens()) return { entry, storePath };
|
||||
for (let attempt = 0; attempt < 4; attempt += 1) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
for (let attempt = 0; attempt < 10; attempt += 1) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
entry = loadSessionStore(storePath)[params.sessionKey];
|
||||
if (hasTokens()) break;
|
||||
}
|
||||
@ -359,9 +361,13 @@ export async function runSubagentAnnounceFlow(params: {
|
||||
}
|
||||
|
||||
if (!reply) {
|
||||
reply = await readLatestAssistantReply({
|
||||
sessionKey: params.childSessionKey,
|
||||
});
|
||||
// Retry with backoff — transcript may not be flushed yet
|
||||
for (let attempt = 0; attempt < 5 && !reply; attempt += 1) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
reply = await readLatestAssistantReply({
|
||||
sessionKey: params.childSessionKey,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!outcome) outcome = { status: "unknown" };
|
||||
|
||||
@ -59,4 +59,14 @@ describe("subagents utils", () => {
|
||||
expect(formatDurationShort(45_000)).toBe("45s");
|
||||
expect(formatDurationShort(65_000)).toBe("1m5s");
|
||||
});
|
||||
|
||||
it("formats zero duration as <1s instead of n/a", () => {
|
||||
expect(formatDurationShort(0)).toBe("<1s");
|
||||
expect(formatDurationShort(499)).toBe("<1s");
|
||||
});
|
||||
|
||||
it("returns n/a for undefined/negative durations", () => {
|
||||
expect(formatDurationShort(undefined)).toBe("n/a");
|
||||
expect(formatDurationShort(-1)).toBe("n/a");
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,8 +2,10 @@ import type { SubagentRunRecord } from "../../agents/subagent-registry.js";
|
||||
import { truncateUtf16Safe } from "../../utils.js";
|
||||
|
||||
export function formatDurationShort(valueMs?: number) {
|
||||
if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) return "n/a";
|
||||
if (valueMs === undefined || valueMs === null || !Number.isFinite(valueMs) || valueMs < 0)
|
||||
return "n/a";
|
||||
const totalSeconds = Math.round(valueMs / 1000);
|
||||
if (totalSeconds === 0) return "<1s";
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user