v0.9.12

rohitg00/agentmemoryv0.9.12May 13, 2026by rohitg00

AI Summary

Fixes BM25 non-ASCII support, populates vector index at runtime, hardens viewer dashboard, and adds bearer token guard.

Key Highlights

  • BM25 tokenizer now indexes non-ASCII
  • Vector index populated at runtime
  • Viewer dashboard no longer stuck on 'Loading'
  • Integrations warn when sending bearer token over plaintext HTTP
  • RetentionScore type no longer declares source twice

New Features

  • BM25 unicode support
  • Vector index population
  • Viewer dashboard fix
  • Bearer token plaintext guard
  • Type strictness fix

Full Release Notes

Four landed PRs since v0.9.11 — one type-correctness fix, one search-quality fix (BM25 unicode + vector-index live-write), one viewer hardening (CSP-clean fonts + load-error surface), and one integrations security hardening (bearer token over plaintext HTTP).

## Contributors

Huge thanks to four external contributors this release:

- [@mvanhorn](https://github.com/mvanhorn) — plaintext-bearer-auth guard across Hermes (Python), OpenClaw (mjs), and pi (TypeScript) plus the `AGENTMEMORY_REQUIRE_HTTPS=1` escalation knob ([#315](https://github.com/rohitg00/agentmemory/pull/315))
- [@nik1t7n](https://github.com/nik1t7n) — original repro for the BM25 non-ASCII tokenizer bug + vector-index-never-populated trace ([#295](https://github.com/rohitg00/agentmemory/issues/295))
- [@hem57](https://github.com/hem57) — Windows repro screenshot + browser-console CSP-violation trace that pinned down the viewer "stuck Loading" path ([#323](https://github.com/rohitg00/agentmemory/issues/323))
- [@cl0ckt0wer](https://github.com/cl0ckt0wer) — precise file:line trace for the duplicate `RetentionScore.source` declaration ([#277](https://github.com/rohitg00/agentmemory/issues/277))

## Fixed

### BM25 tokenizer now indexes non-ASCII; vector index now actually populated at runtime ([#327](https://github.com/rohitg00/agentmemory/pull/327), closes [#295](https://github.com/rohitg00/agentmemory/issues/295))

Two bugs in one PR:

**BM25 tokenizer regex stripped every non-ASCII character.** `src/state/search-index.ts` used `\w` (JS `\w` is ASCII-only), so non-English search returned empty results across the board — Greek, accented Latin, Hebrew, Arabic, Cyrillic. Regex replaced with `/[^\p{L}\p{N}\s/.\\-_]/gu` (Unicode letters/numbers, preserves underscore for `memory_recall`-style identifiers, keeps existing path/separator handling).

**`VectorIndex.add()` had zero callers anywhere in `src/`.** The vector index was loaded from disk at startup and never updated at runtime, so hybrid search returned stale results forever. New `vectorIndexAddGuarded()` helper in `src/functions/search.ts` wires `vectorIndex.add()` into `remember.ts`, `observe.ts` synthetic-compression branch, `compress.ts` post-LLM compression, and the cold-start `rebuildIndex()` walk — with a per-write dimension guard (symmetric to the persistence-load guard from #248), 16k-char input clipping (so an oversized memory can't 400 the embed call), and consistent stderr logging that no longer swallows embed failures.

**`migrateVectorIndex()` utility** re-embeds every memory + per-session observation against a new provider when dimensions change; per-session try/catch isolation so one bad session can't abort the whole migration; structured `failedSessions[]` result with a `"<sessions-list-failed>"` sentinel that distinguishes a catastrophic list-failure from per-session failures.

Soft-fail throughout: a downed embedder never breaks an upstream save. Live-tested end-to-end against Greek fixtures (thanks @nik1t7n for the original repro).

**CJK caveat preserved**: this fix recovers Greek, Cyrillic, accented Latin, Hebrew, Arabic, and other space-delimited scripts. CJK languages without spaces between characters still tokenize as a single sentence-long token — separate concern, needs a segmenter (PR #224 area).

### Integrations now warn when sending the bearer token over plaintext HTTP ([#315](https://github.com/rohitg00/agentmemory/pull/315), closes [#275](https://github.com/rohitg00/agentmemory/issues/275))

Symmetric guard across all three plugin runtimes (Python / mjs / TypeScript): a request that would attach `Authorization: Bearer <secret>` to a `http://<non-loopback>:port` URL now logs a one-time stderr warning telling the operator the token is observable on the wire.

Loopback hosts (`localhost`, `127.0.0.1`, `::1`) and `https://` URLs are exempt.

New env knob `AGENTMEMORY_REQUIRE_HTTPS=1` escalates the warning to a hard refusal — the plugin throws before any request is sent, so a misconfigured deployment can fail loudly instead of leaking the bearer once.

Edge cases verified by 13 tests: IPv6 `[::1]` loopback (loopback), RFC1918 LAN IPs (`192.168.x.x` / `10.x.x.x` warn — NOT loopback by design), lookalike hostnames (`localhost.evil.com` warns), no-secret short-circuit (guard never fires when no bearer would be sent), https-with-secret silent. Thanks [@mvanhorn](https://github.com/mvanhorn).

### Viewer dashboard no longer sticks on "Loading dashboard…" ([#335](https://github.com/rohitg00/agentmemory/pull/335), closes [#323](https://github.com/rohitg00/agentmemory/issues/323))

Two narrow fixes from @hem57's Windows repro:

1. **Removed the `<link rel="stylesheet">` to `fonts.googleapis.com`.** The viewer's strict CSP (`default-src 'none'`, `style-src 'unsafe-inline'`, `font-src 'self'`) blocks external stylesheet origins by design, so every page load logged a CSP violation for the font CSS and another for each blocked font file. System-font fallbacks were already declared on every `--font-*` CSS variable so dropping the external `<link>` is a clean swap.

2. **Wrapped `loadDashboard()` body in a `try/catch`** that renders the error inline (`"Dashboard failed to load: <reason>"`) instead of leaving the placeholder text up forever. Future "stuck Loading" reports now come with concrete error messages instead of just a screenshot of the placeholder.

### `RetentionScore` type no longer declares `source` twice ([#326](https://github.com/rohitg00/agentmemory/pull/326), closes [#277](https://github.com/rohitg00/agentmemory/issues/277))

`src/types.ts:835` and `:842` both declared `source?: "episodic" | "semantic"` on `RetentionScore`. TypeScript silently accepts duplicate property declarations when the types are identical, so the build never errored — but the documented JSDoc on the first declaration (the #124 back-compat note explaining `undefined` should probe both scopes) was effectively shadowed by the duplicate. Removed the second declaration; grep confirmed no caller writes `source` twice on the same row, so the cleanup is a pure type-correctness fix with no runtime change. Thanks @cl0ckt0wer.

## Changed

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

## Install / upgrade

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

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

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