Skip to content

Add optional Letta memory integration for cross-session recall#39

Open
shranchi0 wants to merge 3 commits into
AshirBorah:mainfrom
shranchi0:feat/letta-memory
Open

Add optional Letta memory integration for cross-session recall#39
shranchi0 wants to merge 3 commits into
AshirBorah:mainfrom
shranchi0:feat/letta-memory

Conversation

@shranchi0

Copy link
Copy Markdown
Collaborator

Summary

  • Adds an opt-in session memory feature powered by Letta that records session lifecycle events and lets users query past context via natural language
  • Completely optional — the feature is inert when letta-client is not installed, and dormant when installed but not enabled
  • Install with pip install tame[memory], then toggle on via command palette (y)

How it works

  • Toggle Memory (y in command palette): First use shows an onboarding dialog explaining the feature. Subsequent uses toggle on/off instantly.
  • Ask Memory (a in command palette): Opens a dialog where you can ask questions like "what fixed the timeout error?" — the Letta agent searches its archival memory of past session events
  • Clear Memory (j in command palette): Wipes all stored session memory (with confirmation)
  • Status bar shows [Memory: On], [Memory: Off], or [Memory: ⚠] when letta-client is installed

What gets recorded (when enabled)

  • Session created (name, working directory, timestamp)
  • Session ended (exit code, duration)
  • Errors detected by pattern matcher
  • Status changes (state transitions)

Architecture

tame/integrations/
└── letta/
    ├── __init__.py
    ├── client.py      # Thin wrapper around Letta SDK
    ├── bridge.py      # Event bridge (fire-and-forget async)
    └── prompts.py     # Agent persona/system prompt

Files changed

  • New: tame/integrations/letta/ — client, bridge, prompts
  • New: tame/ui/widgets/memory_dialogs.py — enable, recall, clear modals
  • Modified: tame/app.py — conditional bridge init, lifecycle hooks, 3 actions
  • Modified: tame/ui/widgets/command_palette.py — y/a/j entries
  • Modified: tame/ui/widgets/status_bar.py — memory indicator
  • Modified: tame/config/defaults.py[letta] config section
  • Modified: pyproject.tomlmemory optional extra

Test plan

  • ruff check passes
  • ruff format --check passes
  • All 268 tests pass (no letta-client installed — feature stays inert)
  • Manual: install letta-client, run letta server, toggle memory on, create/kill sessions, use "Ask Memory"
  • Manual: verify existing functionality is completely unaffected without letta-client

Adds an opt-in session memory feature powered by Letta that records
session lifecycle events (created, ended, errors, state changes) and
lets users query past context via natural language.

New files:
- tame/integrations/letta/ — client wrapper, event bridge, agent prompt
- tame/ui/widgets/memory_dialogs.py — enable, recall, and clear dialogs

Integration points:
- app.py: conditional bridge init, session lifecycle hooks, 3 new actions
  (toggle_memory, recall_memory, clear_memory)
- command_palette.py: y/a/j keys for memory commands
- status_bar.py: [Memory: On/Off] indicator
- config/defaults.py: [letta] section (enabled, server_url)
- pyproject.toml: optional "memory" extra (letta-client)

The feature is completely inert when letta-client is not installed.
When installed but not enabled, only a status bar indicator appears.
When user toggles memory on for the first time, TAME now handles
the full setup automatically:
1. Installs letta-client via uv if not present
2. Starts letta server as a background subprocess
3. Waits for server readiness (health endpoint polling)
4. Connects and creates the memory agent

On subsequent TAME launches, auto-connects to the running server.
On TAME exit, the background server is cleaned up.

The onboarding dialog adapts its text based on whether letta-client
needs to be installed or is already present.
mypy caught that _run_memory_setup() (async) was called without await
from the sync callback _handle_memory_enable. Use self.call_later()
to schedule it on the Textual event loop instead.
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