Bug-fix patch focused on search recall correctness and plugin compatibility. Pins iii-engine to v0.11.2 because v0.11.6 introduces a new sandbox-everything-via-iii worker add model that agentmemory hasn't been refactored for yet — pin lifts once that refactor lands. Adds a hard guard against silent vector-index corruption, fixes BM25 indexing for memories saved via memory_save, and lands four Hermes plugin fixes that make the memory provider actually usable end-to-end.
If you've been seeing memory_smart_search return empty results for memories you just saved, this release fixes that. If you've been hitting hermes memory status reporting "not available" against a healthy systemd-managed install, this release fixes that too.
Fixed
-
BM25 search now indexes memories saved via
memory_save.mem::rememberwas writing toKV.memoriesbut never callinggetSearchIndex().add(), somemory_smart_searchandmemory_recallreturned empty for everything saved through that path — for every version since v0.9.0. Synthesizes aCompressedObservationfrom the saved Memory (title + content + concepts + files) and adds it to BM25 right after the durable write.rebuildIndex()now walksKV.memoriesso a fresh rebuild covers the full corpus, and a startup backfill retroactively indexes pre-existing memories on first start after upgrade — no manual reindex required. NewSearchIndex.has(id)is the idempotency gate. (#258, closes #257 — thanks @Nizar-BenHamida for the precise repro and log capture) -
Embedding providers no longer silently corrupt the vector index when an API returns wrong-dimension vectors.
cosineSimilarityreturns0on length mismatch instead of throwing, so a wrong-size vector got stored, never matched anything, and the corresponding memory became invisible without a single log line.withDimensionGuard()now wraps every embedding provider at the factory boundary insrc/providers/embedding/index.ts—embed(),embedBatch()(per-vector, indexed errors likeembedBatch[3]), andembedImage()all throw a descriptive error when the returnedFloat32Arraylength doesn't matchprovider.dimensions. The persistence-restore path got the same defense:IndexPersistence.load()now refuses to start when persisted vectors mismatch the active provider, with an actionable error spelling out the recovery paths (re-embed /AGENTMEMORY_DROP_STALE_INDEX=true/ switch back). (#248, closes #247 and #256 — thanks @AmmarSaleh50 for the issue analysis, the fix PR, and the test coverage) -
Hermes plugin:
handle_tool_callnow returns JSON strings, not raw Python dicts. Hermes stores the return value as the tool resultcontentfield in session history. Anthropic-protocol providers reject non-string content with a 400 on the next request — once triggered, every subsequent request in the affected session 400s until the session JSON is hand-cleaned. Wrapped all four return paths (memory_recall,memory_save,memory_search, unknown-tool) injson.dumps()and tightened the return-type annotationAny → stron both the abstract base and the concrete class. Matches the contract thatsrc/mcp/standalone.tsalready honors. (#255, closes #254 — thanks @KyoMio for the Anthropic-protocol-specific repro) -
Hermes plugin:
hermes memory statusnow reflects the real service state on systemd / launchd installs. When agentmemory runs as an external service whose runtime config lives in~/.agentmemory/.env, those values never reach the Hermes CLI shell. Hermes status readsos.environagainstget_config_schema()'senv_varkeys, finds them unset, and reports the plugin as "not available" — even though the service is healthy. The plugin now preloads~/.agentmemory/.envat import time usingos.environ.setdefault, bridging the agentmemory-managed and Hermes-managed config source-of-truths. Anything explicitly exported in the shell still wins. Best-effort: malformed / absent file is silently skipped. Both~/.agentmemory/.envand$XDG_CONFIG_HOME/agentmemory/.envare checked. (#253, closes #250 — thanks @OptionalCoin for the systemd repro and tracing it to env-source divergence) -
Hermes plugin: memory provider hooks accept passthrough kwargs. Hermes calls memory provider hooks with extra context kwargs (e.g.
session_id) at runtime that the existing strict signatures rejected withsync_turn() got an unexpected keyword argument 'session_id'. Hooks "succeeded" from Hermes's perspective but every conversation turn silently failed sync. Added**kwargs: Anytosync_turn,on_session_end,on_pre_compress,on_memory_write,prefetch,queue_prefetch, andshutdown. Where Hermes passessession_id, the patch prefers it over the cachedself._session_idso multi-session gateway contexts route to the right session. Same change applied to the abstractMemoryProviderfallback for the import-error path. (#252, closes #249 — thanks @OptionalCoin for the precise log analysis) -
agentmemory demonow actually seeds observations.seedDemoSessionposted to/agentmemory/observewithoutprojectandcwd, which the API requires as non-empty strings, so every observation 400'd and the demo silently reported "Seeded 0 observations across 3 sessions". Two-line fix: re-stageproject+cwdinto the observe payload alongsidesessionId. The smart-search queries the demo prints will now return real hits. (#251, closes #229 — thanks @seishonagon for the precise root-cause analysis) -
LLM compression / summarization timeouts increased. Larger sessions were hitting the 120s consolidation timeout under heavier workloads, leaving partial state. Bumped per-step ceilings to give slow providers (esp. local models) room to finish. (#213 — thanks @xuli500177)
-
pi/ OpenClaw / Hermes integration fixes. Tested round-trip fixes across the three integration plugins to keep them aligned with the latest hooks contract. (#230 — thanks @deepmroot)
Changed
-
iii-enginepinned to v0.11.2 across every install path. v0.11.6 introduces a new architecture where workers run inside sandboxed microVMs registered viaiii worker add. agentmemory still uses the olderiii-exec watch + node dist/index.mjsworker model fromiii-config.yaml, which doesn't pass the new engine's stricter trigger validation cleanly — the worker drops into an EPIPE reconnect loop and recall stops working. Pinning to v0.11.2 (the last engine that runs agentmemory's current architecture cleanly) until we refactor agentmemory to register itself viaiii worker addand run inside the new sandbox model.src/cli.tsauto-installer downloadsgithub.com/iii-hq/iii/releases/download/iii/v0.11.2/iii-<arch>.tar.gzdirectly. Per-arch coverage: darwin arm64/x64, linux x64/arm64/armv7, win32 x64/arm64.- Docker fallback pulls
iiidev/iii:0.11.2instead of:latest. docker-compose.ymlusesimage: iiidev/iii:${AGENTMEMORY_III_VERSION:-0.11.2}so the override env var actually takes effect for compose users.- Install instructions and Windows guide updated to point at the v0.11.2 release page.
- Escape hatch:
AGENTMEMORY_III_VERSION=<version>overrides the pin for users who've moved to the sandbox model manually. - Windows ZIP path detection in
runUpgradeso the auto-installer doesn't try to pipe a.zipthroughtar -xz. (#260) - Follow-up tracked separately: refactor agentmemory to register as a sandboxed worker via
iii worker addso the pin can be lifted.
-
README documents how to extend agentmemory with
iii worker add. New "Powered by iii" section maps eachiii worker add <name>to a concrete agentmemory capability — multi-instance memory, scheduled consolidation, durable retries on embeddings, sandboxed code exec, SQL state, extra MCP host. Lists only workers actually published to workers.iii.dev with direct links. (#242) -
README iii Console section corrected. The console ships with
iiias a subcommand; there's no separate installer. Replaced the boguscurl install.iii.dev/console/main/install.shline, simplified the launch command toiii console --port 3114, and added the missing console pages to the capability table (Workers, Queues, Config, Flow). Replaced the dashboard screenshot with the Workers page so users see real agentmemory instances connected. (#243)
Notes
If you're upgrading from <0.9.5 and have an existing vector index on disk, the new dim-guard will refuse to load if your active embedding provider declares a different dimension than what's persisted. This is the intended safe default — set AGENTMEMORY_DROP_STALE_INDEX=true to discard and rebuild from live observations, or re-embed against the new provider before starting.
If you've been on iii-engine v0.11.6 and noticed search returning empty after save, install agentmemory 0.9.5 fresh (or run npx @agentmemory/agentmemory upgrade) to pull pinned engine v0.11.2. v0.11.6 brings a new sandbox-everything-via-iii worker add model that agentmemory hasn't been refactored for yet — that work is tracked as a follow-up; this release just keeps existing users unblocked.