feat(memory): persistent agent memory system with dashboard UI#606
Draft
kovtcharov wants to merge 4 commits intomainfrom
Draft
feat(memory): persistent agent memory system with dashboard UI#606kovtcharov wants to merge 4 commits intomainfrom
kovtcharov wants to merge 4 commits intomainfrom
Conversation
## Summary - **`gaia init` now installs RAG dependencies** for `chat`, `rag`, and `all` profiles — adds `pip_extras` field to profile definitions and a new `_install_pip_extras()` step that detects editable vs package install, tries `uv pip` first with `pip` fallback - **Added `self.rag` None guards** to 8 RAG tools in `rag_tools.py` that were crashing with `'NoneType' object has no attribute 'index_document'` when RAG deps not installed - **Widened ChatAgent RAG init exception catch** from `ImportError` to `Exception` with warning-level logging and debug traceback - **Updated Agent UI docs** to include `[rag]` in install instructions (`[ui,rag]`) ## Test plan - [x] Lint passing (black, isort, pylint, flake8) - [x] All 1104 unit tests passing - [ ] `gaia init --profile chat` installs RAG deps automatically - [ ] Agent UI document indexing works after `pip install -e ".[rag]"` - [ ] RAG tools return actionable error when deps not installed (instead of crashing) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
C-1: Guard winreg import and all registry-scanning methods in discovery.py
so the module loads cleanly on Linux/macOS where winreg is absent.
Also guard _scan_credential_manager() behind sys.platform check to
avoid subprocess.CREATE_NO_WINDOW AttributeError on non-Windows.
C-3: Replace direct _lock/_conn access in CLI with two new MemoryStore
public methods: get_source_counts() and delete_by_source(source).
delete_by_source() wraps FTS cleanup + DELETE in a single atomic
transaction with rollback, removing the per-ID loop that could
leave knowledge/FTS diverged on partial failure.
C-4: Add close_store() to memory router module; call it from FastAPI
lifespan shutdown so the WAL is checkpointed and the SQLite
connection is released cleanly on server exit.
M-2: list_knowledge endpoint now excludes sensitive items by default.
New include_sensitive=false query param (default false) controls
visibility; sensitive=true still filters to sensitive-only.
M-6: Add append-only comment to conversations FTS trigger block noting
that an AFTER UPDATE trigger would be required if store_turn()
ever changes to update existing rows.
Tests: +9 tests (394 total) covering get_source_counts, delete_by_source
rollback discipline, and all three sensitive filter modes in the router.
- Fix _original_user_input=None fallback bug in _after_process_query (getattr default ignored None; switch to `or` to handle init state) - Extract VALID_CATEGORIES/MAX_CONTENT_LENGTH/MAX_TURN_LENGTH and other magic numbers to named module-level constants in memory_store.py - Import constants in memory.py to eliminate duplicate category sets and ensure truncation limits stay in sync across all call sites - DRY: memory router imports VALID_CATEGORIES from data layer instead of redefining its own copy - Clean up unused imports in test files (F401/F811 flake8 violations) - 394 unit tests passing, flake8 clean
e0eff31 to
068eead
Compare
Replace substring `"github.com" in url_lower` with urlparse().hostname comparison to fix CodeQL CWE-20 "Incomplete URL substring sanitization". A crafted URL like http://evil.com/github.com could otherwise bypass the check. Hostname equality/suffix match is unambiguous.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/gaia/agents/base/memory_store.py): SQLite + FTS5 data layer with knowledge CRUD, conversation history, tool call logging, confidence scoring/decay, deduplication (Szymkiewicz-Simpson ≥80%), and temporal awareness (due_at/reminded_at)src/gaia/agents/base/memory.py): agent integration layer — 5 LLM-callable tools (remember,recall,update_memory,forget,search_past_conversations), heuristic preference extraction, frozen system-prompt injection + per-turn dynamic context for KV-cache reusesrc/gaia/ui/routers/memory.py): 15 FastAPI endpoints — knowledge CRUD, entity/context browsing, tool performance stats, conversation search, FTS rebuild, pruningsrc/gaia/apps/webui/src/components/MemoryDashboard.*): React/TypeScript — stats cards, activity timeline, knowledge browser with FTS search/filter, entity graph, tool performance table, error log, conversation viewerdiscovery.py: system discovery module (git history, filesystem, installed apps, browser history) for bootstrap onboardinggaia memorycommand (stats, search, add, dashboard)docs/guides/memory.mdx,docs/sdk/sdks/memory.mdx,docs/spec/agent-memory-architecture.md,docs/spec/openjarvis-memory-analysis.mdReliability hardening
10 rounds of corner-case analysis and fixes:
try/except: rollback; raise— prevents Python sqlite3 implicit transactions from being committed out-of-orderapply_confidence_decay()addsAND updated_at < cutoffso items are not double-decayed on rapid restartsget_sessions()orderingMIN(CASE WHEN role='user')with correlated subquery ordered byid ASC_extract_heuristics()usesfinditer()instead ofsearch()args_jsontruncationlog_tool_call()truncates args to 500 chars (matchingresult_summary/error)remember()andupdate_memory()tools now actually truncate to 2000 chars before storingTest plan
uv run pytest tests/unit/test_memory_store.py— 372 unit tests for MemoryStoreuv run pytest tests/unit/test_memory_mixin.py— MemoryMixin lifecycle, tool registration, truncationuv run pytest tests/unit/test_memory_router.py— REST API endpoint validationgaia memory stats— CLI smoke testgaia chat --ui→ Memory Dashboard tab in browser