fix: compact codex steer rejection disclosure
This commit is contained in:
@@ -222,6 +222,8 @@ interface CodexSteerOptions {
|
||||
dryRun: boolean;
|
||||
retryAttempts: number;
|
||||
retryDelayMs: number;
|
||||
full: boolean;
|
||||
raw: boolean;
|
||||
}
|
||||
|
||||
type CodexSteerFailureReason =
|
||||
@@ -258,7 +260,6 @@ interface CodexSteerAttemptSummary {
|
||||
scope: ClassifiedCodexSteerError["scope"] | null;
|
||||
retryable: boolean;
|
||||
message: string | null;
|
||||
upstreamBodyPreview?: unknown;
|
||||
}
|
||||
|
||||
interface CompactTaskMutationResponseOptions {
|
||||
@@ -718,6 +719,22 @@ function classifySteerFailure(response: unknown, targetPath: string, stableProxy
|
||||
};
|
||||
}
|
||||
|
||||
function compactSteerFailureDiagnostics(diagnostics: ClassifiedCodexSteerError, includeDetails: boolean): Record<string, unknown> {
|
||||
return {
|
||||
reason: diagnostics.reason,
|
||||
scope: diagnostics.scope,
|
||||
status: diagnostics.status,
|
||||
exitCode: diagnostics.exitCode,
|
||||
retryable: diagnostics.retryable,
|
||||
message: diagnostics.message,
|
||||
recommendedCrossChecks: diagnostics.recommendedCrossChecks,
|
||||
...(includeDetails ? {
|
||||
upstreamBodyPreview: diagnostics.upstreamBodyPreview,
|
||||
rawProxyEquivalent: diagnostics.rawProxyEquivalent,
|
||||
} : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function unwrapSteerResponse(response: unknown, targetPath: string, stableProxyPath: string, rawProxyEquivalent: string): { ok: true; upstream: { ok: unknown; status: unknown }; body: Record<string, unknown> } | { ok: false; diagnostics: ClassifiedCodexSteerError; rawResponse: unknown } {
|
||||
const record = asRecord(response);
|
||||
const body = responseBody(record);
|
||||
@@ -771,6 +788,41 @@ function compactTerminalSteerRejection(taskId: string, response: unknown): Recor
|
||||
};
|
||||
}
|
||||
|
||||
function attachSteerDisclosure(
|
||||
result: Record<string, unknown>,
|
||||
disclosure: { full: boolean; raw: boolean },
|
||||
response: unknown,
|
||||
targetPath: string,
|
||||
stableProxyPath: string,
|
||||
rawProxyEquivalent: string,
|
||||
): Record<string, unknown> {
|
||||
if (!disclosure.full && !disclosure.raw) return result;
|
||||
const record = asRecord(response);
|
||||
const body = responseBody(record);
|
||||
result.disclosure = {
|
||||
defaultPolicy: "compact rejection; upstream body and raw response are only included with explicit --full or --raw",
|
||||
full: disclosure.full,
|
||||
raw: disclosure.raw,
|
||||
defaultOmitted: ["request", "diagnostics.upstreamBodyPreview", "rawFailure"],
|
||||
};
|
||||
if (disclosure.full) {
|
||||
result.request = {
|
||||
path: targetPath,
|
||||
stableProxyPath,
|
||||
method: "POST",
|
||||
bodySummary: {
|
||||
promptOmitted: true,
|
||||
},
|
||||
};
|
||||
result.diagnostics = {
|
||||
upstreamBodyPreview: previewJson(body ?? record, { maxDepth: 4, maxArrayItems: 8, maxObjectKeys: 24, maxStringLength: 600 }),
|
||||
rawProxyEquivalent,
|
||||
};
|
||||
}
|
||||
if (disclosure.raw) result.rawFailure = response;
|
||||
return result;
|
||||
}
|
||||
|
||||
function steerSuccessAttempt(attempt: number, durationMs: number, upstream: { ok: unknown; status: unknown }): CodexSteerAttemptSummary {
|
||||
const status = typeof upstream.status === "number" && Number.isFinite(upstream.status) ? upstream.status : null;
|
||||
return {
|
||||
@@ -797,7 +849,6 @@ function steerFailureAttempt(attempt: number, durationMs: number, diagnostics: C
|
||||
scope: diagnostics.scope,
|
||||
retryable: diagnostics.retryable,
|
||||
message: diagnostics.message,
|
||||
upstreamBodyPreview: diagnostics.upstreamBodyPreview,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4027,7 +4078,7 @@ function parseSubmitOptions(args: string[]): CodexSubmitOptions {
|
||||
|
||||
function parseSteerOptions(args: string[]): CodexSteerOptions {
|
||||
assertKnownOptions(args, {
|
||||
flags: ["--prompt-stdin", "--stdin", "--dry-run", "--no-retry"],
|
||||
flags: ["--prompt-stdin", "--stdin", "--dry-run", "--no-retry", "--full", "--raw"],
|
||||
valueOptions: ["--prompt-file", "--file", "--retry-attempts", "--retry-delay-ms"],
|
||||
}, "codex steer");
|
||||
const retryAttempts = hasFlag(args, "--no-retry")
|
||||
@@ -4038,6 +4089,8 @@ function parseSteerOptions(args: string[]): CodexSteerOptions {
|
||||
dryRun: hasFlag(args, "--dry-run"),
|
||||
retryAttempts,
|
||||
retryDelayMs: nonNegativeIntegerOption(args, ["--retry-delay-ms"], defaultSteerRetryDelayMs, maxSteerRetryDelayMs),
|
||||
full: hasFlag(args, "--full") || hasFlag(args, "--raw"),
|
||||
raw: hasFlag(args, "--raw"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5997,7 +6050,7 @@ function codexSteerTask(taskId: string, args: string[], fetcher: CodexResponseFe
|
||||
};
|
||||
}
|
||||
const attempts: CodexSteerAttemptSummary[] = [];
|
||||
let failedResponse: { ok: false; diagnostics: ClassifiedCodexSteerError } | null = null;
|
||||
let failedResponse: { ok: false; diagnostics: ClassifiedCodexSteerError; rawResponse: unknown } | null = null;
|
||||
let successfulResponse: { ok: true; upstream: { ok: unknown; status: unknown }; body: Record<string, unknown> } | null = null;
|
||||
for (let attempt = 1; attempt <= options.retryAttempts; attempt += 1) {
|
||||
const startedAt = Date.now();
|
||||
@@ -6011,18 +6064,27 @@ function codexSteerTask(taskId: string, args: string[], fetcher: CodexResponseFe
|
||||
attempts.push(steerFailureAttempt(attempt, durationMs, response.diagnostics));
|
||||
failedResponse = response;
|
||||
const terminalRejection = compactTerminalSteerRejection(taskId, response.rawResponse);
|
||||
if (terminalRejection !== null) return terminalRejection;
|
||||
if (terminalRejection !== null) {
|
||||
terminalRejection.commands = {
|
||||
...(asRecord(terminalRejection.commands) ?? {}),
|
||||
fullDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --full`,
|
||||
rawDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --raw`,
|
||||
};
|
||||
return attachSteerDisclosure(terminalRejection, options, response.rawResponse, targetPath, stableProxyPath, rawProxyEquivalent);
|
||||
}
|
||||
if (!shouldRetrySteerFailure(response.diagnostics, attempt, options.retryAttempts)) break;
|
||||
sleepSync(options.retryDelayMs);
|
||||
}
|
||||
if (successfulResponse === null) {
|
||||
const diagnostics = failedResponse?.diagnostics ?? classifySteerFailure(null, targetPath, stableProxyPath, rawProxyEquivalent);
|
||||
const transportDeliveryUnconfirmed = diagnostics.reason === "stable-proxy-failed" || diagnostics.reason === "backend-core-unreachable";
|
||||
const compactDiagnostics = compactSteerFailureDiagnostics(diagnostics, options.full);
|
||||
return {
|
||||
ok: false,
|
||||
steer: {
|
||||
accepted: false,
|
||||
prompt,
|
||||
promptChars: options.prompt.length,
|
||||
promptOmitted: true,
|
||||
attempts,
|
||||
deliveryUnconfirmed: transportDeliveryUnconfirmed,
|
||||
retryPolicy: {
|
||||
@@ -6034,9 +6096,14 @@ function codexSteerTask(taskId: string, args: string[], fetcher: CodexResponseFe
|
||||
note: "codex steer retried only retryable stable-proxy/backend-core failures; raw microservice proxy uses the same tunnel and is diagnostic, not a lower-noise fallback.",
|
||||
},
|
||||
},
|
||||
request,
|
||||
...(options.full ? {
|
||||
request: {
|
||||
...request,
|
||||
body: { prompt: { chars: options.prompt.length, textOmitted: true } },
|
||||
},
|
||||
} : {}),
|
||||
diagnostics: {
|
||||
...diagnostics,
|
||||
...compactDiagnostics,
|
||||
attempts,
|
||||
retryPolicy: {
|
||||
attempted: attempts.length,
|
||||
@@ -6057,10 +6124,19 @@ function codexSteerTask(taskId: string, args: string[], fetcher: CodexResponseFe
|
||||
dryRun: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --dry-run`,
|
||||
retry: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path>`,
|
||||
noRetry: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --no-retry`,
|
||||
fullDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --full`,
|
||||
rawDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --raw`,
|
||||
rawProxy: rawProxyEquivalent,
|
||||
tasks: "bun scripts/cli.ts codex tasks --view supervisor --limit 20",
|
||||
health: "bun scripts/cli.ts microservice health code-queue",
|
||||
},
|
||||
disclosure: {
|
||||
defaultPolicy: "compact rejection; request prompt, upstream body preview, and raw response require explicit --full or --raw",
|
||||
full: options.full,
|
||||
raw: options.raw,
|
||||
defaultOmitted: ["request.body.prompt.text", "diagnostics.upstreamBodyPreview", "rawFailure"],
|
||||
},
|
||||
...(options.raw ? { rawFailure: failedResponse?.rawResponse ?? null } : {}),
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user