v0.9.13

rohitg00/agentmemoryv0.9.13May 15, 2026by rohitg00

AI Summary

Adds `.env.example` discovery, CJK BM25 tokenizer, load harness, deploy templates, and updates Gemini provider defaults.

Key Highlights

  • .env.example discovery + CI sync-checker
  • CJK tokenizer for BM25 search
  • benchmark/load-100k.ts load harness
  • One-click deploy templates (fly.io, Railway, etc.)
  • Gemini provider defaults bumped to GA models

New Features

  • .env.example discovery
  • CJK tokenizer
  • Load benchmark harness
  • Deploy templates
  • Gemini defaults update

Full Release Notes

Six PRs landed since v0.9.12 — `.env.example` discovery shipped (#372), CJK BM25 tokenizer landed (#344 / PR #362), `benchmark/load-100k.ts` load harness landed (#346 / PR #363), one-click deploy templates for fly.io / Railway / Render / Coolify added (#343 / PR #361), Gemini provider defaults moved to current GA models (#246 + #368 / PR #370), and the in-tree Python ecosystem story switched from a duplicate REST client to a one-page `iii-sdk` example (#342 / PR #364). Plus 14 Dependabot security advisories closed via Next.js + PostCSS bumps.

## Contributors

Huge thanks to three external contributors this release:

- [@fatinghenji](https://github.com/fatinghenji) — pre-cleanup work on the OpenAI-compatible LLM provider (PR #240 / PR #307); the universal-adapter shape will land in the next minor once branch maintenance catches up
- [@AmmarSaleh50](https://github.com/AmmarSaleh50) — Gemini embedding migration with L2-norm + 768-dim plumbing (PR #246, folded into PR #370)
- [@yut304](https://github.com/yut304) — Gemini LLM default deprecation fix (PR #368, folded into PR #370)

## Added

### `.env.example` at repo root + bundled in the npm tarball ([#383](https://github.com/rohitg00/agentmemory/pull/383), closes [#372](https://github.com/rohitg00/agentmemory/issues/372), [#47](https://github.com/rohitg00/agentmemory/issues/47), [#293](https://github.com/rohitg00/agentmemory/issues/293), partial [#233](https://github.com/rohitg00/agentmemory/issues/233))

Every env var actually read by `src/` is now documented in one place, grouped by surface: LLM provider, embedding provider, auth, search tuning, behaviour flags, CLI runtime, ports, iii engine pin, Claude Code bridge, Obsidian export. Every line is commented out by default so the file ships as a config template, not a config. The npm package now lists `.env.example` in its `files` field so `npm i -g @agentmemory/agentmemory` carries it.

New `agentmemory init` CLI command copies the bundled template to `~/.agentmemory/.env` if absent; refuses to overwrite an existing config and prints a diff command pointing at the latest template. The exists-check + copy is now a single atomic `copyFile(template, target, COPYFILE_EXCL)` so two parallel `init` runs cannot race.

New `scripts/check-env-example.mjs` CI sync-checker walks every `.ts` / `.mts` / `.mjs` / `.js` file under `src/` and fails CI when the runtime reads an env var the template doesn't document (or vice versa). Plugged into `.github/workflows/ci.yml` after `npm test`. Initial bootstrap: 60 keys in sync.

### CJK tokenizer for BM25 search ([#362](https://github.com/rohitg00/agentmemory/pull/362), closes [#344](https://github.com/rohitg00/agentmemory/issues/344))

New `src/state/cjk-segmenter.ts` detects CJK input by Unicode block and routes to `@node-rs/jieba` (Chinese, native, no model download), `tiny-segmenter` (Japanese, pure JS, ~25 KB), or rule-based syllable-block split (Korean). Both segmenters declared in `optionalDependencies` so the base install stays lean; soft-fail with a one-time stderr hint when the dep is missing. Order-preserving single-pass tokenization across mixed CJK + non-CJK runs — regression test for `"abc 메모리 def 项目 ghi"` returns `["abc","메모리","def","项目","ghi"]`.

### `benchmark/load-100k.ts` load harness ([#363](https://github.com/rohitg00/agentmemory/pull/363), closes [#346](https://github.com/rohitg00/agentmemory/issues/346))

Hand-rolled, dependency-free harness that seeds N synthetic memories against a local daemon at `http://localhost:3111` and records p50 / p90 / p99 latency + throughput for `POST /agentmemory/remember`, `POST /agentmemory/smart-search`, and `GET /agentmemory/memories?latest=true` across the matrix N ∈ {1k, 10k, 100k} × concurrency C ∈ {1, 10, 100}. Content drawn from a seedable `mulberry32` PRNG so re-running against the same build produces the same seed corpus. Results land in `benchmark/results/load-100k-<short-git-sha>.json`. Wired as `npm run bench:load`.

### One-click deploy templates: fly.io / Railway / Render / Coolify ([#361](https://github.com/rohitg00/agentmemory/pull/361), closes [#343](https://github.com/rohitg00/agentmemory/issues/343))

Each template under `deploy/<platform>/` ships a multi-stage Dockerfile that `COPY --from=iiidev/iii:0.11.2`s the engine binary into a `node:22-slim` runtime, npm-installs `@agentmemory/agentmemory` under `/opt/agentmemory` with `iii-sdk` pinned via `package.json` overrides (avoids the caret-resolves-to-0.11.6 drift), and runs an entrypoint that rewrites the bundled `iii-config.yaml` to bind `0.0.0.0` + use absolute `/data` paths, chowns the platform-mounted volume to `node:node` via `gosu`, generates a first-boot HMAC secret, and exec's the agentmemory CLI as the unprivileged `node` user under `tini` (with `TINI_SUBREAPER=1`). Verified end-to-end on fly.io (machine in `iad`, 1 GB volume, healthcheck passing). Coolify template uses `expose:` instead of `ports:` so Traefik handles TLS termination + domain routing.

### `examples/python/` quickstart via `iii-sdk` ([#364](https://github.com/rohitg00/agentmemory/pull/364), closes [#342](https://github.com/rohitg00/agentmemory/issues/342))

Quickstart + observation/recall flow showing `iii-sdk` (Python) calling `mem::remember` / `mem::smart-search` / `mem::context` directly over `ws://localhost:49134`. Replaces a duplicate-transport Python REST client (initial PR #360, closed) with a single-SDK story — the same `iii-sdk` install (`pip install iii-sdk` / `cargo add iii-sdk` / `npm install iii-sdk`) talks to every agentmemory function from any language.

## Changed

### Gemini provider defaults bumped to current GA models ([#370](https://github.com/rohitg00/agentmemory/pull/370), closes [#368](https://github.com/rohitg00/agentmemory/pull/368), [#246](https://github.com/rohitg00/agentmemory/pull/246))

LLM default `gemini-2.0-flash` → `gemini-2.5-flash` (the `gemini-flash-latest` moving alias was rejected — production behaviour should be deterministic from a release perspective).

Embedding default `text-embedding-004` → `gemini-embedding-001` (the previous default is deprecated and shuts down 2026-01-14 per [`ai.google.dev/gemini-api/docs/deprecations`](https://ai.google.dev/gemini-api/docs/deprecations)). Three implementation details ride along:

1. URL path `:batchEmbedContent` → `:batchEmbedContents` (plural — the new model's batch endpoint).
2. Every request now sends `outputDimensionality: 768` so the returned vectors match `GeminiEmbeddingProvider.dimensions = 768` and the index-restore dim guard from #248 — no reindex needed for existing users.
3. Returned vectors are L2-normalized before the result-array push because `gemini-embedding-001` does **not** normalize by default unlike `text-embedding-004` — without this the downstream cosine-similarity math silently collapses recall. `l2Normalize` warns once on a zero-norm embedding so operators can correlate index quality dips with upstream regressions.

## Security

### 14 open Dependabot advisories closed via Next.js + PostCSS bumps ([#348](https://github.com/rohitg00/agentmemory/pull/348))

13 Next.js advisories closed: middleware/proxy bypass, SSRF on WebSocket upgrades, DoS via connection exhaustion, CSP-nonce XSS, image-opt DoS, RSC cache poisoning, beforeInteractive XSS, and segment-prefetch routes — by bumping the website's Next.js to `^16.2.6`. The PostCSS XSS-via-unescaped-`</style>` advisory closed by pinning to `^8.5.10` via `overrides` in `website/package.json`. Verified `npm audit --omit=dev` returns 0 and `npm run build` clean on Next 16.2.6.

Dependabot now runs weekly against six update streams (npm × 5 paths + github-actions) per the new `.github/dependabot.yml`.

## Install / upgrade

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

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

# After install:
npx @agentmemory/agentmemory init   # copy bundled .env.example to ~/.agentmemory/.env
```

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