diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cb1b0398cc..98d5b925dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Docs: https://docs.openclaw.ai - Cron: honor `cron.retry.retryOn: ["network"]` for common network error codes such as `EAI_AGAIN`, `EHOSTUNREACH`, and `ENETUNREACH`. - Gateway chat: broadcast returned agent-run error payloads after an agent starts so ACP/WebChat clients receive terminal idle-timeout errors. Fixes #84945. - Dashboard/CLI: allow macOS browser launching through `open` even when SSH environment variables are present, while preserving Linux SSH no-display protection. Fixes #67088. Thanks @theglove44. +- Codex app-server: keep native web search observations out of mirrored chat transcripts while preserving tool progress telemetry. Fixes #85109. Thanks @ugitmebaby. - Agents/OpenAI: preserve structured provider error code, type, and redacted body metadata on boundary-aware transport failures. - Doctor/Codex: point native Codex asset warnings at the canonical `openclaw migrate plan codex` preview command. Fixes #84948. Thanks @markoa. - CLI/models: make `capability model auth logout --agent` remove auth profiles from the selected non-default agent store. Fixes #85092. Thanks @islandpreneur007. diff --git a/extensions/codex/src/app-server/event-projector.test.ts b/extensions/codex/src/app-server/event-projector.test.ts index f362c65b6f8..baa9045e40f 100644 --- a/extensions/codex/src/app-server/event-projector.test.ts +++ b/extensions/codex/src/app-server/event-projector.test.ts @@ -2031,6 +2031,40 @@ describe("CodexAppServerEventProjector", () => { expect(toolResultContent.content).toBe("opened"); }); + it("does not mirror Codex-native web searches into transcript snapshots", async () => { + const projector = await createProjector(); + + await projector.handleNotification( + forCurrentTurn("item/completed", { + item: { + type: "webSearch", + id: "search-observed", + status: "completed", + durationMs: 5, + }, + }), + ); + + const result = projector.buildResult(buildEmptyToolTelemetry()); + + expect( + result.messagesSnapshot.some((message) => { + const record = message as unknown as Record; + if (record.role === "toolResult") { + return true; + } + const content = Array.isArray(record.content) ? record.content : []; + return content.some((entry) => { + return ( + typeof entry === "object" && + entry !== null && + (entry as Record).type === "toolCall" + ); + }); + }), + ).toBe(false); + }); + it("emits verbose summaries for transcript-recorded dynamic tool calls", async () => { const onAgentEvent = vi.fn(); const onToolResult = vi.fn(); diff --git a/extensions/codex/src/app-server/event-projector.ts b/extensions/codex/src/app-server/event-projector.ts index e05c338ee34..20181da8ee2 100644 --- a/extensions/codex/src/app-server/event-projector.ts +++ b/extensions/codex/src/app-server/event-projector.ts @@ -1234,7 +1234,7 @@ export class CodexAppServerEventProjector { } private recordNativeToolTranscriptCall(item: CodexThreadItem | undefined): void { - if (!item || !shouldSynthesizeToolProgressForItem(item)) { + if (!item || !shouldRecordNativeToolTranscript(item)) { return; } const name = itemName(item); @@ -1249,7 +1249,7 @@ export class CodexAppServerEventProjector { } private recordNativeToolTranscriptResult(item: CodexThreadItem | undefined): void { - if (!item || !shouldSynthesizeToolProgressForItem(item)) { + if (!item || !shouldRecordNativeToolTranscript(item)) { return; } const name = itemName(item); @@ -1776,6 +1776,10 @@ function shouldSynthesizeToolProgressForItem(item: CodexThreadItem): boolean { } } +function shouldRecordNativeToolTranscript(item: CodexThreadItem): boolean { + return shouldSynthesizeToolProgressForItem(item) && item.type !== "webSearch"; +} + function isMutatingNativeToolItem(item: CodexThreadItem): boolean { return item.type === "commandExecution" || item.type === "fileChange"; }