Skip to content

Commit b962110

Browse files
clawsweeper[bot]ferminquantTakhoffman
authored
fix(codex): preserve source reply mode for active runs (#86325)
Summary: - This PR forwards Codex app-server source reply delivery mode into active run handling, adds a focused regression test, and adds a changelog entry. - PR surface: Source +1, Tests +38, Docs +1. Total +40 across 3 files. - Reproducibility: yes. Source inspection shows the shared active-run queue rejects `message_tool_only` replies when the active handle lacks that mode, and current main's Codex app-server handle omits it. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(codex): preserve source reply mode for active runs Validation: - ClawSweeper review passed for head d8fac59. - Required merge gates passed before the squash merge. Prepared head SHA: d8fac59 Review: #86325 (comment) Co-authored-by: Fermin Quant <[email protected]> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <[email protected]>
1 parent ab910f8 commit b962110

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Docs: https://docs.openclaw.ai
1616
- Docker: restore writable `~/.config` in runtime images. Fixes #85968. Thanks @hkoessler and @Bartok9.
1717
- Plugin SDK: keep legacy root diagnostic subscriptions connected when built plugin SDK aliases resolve diagnostic helpers through a separate module graph.
1818
- Tests: normalize macOS canonical temp paths in exec allowlists, fs-safe trash assertions, installed plugin matching, Telegram topic-name stores, and built ACPX MCP server expectations so native macOS proof runners cover the intended behavior.
19+
- Codex/app-server: preserve message-tool-only source reply delivery mode on active runs so sub-agent completion wakeups can steer the active Codex turn instead of being rejected. (#86287) Thanks @ferminquant.
1920
- Tests: normalize bundled plugin lifecycle probe paths and state-root lookup so native Windows release sweeps accept valid packaged plugin installs.
2021
- Config: keep benign legacy metadata write anomalies out of default doctor and config command output while preserving explicit anomaly logging for diagnostics.
2122
- Codex: log when implicit app-server `never` approvals are promoted for OpenClaw tool policy, including whether the trigger was a `before_tool_call` hook or trusted tool policy.

extensions/codex/src/app-server/run-attempt.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7884,6 +7884,44 @@ describe("runCodexAppServerAttempt", () => {
78847884
expect(interrupt?.params).toEqual({ threadId: "thread-1", turnId: "turn-1" });
78857885
});
78867886

7887+
it("accepts message-tool-only steering for active Codex app-server source replies", async () => {
7888+
const { requests, waitForMethod, completeTurn } = createStartedThreadHarness();
7889+
const params = createParams(
7890+
path.join(tempDir, "session.jsonl"),
7891+
path.join(tempDir, "workspace"),
7892+
);
7893+
params.sourceReplyDeliveryMode = "message_tool_only";
7894+
7895+
const run = runCodexAppServerAttempt(params);
7896+
await waitForMethod("turn/start");
7897+
7898+
expect(
7899+
queueActiveRunMessageForTest("session-1", "subagent complete", {
7900+
debounceMs: 1,
7901+
steeringMode: "all",
7902+
sourceReplyDeliveryMode: "message_tool_only",
7903+
}),
7904+
).toBe(true);
7905+
7906+
await vi.waitFor(
7907+
() =>
7908+
expect(requests.filter((entry) => entry.method === "turn/steer")).toEqual([
7909+
{
7910+
method: "turn/steer",
7911+
params: {
7912+
threadId: "thread-1",
7913+
expectedTurnId: "turn-1",
7914+
input: [{ type: "text", text: "subagent complete", text_elements: [] }],
7915+
},
7916+
},
7917+
]),
7918+
{ interval: 1 },
7919+
);
7920+
7921+
await completeTurn({ threadId: "thread-1", turnId: "turn-1" });
7922+
await run;
7923+
});
7924+
78877925
it("batches default queued steering before sending turn/steer", async () => {
78887926
const { requests, waitForMethod, completeTurn } = createStartedThreadHarness();
78897927

extensions/codex/src/app-server/run-attempt.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,6 +2929,7 @@ export async function runCodexAppServerAttempt(
29292929
activeSteeringQueue.queue(text, options),
29302930
isStreaming: () => !completed,
29312931
isCompacting: () => projector?.isCompacting() ?? false,
2932+
sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
29322933
cancel: () => runAbortController.abort("cancelled"),
29332934
abort: () => runAbortController.abort("aborted"),
29342935
};

0 commit comments

Comments
 (0)