Skip to content

fix(retaindb): fix API routes, add write queue, dialectic, agent model, file tools#5461

Merged
teknium1 merged 3 commits into
mainfrom
hermes/hermes-ef6f7818
Apr 6, 2026
Merged

fix(retaindb): fix API routes, add write queue, dialectic, agent model, file tools#5461
teknium1 merged 3 commits into
mainfrom
hermes/hermes-ef6f7818

Conversation

@teknium1

@teknium1 teknium1 commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Salvage of PR #5456 by @Alinxus (original RetainDB plugin author).

The RetainDB plugin shipped in #4623 was broken end-to-end — every API route was wrong, silently 404ing. Users who activated RetainDB got zero memory.

What the contributor fixed (cherry-picked from #5456):

  • All 6 API routes corrected to match real RetainDB API
  • HTTP client rewritten with correct dual-header auth (Authorization + X-API-Key)
  • memory_type enum fixed to real API values (factual, preference, goal, instruction, event, opinion)
  • Durable SQLite write-behind queue (crash-safe, zero blocking on agent hot path)
  • Three-stream background prefetch: context + dialectic synthesis + agent self-model
  • Agent identity seeding from SOUL.md
  • 5 shared file store tools (upload, list, read, ingest, delete)
  • on_memory_write hook fixed to use correct endpoint

Follow-up improvements:

  • SQLite connection pooling: Thread-local connection cache instead of creating+closing a new connection per operation
  • Thread accumulation guard: Previous prefetch batch is joined before spawning new threads, preventing accumulation on rapid calls
  • Shutdown cleanup: Prefetch threads joined before stopping the write queue
  • 73 tests covering _Client HTTP payloads, _WriteQueue crash recovery & connection reuse, _build_overlay deduplication, RetainDBMemoryProvider lifecycle/tools/prefetch/hooks, thread accumulation guard, and reasoning_level heuristic

Files changed

  • plugins/memory/retaindb/__init__.py — rewritten plugin (302 → ~760 lines)
  • tests/plugins/test_retaindb_plugin.py — new, 73 tests

Test results

73 passed (retaindb tests)
65 passed (memory provider + e2e tests — no regressions)

Closes #5456. Credit to @Alinxus for the original fix — their commits are cherry-picked with authorship preserved.

Alinxus and others added 3 commits April 6, 2026 00:44
…l, file tools

The previous implementation hit endpoints that do not exist on the RetainDB
API (/v1/recall, /v1/ingest, /v1/remember, /v1/search, /v1/profile/:p/:u).
Every operation was silently failing with 404. This rewrites the plugin against
the real API surface and adds several new capabilities.

API route fixes:
- Context query: POST /v1/context/query (was /v1/recall)
- Session ingest: POST /v1/memory/ingest/session (was /v1/ingest)
- Memory write: POST /v1/memory with legacy fallback to /v1/memories (was /v1/remember)
- Memory search: POST /v1/memory/search (was /v1/search)
- User profile: GET /v1/memory/profile/:userId (was /v1/profile/:project/:userId)
- Memory delete: DELETE /v1/memory/:id with fallback (was /v1/memory/:id, wrong base)

Durable write-behind queue:
- SQLite spool at ~/.hermes/retaindb_queue.db
- Turn ingest is fully async — zero blocking on the hot path
- Pending rows replay automatically on restart after a crash
- Per-row error marking with retry backoff

Background prefetch (fires at turn-end, ready for next turn-start):
- Context: profile + semantic query, deduped overlay block
- Dialectic synthesis: LLM-powered synthesis of what is known about the
  user for the current query, with dynamic reasoning level based on
  message length (low / medium / high)
- Agent self-model: persona, persistent instructions, working style
  derived from AGENT-scoped memories
- All three run in parallel daemon threads, consumed atomically at
  turn-start within the prefetch timeout budget

Agent identity seeding:
- SOUL.md content ingested as AGENT-scoped memories on startup
- Enables persistent cross-session agent self-knowledge

Shared file store tools (new):
- retaindb_upload_file: upload local file, optional auto-ingest
- retaindb_list_files: directory listing with prefix filter
- retaindb_read_file: fetch and decode text content
- retaindb_ingest_file: chunk + embed + extract memories from stored file
- retaindb_delete_file: soft delete

Built-in memory mirror:
- on_memory_write() now hits the correct write endpoint
- SQLite write queue: thread-local connection pooling instead of
  creating+closing a new connection per operation
- Prefetch threads: join previous batch before spawning new ones to
  prevent thread accumulation on rapid queue_prefetch() calls
- Shutdown: join prefetch threads before stopping write queue
- Add 73 tests covering _Client HTTP payloads, _WriteQueue crash
  recovery & connection reuse, _build_overlay deduplication,
  RetainDBMemoryProvider lifecycle/tools/prefetch/hooks, thread
  accumulation guard, and reasoning_level heuristic
@github-actions

github-actions Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: Outbound network calls (POST/PUT)

Outbound POST/PUT requests in new code could be data exfiltration. Verify the destination URLs are legitimate.

Matches (first 10):

301:+        resp = requests.post(url, files={"file": (filename, io.BytesIO(data), mime_type)}, data=fields, headers=headers, timeout=30)

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@teknium1 teknium1 merged commit 5747590 into main Apr 6, 2026
3 of 4 checks passed
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