Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f503eb6
feat(memory): add pluggable memory provider interface with profile is…
teknium1 Mar 31, 2026
c27eacb
refactor(memory): drop cognitive plugin, rewrite OpenViking as full p…
teknium1 Mar 31, 2026
dfe4c6e
fix(memory): harden Mem0 plugin — thread safety, non-blocking sync, c…
teknium1 Mar 31, 2026
9824dee
fix(memory): enforce single external memory provider limit
teknium1 Mar 31, 2026
bfaeb0f
feat(memory): add ByteRover memory provider plugin
teknium1 Mar 31, 2026
7bc943f
fix(memory): thread remaining sync_turns, fix holographic, add config…
teknium1 Mar 31, 2026
0b9f2ff
feat(memory): extract Honcho as a MemoryProvider plugin
teknium1 Mar 31, 2026
dc58368
feat(memory): wire MemoryManager into run_agent.py
teknium1 Mar 31, 2026
52673c9
refactor(memory): remove legacy Honcho integration from core
teknium1 Mar 31, 2026
55107a1
refactor(memory): restructure plugins, add CLI, clean gateway, migrat…
teknium1 Mar 31, 2026
5d278aa
feat(memory): standardize plugin config + add per-plugin documentation
teknium1 Mar 31, 2026
7a34aeb
docs: add memory providers user guide + developer guide
teknium1 Mar 31, 2026
d92ea74
fix(memory): auto-migrate Honcho users to memory provider plugin
teknium1 Mar 31, 2026
f49eebf
fix(memory): only auto-migrate Honcho when enabled + credentialed
teknium1 Mar 31, 2026
0201f8c
feat(memory): auto-install pip dependencies during hermes memory setup
teknium1 Mar 31, 2026
5978ade
fix: remove remaining Honcho crash risks from cli.py and gateway
teknium1 Mar 31, 2026
479b02e
fix: include plugins/ in pyproject.toml package list
teknium1 Mar 31, 2026
b77e0c2
fix(memory): correct pip-to-import name mapping for dep checks
teknium1 Mar 31, 2026
192bc22
chore: remove dead code from old plugin memory registration path
teknium1 Mar 31, 2026
3f1908a
chore: delete dead honcho_integration/cli.py and its tests
teknium1 Mar 31, 2026
7aabf5d
refactor: move honcho_integration/ into the honcho plugin
teknium1 Mar 31, 2026
2b22c57
docs: update architecture + gateway-internals for memory provider system
teknium1 Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions agent/builtin_memory_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""BuiltinMemoryProvider — wraps MEMORY.md / USER.md as a MemoryProvider.

Always registered as the first provider. Cannot be disabled or removed.
This is the existing Hermes memory system exposed through the provider
interface for compatibility with the MemoryManager.

The actual storage logic lives in tools/memory_tool.py (MemoryStore).
This provider is a thin adapter that delegates to MemoryStore and
exposes the memory tool schema.
"""

from __future__ import annotations

import json
import logging
from typing import Any, Dict, List, Optional

from agent.memory_provider import MemoryProvider

logger = logging.getLogger(__name__)


class BuiltinMemoryProvider(MemoryProvider):
"""Built-in file-backed memory (MEMORY.md + USER.md).

Always active, never disabled by other providers. The `memory` tool
is handled by run_agent.py's agent-level tool interception (not through
the normal registry), so get_tool_schemas() returns an empty list —
the memory tool is already wired separately.
"""

def __init__(
self,
memory_store=None,
memory_enabled: bool = False,
user_profile_enabled: bool = False,
):
self._store = memory_store
self._memory_enabled = memory_enabled
self._user_profile_enabled = user_profile_enabled

@property
def name(self) -> str:
return "builtin"

def is_available(self) -> bool:
"""Built-in memory is always available."""
return True

def initialize(self, session_id: str, **kwargs) -> None:
"""Load memory from disk if not already loaded."""
if self._store is not None:
self._store.load_from_disk()

def system_prompt_block(self) -> str:
"""Return MEMORY.md and USER.md content for the system prompt.

Uses the frozen snapshot captured at load time. This ensures the
system prompt stays stable throughout a session (preserving the
prompt cache), even though the live entries may change via tool calls.
"""
if not self._store:
return ""

parts = []
if self._memory_enabled:
mem_block = self._store.format_for_system_prompt("memory")
if mem_block:
parts.append(mem_block)
if self._user_profile_enabled:
user_block = self._store.format_for_system_prompt("user")
if user_block:
parts.append(user_block)

return "\n\n".join(parts)

def prefetch(self, query: str) -> str:
"""Built-in memory doesn't do query-based recall — it's injected via system_prompt_block."""
return ""

def sync_turn(self, user_content: str, assistant_content: str) -> None:
"""Built-in memory doesn't auto-sync turns — writes happen via the memory tool."""

def get_tool_schemas(self) -> List[Dict[str, Any]]:
"""Return empty list.

The `memory` tool is an agent-level intercepted tool, handled
specially in run_agent.py before normal tool dispatch. It's not
part of the standard tool registry. We don't duplicate it here.
"""
return []

def handle_tool_call(self, tool_name: str, args: Dict[str, Any], **kwargs) -> str:
"""Not used — the memory tool is intercepted in run_agent.py."""
return json.dumps({"error": "Built-in memory tool is handled by the agent loop"})

def shutdown(self) -> None:
"""No cleanup needed — files are saved on every write."""

# -- Property access for backward compatibility --------------------------

@property
def store(self):
"""Access the underlying MemoryStore for legacy code paths."""
return self._store

@property
def memory_enabled(self) -> bool:
return self._memory_enabled

@property
def user_profile_enabled(self) -> bool:
return self._user_profile_enabled
Loading