fix(agents): log cli subprocess turn digests

This commit is contained in:
Peter Steinberger
2026-05-29 09:40:23 +01:00
parent d0ea9667ee
commit e130c1acbf
2 changed files with 43 additions and 25 deletions

View File

@@ -686,6 +686,7 @@ describe("runCliAgent spawn path", () => {
});
it("runs CLI through supervisor and returns payload", async () => {
const logInfoSpy = vi.spyOn(cliBackendLog, "info").mockImplementation(() => undefined);
supervisorSpawnMock.mockResolvedValueOnce(
createManagedRun({
reason: "exit",
@@ -706,32 +707,44 @@ describe("runCliAgent spawn path", () => {
});
context.reusableCliSession = { sessionId: "thread-123" };
const result = await executePreparedCliRun(context, "thread-123");
try {
const result = await executePreparedCliRun(context, "thread-123");
expect(result.text).toBe("ok");
const input = mockCallArg(supervisorSpawnMock) as {
argv?: string[];
mode?: string;
timeoutMs?: number;
noOutputTimeoutMs?: number;
replaceExistingScope?: boolean;
scopeKey?: string;
};
expect(input.mode).toBe("child");
expect(input.argv).toEqual([
"codex",
"exec",
"resume",
"thread-123",
"--skip-git-repo-check",
"--model",
"gpt-5.4",
"hi",
]);
expect(input.timeoutMs).toBe(1_000);
expect(input.noOutputTimeoutMs).toBeGreaterThanOrEqual(1_000);
expect(input.replaceExistingScope).toBe(true);
expect(input.scopeKey).toContain("thread-123");
expect(result.text).toBe("ok");
const input = mockCallArg(supervisorSpawnMock) as {
argv?: string[];
mode?: string;
timeoutMs?: number;
noOutputTimeoutMs?: number;
replaceExistingScope?: boolean;
scopeKey?: string;
};
expect(input.mode).toBe("child");
expect(input.argv).toEqual([
"codex",
"exec",
"resume",
"thread-123",
"--skip-git-repo-check",
"--model",
"gpt-5.4",
"hi",
]);
expect(input.timeoutMs).toBe(1_000);
expect(input.noOutputTimeoutMs).toBeGreaterThanOrEqual(1_000);
expect(input.replaceExistingScope).toBe(true);
expect(input.scopeKey).toContain("thread-123");
const turnLog = logInfoSpy.mock.calls
.map(([message]) => message)
.find((message) => message.startsWith("cli turn:"));
expect(turnLog).toContain("provider=codex-cli");
expect(turnLog).toContain("model=gpt-5.4");
expect(turnLog).toContain("outBytes=2 outHash=2689367b205c");
expect(turnLog).not.toContain("ok");
} finally {
logInfoSpy.mockRestore();
}
});
it("passes Codex system prompts through model_instructions_file", async () => {

View File

@@ -40,6 +40,7 @@ import {
import {
cliBackendLog,
CLI_BACKEND_LOG_OUTPUT_ENV,
formatCliBackendOutputDigest,
LEGACY_CLAUDE_CLI_LOG_OUTPUT_ENV,
} from "./log.js";
import type { PreparedCliRunContext } from "./types.js";
@@ -368,6 +369,7 @@ export async function executePreparedCliRun(
try {
return await enqueueCliRun(queueKey, async () => {
const cliTurnStartedAt = Date.now();
const restoreSkillEnv = params.skillsSnapshot
? applySkillEnvOverridesFromSnapshot({
snapshot: params.skillsSnapshot,
@@ -781,6 +783,9 @@ export async function executePreparedCliRun(
fallbackSessionId: resolvedSessionId,
});
const rawText = parsed.text;
cliBackendLog.info(
`cli turn: provider=${params.provider} model=${context.modelId} durationMs=${Date.now() - cliTurnStartedAt} ${formatCliBackendOutputDigest(rawText)}`,
);
return {
...parsed,
rawText,