v0.9.10

rohitg00/agentmemoryv0.9.10May 12, 2026by rohitg00

AI Summary

Fixes distroless volume permissions, viewer reverse proxy support, and mem::context budget loop.

Key Highlights

  • Docker volume chowned to UID 65532
  • Viewer dashboard works behind reverse proxy on standard ports
  • mem::context budget loop no longer bails on oversized block
  • README polish (badges)

New Features

  • Volume permissions fix
  • Reverse proxy support
  • Budget loop fix
  • README polish

Full Release Notes

Three deployment-shape fixes reported live by [@flamerged](https://github.com/flamerged) ([#299](https://github.com/rohitg00/agentmemory/issues/299), [#301](https://github.com/rohitg00/agentmemory/issues/301)): the v0.9.7 docker-compose persistence fix was incomplete because the distroless engine runs as UID 65532 but `docker volume create` initializes the named volume mountpoint as `root:root mode 755`; the viewer's port-detection JS hardcoded `'3113'` so any reverse-proxy fronting on port 80/443 returned an empty dashboard; and the `mem::context` budget loop short-circuited the entire selection on the first oversized block — pinning a large slot could starve all other context blocks even when smaller ones would have fit.

## Fixed

### `docker-compose.yml` now chowns the named volume to UID 65532 before the engine starts

The `iiidev/iii` image is **distroless and runs as UID 65532**; docker initializes named volumes as **root:root mode 755**; the engine has no `sh` / `chown` to self-heal at startup, so writes to `/data/state_store.db` and `/data/stream_store` returned `Permission denied (os error 13)`. The engine silently buffered in RAM, the API kept reporting `success: true`, and state evaporated on every container restart — the exact symptom v0.9.7's working-directory fix set out to solve.

The compose file now ships an `iii-init` one-shot service (`busybox:1.36`, ~4 MB image, exits in <100 ms) that runs `chown -R 65532:65532 /data && chmod 755 /data` once at compose-up, plus `user: "65532:65532"` on the `iii-engine` service and `depends_on.iii-init.condition: service_completed_successfully` so the engine never starts before the volume is owner-correct.

**Migration**: existing deployments that already hit the bug should run `docker compose down && docker compose up -d` after upgrading — the init container fixes the volume in place on the first run, no manual `chown` needed.

(#304, closes [#301](https://github.com/rohitg00/agentmemory/issues/301) — thanks [@flamerged](https://github.com/flamerged) for the precise UID + mountpoint trace and the chown workaround that confirmed the fix shape)

### Viewer dashboard now works behind any reverse proxy on standard ports (80 / 443)

`src/viewer/index.html` resolved the REST base URL through:

```js
// before
var viewerPort = params.get('port') || window.location.port || '3113';
```

When the page was served on port 80 / 443, `window.location.port` was the empty string, the fallback hardcoded `'3113'`, and every browser-side `/agentmemory/*` fetch went to `<host>:3113` — typically loopback-only on the self-hosted shape, so unreachable from outside. The viewer rendered cleanly but every panel showed the empty "first run" state even when `curl <proxy-host>/agentmemory/sessions` returned correct data.

The fix uses `window.location.origin` as the REST base when neither `?port=` nor `window.location.port` is set, and `window.location.host` for the WebSocket URL so the same-origin path works for both REST and live updates. Behaviour with an explicit `?port=N` or non-default `window.location.port` is unchanged.

(#304, closes [#299](https://github.com/rohitg00/agentmemory/issues/299) — thanks [@flamerged](https://github.com/flamerged) for the deployment context + the lines-927–930 trace)

### `mem::context` budget loop no longer bails the entire selection on the first oversized block

The selection loop in `src/functions/context.ts` used `break` when `usedTokens + block.tokens > budget`, so a single oversized block at the top of the sorted list — most commonly a fat pinned slot under #288's new injection path — cut off every smaller block that would have fit. Switched to `continue`, so smaller blocks downstream of an oversized one can still slip into the remaining budget. Net effect: pinned-slot priority semantic is preserved (pinned blocks still sort first via `recency: Date.now()`), but the worst case no longer starves the entire context. Total tokens still bounded by `tokenBudget` (default 2000); only the composition under contention changes.

### Bonus — README polish

[@PR #305](https://github.com/rohitg00/agentmemory/pull/305) added the Trendshift `#1 Repository Of The Day` trophy badge and a star history chart to the top of the README, dropped Hermes + OpenClaw into the tagline alongside the other first-party integrations they already ship plugins for, and reflowed the Karpathy-gist sentence onto a single italic line for narrower viewports.

## Changed

- `@agentmemory/mcp` package version bumped 0.9.9 → 0.9.10 to lockstep with the main package.

## Install / upgrade

```bash
npm i -g @agentmemory/agentmemory@0.9.10
# or
npx @agentmemory/agentmemory

# MCP standalone shim
npx -y @agentmemory/mcp
```

If you ran the v0.9.7+ Docker compose stack and saw state vanish on every restart, the init container shipped in this release fixes the volume in place — just `docker compose down && docker compose up -d` after upgrading.

**Full changelog:** [v0.9.9...v0.9.10](https://github.com/rohitg00/agentmemory/compare/v0.9.9...v0.9.10)