diff --git a/scripts/deadcode-exports.baseline.mjs b/scripts/deadcode-exports.baseline.mjs index 5ec04485afd2..f57bb1b6f67d 100644 --- a/scripts/deadcode-exports.baseline.mjs +++ b/scripts/deadcode-exports.baseline.mjs @@ -666,12 +666,9 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/llm/utils/oauth/github-copilot.ts: testing", "src/llm/utils/oauth/openai-chatgpt.ts: loginOpenAICodex", "src/llm/utils/oauth/openai-chatgpt.ts: refreshOpenAICodexToken", - "src/logging/diagnostic-phase.ts: recordDiagnosticPhase", "src/logging/diagnostic-run-activity.ts: markDiagnosticModelStartedForTest", "src/logging/diagnostic-run-activity.ts: markDiagnosticRunProgressForTest", "src/logging/diagnostic-run-activity.ts: markDiagnosticToolStartedForTest", - "src/logging/diagnostic-session-context.ts: parseCronRunSessionKey", - "src/logging/diagnostic-session-context.ts: readLastAssistantFromSessionFile", "src/logging/redact-internal.ts: withFullContextToolPayloadRedaction", "src/logging/secret-redaction-registry.ts: resetSecretRedactionRegistryForTest", "src/mcp/channel-bridge.ts: shouldRetryInitialMcpGatewayConnect", diff --git a/scripts/repro/limit-edge-case-live-proof.mjs b/scripts/repro/limit-edge-case-live-proof.mjs index 743238fa2135..f286537cf5f1 100644 --- a/scripts/repro/limit-edge-case-live-proof.mjs +++ b/scripts/repro/limit-edge-case-live-proof.mjs @@ -12,8 +12,8 @@ import { testing as voiceCallCliTesting } from "../../extensions/voice-call/src/ import { loadSessionLogs, loadSessionUsageTimeSeries } from "../../src/infra/session-cost-usage.ts"; import { getRecentDiagnosticPhases, - recordDiagnosticPhase, resetDiagnosticPhasesForTest, + withDiagnosticPhase, } from "../../src/logging/diagnostic-phase.ts"; /** @@ -30,26 +30,8 @@ export async function withProofTempRoot(callback) { async function main() { resetDiagnosticPhasesForTest(); - recordDiagnosticPhase({ - name: "phase-a", - startedAt: 1, - endedAt: 2, - durationMs: 1, - cpuUserMs: 0, - cpuSystemMs: 0, - cpuTotalMs: 0, - cpuCoreRatio: 0, - }); - recordDiagnosticPhase({ - name: "phase-b", - startedAt: 3, - endedAt: 4, - durationMs: 1, - cpuUserMs: 0, - cpuSystemMs: 0, - cpuTotalMs: 0, - cpuCoreRatio: 0, - }); + await withDiagnosticPhase("phase-a", () => undefined); + await withDiagnosticPhase("phase-b", () => undefined); const zeroPhases = getRecentDiagnosticPhases(0); assert.equal(zeroPhases.length, 0); console.log("getRecentDiagnosticPhases(0).length =", zeroPhases.length); diff --git a/src/logging/diagnostic-phase.test.ts b/src/logging/diagnostic-phase.test.ts index e9d48b411966..5c1d09d67d31 100644 --- a/src/logging/diagnostic-phase.test.ts +++ b/src/logging/diagnostic-phase.test.ts @@ -2,33 +2,15 @@ import { describe, expect, it } from "vitest"; import { getRecentDiagnosticPhases, - recordDiagnosticPhase, resetDiagnosticPhasesForTest, + withDiagnosticPhase, } from "./diagnostic-phase.js"; describe("getRecentDiagnosticPhases", () => { - it("returns an empty list for zero, negative, and non-finite limits", () => { + it("returns an empty list for zero, negative, and non-finite limits", async () => { resetDiagnosticPhasesForTest(); - recordDiagnosticPhase({ - name: "phase-a", - startedAt: 1, - endedAt: 2, - durationMs: 1, - cpuUserMs: 0, - cpuSystemMs: 0, - cpuTotalMs: 0, - cpuCoreRatio: 0, - }); - recordDiagnosticPhase({ - name: "phase-b", - startedAt: 3, - endedAt: 4, - durationMs: 1, - cpuUserMs: 0, - cpuSystemMs: 0, - cpuTotalMs: 0, - cpuCoreRatio: 0, - }); + await withDiagnosticPhase("phase-a", () => undefined); + await withDiagnosticPhase("phase-b", () => undefined); expect(getRecentDiagnosticPhases(0)).toEqual([]); expect(getRecentDiagnosticPhases(-1)).toEqual([]); @@ -36,28 +18,10 @@ describe("getRecentDiagnosticPhases", () => { expect(getRecentDiagnosticPhases(Number.POSITIVE_INFINITY)).toEqual([]); }); - it("returns the most recent phases for positive limits", () => { + it("returns the most recent phases for positive limits", async () => { resetDiagnosticPhasesForTest(); - recordDiagnosticPhase({ - name: "phase-a", - startedAt: 1, - endedAt: 2, - durationMs: 1, - cpuUserMs: 0, - cpuSystemMs: 0, - cpuTotalMs: 0, - cpuCoreRatio: 0, - }); - recordDiagnosticPhase({ - name: "phase-b", - startedAt: 3, - endedAt: 4, - durationMs: 1, - cpuUserMs: 0, - cpuSystemMs: 0, - cpuTotalMs: 0, - cpuCoreRatio: 0, - }); + await withDiagnosticPhase("phase-a", () => undefined); + await withDiagnosticPhase("phase-b", () => undefined); const recent = getRecentDiagnosticPhases(1); expect(recent).toHaveLength(1); diff --git a/src/logging/diagnostic-phase.ts b/src/logging/diagnostic-phase.ts index c326cb56943e..c4c7b3a32b72 100644 --- a/src/logging/diagnostic-phase.ts +++ b/src/logging/diagnostic-phase.ts @@ -56,7 +56,7 @@ export function getRecentDiagnosticPhases(limit = 8): DiagnosticPhaseSnapshot[] } /** Records a completed phase in memory and emits it when diagnostics are enabled. */ -export function recordDiagnosticPhase(snapshot: DiagnosticPhaseSnapshot): void { +function recordDiagnosticPhase(snapshot: DiagnosticPhaseSnapshot): void { pushRecentPhase(snapshot); if (!areDiagnosticsEnabledForProcess()) { return; diff --git a/src/logging/diagnostic-session-context.test.ts b/src/logging/diagnostic-session-context.test.ts index b1fa59c55811..11734b443c62 100644 --- a/src/logging/diagnostic-session-context.test.ts +++ b/src/logging/diagnostic-session-context.test.ts @@ -10,8 +10,6 @@ import { import { formatCronSessionDiagnosticFields, formatStoppedCronSessionDiagnosticFields, - parseCronRunSessionKey, - readLastAssistantFromSessionFile, resolveCronSessionDiagnosticContext, } from "./diagnostic-session-context.js"; @@ -39,11 +37,11 @@ describe("diagnostic session context", () => { }); it("parses cron run session keys", () => { - expect(parseCronRunSessionKey("agent:clawblocker:cron:job-123:run:run-456")).toEqual({ - agentId: "clawblocker", - cronJobId: "job-123", - cronRunId: "run-456", - }); + expect( + resolveCronSessionDiagnosticContext({ + sessionKey: "agent:clawblocker:cron:job-123:run:run-456", + }), + ).toMatchObject({ agentId: "clawblocker", cronJobId: "job-123", cronRunId: "run-456" }); }); it("formats cron job and last assistant context for stalled session logs", async () => { @@ -93,14 +91,18 @@ describe("diagnostic session context", () => { }); it("reads the latest assistant message from a transcript tail", () => { - const filePath = path.join(tempDir!, "session.jsonl"); + const filePath = path.join(tempDir!, "agents", "clawblocker", "sessions", "run-456.jsonl"); writeJsonl(filePath, [ { message: { role: "assistant", content: "older" } }, { message: { role: "user", content: "later user" } }, { message: { role: "assistant", content: "newer" } }, ]); - expect(readLastAssistantFromSessionFile(filePath)).toBe("newer"); + expect( + resolveCronSessionDiagnosticContext({ + sessionKey: "agent:clawblocker:cron:job-123:run:run-456", + }).lastAssistant, + ).toBe("newer"); }); it("keeps bounded quoted fields UTF-16 safe", () => { @@ -112,6 +114,11 @@ describe("diagnostic session context", () => { }); it("ignores missing transcript tail files", () => { - expect(readLastAssistantFromSessionFile(path.join(tempDir!, "missing.jsonl"))).toBeUndefined(); + expect( + resolveCronSessionDiagnosticContext({ + sessionKey: "agent:clawblocker:cron:job-123:run:run-456", + activeSessionId: "missing", + }).lastAssistant, + ).toBeUndefined(); }); }); diff --git a/src/logging/diagnostic-session-context.ts b/src/logging/diagnostic-session-context.ts index 9b1577a68947..2d9c06c49c33 100644 --- a/src/logging/diagnostic-session-context.ts +++ b/src/logging/diagnostic-session-context.ts @@ -26,7 +26,7 @@ function quoteLogField(value: string): string { return `"${truncated.replace(/["\\]/g, "\\$&")}"`; } -export function parseCronRunSessionKey(sessionKey?: string): { +function parseCronRunSessionKey(sessionKey?: string): { agentId?: string; cronJobId?: string; cronRunId?: string; @@ -105,7 +105,7 @@ function textFromContent(content: unknown): string | undefined { return texts.length ? texts.join(" ") : undefined; } -export function readLastAssistantFromSessionFile(filePath: string | undefined): string | undefined { +function readLastAssistantFromSessionFile(filePath: string | undefined): string | undefined { if (!filePath) { return undefined; }