fix: reduce codex supervisor output noise

This commit is contained in:
Codex
2026-05-22 14:52:38 +00:00
parent b9185e0379
commit 2ed9e79d67
7 changed files with 474 additions and 42 deletions
+255 -13
View File
@@ -12,6 +12,10 @@ const defaultOutputLimit = 20;
const defaultTextPreviewChars = 12_000;
const defaultTasksLimit = 20;
const maxTasksLimit = 100;
const supervisorRecentCompletedLimit = 5;
const supervisorPromptPreviewChars = 160;
const supervisorBodyPreviewChars = 180;
const supervisorRecentBodyPreviewChars = 80;
const steerPromptPreviewChars = 320;
const minimaxSubmitModel = "minimax-m2.7";
const deepseekSubmitModel = "deepseek-chat";
@@ -187,7 +191,35 @@ interface CodexTasksEntry {
};
}
interface CodexTasksSection {
interface CodexTasksSupervisorEntry {
taskId: string;
queueId: string | null;
status: string | null;
currentAttempt: number | null;
updatedAt: string | null;
finishedAt: string | null;
unreadTerminal: boolean;
issueRefs: string[];
classification: {
kind: "direct-progress" | "deployment-fix" | "verification" | "management-noise" | "documentation" | "unknown";
labels: string[];
managementNoise: boolean;
reason: string;
};
prompt: Record<string, unknown>;
lastMessage: Record<string, unknown> | null;
queuedReason: Record<string, unknown> | null;
commands: {
show: string;
detail: string;
trace: string;
output: string;
full: string;
read: string;
};
}
interface CodexTasksSection<T = CodexTasksEntry> {
count: number;
returned: number;
truncated: boolean;
@@ -195,8 +227,11 @@ interface CodexTasksSection {
commands: {
next: string | null;
full: string;
detailTemplate?: string;
traceTemplate?: string;
outputTemplate?: string;
};
items: CodexTasksEntry[];
items: T[];
}
interface CodexTasksDegraded {
@@ -362,6 +397,10 @@ function textPreview(value: string, maxChars: number): Record<string, unknown> {
};
}
function compactInlinePreview(value: string, maxChars: number): Record<string, unknown> {
return textPreview(value.replace(/\s+/gu, " ").trim(), maxChars);
}
function fmtDuration(ms: unknown): string {
const value = Number(ms);
if (!Number.isFinite(value) || value < 0) return "--";
@@ -1572,6 +1611,75 @@ function taskQueuedRunnable(task: Record<string, unknown>): boolean {
return asRecord(task.queuedReason)?.code === "ready";
}
function taskIssueRefs(task: Record<string, unknown>, summary: Record<string, unknown> | null): string[] {
const text = [
asString(task.displayPrompt),
asString(task.basePrompt),
asString(task.prompt),
asString(summary?.initialPrompt),
asString(summary?.basePrompt),
asString(summary?.prompt),
asString(summary?.lastError),
asString(task.lastError),
].join("\n");
return Array.from(new Set(Array.from(text.matchAll(/#(\d{1,6})\b/gu)).map((match) => `#${match[1]}`))).slice(0, 8);
}
function taskClassification(task: Record<string, unknown>, summary: Record<string, unknown> | null): CodexTasksSupervisorEntry["classification"] {
const text = [
asString(task.displayPrompt),
asString(task.basePrompt),
asString(task.prompt),
asString(task.lastError),
asString(summary?.lastError),
asString(asRecord(summary?.lastAssistantMessage)?.text),
].join("\n").toLowerCase();
const matches = (pattern: RegExp): boolean => pattern.test(text);
const labels: string[] = [];
if (matches(/\b(?:gate|report|aggregator|runbook|contract|audit|review|brief|evidence|diagnostic|observability|visibility|preflight|smoke)\b|||||||/iu)) labels.push("management-or-verification");
if (matches(/\b(?:deploy|deployment|prod|dev|release|artifact|ci|cd)\b|||线/iu)) labels.push("deployment");
if (matches(/\b(?:fix|bug|repair|implement|feature|ui|frontend|backend|api|database|db|workbench|patch-panel|box-simu|gateway-simu)\b|||||线|仿|/iu)) labels.push("direct-work");
if (matches(/\b(?:doc|docs|reference|markdown)\b||/iu)) labels.push("documentation");
if (labels.length === 0) labels.push("uncategorized");
if (labels.includes("management-or-verification") && !labels.includes("direct-work") && !labels.includes("deployment")) {
return { kind: "management-noise", labels, managementNoise: true, reason: "matched report/gate/review/diagnostic terms without direct implementation or deployment terms" };
}
if (labels.includes("deployment")) {
return { kind: "deployment-fix", labels, managementNoise: labels.includes("management-or-verification") && !labels.includes("direct-work"), reason: "matched deployment or artifact terms" };
}
if (labels.includes("direct-work")) {
return { kind: "direct-progress", labels, managementNoise: false, reason: "matched implementation, user-visible, runtime, or repair terms" };
}
if (labels.includes("management-or-verification")) {
return { kind: "verification", labels, managementNoise: true, reason: "matched verification/report terms; keep folded unless it blocks real work" };
}
if (labels.includes("documentation")) {
return { kind: "documentation", labels, managementNoise: false, reason: "matched documentation terms" };
}
return { kind: "unknown", labels, managementNoise: false, reason: "no strong classifier term matched" };
}
function supervisorLastMessage(summaryLastAssistant: unknown, maxChars: number): Record<string, unknown> | null {
if (summaryLastAssistant === undefined || summaryLastAssistant === null) return null;
const record = asRecord(summaryLastAssistant) ?? {};
const text = asString(record.text);
if (text.length === 0) {
return {
at: record.at ?? null,
seq: record.seq ?? null,
source: record.source ?? "none",
...compactInlinePreview("", maxChars),
};
}
return {
at: record.at ?? null,
seq: record.seq ?? null,
source: record.source ?? "none",
...compactInlinePreview(text, maxChars),
};
}
function taskWatchEntry(task: Record<string, unknown>, summary: Record<string, unknown> | null): CodexTasksEntry {
const taskId = asString(task.id);
const summaryCommands = summary === null ? null : asRecord(summary.commands);
@@ -1610,6 +1718,40 @@ function taskWatchEntry(task: Record<string, unknown>, summary: Record<string, u
};
}
function taskSupervisorEntry(task: Record<string, unknown>, summary: Record<string, unknown> | null, bodyPreviewChars = supervisorBodyPreviewChars): CodexTasksSupervisorEntry {
const taskId = asString(task.id);
const summaryCommands = summary === null ? null : asRecord(summary.commands);
const summaryLastAssistant = summary?.lastAssistantMessage ?? task.lastAssistantMessage;
const showCommand = typeof summary?.cliHint === "string" && summary.cliHint.length > 0
? summary.cliHint
: `bun scripts/cli.ts codex task ${taskId}`;
const traceCommand = typeof summary?.traceHint === "string" && summary.traceHint.length > 0
? summary.traceHint
: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`;
return {
taskId,
queueId: asString(task.queueId) || null,
status: asString(task.status) || null,
currentAttempt: typeof task.currentAttempt === "number" && Number.isFinite(task.currentAttempt) ? task.currentAttempt : null,
updatedAt: asString(task.updatedAt) || null,
finishedAt: asString(task.finishedAt) || null,
unreadTerminal: taskUnreadTerminal(task),
issueRefs: taskIssueRefs(task, summary),
classification: taskClassification(task, summary),
prompt: compactInlinePreview(asString(task.displayPrompt ?? task.basePrompt ?? task.prompt), supervisorPromptPreviewChars),
lastMessage: supervisorLastMessage(summaryLastAssistant, bodyPreviewChars),
queuedReason: compactQueuedReason(task.queuedReason),
commands: {
show: typeof summaryCommands?.show === "string" && summaryCommands.show.length > 0 ? summaryCommands.show : showCommand,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
trace: typeof summaryCommands?.trace === "string" && summaryCommands.trace.length > 0 ? summaryCommands.trace : traceCommand,
output: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`,
full: `bun scripts/cli.ts codex task ${taskId} --full`,
read: `bun scripts/cli.ts codex read ${taskId}`,
},
};
}
function buildTaskWatchSection(
tasks: Record<string, unknown>[],
summaries: Map<string, Record<string, unknown>>,
@@ -1633,6 +1775,33 @@ function buildTaskWatchSection(
};
}
function buildSupervisorTaskSection(
tasks: Record<string, unknown>[],
summaries: Map<string, Record<string, unknown>>,
limit: number,
nextCommand: string | null,
fullCommand: string,
bodyPreviewChars = supervisorBodyPreviewChars,
): CodexTasksSection<CodexTasksSupervisorEntry> {
const visibleTasks = tasks.slice(0, limit);
const items = visibleTasks.map((task) => taskSupervisorEntry(task, summaries.get(taskOverviewCandidateKey(task)) ?? null, bodyPreviewChars));
const truncated = tasks.length > limit;
return {
count: tasks.length,
returned: items.length,
truncated,
hasMore: truncated,
commands: {
next: truncated ? nextCommand : null,
full: fullCommand,
detailTemplate: "bun scripts/cli.ts codex task <taskId> --detail",
traceTemplate: `bun scripts/cli.ts codex task <taskId> --trace --tail --limit ${defaultTraceLimit}`,
outputTemplate: `bun scripts/cli.ts codex output <taskId> --tail --limit ${defaultOutputLimit}`,
},
items,
};
}
function collectTaskWatchDegraded(summaryErrors: Array<{ taskId: string; message: string }>, omittedTaskCount = 0): CodexTasksDegraded | null {
if (summaryErrors.length === 0 && omittedTaskCount === 0) return null;
return {
@@ -1784,18 +1953,26 @@ function codexTasksOverviewResult(
const allTasks = filterTasksForOptions(taskPage.tasks, options);
const runningTasks = sortRunningWatchTasks(allTasks);
const unreadCompletedTasks = sortCompletedWatchTasks(allTasks).filter((task) => taskUnreadTerminal(task));
const recentCompletedTasks = options.unreadOnly ? [] : sortCompletedWatchTasks(allTasks);
const recentCompletedTasks = options.unreadOnly ? [] : sortCompletedWatchTasks(allTasks).filter((task) => !taskUnreadTerminal(task));
const queuedTasks = options.unreadOnly ? [] : sortQueuedWatchTasks(allTasks);
const nextBeforeId = asString(taskPage.pagination.nextBeforeId) || null;
const sourceHasMore = asBoolean(taskPage.pagination.hasMore);
const nextCommand = sourceHasMore && nextBeforeId !== null ? taskListCommand({ ...options, beforeId: nextBeforeId }) : null;
const fullCommand = taskListCommand({ ...options, view: "full" });
const runningSection = buildTaskWatchSection(runningTasks, summaries, options.limit, nextCommand, fullCommand);
const unreadSection = buildTaskWatchSection(unreadCompletedTasks, summaries, options.limit, nextCommand, fullCommand);
const recentSection = buildTaskWatchSection(recentCompletedTasks, summaries, options.limit, nextCommand, fullCommand);
const queuedSection = buildTaskWatchSection(queuedTasks, summaries, options.limit, nextCommand, fullCommand);
const recentLimit = Math.min(options.limit, supervisorRecentCompletedLimit);
const runningSection = buildSupervisorTaskSection(runningTasks, summaries, options.limit, nextCommand, fullCommand);
const unreadSection = buildSupervisorTaskSection(unreadCompletedTasks, summaries, options.limit, nextCommand, fullCommand);
const recentSection = buildSupervisorTaskSection(recentCompletedTasks, summaries, recentLimit, nextCommand, fullCommand, supervisorRecentBodyPreviewChars);
const queuedSection = buildSupervisorTaskSection(queuedTasks, summaries, options.limit, nextCommand, fullCommand);
const pagination = taskPage.pagination;
const diagnostics = compactExecutionDiagnostics(asRecord(taskPage.queue)?.executionDiagnostics);
const visibleSupervisorItems = [...runningSection.items, ...unreadSection.items, ...recentSection.items, ...queuedSection.items];
const classifierCounts = visibleSupervisorItems.reduce((counts, item) => {
const key = item.classification.kind;
counts[key] = (counts[key] ?? 0) + 1;
if (item.classification.managementNoise) counts.managementNoise = (counts.managementNoise ?? 0) + 1;
return counts;
}, {} as Record<string, number>);
return {
upstream,
supervisor: {
@@ -1820,6 +1997,13 @@ function codexTasksOverviewResult(
bounded: true,
disclosure: {
defaultView: "supervisor",
policy: "bounded summary rows only; prompt/body are short previews and raw detail requires explicit task/full/trace/output commands",
outputBudget: {
promptPreviewChars: supervisorPromptPreviewChars,
bodyPreviewChars: supervisorBodyPreviewChars,
recentCompletedReturnedLimit: recentLimit,
recentCompletedBodyPreviewChars: supervisorRecentBodyPreviewChars,
},
fullCommand,
next: nextCommand,
rawOverview: `bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview${tasksListQueryString(options)} --raw`,
@@ -1831,6 +2015,7 @@ function codexTasksOverviewResult(
recentCompleted: recentSection.count,
queued: queuedSection.count,
},
classifierCounts,
executionDiagnostics: diagnostics,
degraded,
commands: {
@@ -1901,7 +2086,7 @@ function visibleTaskIdsForOverview(tasks: Record<string, unknown>[], options: Co
return Array.from(new Set([
...sortRunningWatchTasks(filtered).slice(0, options.limit),
...sortCompletedWatchTasks(filtered).filter((task) => taskUnreadTerminal(task)).slice(0, options.limit),
...sortCompletedWatchTasks(filtered).slice(0, options.limit),
...sortCompletedWatchTasks(filtered).filter((task) => !taskUnreadTerminal(task)).slice(0, Math.min(options.limit, supervisorRecentCompletedLimit)),
...sortQueuedWatchTasks(filtered).slice(0, options.limit),
].map((task) => taskOverviewCandidateKey(task))))
.filter((taskId) => taskId.length > 0);
@@ -1915,6 +2100,10 @@ function codexTasksQuery(taskArgs: string[], fetcher: CodexResponseFetcher = cor
return codexTasksOverviewResult(page, upstream, options, summaries, degraded);
}
export function codexTasksQueryForTest(taskArgs: string[], fetcher: CodexResponseFetcher): unknown {
return codexTasksQuery(taskArgs, fetcher);
}
async function codexTasksQueryAsync(taskArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const options = parseTasksOptions(taskArgs);
const byId = new Map<string, Record<string, unknown>>();
@@ -2566,6 +2755,57 @@ function authBrokerNeededStatus(tokenCoverage: Record<string, unknown>, runtimeA
};
}
function activeRunnerDevContainerCapability(): Record<string, unknown> {
const ghTokenPresent = typeof process.env.GH_TOKEN === "string" && process.env.GH_TOKEN.length > 0;
const githubTokenPresent = typeof process.env.GITHUB_TOKEN === "string" && process.env.GITHUB_TOKEN.length > 0;
const anyToken = ghTokenPresent || githubTokenPresent;
return {
scope: "current-cli-process",
applicableWhen: "this command is running inside the active Code Queue runner/dev container",
observed: true,
ok: anyToken,
ghTokenPresent,
githubTokenPresent,
credentialSource: ghTokenPresent ? "GH_TOKEN" : githubTokenPresent ? "GITHUB_TOKEN" : null,
notEquivalentToSchedulerEnv: true,
relationToRemotePreflight: "independent-scope; scheduler-runner-env auth-missing does not prove the active runner/dev container lacks GitHub PR capability",
valuesPrinted: false,
commands: {
authStatus: "bun scripts/cli.ts gh auth status --repo pikasTech/unidesk",
prCreateDryRun: "bun scripts/cli.ts gh pr create --repo pikasTech/unidesk --title <title> --body-file <file> --base master --head <head> --dry-run",
prCommentDryRun: "bun scripts/cli.ts gh pr comment create <number> --repo pikasTech/unidesk --body-file <file> --dry-run",
},
interpretation: anyToken
? "current CLI process has a GitHub token candidate; validate with gh auth status and PR dry-run before declaring this runner unable to create/comment PRs"
: "current CLI process did not expose GH_TOKEN/GITHUB_TOKEN; this still does not prove another active runner/dev container lacks token coverage",
};
}
function prPreflightScopeBoundary(tokenCoverage: Record<string, unknown> | null): Record<string, unknown> {
const schedulerScope = typeof tokenCoverage?.scope === "string" ? tokenCoverage.scope : "scheduler-runner-env";
return {
schedulerPreflightScope: schedulerScope,
activeRunnerDevContainerScope: "current-cli-process",
scopesAreIndependent: true,
authMissingInterpretation: "auth-missing from codex pr-preflight --remote is scoped to the scheduler/runtime preflight surface; do not simplify it to 'the active runner cannot create PRs'",
currentRunnerCheck: "use activeRunnerDevContainer plus bun scripts/cli.ts gh auth status --repo pikasTech/unidesk for the current dev container",
valuesPrinted: false,
};
}
function decoratePrPreflightScopeBoundary(record: Record<string, unknown>): Record<string, unknown> {
const preflight = asRecord(record.preflight);
const tokenCoverage = asRecord(preflight?.tokenCoverage ?? record.tokenCoverage);
const scopeBoundary = prPreflightScopeBoundary(tokenCoverage);
const activeRunnerDevContainer = activeRunnerDevContainerCapability();
return {
...record,
scopeBoundary,
activeRunnerDevContainer,
...(preflight === null ? {} : { preflight: { ...preflight, scopeBoundary } }),
};
}
function compactPrRuntimePreflight(preflight: Record<string, unknown>, options: CodexPrPreflightOptions): Record<string, unknown> {
const pull = asRecord(preflight.pullRequestDelivery) ?? {};
const tools = asRecord(pull.tools) ?? {};
@@ -2615,6 +2855,7 @@ function compactPrRuntimePreflight(preflight: Record<string, unknown>, options:
},
tokenCoverage,
authBroker: authBrokerNeededStatus(tokenCoverage, authBrokerRuntime, systemGhBinary, unideskGhCli),
scopeBoundary: prPreflightScopeBoundary(tokenCoverage),
prCapabilityContract: {
targetBranch,
tokenSource: tokenCoverage.source,
@@ -2711,11 +2952,12 @@ function compactPrRuntimePreflight(preflight: Record<string, unknown>, options:
limitations,
risks,
runnerDisposition: ok ? "ready" : "infra-blocked",
activeRunnerDevContainer: activeRunnerDevContainerCapability(),
recoveryHint: ok
? tokenCoverage.source === "auth-broker"
? "Runner PR workflow has auth-broker coverage for GitHub REST preflight; real PR creation still requires commander authorization."
: "Runner PR workflow has env-token coverage for the scheduler."
: "Configure auth-broker or inject GH_TOKEN/GITHUB_TOKEN into the Code Queue scheduler runtime secret for the target queue, then rerun this preflight before creating a PR.",
: "Scheduler preflight lacks GitHub auth coverage. Configure auth-broker or inject GH_TOKEN/GITHUB_TOKEN into the scheduler runtime secret for scheduler-scoped admission; separately check activeRunnerDevContainer and gh auth status before declaring the current runner unable to create/comment PRs.",
commands: {
local: "bun scripts/cli.ts gh auth status --repo pikasTech/unidesk",
runner: "bun scripts/cli.ts codex pr-preflight --remote",
@@ -2815,7 +3057,7 @@ function codeQueuePrPreflight(optionArgs: string[] = [], transport: CodeQueuePrP
const remoteRecord = asRecord(remoteResponse);
if (remoteRecord !== null) {
if (remoteRecord.ok === false) {
return {
return decoratePrPreflightScopeBoundary({
...remoteRecord,
controlPlane: {
...(asRecord(remoteRecord.controlPlane) ?? {}),
@@ -2827,9 +3069,9 @@ function codeQueuePrPreflight(optionArgs: string[] = [], transport: CodeQueuePrP
},
localObservation: localRecord,
remoteObservation: remoteRecord,
};
});
}
return {
return decoratePrPreflightScopeBoundary({
...remoteRecord,
controlPlane: {
...(asRecord(remoteRecord.controlPlane) ?? {}),
@@ -2841,7 +3083,7 @@ function codeQueuePrPreflight(optionArgs: string[] = [], transport: CodeQueuePrP
},
localObservation: localRecord,
remoteObservation: remoteRecord,
};
});
}
}
if (localRecord?.ok !== true) {