From cf5c60a3429524453191dfbfc6bbd4802f178eee Mon Sep 17 00:00:00 2001 From: pi Date: Wed, 10 Jun 2026 16:25:26 +0200 Subject: [PATCH] fix(base): work around mempalace diary_write top-level anyOf Anthropic's tools API rejects top-level anyOf/oneOf/allOf in input_schema. Mempalace 3.3.x/3.4.0 advertise diary_write with `anyOf: [{required:[entry]}, {required:[content]}]`, breaking pi on first prompt with: tools..custom.input_schema: input_schema does not support oneOf, allOf, or anyOf at the top level Patch the installed mcp_server.py after `uv tool install` to drop the anyOf block and require ["agent_name", "entry"] instead. The handler still accepts `content` server-side as a kwarg alias, so callers using either name keep working. The workaround is idempotent and self-deactivating: once upstream ships the fix the regex no longer matches and the RUN is a silent no-op. Also pin mempalace to 3.4.0 via a new MEMPALACE_VERSION build arg so future bumps are a deliberate, reviewable diff rather than an implicit pull of latest (an implicit upgrade is what swept the broken schema in unannounced). Refs MemPalace/mempalace#1728, MemPalace/mempalace#1735 --- CHANGELOG.md | 33 ++++++++++++++++++++++++++++++++- Dockerfile.base | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e26992d..0bfb176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,38 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`). ## Unreleased -_(no changes since v1.0.0)_ +_(no changes since v1.0.1)_ + +## v1.0.1 — 2026-06-10 + +Patch release. Works around an upstream MemPalace bug that broke pi at +first prompt against the Anthropic Claude API. + +### Fixed + +- **`mempalace_diary_write` schema rejected by Anthropic API.** Mempalace + 3.3.x and 3.4.0 advertise `diary_write`'s `input_schema` with a + top-level `anyOf: [{required:[entry]}, {required:[content]}]` to + express "either `entry` or `content` must be supplied". Anthropic's + tools API rejects top-level `anyOf` / `oneOf` / `allOf` outright, so + pi failed to register tools at session start with + `tools..custom.input_schema: input_schema does not support oneOf, + allOf, or anyOf at the top level`. `Dockerfile.base` now patches the + installed `mcp_server.py` after `uv tool install` to drop the `anyOf` + block and require `["agent_name", "entry"]` instead. The mempalace + handler still accepts `content` server-side as a kwarg alias, so + callers using either name keep working. Tracked upstream: + [issue #1728](https://github.com/MemPalace/mempalace/issues/1728), + [PR #1735](https://github.com/MemPalace/mempalace/pull/1735). + The workaround is idempotent + self-deactivating and will be removed + once a fixed mempalace release lands on PyPI. + +### Changed + +- **Mempalace pinned to 3.4.0** via `MEMPALACE_VERSION` build arg. + Future bumps must be a reviewable diff rather than an implicit pull + of `latest` (the broken 3.3.x/3.4.0 schema slipping in unannounced + is what caused this release). ## v1.0.0 — 2026-06-09 diff --git a/Dockerfile.base b/Dockerfile.base index d773f07..f7ea7bb 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -273,14 +273,49 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64" # Always installed in the base. Set INSTALL_MEMPALACE=false at base-build # time to shave ~300 MB. ARG INSTALL_MEMPALACE=true +# Pin to a known-good version. Bump deliberately, not implicitly: an +# unpinned install silently swept in mempalace 3.3.x/3.4.0 with a broken +# diary_write schema (see workaround RUN below + issue #1728). Pinning +# makes mempalace upgrades a reviewable diff rather than a surprise. +ARG MEMPALACE_VERSION=3.4.0 ENV UV_TOOL_DIR=/opt/uv-tools ENV UV_TOOL_BIN_DIR=/usr/local/bin RUN if [ "${INSTALL_MEMPALACE}" = "true" ]; then \ mkdir -p /opt/uv-tools && \ - uv tool install --no-cache mempalace && \ + uv tool install --no-cache "mempalace==${MEMPALACE_VERSION}" && \ /opt/uv-tools/mempalace/bin/python -c "import mempalace; print('mempalace', mempalace.__version__ if hasattr(mempalace, '__version__') else 'installed')" ; \ fi +# ── workaround: strip top-level anyOf from mempalace_diary_write schema ── +# Mempalace 3.3.x/3.4.0 advertise diary_write's input_schema with a +# top-level `anyOf: [{required:[entry]}, {required:[content]}]` to express +# "either entry or content must be supplied". Anthropic's tools API rejects +# top-level anyOf/oneOf/allOf, so pi/Claude fail at session start with +# `tools..custom.input_schema: input_schema does not support oneOf, +# allOf, or anyOf at the top level`. +# +# Patch the advertised schema to require ["agent_name", "entry"] and remove +# the anyOf block. The handler keeps accepting `content` server-side as a +# kwarg alias so existing callers still work. +# +# Idempotent and self-deactivating: once upstream releases the fix the +# regex no longer matches and this RUN is a silent no-op. +# Upstream tracking: +# https://github.com/MemPalace/mempalace/issues/1728 +# https://github.com/MemPalace/mempalace/pull/1735 +# TODO: remove this RUN once a mempalace release containing PR #1735 is on +# PyPI and installed by the line above. +RUN if [ "${INSTALL_MEMPALACE}" = "true" ]; then \ + MP_FILE="$(find /opt/uv-tools/mempalace -path '*/mempalace/mcp_server.py' | head -n1)" && \ + if [ -z "$MP_FILE" ]; then echo "mempalace mcp_server.py not found" >&2; exit 1; fi && \ + perl -0777 -i -pe 's/(?:[ \t]*\#[^\n]*\n)*[ \t]*"required":\s*\[\s*"agent_name"\s*\]\s*,\s*\n[ \t]*"anyOf":\s*\[\s*\n[ \t]*\{\s*"required":\s*\[\s*"entry"\s*\]\s*\}\s*,\s*\n[ \t]*\{\s*"required":\s*\[\s*"content"\s*\]\s*\}\s*,?\s*\n[ \t]*\]\s*,\s*\n/ "required": ["agent_name", "entry"],\n/s' "$MP_FILE" && \ + if grep -q '"required": \["agent_name", "entry"\]' "$MP_FILE"; then \ + echo "mempalace diary_write anyOf workaround: applied (or already clean)"; \ + else \ + echo "WARN: mempalace diary_write anyOf workaround did not match expected schema — upstream may have changed shape" >&2; \ + fi ; \ + fi + # ── mempalace-toolkit — bash wrappers for session/docs mining ──────── ARG INSTALL_MEMPALACE_TOOLKIT=true ARG MEMPALACE_TOOLKIT_REF=main