fix: honor codex approval decisions (#71338) (thanks @Lucenx9)

This commit is contained in:
Peter Steinberger
2026-04-25 02:39:35 +01:00
parent 453789914b
commit 56de930628
3 changed files with 61 additions and 3 deletions

View File

@@ -775,6 +775,43 @@ describe("Codex app-server approval bridge", () => {
).toEqual({
decision: "decline",
});
expect(
buildApprovalResponse("item/commandExecution/requestApproval", undefined, "approved-once"),
).toEqual({
decision: "accept",
});
expect(
buildApprovalResponse("item/commandExecution/requestApproval", undefined, "approved-session"),
).toEqual({
decision: "acceptForSession",
});
expect(
buildApprovalResponse(
"item/commandExecution/requestApproval",
{ availableDecisions: ["cancel"] },
"approved-once",
),
).toEqual({
decision: "cancel",
});
expect(
buildApprovalResponse(
"item/commandExecution/requestApproval",
{ availableDecisions: ["accept", "cancel"] },
"denied",
),
).toEqual({
decision: "cancel",
});
expect(
buildApprovalResponse(
"item/commandExecution/requestApproval",
{ availableDecisions: ["decline"] },
"cancelled",
),
).toEqual({
decision: "decline",
});
expect(buildApprovalResponse("item/fileChange/requestApproval", undefined, "denied")).toEqual({
decision: "decline",
});

View File

@@ -260,10 +260,10 @@ function commandApprovalDecision(
outcome: AppServerApprovalOutcome,
): JsonValue {
if (outcome === "cancelled") {
return "cancel";
return commandRejectionDecision(requestParams, "cancel");
}
if (outcome === "denied" || outcome === "unavailable") {
return "decline";
return commandRejectionDecision(requestParams, "decline");
}
if (outcome === "approved-session") {
if (hasAvailableDecision(requestParams, "acceptForSession")) {
@@ -274,7 +274,9 @@ function commandApprovalDecision(
return amendmentDecision;
}
}
return hasAvailableDecision(requestParams, "accept") ? "accept" : "decline";
return hasAvailableDecision(requestParams, "accept")
? "accept"
: commandRejectionDecision(requestParams, "decline");
}
function fileChangeApprovalDecision(outcome: AppServerApprovalOutcome): JsonValue {
@@ -517,6 +519,24 @@ function findAvailableCommandAmendmentDecision(
);
}
function commandRejectionDecision(
requestParams: JsonObject | undefined,
preferred: "decline" | "cancel",
): JsonValue {
const available = requestParams?.availableDecisions;
if (!Array.isArray(available)) {
return preferred;
}
if (available.includes(preferred)) {
return preferred;
}
const alternate = preferred === "decline" ? "cancel" : "decline";
if (available.includes(alternate)) {
return alternate;
}
return preferred;
}
function approvalResolutionMessage(outcome: AppServerApprovalOutcome): string {
if (outcome === "approved-session") {
return "Codex app-server approval granted for the session.";