fix(codex): skip native web search transcript mirroring (#85346)

* fix(codex): skip native web search transcript mirroring

* test(codex): type transcript snapshot assertion
This commit is contained in:
Peter Steinberger
2026-05-22 14:14:01 +01:00
committed by GitHub
parent fc7a531f6c
commit c3531fcd7b
3 changed files with 41 additions and 2 deletions

View File

@@ -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.

View File

@@ -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<string, unknown>;
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<string, unknown>).type === "toolCall"
);
});
}),
).toBe(false);
});
it("emits verbose summaries for transcript-recorded dynamic tool calls", async () => {
const onAgentEvent = vi.fn();
const onToolResult = vi.fn();

View File

@@ -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";
}