fix: expose codex submit queue context
This commit is contained in:
@@ -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`);
|
||||
}
|
||||
@@ -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
@@ -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}`,
|
||||
|
||||
Reference in New Issue
Block a user