fix: expose codex submit queue context

This commit is contained in:
Codex
2026-05-23 08:05:06 +00:00
parent 084a136525
commit e8fe7d1d9b
5 changed files with 297 additions and 6 deletions
@@ -0,0 +1,107 @@
import { compactSubmitSuccessResponseForTest } from "./src/code-queue";
type JsonRecord = Record<string, unknown>;
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}
function asRecord(value: unknown): JsonRecord {
assertCondition(typeof value === "object" && value !== null && !Array.isArray(value), "expected JSON object", { value });
return value as JsonRecord;
}
function asArray(value: unknown): unknown[] {
assertCondition(Array.isArray(value), "expected JSON array", { value });
return value as unknown[];
}
function task(id: string, status: string, queueId = "commander-efficiency"): JsonRecord {
return {
id,
queueId,
status,
prompt: `Focused submit summary contract for ${id}`,
displayPrompt: `Focused submit summary contract for ${id}`,
providerId: "D601",
model: "gpt-5.5",
currentAttempt: status === "queued" ? 0 : 1,
maxAttempts: 99,
createdAt: "2026-05-23T00:00:00.000Z",
updatedAt: "2026-05-23T00:00:00.000Z",
};
}
function manyIds(prefix: string, count: number): string[] {
return Array.from({ length: count }, (_, index) => `${prefix}-${String(index + 1).padStart(2, "0")}`);
}
export function runCodeQueueSubmitSummaryContract(): JsonRecord {
const submittedId = "codex_submitted_queued";
const activeIds = manyIds("codex_running", 18);
const response = compactSubmitSuccessResponseForTest({
tasks: [task(submittedId, "queued")],
queue: {
counts: { running: 18, queued: 5, succeeded: 9 },
activeTaskIds: [],
queuedTaskIds: { items: [], count: 5, returned: 0, truncated: true },
databaseActiveTaskIds: activeIds,
databaseActiveTaskCount: activeIds.length,
executionDiagnostics: {
state: "healthy",
databaseActiveTaskIds: activeIds,
databaseActiveTaskCount: activeIds.length,
schedulerActiveRunSlotCount: 0,
schedulerActiveTaskIds: [],
heartbeatFreshTaskIds: activeIds,
},
},
}, { ok: true, status: 200 }, { mode: "local-atomic-directory-submit-serialization", acquiredAfterMs: 1, heldMs: 2, throttleMs: 2000 });
const data = asRecord(response);
const submitted = asRecord(data.submitted);
const submittedTasks = asArray(submitted.tasks);
const submittedTask = asRecord(submittedTasks[0]);
const queue = asRecord(data.queue);
const queuedTaskIds = asRecord(queue.queuedTaskIds);
const activeTaskIds = asRecord(queue.activeTaskIds);
const databaseActiveTaskIds = asRecord(queue.databaseActiveTaskIds);
const submittedTaskIds = asRecord(queue.submittedTaskIds);
const countContext = asRecord(queue.countContext);
const listPreviewPolicy = asRecord(queue.listPreviewPolicy);
const omittedCounts = asRecord(listPreviewPolicy.omittedCounts);
const responseJson = JSON.stringify(response);
assertCondition(submittedTask.id === submittedId && submittedTask.status === "queued", "submit response should keep the newly queued task", submittedTask);
assertCondition(asArray(submittedTaskIds.items).includes(submittedId), "submittedTaskIds should expose the just-submitted id", submittedTaskIds);
assertCondition(asArray(queuedTaskIds.items).includes(submittedId), "queuedTaskIds preview should force-include the just-submitted queued task", queuedTaskIds);
assertCondition(queuedTaskIds.count === 5 && queuedTaskIds.returned === 1 && queuedTaskIds.omitted === 4, "queuedTaskIds should preserve aggregate queued count without dumping all ids", queuedTaskIds);
assertCondition(String(queuedTaskIds.source || "").includes("submittedTaskIds"), "queuedTaskIds source should explain submitted-task fallback", queuedTaskIds);
assertCondition(String(queuedTaskIds.note || "").includes("count remains authoritative"), "queuedTaskIds should explain aggregate-count fallback", queuedTaskIds);
assertCondition(asArray(activeTaskIds.items).length === 15, "activeTaskIds preview should stay bounded", activeTaskIds);
assertCondition(activeTaskIds.count === 18 && activeTaskIds.omitted === 3 && activeTaskIds.truncated === true, "activeTaskIds should preserve active count and truncation", activeTaskIds);
assertCondition(String(activeTaskIds.source || "").includes("databaseActiveTaskIds"), "activeTaskIds should fall back to database active ids when upstream activeTaskIds is empty", activeTaskIds);
assertCondition(databaseActiveTaskIds.count === 18 && databaseActiveTaskIds.returned === 15, "databaseActiveTaskIds preview should preserve count context", databaseActiveTaskIds);
assertCondition(countContext.running === 18 && countContext.active === 18 && countContext.databaseActive === 18, "countContext should expose accurate active counts", countContext);
assertCondition(listPreviewPolicy.bounded === true && listPreviewPolicy.countsAreAuthoritative === true, "list preview policy should document bounded low-noise output", listPreviewPolicy);
assertCondition(listPreviewPolicy.truncated === true && omittedCounts.activeTaskIds === 3 && omittedCounts.queuedTaskIds === 4, "list preview policy should disclose omitted counts", listPreviewPolicy);
assertCondition(String(listPreviewPolicy.note || "").includes("Low-noise mutation output omits"), "list preview policy should include a clear truncation note", listPreviewPolicy);
assertCondition(submitted.promptOmitted === true && !responseJson.includes("Focused submit summary contract"), "submit confirmation should not leak prompt text", response);
assertCondition(responseJson.length < 12_000, "submit confirmation should remain low-noise", { chars: responseJson.length });
return {
ok: true,
checks: [
"newly queued submitted task is included in queuedTaskIds preview",
"running count context falls back to database active ids",
"bounded id previews disclose omitted counts",
"submit confirmation omits prompt text and remains low-noise",
],
};
}
if (import.meta.main) {
process.stdout.write(`${JSON.stringify(runCodeQueueSubmitSummaryContract(), null, 2)}\n`);
}
+5
View File
@@ -34,6 +34,7 @@ const syntaxFiles = [
"scripts/code-queue-prompt-lint-contract-test.ts",
"scripts/code-queue-cli-steer-test.ts",
"scripts/code-queue-cli-submit-prompt-contract-test.ts",
"scripts/code-queue-submit-summary-contract-test.ts",
"scripts/code-queue-cli-read-terminal-contract-test.ts",
"scripts/code-queue-gh-auth-redaction-contract-test.ts",
"scripts/microservice-health-output-contract-test.ts",
@@ -315,6 +316,8 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
fileItem("scripts/code-queue-prompt-lint-contract-test.ts"),
fileItem("scripts/code-queue-cli-steer-test.ts"),
fileItem("scripts/code-queue-cli-read-terminal-contract-test.ts"),
fileItem("scripts/code-queue-cli-submit-prompt-contract-test.ts"),
fileItem("scripts/code-queue-submit-summary-contract-test.ts"),
fileItem("scripts/code-queue-submit-routing-contract-test.ts"),
fileItem("scripts/code-queue-gh-auth-redaction-contract-test.ts"),
fileItem("scripts/code-queue-supervisor-disclosure-contract-test.ts"),
@@ -359,6 +362,7 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
items.push(commandItem("code-queue:cli-steer-contract", ["bun", "scripts/code-queue-cli-steer-test.ts"], 30_000));
items.push(commandItem("code-queue:read-terminal-contract", ["bun", "scripts/code-queue-cli-read-terminal-contract-test.ts"], 30_000));
items.push(commandItem("code-queue:submit-prompt-contract", ["bun", "scripts/code-queue-cli-submit-prompt-contract-test.ts"], 30_000));
items.push(commandItem("code-queue:submit-summary-contract", ["bun", "scripts/code-queue-submit-summary-contract-test.ts"], 30_000));
items.push(commandItem("code-queue:submit-routing-contract", ["bun", "scripts/code-queue-submit-routing-contract-test.ts"], 30_000));
items.push(commandItem("code-queue:gh-auth-redaction-contract", ["bun", "scripts/code-queue-gh-auth-redaction-contract-test.ts"], 30_000));
items.push(commandItem("code-queue:supervisor-disclosure-contract", ["bun", "scripts/code-queue-supervisor-disclosure-contract-test.ts"], 30_000));
@@ -392,6 +396,7 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
items.push(skippedItem("code-queue:cli-steer-contract", "Code Queue steer CLI contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:read-terminal-contract", "Code Queue terminal read contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:submit-prompt-contract", "Code Queue submit prompt contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:submit-summary-contract", "Code Queue submit summary contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:submit-routing-contract", "Code Queue submit routing contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:gh-auth-redaction-contract", "Code Queue GitHub auth output redaction contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:supervisor-disclosure-contract", "Code Queue supervisor disclosure contract is opt-in with script checks", "--scripts-typecheck or --full"));
+183 -5
View File
@@ -22,6 +22,7 @@ const supervisorBodyPreviewChars = 70;
const supervisorRecentBodyPreviewChars = 50;
const diagnosticsIdPreviewLimit = 3;
const diagnosticsReasonPreviewLimit = 2;
const mutationQueueIdPreviewLimit = 15;
const steerPromptPreviewChars = 320;
const detailAttemptReturnedLimit = 3;
const detailInitialPromptPreviewChars = 1200;
@@ -253,6 +254,11 @@ interface CompactTaskMutationResponseOptions {
fullPrompt?: boolean;
}
interface CompactSubmitQueueConfirmationOptions {
submittedTasks?: Record<string, unknown>[];
idPreviewLimit?: number;
}
interface CodexTasksOptions {
queueId: string | undefined;
requestedLimit: number;
@@ -3658,17 +3664,187 @@ function compactSubmitTaskConfirmation(task: unknown): Record<string, unknown> {
};
}
function compactSubmitQueueConfirmation(value: unknown): Record<string, unknown> | null {
function orderedUniqueStringList(values: string[]): string[] {
const seen = new Set<string>();
const items: string[] = [];
for (const value of values) {
if (seen.has(value)) continue;
seen.add(value);
items.push(value);
}
return items;
}
function compactIdPreview(knownIds: string[], totalCount: number, limit: number, source: string, note: string | null = null): Record<string, unknown> {
const all = orderedUniqueStringList(knownIds);
const count = Math.max(0, totalCount, all.length);
const items = all.slice(0, limit);
const omitted = Math.max(0, count - items.length);
return {
items,
count,
returned: items.length,
omitted,
truncated: omitted > 0 || all.length > items.length,
source,
...(note === null ? {} : { note }),
};
}
function idPreviewInputItems(value: unknown): string[] {
const record = asRecord(value);
return stringList(record?.items ?? value);
}
function idPreviewInputCount(value: unknown): number {
const record = asRecord(value);
const explicit = asNumber(record?.count, Number.NaN);
if (Number.isFinite(explicit)) return explicit;
return idPreviewInputItems(value).length;
}
function countForStatus(counts: Record<string, unknown>, status: string): number {
return asNumber(counts[status], 0);
}
function maxFiniteNumber(values: number[]): number {
const finite = values.filter((value) => Number.isFinite(value));
return finite.length === 0 ? 0 : Math.max(...finite);
}
function taskIdsForStatuses(tasks: Record<string, unknown>[], statuses: Set<string> | null): string[] {
return tasks.flatMap((task) => {
const id = asString(task.id);
if (id.length === 0) return [];
if (statuses !== null && !statuses.has(asString(task.status))) return [];
return [id];
});
}
function previewSource(parts: string[], fallback: string): string {
const unique = orderedUniqueStringList(parts.filter((part) => part.length > 0));
return unique.length > 0 ? unique.join("+") : fallback;
}
function compactSubmitQueueConfirmation(value: unknown, options: CompactSubmitQueueConfirmationOptions = {}): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
const counts = asRecord(record.counts) ?? {};
const diagnosticsRecord = asRecord(record.executionDiagnostics) ?? {};
const submittedTasks = options.submittedTasks ?? [];
const idPreviewLimit = Math.max(1, Math.min(options.idPreviewLimit ?? mutationQueueIdPreviewLimit, maxTasksLimit));
const submittedTaskIds = taskIdsForStatuses(submittedTasks, null);
const submittedQueuedTaskIds = taskIdsForStatuses(submittedTasks, new Set(["queued", "retry_wait"]));
const submittedActiveTaskIds = taskIdsForStatuses(submittedTasks, new Set(["running", "judging"]));
const upstreamQueuedTaskIds = idPreviewInputItems(record.queuedTaskIds);
const queuedKnownIds = orderedUniqueStringList([...submittedQueuedTaskIds, ...upstreamQueuedTaskIds]);
const queuedStatusCount = countForStatus(counts, "queued") + countForStatus(counts, "retry_wait");
const queuedCount = Math.max(queuedKnownIds.length, idPreviewInputCount(record.queuedTaskIds), queuedStatusCount);
const queuedPreview = compactIdPreview(
queuedKnownIds,
queuedCount,
idPreviewLimit,
previewSource([
submittedQueuedTaskIds.length > 0 ? "submittedTaskIds" : "",
upstreamQueuedTaskIds.length > 0 ? "upstreamQueuedTaskIds" : "",
queuedKnownIds.length === 0 && queuedCount > 0 ? "aggregateCountsOnly" : "",
], "none"),
queuedCount > queuedKnownIds.length ? "Upstream did not enumerate every queued id in this low-noise mutation response; count remains authoritative." : null,
);
const upstreamActiveTaskIds = idPreviewInputItems(record.activeTaskIds);
const databaseActiveTaskIds = idPreviewInputItems(record.databaseActiveTaskIds);
const diagnosticsDatabaseActiveTaskIds = idPreviewInputItems(diagnosticsRecord.databaseActiveTaskIds);
const diagnosticsHeartbeatTaskIds = idPreviewInputItems(diagnosticsRecord.heartbeatFreshTaskIds);
const activeKnownIds = orderedUniqueStringList([
...submittedActiveTaskIds,
...upstreamActiveTaskIds,
...databaseActiveTaskIds,
...diagnosticsDatabaseActiveTaskIds,
...diagnosticsHeartbeatTaskIds,
]);
const statusActiveCount = countForStatus(counts, "running") + countForStatus(counts, "judging");
const databaseActiveTaskCount = maxFiniteNumber([
databaseActiveTaskIds.length,
diagnosticsDatabaseActiveTaskIds.length,
asNumber(record.databaseActiveTaskCount, Number.NaN),
asNumber(diagnosticsRecord.databaseActiveTaskCount, Number.NaN),
]);
const activeCount = maxFiniteNumber([
activeKnownIds.length,
idPreviewInputCount(record.activeTaskIds),
databaseActiveTaskCount,
statusActiveCount,
]);
const activePreview = compactIdPreview(
activeKnownIds,
activeCount,
idPreviewLimit,
previewSource([
submittedActiveTaskIds.length > 0 ? "submittedTaskIds" : "",
upstreamActiveTaskIds.length > 0 ? "upstreamActiveTaskIds" : "",
databaseActiveTaskIds.length > 0 ? "databaseActiveTaskIds" : "",
diagnosticsDatabaseActiveTaskIds.length > 0 ? "executionDiagnostics.databaseActiveTaskIds" : "",
diagnosticsHeartbeatTaskIds.length > 0 ? "executionDiagnostics.heartbeatFreshTaskIds" : "",
activeKnownIds.length === 0 && activeCount > 0 ? "aggregateCountsOnly" : "",
], "none"),
activeCount > activeKnownIds.length ? "Upstream only exposed aggregate active counts for part of the running set; count remains authoritative." : null,
);
const databaseActivePreview = compactIdPreview(
orderedUniqueStringList([...databaseActiveTaskIds, ...diagnosticsDatabaseActiveTaskIds]),
maxFiniteNumber([databaseActiveTaskCount, idPreviewInputCount(record.databaseActiveTaskIds), idPreviewInputCount(diagnosticsRecord.databaseActiveTaskIds)]),
idPreviewLimit,
previewSource([
databaseActiveTaskIds.length > 0 ? "databaseActiveTaskIds" : "",
diagnosticsDatabaseActiveTaskIds.length > 0 ? "executionDiagnostics.databaseActiveTaskIds" : "",
databaseActiveTaskCount > 0 && databaseActiveTaskIds.length === 0 && diagnosticsDatabaseActiveTaskIds.length === 0 ? "aggregateCountsOnly" : "",
], "none"),
);
const submittedPreview = compactIdPreview(submittedTaskIds, submittedTaskIds.length, idPreviewLimit, "response.tasks");
const omittedCounts = {
activeTaskIds: asNumber(activePreview.omitted, 0),
databaseActiveTaskIds: asNumber(databaseActivePreview.omitted, 0),
queuedTaskIds: asNumber(queuedPreview.omitted, 0),
submittedTaskIds: asNumber(submittedPreview.omitted, 0),
};
const listsTruncated = Object.values(omittedCounts).some((count) => count > 0)
|| activePreview.truncated === true
|| databaseActivePreview.truncated === true
|| queuedPreview.truncated === true
|| submittedPreview.truncated === true;
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),
activeTaskIds: activePreview,
databaseActiveTaskCount,
databaseActiveTaskIds: databaseActivePreview,
queuedTaskIds: queuedPreview,
executionDiagnostics: compactQueueExecutionDiagnostics(record.executionDiagnostics),
...(submittedTasks.length === 0 ? {} : { submittedTaskIds: submittedPreview }),
countContext: {
queued: countForStatus(counts, "queued"),
retryWait: countForStatus(counts, "retry_wait"),
running: countForStatus(counts, "running"),
judging: countForStatus(counts, "judging"),
active: statusActiveCount,
databaseActive: databaseActiveTaskCount,
submitted: submittedTaskIds.length,
},
listPreviewPolicy: {
bounded: true,
idPreviewLimit,
countsAreAuthoritative: true,
truncated: listsTruncated,
omittedCounts,
note: listsTruncated
? "Low-noise mutation output omits additional task ids from one or more previews; use the raw command for full upstream queue detail."
: "Low-noise mutation output includes all known task ids returned for these previews.",
rawCommand: "bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview?limit=30 --raw --full",
},
byQueue: Array.isArray(record.byQueue) ? record.byQueue : undefined,
};
}
@@ -3683,7 +3859,9 @@ function compactSubmitConcurrencyGuard(value: Record<string, unknown>): Record<s
}
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 rawTasks = asArray(body.tasks);
const submittedTasks = rawTasks.map((task) => asRecord(task)).filter((task): task is Record<string, unknown> => task !== null);
const allTasks = rawTasks.map(compactSubmitTaskConfirmation);
const tasks = allTasks.slice(0, defaultTasksLimit);
const allTaskIds = allTasks.map((task) => asString(task.id)).filter(Boolean);
const taskIds = allTaskIds.slice(0, defaultTasksLimit);
@@ -3710,7 +3888,7 @@ function compactSubmitSuccessResponse(body: Record<string, unknown>, upstream: R
reason: "codex submit is a write operation; default output confirms persistence and provides drill-down commands without echoing prompt text.",
},
},
queue: compactSubmitQueueConfirmation(body.queue),
queue: compactSubmitQueueConfirmation(body.queue, { submittedTasks }),
submitConcurrencyGuard: compactSubmitConcurrencyGuard(lock),
commands: {
firstTask: firstTaskId === null ? null : `bun scripts/cli.ts codex task ${firstTaskId}`,