RFC: optional semantic-memory providers for buzz-agent and buzz-acp
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Problem
Buzz has a strong portable core-memory mechanism through NIP-AE engrams, but agents do not currently have an optional semantic-memory layer for large, continuously growing conversation history. Operators who want retrieval across sessions and harnesses must wire that lifecycle outside Buzz, which makes behavior inconsistent between the built-in `buzz-agent` and external ACP runtimes such as Codex, Grok, or Hermes.
This proposal is to add an **optional semantic-memory provider interface** that complements rather than replaces NIP-AE core memory:
- NIP-AE remains the canonical portable home for identity, durable rules, and goals.
- A semantic provider stores extracted conversational facts and retrieves only relevant records per turn.
- Provider state remains external and operator-controlled.
- The feature is disabled by default and fail-open when unavailable.
## Proposed first provider: self-hosted Mem0 OSS
Mem0 OSS exposes a language-neutral REST API for create/search/update/delete operations and scopes records with `user_id`, `agent_id`, and `run_id`. A Rust client therefore does not require embedding the Python SDK or changing the relay protocol.
Suggested initial integration:
1. A small shared provider abstraction used by both `buzz-agent` and `buzz-acp`.
2. A self-hosted Mem0 OSS implementation using its unversioned REST endpoints (`/memories`, `/search`, and individual memory CRUD routes).
3. Optional automatic recall before a turn and writeback after a successful completed turn.
4. Explicit `memory_search` and `memory_add` tools for the built-in agent. Update/delete tools could follow after the permission model is agreed.
5. Stable scopes for:
- owner-shared memory;
- current-agent memory;
- optional session/run memory.
6. Retrieved memory framed as untrusted data, never instructions.
## Safety and lifecycle defaults
- Provider disabled by default.
- No limit on records retained by the provider; prompt injection remains independently bounded.
- Safe finite per-turn retrieval/injection defaults with operator overrides.
- Automatic writeback explicitly configurable and limited to completed turns.
- Canceled, failed, and incomplete turns are not stored automatically.
- Memory contents, queries, and credentials are omitted from tracing fields and errors.
- API credentials supplied through environment/file injection rather than agent persona text or prompts.
- No relay schema or new Nostr event kind required.
## Interaction with existing Buzz memory
This would not change `[Agent Memory — core]` or the current NIP-AE lifecycle. A typical prompt would contain:
1. Buzz base/system/persona context;
2. NIP-AE core memory;
3. a bounded block of relevant semantic memories;
4. current channel/thread context.
That keeps canonical agent identity portable through Buzz while allowing larger operator-owned stores to grow independently.
## Validation performed
A local Rust implementation has been exercised against a self-hosted Mem0 OSS deployment with a real `buzz-acp` Codex identity:
- a fresh Buzz turn was acknowledged and written;
- a separate later turn recalled the exact proof phrase without containing it in the recall request;
- a direct scoped Mem0 query independently found the persisted record;
- the provider was used through the ordinary ACP prompt lifecycle, not by asking the agent to call a separate memory plugin;
- unit tests cover authentication, user/agent scoping, response normalization, bounded valid-JSON prompt rendering, untrusted-data framing, and fail-open lifecycle behavior;
- targeted formatting, Clippy, and Rust tests pass for `buzz-agent` and `buzz-acp`.
No deployment URLs, secrets, or operator-specific wrappers are part of the proposed contribution.
## Deliberate non-goals for the first PR
- Replacing NIP-AE core memory.
- Bundling Bitwarden/BWS-specific credential resolution; operators can inject the resulting environment variable externally.
- Changing kind:10100 agent-directory publication. That area already has active work in #5546 and #5612.
- Bundling Windows ACP wrapper-shim fixes; those are independently useful and should be a separate bug-fix PR.
- Supporting the hosted Mem0 Platform API in the first implementation. Its paths and authentication differ from self-hosted OSS and should be a separate adapter if desired.
## Questions for maintainers
1. Does an optional semantic-memory provider fit the intended boundary of `buzz-agent` and `buzz-acp`?
2. Would maintainers prefer a shared `buzz-memory` crate, or a smaller provider module in an existing crate?
3. Should automatic writeback default to off even after the provider is enabled?
4. Should the first PR include only search/add, leaving model-initiated update/delete for a later permission-aware change?
5. Is a finite injection budget with an explicit operator override acceptable, while leaving provider storage itself unlimited?
If the direction is welcome, I can send a focused DCO-signed PR containing only the provider abstraction, self-hosted Mem0 adapter, lifecycle wiring, documentation, and tests.
Contributor guide
Assessment
This issue has not been assessed yet.