diff --git a/CHANGELOG.md b/CHANGELOG.md index fc886cba7e1..eebc60af1dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Codex harness: route native `request_user_input` prompts back to the originating chat, preserve queued follow-up answers, and honor newer app-server command approval amendment decisions. +- Codex harness/context-engine: redact context-engine assembly failures before logging, so fallback warnings do not serialize raw error objects. (#70809) Thanks @jalehman. - Codex harness/Windows: resolve npm-installed `codex.cmd` shims through PATHEXT before starting the native app-server, so `codex/*` models work without a manual `.exe` shim. Fixes #70913. - Slack/groups: classify MPIM group DMs as group chat context and suppress verbose tool/plan progress on Slack non-DM surfaces, so internal "Working…" traces no longer leak into rooms. Fixes #70912. - Agents/replay: stop OpenAI/Codex transcript replay from synthesizing missing tool results while still preserving synthetic repair on Anthropic, Gemini, and Bedrock transport-owned sessions. (#61556) Thanks @VictorJeon and @vincentkoc. diff --git a/extensions/codex/src/app-server/run-attempt.context-engine.test.ts b/extensions/codex/src/app-server/run-attempt.context-engine.test.ts index 9598f3d4ffc..7a7f3f7b324 100644 --- a/extensions/codex/src/app-server/run-attempt.context-engine.test.ts +++ b/extensions/codex/src/app-server/run-attempt.context-engine.test.ts @@ -4,6 +4,7 @@ import path from "node:path"; import type { AgentMessage } from "@mariozechner/pi-agent-core"; import { SessionManager } from "@mariozechner/pi-coding-agent"; import type { EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness"; +import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { ContextEngine } from "../../../../src/context-engine/types.js"; import type { CodexServerNotification } from "./protocol.js"; @@ -365,6 +366,41 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => { ); }); + it("logs assemble failures as a formatted message instead of the raw error object", async () => { + const sessionFile = path.join(tempDir, "session.jsonl"); + const workspaceDir = path.join(tempDir, "workspace"); + const rawError = new Error("Authorization: Bearer sk-abcdefghijklmnopqrstuv"); + const contextEngine = createContextEngine({ + assemble: vi.fn(async () => { + throw rawError; + }), + bootstrap: undefined, + }); + const warn = vi.spyOn(embeddedAgentLog, "warn").mockImplementation(() => undefined); + const harness = createStartedThreadHarness(); + const params = createParams(sessionFile, workspaceDir); + params.contextEngine = contextEngine; + + const run = runCodexAppServerAttempt(params); + await harness.waitForMethod("turn/start"); + await harness.completeTurn(); + await run; + + expect(warn).toHaveBeenCalledWith( + "context engine assemble failed; using Codex baseline prompt", + { + error: expect.any(String), + }, + ); + const warning = warn.mock.calls.find( + ([message]) => message === "context engine assemble failed; using Codex baseline prompt", + ); + expect(warning?.[1]).not.toEqual({ error: rawError }); + expect(String((warning?.[1] as { error?: unknown } | undefined)?.error)).not.toContain( + "sk-abcdefghijklmnopqrstuv", + ); + }); + it("falls back to ingestBatch and skips turn maintenance on prompt failure", async () => { const sessionFile = path.join(tempDir, "session.jsonl"); const workspaceDir = path.join(tempDir, "workspace"); diff --git a/extensions/codex/src/app-server/run-attempt.ts b/extensions/codex/src/app-server/run-attempt.ts index c795b939785..8164d17d0de 100644 --- a/extensions/codex/src/app-server/run-attempt.ts +++ b/extensions/codex/src/app-server/run-attempt.ts @@ -217,7 +217,7 @@ export async function runCodexAppServerAttempt( prePromptMessageCount = projection.prePromptMessageCount; } catch (assembleErr) { embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { - error: assembleErr, + error: formatErrorMessage(assembleErr), }); } }