diff --git a/src/agents/subagent-announce.ts b/src/agents/subagent-announce.ts index 444726efc..a823875c4 100644 --- a/src/agents/subagent-announce.ts +++ b/src/agents/subagent-announce.ts @@ -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" }; diff --git a/src/auto-reply/reply/subagents-utils.test.ts b/src/auto-reply/reply/subagents-utils.test.ts index a7496a16d..4c7c5a077 100644 --- a/src/auto-reply/reply/subagents-utils.test.ts +++ b/src/auto-reply/reply/subagents-utils.test.ts @@ -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"); + }); }); diff --git a/src/auto-reply/reply/subagents-utils.ts b/src/auto-reply/reply/subagents-utils.ts index 9afbff9e0..10d0d15e8 100644 --- a/src/auto-reply/reply/subagents-utils.ts +++ b/src/auto-reply/reply/subagents-utils.ts @@ -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;