fix(openclaw): probe append capability in local-daemon mode (#3686) (#3706)
`detectAppendCapability` was wired into the four external-API code paths only (#1102: "wired into all 4 checkExternalApiHealth call sites"); local-daemon mode has no such call site, so it was never probed. `supportsUpdateModeAppend` stayed `false` there forever, retain fell back to per-turn document ids sequenced from an in-memory counter, and every host restart replayed `…:turn:000001` onto the previous cycle's document — which retain's default `update_mode: 'replace'` deletes before reprocessing. A production deployment with months of daily traffic on one session was left with 29 documents. The daemon is a Hindsight API like any other. Treat it as one: - probe `<daemon>/version` in all three local-daemon paths — initial start, the healthy-daemon re-check, and reinit — so append mode engages and document ids become session-stable - `getActiveApiEndpoint()` resolves "the API we are talking to" (external URL or spawned daemon); `refreshQueueOperationIdCapability` uses it, so local-daemon retains finally carry `operation_id` instead of being hard-gated on `usingExternalApi` and replaying non-idempotently - initialize the retain queue in both modes: a daemon that is still booting or has crashed is as unreachable as a remote API, and a failed retain was simply dropped - stamp a per-process boot token into fallback ids (`…:turn:<boot>:000001`). The counter is in memory *and* FIFO-capped at MAX_TRACKED_SESSIONS, so ids could be recycled without any restart; this holds even when a probe fails transiently and the fallback re-engages. Tests: new local-daemon-parity.test.ts drives the real `service.start()` against a mocked daemon — probes /version and enables append, keeps the fallback when the daemon reports `store_document_text: false`, picks up a queue file from a previous session, and mints a fresh boot token per process. Verified red on the pre-fix code.
N
Nicolò Boschi committed
d97b560e2ca1b0c8ddce9076a40c4e8a2467751e
Parent: 1b74e3e
Committed by GitHub <noreply@github.com>
on 8/24/2026, 9:07:39 AM