Skip to content

feat(pi-memory-mem0): observedAt + LoCoMo eval harness#77

Merged
Weaxs merged 3 commits into
masterfrom
feat/mem0-eval-observedat
Jul 4, 2026
Merged

feat(pi-memory-mem0): observedAt + LoCoMo eval harness#77
Weaxs merged 3 commits into
masterfrom
feat/mem0-eval-observedat

Conversation

@Weaxs

@Weaxs Weaxs commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

What

Adds a memory-eval harness (tests/eval, private workspace package) that benchmarks pi-memory and pi-memory-mem0 against LoCoMo, and a product change to pi-memory-mem0 that fell out of building it.

pi-memory-mem0: observedAt

Mem0Provider.add() gains an optional observedAt (Date | string). mem0's extraction prompt documents an "Observation Date" used to ground relative time references ("yesterday", "last week"), but never exposes a way to set it — it always falls back to the system clock, which mis-stamps facts when ingesting historical conversations.

  • OSS mode: intercepts the extraction LLM call and rewrites the Observation/Current Date prompt sections to observedAt (serialized via a mutex, since the LLM wrapper is shared instance state).
  • Platform mode: forwards it as the add() timestamp field.
  • Omitting observedAt preserves current behavior for live turns.

Exported formatObservedAt / rewriteObservationDate with unit tests (+6).

tests/eval

  • LoCoMo loader — forgiving JSON adapter, parses the non-standard timestamp format to ISO.
  • run-mem0.ts — passive extraction runner: ingest → semantic search → recall + token-F1. Per-run isolated vector-store & snapshot paths (mem0's memory store is SQLite-backed at ~/.mem0/vector_store.db and silently accumulates across runs).
  • run-memory.ts — real agent write loop: per session an LLM emits memory_add/replace/remove ops applied to a real MemoryStore (char caps + threat scan enforced).
  • judge-llm.ts — LLM-judge post-processing → recallJudge.
  • Retry (5xx/throttle/DNS), concurrency pool, model config from a pi models.json.

Results (LoCoMo 2-sample, flash extract + pro judge)

Runner LLM-judge recall
pi-memory-mem0 ~0.44
pi-memory ~0.19

Not a leaderboard — LoCoMo rewards exhaustive detail recall, which pi-memory deliberately discards under its char budget. The README explains the mismatch. mem0's score rose from ~0.27 after the vector-store isolation and observedAt fixes.

Notes

  • Datasets/results are gitignored; runs are manual (no CI hook).
  • Eval package is private, not published.

Weaxs added 3 commits July 4, 2026 22:45
Mem0Provider.add() gains an optional observedAt (Date | string). mem0's
extraction prompt documents an Observation Date used to ground relative
time references, but never exposes a way to set it — it always falls back
to the system clock, which mis-stamps facts when ingesting historical
conversations. OSS mode now intercepts the extraction LLM call and rewrites
the Observation/Current Date sections to observedAt (serialized via a mutex
since the LLM wrapper is shared instance state); platform mode forwards it
as the add() timestamp field. Omitting observedAt preserves current
behavior for live turns.

Adds tests/eval, a private workspace package that benchmarks pi-memory and
pi-memory-mem0 against LoCoMo: forgiving dataset loader, token-F1 + LLM-judge
scoring, retry/concurrency, and per-run isolated vector-store/snapshot paths
so runs don't accumulate. On the 2-sample slice, wiring observedAt plus
isolating the vector store moved LLM-judge recall from ~0.27 to ~0.44.
Replace the heuristic curated runner with an agent-style write loop: for each
conversation session an LLM sees the turns plus the current memory snapshot and
emits memory_add/replace/remove ops, applied to a real MemoryStore (2200/1375
char caps + threat scan enforced). Scoring uses the resulting snapshot under the
same LLM-judge as the mem0 runner, so the two share a scale.

Document the 2-sample results and, crucially, why the mem0 (~0.44) vs pi-memory
(~0.19) judge gap is not a leaderboard: LoCoMo rewards exhaustive detail recall,
which pi-memory deliberately discards under its char budget. Also note the
per-run vector-store isolation and observedAt fixes behind mem0's jump from
~0.27, judge variance, and the reasoning-model max_tokens requirement.
workflow_dispatch-only job that runs the LoCoMo eval on the self-hosted
runner. Inputs pick the runner (mem0 / curated / both), sample count, top-k,
and the extraction/judge models. Reuses PI_INTEGRATION_BASE_URL/API_KEY to
write a temp models.json (provider deepseek-integration), fetches LoCoMo,
runs the eval + LLM-judge, writes a summary table to the job summary, and
uploads results/*.json as an artifact. Uses prebuild-better-sqlite3 for
mem0's OSS SQLite vector store.
@Weaxs Weaxs merged commit f55c994 into master Jul 4, 2026
14 checks passed
@Weaxs Weaxs deleted the feat/mem0-eval-observedat branch July 4, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant