mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 06:16:46 +00:00
fix(codex): preserve raw reasoning source-reply guard
This commit is contained in:
@@ -5653,6 +5653,43 @@ describe("runCodexAppServerAttempt", () => {
|
||||
expect(harness.request.mock.calls.some(([method]) => method === "turn/interrupt")).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps waiting after raw reasoning completes before a visible message call", async () => {
|
||||
const harness = createStartedThreadHarness();
|
||||
const params = createParams(
|
||||
path.join(tempDir, "session.jsonl"),
|
||||
path.join(tempDir, "workspace"),
|
||||
);
|
||||
params.timeoutMs = 60_000;
|
||||
params.sourceReplyDeliveryMode = "message_tool_only";
|
||||
|
||||
let settled = false;
|
||||
const run = runCodexAppServerAttempt(params, {
|
||||
turnCompletionIdleTimeoutMs: 15,
|
||||
turnTerminalIdleTimeoutMs: 500,
|
||||
}).finally(() => {
|
||||
settled = true;
|
||||
});
|
||||
await harness.waitForMethod("turn/start");
|
||||
await harness.notify({
|
||||
method: "rawResponseItem/completed",
|
||||
params: {
|
||||
threadId: "thread-1",
|
||||
turnId: "turn-1",
|
||||
item: { id: "raw-reasoning-1", type: "reasoning" },
|
||||
},
|
||||
});
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 25));
|
||||
expect(settled).toBe(false);
|
||||
|
||||
await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
|
||||
const result = await run;
|
||||
expect(result.aborted).toBe(false);
|
||||
expect(result.timedOut).toBe(false);
|
||||
expect(result.promptError).toBeNull();
|
||||
expect(harness.request.mock.calls.some(([method]) => method === "turn/interrupt")).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps the normal completion idle guard after non-source reasoning completes", async () => {
|
||||
const harness = createStartedThreadHarness();
|
||||
const params = createParams(
|
||||
|
||||
@@ -2460,6 +2460,10 @@ export async function runCodexAppServerAttempt(
|
||||
isReasoningItemCompletionNotification(notification) &&
|
||||
activeTurnItemIds.size === 0 &&
|
||||
params.sourceReplyDeliveryMode === "message_tool_only";
|
||||
const shouldArmPostRawReasoningSourceReplyWatch =
|
||||
rawResponseItemCompletedWithNoActiveItems &&
|
||||
isRawReasoningCompletionNotification(notification) &&
|
||||
params.sourceReplyDeliveryMode === "message_tool_only";
|
||||
const shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem =
|
||||
isCurrentTurnNotification &&
|
||||
notification.method === "item/completed" &&
|
||||
@@ -2480,7 +2484,10 @@ export async function runCodexAppServerAttempt(
|
||||
armTurnAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
||||
} else if (postToolRawAssistantCompletionNeedsTerminalGuard) {
|
||||
armTurnCompletionIdleWatch({ timeoutMs: postToolRawAssistantCompletionIdleTimeoutMs });
|
||||
} else if (shouldArmPostReasoningSourceReplyWatch) {
|
||||
} else if (
|
||||
shouldArmPostReasoningSourceReplyWatch ||
|
||||
shouldArmPostRawReasoningSourceReplyWatch
|
||||
) {
|
||||
armTurnCompletionIdleWatch({ timeoutMs: CODEX_POST_REASONING_SOURCE_REPLY_IDLE_TIMEOUT_MS });
|
||||
} else if (unblockedAssistantCompletionRelease) {
|
||||
armTurnAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
||||
@@ -2511,6 +2518,7 @@ export async function runCodexAppServerAttempt(
|
||||
!postToolRawAssistantCompletionNeedsTerminalGuard &&
|
||||
!rawResponseItemCompletedWithNoActiveItems &&
|
||||
!shouldArmPostReasoningSourceReplyWatch &&
|
||||
!shouldArmPostRawReasoningSourceReplyWatch &&
|
||||
!shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem
|
||||
) {
|
||||
// The short completion-idle watchdog guards blind gaps after Codex
|
||||
@@ -5274,6 +5282,14 @@ function isReasoningItemCompletionNotification(notification: CodexServerNotifica
|
||||
return item ? readString(item, "type") === "reasoning" : false;
|
||||
}
|
||||
|
||||
function isRawReasoningCompletionNotification(notification: CodexServerNotification): boolean {
|
||||
if (!isJsonObject(notification.params) || notification.method !== "rawResponseItem/completed") {
|
||||
return false;
|
||||
}
|
||||
const item = isJsonObject(notification.params.item) ? notification.params.item : undefined;
|
||||
return item ? readString(item, "type") === "reasoning" : false;
|
||||
}
|
||||
|
||||
function isAssistantCompletionReleaseNotification(
|
||||
notification: CodexServerNotification,
|
||||
turnCrossedToolHandoff: boolean,
|
||||
|
||||
Reference in New Issue
Block a user