fix: reduce codex submit success noise

This commit is contained in:
Codex
2026-05-23 00:16:20 +00:00
parent 65ac76c235
commit 774c32515e
6 changed files with 132 additions and 11 deletions
@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { compactSubmitSuccessResponseForTest } from "./src/code-queue";
type JsonRecord = Record<string, unknown>;
@@ -91,6 +92,35 @@ export function runCodeQueueCliSubmitPromptContract(): JsonRecord {
const duplicateMessage = String(nestedRecord(duplicateSource.json, ["error"]).message || "");
assertCondition(duplicateMessage.includes("exactly one prompt source"), "duplicate prompt source error should be explicit", { duplicateMessage });
const longSubmittedPrompt = `${multilinePrompt}${"submitted prompt body must not be echoed\n".repeat(80)}`;
const submitSuccess = compactSubmitSuccessResponseForTest({
tasks: [{
id: "codex_submit_success_contract",
queueId: "prompt-contract",
status: "queued",
providerId: "D601",
model: "gpt-5.5",
cwd: "/workspace",
prompt: longSubmittedPrompt,
maxAttempts: 99,
createdAt: "2026-05-22T00:00:00.000Z",
updatedAt: "2026-05-22T00:00:00.000Z",
}],
queue: {
total: 1,
queueCount: 1,
counts: { queued: 1 },
queuedTaskIds: ["codex_submit_success_contract"],
},
}, { ok: true, status: 200 }, { mode: "local-atomic-directory-submit-serialization", acquiredAfterMs: 1, heldMs: 2, throttleMs: 2000 });
const submitSuccessJson = JSON.stringify(submitSuccess);
const submitted = nestedRecord(submitSuccess, ["submitted"]);
assertCondition(submitted.accepted === true, "submit success should confirm accepted write", submitSuccess);
assertCondition((submitted.taskIds as unknown[]).includes("codex_submit_success_contract"), "submit success should expose task id", submitSuccess);
assertCondition(submitSuccessJson.includes("promptOmitted"), "submit success should explicitly mark prompt omitted", submitSuccess);
assertCondition(!submitSuccessJson.includes("submitted prompt body must not be echoed"), "submit success must not echo prompt text", submitSuccess);
assertCondition(!submitSuccessJson.includes("promptPreview"), "submit success must not include promptPreview", submitSuccess);
const help = runCli(["codex", "submit", "--help"]);
assertCondition(help.status === 0 && help.json?.ok === true, "codex submit help should succeed", help.json ?? { stdout: help.stdout });
const data = nestedRecord(help.json?.data, []);
@@ -113,6 +143,7 @@ export function runCodeQueueCliSubmitPromptContract(): JsonRecord {
"submit --prompt-file preserves reviewed file contents",
"submit positional prompt is redacted from the outer command envelope",
"duplicate submit prompt source fails explicitly",
"submit success confirms write without echoing prompt",
"codex submit help documents stdin/file recommendations and copyable examples",
],
};
+96 -6
View File
@@ -2773,6 +2773,101 @@ function compactTaskMutationResponse(task: unknown, options: CompactTaskMutation
};
}
function compactSubmitTaskConfirmation(task: unknown): Record<string, unknown> {
const record = asRecord(task) ?? {};
const taskId = asString(record.id);
const prompt = asString(record.displayPrompt ?? record.basePrompt ?? record.prompt);
return {
id: taskId || null,
queueId: record.queueId ?? null,
status: record.status ?? null,
queuedReason: record.queuedReason ?? null,
providerId: record.providerId ?? null,
model: record.model ?? null,
reasoningEffort: record.reasoningEffort ?? null,
cwd: record.cwd ?? null,
executionMode: record.executionMode ?? null,
maxAttempts: record.maxAttempts ?? null,
createdAt: record.createdAt ?? null,
updatedAt: record.updatedAt ?? null,
promptChars: prompt.length,
promptOmitted: true,
commands: taskId.length === 0 ? null : {
show: `bun scripts/cli.ts codex task ${taskId}`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
},
};
}
function compactSubmitQueueConfirmation(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
total: record.total ?? null,
queueCount: record.queueCount ?? null,
counts: record.counts ?? null,
activeQueueIds: boundedUniqueStringList(record.activeQueueIds, 8),
activeTaskIds: boundedUniqueStringList(record.activeTaskIds ?? record.databaseActiveTaskIds, 8),
queuedTaskIds: boundedUniqueStringList(record.queuedTaskIds, 8),
executionDiagnostics: compactQueueExecutionDiagnostics(record.executionDiagnostics),
};
}
function compactSubmitConcurrencyGuard(value: Record<string, unknown>): Record<string, unknown> {
return {
mode: value.mode ?? null,
acquiredAfterMs: value.acquiredAfterMs ?? null,
heldMs: value.heldMs ?? null,
throttleMs: value.throttleMs ?? null,
staleMs: value.staleMs ?? null,
};
}
function compactSubmitSuccessResponse(body: Record<string, unknown>, upstream: Record<string, unknown>, lock: Record<string, unknown>): Record<string, unknown> {
const allTasks = asArray(body.tasks).map(compactSubmitTaskConfirmation);
const tasks = allTasks.slice(0, defaultTasksLimit);
const allTaskIds = allTasks.map((task) => asString(task.id)).filter(Boolean);
const taskIds = allTaskIds.slice(0, defaultTasksLimit);
const queueIds = Array.from(new Set(tasks.map((task) => asString(task.queueId)).filter(Boolean))).sort();
const firstTaskId = taskIds[0] ?? null;
const firstQueueId = queueIds[0] ?? null;
return {
ok: true,
upstream,
submitted: {
accepted: true,
taskCount: allTasks.length,
returnedTaskCount: tasks.length,
taskIds,
taskIdsCount: allTaskIds.length,
taskIdsTruncated: allTaskIds.length > taskIds.length,
queueIds,
tasks,
tasksTruncated: allTasks.length > tasks.length,
promptOmitted: true,
outputPolicy: {
default: "write-confirmation",
promptEchoed: false,
reason: "codex submit is a write operation; default output confirms persistence and provides drill-down commands without echoing prompt text.",
},
},
queue: compactSubmitQueueConfirmation(body.queue),
submitConcurrencyGuard: compactSubmitConcurrencyGuard(lock),
commands: {
firstTask: firstTaskId === null ? null : `bun scripts/cli.ts codex task ${firstTaskId}`,
firstTaskDetail: firstTaskId === null ? null : `bun scripts/cli.ts codex task ${firstTaskId} --detail`,
queue: firstQueueId === null ? null : `bun scripts/cli.ts codex tasks --queue ${firstQueueId} --limit ${defaultTasksLimit}`,
supervisor: `bun scripts/cli.ts codex tasks --view supervisor --limit ${defaultTasksLimit}`,
queues: "bun scripts/cli.ts codex queues",
},
};
}
export function compactSubmitSuccessResponseForTest(body: Record<string, unknown>, upstream: Record<string, unknown> = { ok: true, status: 200 }, lock: Record<string, unknown> = {}): Record<string, unknown> {
return compactSubmitSuccessResponse(body, upstream, lock);
}
function codexReadTask(taskId: string): unknown {
const response = unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/read`), { method: "POST", body: {} }));
return {
@@ -3728,12 +3823,7 @@ function codexSubmitTask(args: string[]): unknown {
}
const locked = runWithSubmitLock(() => unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/tasks"), { method: "POST", body: payload })));
const response = locked.result;
return {
upstream: response.upstream,
tasks: asArray(response.body.tasks).map((task) => compactTaskMutationResponse(task, { fullPrompt: true })),
queue: compactQueueMutationSummary(response.body.queue),
submitConcurrencyGuard: locked.lock,
};
return compactSubmitSuccessResponse(response.body, response.upstream, locked.lock);
}
function codexInterruptTask(taskId: string): unknown {
+2 -2
View File
@@ -52,7 +52,7 @@ export function rootHelp(): unknown {
{ command: "schedule list|get|runs|run|retry-run|delete", description: "Manage backend-core scheduled tasks and run history; schedule run <id> supports --wait-ms N and retry-run reuses the failed run's schedule." },
{ command: "schedule upsert-pgdata-backup [--time HH:MM] [--remote-base /SERVER_DATA/UNIDESK_PG_DATA]", description: "Create or update the daily PGDATA physical backup task that uploads monthly rotated archives to Baidu Netdisk." },
{ command: "codex deploy <commitId> [--provider-id D601] [--timeout-ms N]", description: "Disabled legacy Code Queue deploy path; use the dev-only artifact consumer instead." },
{ command: "codex submit [prompt] [--prompt-file path|--prompt-stdin] [--queue queueId] [--provider-id id] [--cwd path] [--model model] [--execution-mode mode] [--max-attempts N] [--reference-task-id id] [--dry-run]", description: "Submit a Code Queue task through backend-core -> code-queue proxy; --dry-run shows the structured request without enqueueing." },
{ command: "codex submit [prompt] [--prompt-file path|--prompt-stdin] [--queue queueId] [--provider-id id] [--cwd path] [--model model] [--execution-mode mode] [--max-attempts N] [--reference-task-id id] [--dry-run]", description: "Submit a Code Queue task through backend-core -> code-queue proxy; --dry-run shows the structured request, while real success only confirms the write and task id." },
{ command: "codex pr-preflight [--remote] [--push-dry-run --push-dry-run-ref refs/heads/probe/<name>] [--pr-create-dry-run --pr-create-dry-run-head <head>] [--issue N]", description: "Read-only PR admission check against the D601 scheduler/runner token, GitHub egress, repo visibility, optional push dry-run, and PR body/create dry-run guard." },
{ command: "codex task <taskId> [--detail] [--trace --tail|--from-start|--after-seq N|--before-seq N --limit N] [--full]", description: "Fetch the bounded review view by default: original prompt, final response, and drill-down commands; detail and trace are opt-in." },
{ command: "codex tasks [--view supervisor|full] [--queue id] [--status status[,status]] [--unread|--unread-only] [--limit N] [--before-id id]", description: "Show the low-noise supervisor view by default: compact task rows, capped recent completions, diagnostics, and drill-down commands; use --view full for detailed rows." },
@@ -278,7 +278,7 @@ function codexHelp(): unknown {
file: "bun scripts/cli.ts codex submit --prompt-file /tmp/code-queue-prompt.md --queue <id> --dry-run",
dryRunThenSubmit: "Run with --dry-run first; remove --dry-run to submit exactly the same payload.",
},
description: "Operate Code Queue through the stable backend-core private proxy path.",
description: "Operate Code Queue through the stable backend-core private proxy path. Real submit success is a low-noise write confirmation and does not echo prompt text.",
};
}