From 3b6fac85ea28e30c66e11798eae6b8f93734fcf3 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 11 Apr 2026 03:20:57 +0100 Subject: [PATCH] chore: prepare 2026.4.10 release --- CHANGELOG.md | 7 +++++++ docs/.generated/plugin-sdk-api-baseline.sha256 | 4 ++-- extensions/codex/package.json | 2 +- pnpm-lock.yaml | 4 ++-- .../moonshot-thinking-stream-wrappers.ts | 15 +++++++++++---- src/agents/sandbox/backend.types.ts | 6 ++++++ src/auto-reply/reply/commands-compact.test.ts | 1 + src/auto-reply/reply/commands-models.test.ts | 6 +++--- .../reply/commands-system-prompt.test.ts | 1 + src/channels/plugins/types.adapters.ts | 1 - 10 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05de90c2a00..c789f37e4cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ Docs: https://docs.openclaw.ai ### Changes +### Fixes + +## 2026.4.10 + +### Changes + - Models/Codex: add the bundled Codex provider and plugin-owned app-server harness so `codex/gpt-*` models use Codex-managed auth, native threads, model discovery, and compaction while `openai/gpt-*` stays on the normal OpenAI provider path. (#64298) - Memory/Active Memory: add a new optional Active Memory plugin that gives OpenClaw a dedicated memory sub-agent right before the main reply, so ongoing chats can automatically pull in relevant preferences, context, and past details without making users remember to manually say "remember this" or "search memory" first. Includes configurable message/recent/full context modes, live `/verbose` inspection, advanced prompt/thinking overrides for tuning, and opt-in transcript persistence for debugging. Docs: https://docs.openclaw.ai/concepts/active-memory. (#63286) Thanks @Takhoffman. - macOS/Talk: add an experimental local MLX speech provider for Talk Mode, with explicit provider selection, local utterance playback, interruption handling, and system-voice fallback. (#63539) Thanks @ImLukeF. @@ -46,6 +52,7 @@ Docs: https://docs.openclaw.ai - Agents/timeouts: extend the default LLM idle window to 120s and keep silent no-token idle timeouts on recovery paths, so slow models can retry or fall back before users see an error. - Gateway/agents: preserve configured model selection and richer `IDENTITY.md` content across agent create/update flows and workspace moves, and fail safely instead of silently overwriting unreadable identity files. (#61577) Thanks @samzong. - Skills/TaskFlow: restore valid frontmatter fences for the bundled `taskflow` and `taskflow-inbox-triage` skills and copy bundled `SKILL.md` files as hard dist-runtime copies so skills stay discoverable and loadable after updates. (#64166, #64469) Thanks @extrasmall0. +- Skills: respect overridden home directories when loading personal skills so service, test, and custom launch environments read the intended user skill directory instead of the process home. - Windows/exec: settle supervisor waits from child exit state after stdout and stderr drain even when `close` never arrives, so CLI commands stop hanging or dying with forced `SIGKILL` on Windows. (#64072) Thanks @obviyus. - Browser/sandbox: prevent sandbox browser CDP startup hangs by recreating containers when the browser security hash changes and by waiting on the correct sandbox browser lifecycle. (#62873) Thanks @Syysean. - QQBot/streaming: make block streaming configurable per QQ bot account via `streaming.mode` (`"partial"` | `"off"`, default `"partial"`) instead of hardcoding it off, so responses can be delivered incrementally. (#63746) diff --git a/docs/.generated/plugin-sdk-api-baseline.sha256 b/docs/.generated/plugin-sdk-api-baseline.sha256 index f81269693a8..21a9beb741f 100644 --- a/docs/.generated/plugin-sdk-api-baseline.sha256 +++ b/docs/.generated/plugin-sdk-api-baseline.sha256 @@ -1,2 +1,2 @@ -0b3c1d24d91e5b7b02d0e6322a8d32c280d1555f82f9a9fa948c28304712f9dd plugin-sdk-api-baseline.json -b50013d51b21a9cd7b3b21baa8ef22ba3be5d97392e040ed740f147e95ccb544 plugin-sdk-api-baseline.jsonl +ee16273fa5ad8c5408e9dad8d96fde86dfa666ef8eb44840b78135814ff97173 plugin-sdk-api-baseline.json +2bd0d5edf23e6a889d6bedb74d0d06411dd7750dac6ebf24971c789f8a69253a plugin-sdk-api-baseline.jsonl diff --git a/extensions/codex/package.json b/extensions/codex/package.json index 0f865d98d76..21063f952d2 100644 --- a/extensions/codex/package.json +++ b/extensions/codex/package.json @@ -4,7 +4,7 @@ "description": "OpenClaw Codex harness and model provider plugin", "type": "module", "dependencies": { - "@mariozechner/pi-coding-agent": "0.65.2", + "@mariozechner/pi-coding-agent": "0.66.1", "ws": "^8.20.0", "zod": "^4.3.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45bd030fb63..f29689ff8cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -421,8 +421,8 @@ importers: extensions/codex: dependencies: '@mariozechner/pi-coding-agent': - specifier: 0.65.2 - version: 0.65.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + specifier: 0.66.1 + version: 0.66.1(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) ws: specifier: ^8.20.0 version: 8.20.0 diff --git a/src/agents/pi-embedded-runner/moonshot-thinking-stream-wrappers.ts b/src/agents/pi-embedded-runner/moonshot-thinking-stream-wrappers.ts index f7e11cda149..504b0f7e0f7 100644 --- a/src/agents/pi-embedded-runner/moonshot-thinking-stream-wrappers.ts +++ b/src/agents/pi-embedded-runner/moonshot-thinking-stream-wrappers.ts @@ -1,10 +1,16 @@ import type { StreamFn } from "@mariozechner/pi-agent-core"; -import { streamSimple } from "@mariozechner/pi-ai"; import type { ThinkLevel } from "../../auto-reply/thinking.js"; import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js"; import { streamWithPayloadPatch } from "./stream-payload-utils.js"; type MoonshotThinkingType = "enabled" | "disabled"; +let piAiRuntimePromise: Promise | undefined; + +async function loadDefaultStreamFn(): Promise { + piAiRuntimePromise ??= import("@mariozechner/pi-ai"); + const runtime = await piAiRuntimePromise; + return runtime.streamSimple; +} function normalizeMoonshotThinkingType(value: unknown): MoonshotThinkingType | undefined { if (typeof value === "boolean") { @@ -66,9 +72,9 @@ export function createMoonshotThinkingWrapper( baseStreamFn: StreamFn | undefined, thinkingType?: MoonshotThinkingType, ): StreamFn { - const underlying = baseStreamFn ?? streamSimple; - return (model, context, options) => - streamWithPayloadPatch(underlying, model, context, options, (payloadObj) => { + return async (model, context, options) => { + const underlying = baseStreamFn ?? (await loadDefaultStreamFn()); + return streamWithPayloadPatch(underlying, model, context, options, (payloadObj) => { let effectiveThinkingType = normalizeMoonshotThinkingType(payloadObj.thinking); if (thinkingType) { @@ -87,4 +93,5 @@ export function createMoonshotThinkingWrapper( } } }); + }; } diff --git a/src/agents/sandbox/backend.types.ts b/src/agents/sandbox/backend.types.ts index 32490b9f1bc..734480713c4 100644 --- a/src/agents/sandbox/backend.types.ts +++ b/src/agents/sandbox/backend.types.ts @@ -47,3 +47,9 @@ export type RegisteredSandboxBackend = { }; export type { SandboxBackendHandle, SandboxBackendId } from "./backend-handle.types.js"; +export type { + SandboxBackendCommandParams, + SandboxBackendCommandResult, + SandboxBackendExecSpec, + SandboxFsBridgeContext, +} from "./backend-handle.types.js"; diff --git a/src/auto-reply/reply/commands-compact.test.ts b/src/auto-reply/reply/commands-compact.test.ts index 70f85c8e577..8de330abb35 100644 --- a/src/auto-reply/reply/commands-compact.test.ts +++ b/src/auto-reply/reply/commands-compact.test.ts @@ -319,6 +319,7 @@ describe("handleCompactCommand", () => { sessionId: "target-session", }), tokensAfter: 321, + skillsSnapshot: { prompt: "target", skills: [] }, }), ); }); diff --git a/src/auto-reply/reply/commands-models.test.ts b/src/auto-reply/reply/commands-models.test.ts index 001a8fc2299..8b7865e7fc7 100644 --- a/src/auto-reply/reply/commands-models.test.ts +++ b/src/auto-reply/reply/commands-models.test.ts @@ -18,11 +18,11 @@ const modelAuthLabelMocks = vi.hoisted(() => ({ })); vi.mock("../../agents/model-catalog.js", () => ({ - loadModelCatalog: (params: unknown) => modelCatalogMocks.loadModelCatalog(params), + loadModelCatalog: modelCatalogMocks.loadModelCatalog, })); vi.mock("../../agents/model-auth-label.js", () => ({ - resolveModelAuthLabel: (params: unknown) => modelAuthLabelMocks.resolveModelAuthLabel(params), + resolveModelAuthLabel: modelAuthLabelMocks.resolveModelAuthLabel, })); const telegramModelsTestPlugin: ChannelPlugin = { @@ -260,7 +260,7 @@ describe("handleModelsCommand", () => { updatedAt: Date.now(), providerOverride: "wrapper-provider", modelOverride: "wrapper-model", - } as HandleCommandsParams["sessionEntry"]; + }; params.sessionStore = { "agent:support:main": { sessionId: "target-session", diff --git a/src/auto-reply/reply/commands-system-prompt.test.ts b/src/auto-reply/reply/commands-system-prompt.test.ts index b597621d567..e2b2a3c5c7b 100644 --- a/src/auto-reply/reply/commands-system-prompt.test.ts +++ b/src/auto-reply/reply/commands-system-prompt.test.ts @@ -82,6 +82,7 @@ function makeParams(): HandleCommandsParams { agentId: "main", sessionEntry: { sessionId: "session-1", + updatedAt: Date.now(), groupId: "group-1", groupChannel: "#general", space: "guild-1", diff --git a/src/channels/plugins/types.adapters.ts b/src/channels/plugins/types.adapters.ts index 7071b36f4dc..8f89f589ea7 100644 --- a/src/channels/plugins/types.adapters.ts +++ b/src/channels/plugins/types.adapters.ts @@ -669,7 +669,6 @@ export type ChannelApprovalDeliveryAdapter = { request: ExecApprovalRequest; }) => boolean; }; - export type ChannelApproveCommandBehavior = | { kind: "allow" } | { kind: "ignore" }