Mark declined Codex tools as blocked

This commit is contained in:
Kelaw - Keshav's Agent
2026-05-06 01:53:15 +05:30
committed by Peter Steinberger
parent 425c9f8787
commit 8dcfc9cb69
2 changed files with 55 additions and 2 deletions

View File

@@ -733,6 +733,52 @@ describe("CodexAppServerEventProjector", () => {
});
});
it("marks declined Codex-native tool results as non-success", async () => {
const onAgentEvent = vi.fn();
const projector = await createProjector({ ...(await createParams()), onAgentEvent });
await projector.handleNotification(
forCurrentTurn("item/completed", {
item: {
type: "commandExecution",
id: "cmd-declined",
command: "pnpm test extensions/codex",
cwd: "/workspace",
processId: null,
source: "agent",
status: "declined",
commandActions: [],
aggregatedOutput: null,
exitCode: null,
durationMs: null,
},
}),
);
expect(onAgentEvent).toHaveBeenCalledWith({
stream: "item",
data: expect.objectContaining({
phase: "end",
kind: "command",
name: "bash",
itemId: "cmd-declined",
status: "blocked",
suppressChannelProgress: true,
}),
});
expect(onAgentEvent).toHaveBeenCalledWith({
stream: "tool",
data: expect.objectContaining({
phase: "result",
name: "bash",
itemId: "cmd-declined",
toolCallId: "cmd-declined",
status: "blocked",
isError: true,
}),
});
});
it("leaves Codex dynamic tool item progress to item/tool/call normalization", async () => {
const onAgentEvent = vi.fn();
const projector = await createProjector({ ...(await createParams()), onAgentEvent });

View File

@@ -706,7 +706,7 @@ export class CodexAppServerEventProjector {
...(params.phase === "result"
? {
status,
isError: status === "failed",
isError: isNonSuccessItemStatus(status),
...itemToolResult(item),
}
: {}),
@@ -1118,17 +1118,24 @@ function itemTitle(item: CodexThreadItem): string {
}
}
function itemStatus(item: CodexThreadItem): "completed" | "failed" | "running" {
function itemStatus(item: CodexThreadItem): "completed" | "failed" | "running" | "blocked" {
const status = readItemString(item, "status");
if (status === "failed") {
return "failed";
}
if (status === "declined") {
return "blocked";
}
if (status === "inProgress" || status === "running") {
return "running";
}
return "completed";
}
function isNonSuccessItemStatus(status: ReturnType<typeof itemStatus>): boolean {
return status === "failed" || status === "blocked";
}
function itemName(item: CodexThreadItem): string | undefined {
if (item.type === "dynamicToolCall" && typeof item.tool === "string") {
return item.tool;