feat: integrate learning-sdk into slackbot for persistent memory#1249
feat: integrate learning-sdk into slackbot for persistent memory#1249
Conversation
88c9cc8 to
0bc7b80
Compare
There was a problem hiding this comment.
Pull request overview
This PR integrates the agentic-learning SDK into the slackbot to enable persistent memory across conversations. Each Slack user gets their own memory agent identified by slackbot-{user_id}, allowing the bot to remember context from previous interactions.
Key changes:
- Added optional Letta API key configuration via Prefect secrets
- Wrapped agent runs with
learning()context manager for memory persistence - Added
agentic-learningas a dependency
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| examples/slackbot/src/slackbot/settings.py | Adds letta_api_key_secret_name setting and loads Letta API key from Prefect secrets in post-validation hook |
| examples/slackbot/src/slackbot/api.py | Imports learning from agentic_learning and wraps agent run with learning context manager using user-specific agent names |
| examples/slackbot/pyproject.toml | Adds agentic-learning to project dependencies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| except Exception: | ||
| pass # If secret doesn't exist, turbopuffer will handle the error | ||
| if not os.getenv("LETTA_API_KEY"): | ||
| try: | ||
| api_key = Secret.load(self.letta_api_key_secret_name, _sync=True).get() # type: ignore | ||
| os.environ["LETTA_API_KEY"] = api_key | ||
| except Exception: |
There was a problem hiding this comment.
[nitpick] The broad exception handling with silent failure means that if the Letta API key secret fails to load for any reason (not just "doesn't exist"), the error will be suppressed. This is consistent with the turbopuffer pattern above (lines 95-100), but it makes debugging issues with secret configuration more difficult. Consider whether specific exception types should be caught (e.g., only catching the "secret not found" exception) to avoid masking other configuration errors.
| except Exception: | |
| pass # If secret doesn't exist, turbopuffer will handle the error | |
| if not os.getenv("LETTA_API_KEY"): | |
| try: | |
| api_key = Secret.load(self.letta_api_key_secret_name, _sync=True).get() # type: ignore | |
| os.environ["LETTA_API_KEY"] = api_key | |
| except Exception: | |
| except ValueError: | |
| pass # If secret doesn't exist, turbopuffer will handle the error | |
| if not os.getenv("LETTA_API_KEY"): | |
| try: | |
| api_key = Secret.load(self.letta_api_key_secret_name, _sync=True).get() # type: ignore | |
| os.environ["LETTA_API_KEY"] = api_key | |
| except ValueError: |
- add letta_api_key_secret_name setting and load LETTA_API_KEY env var
- wrap agent run with learning() context for per-user memory
- add agentic-learning dependency
each slack user gets their own memory agent (slackbot-{user_id})
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
0bc7b80 to
18cf633
Compare
Reverts commits: - 47da4ce fix: use async with for learning context manager (#1252) - 36da4c1 chore: consolidate slackbot memory on letta learning-sdk (#1250) - 30aed2d feat: integrate learning-sdk into slackbot for persistent memory (#1249) The learning SDK's async context manager has a bug where it tries to await pending tasks in __aexit__ after the event loop has already closed, causing "Event loop is closed" errors that crash the slackbot. This restores the original TurboPuffer-based user facts system until the upstream bug is fixed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Reverts commits: - 47da4ce fix: use async with for learning context manager (#1252) - 36da4c1 chore: consolidate slackbot memory on letta learning-sdk (#1250) - 30aed2d feat: integrate learning-sdk into slackbot for persistent memory (#1249) The learning SDK's async context manager has a bug where it tries to await pending tasks in __aexit__ after the event loop has already closed, causing "Event loop is closed" errors that crash the slackbot. This restores the original TurboPuffer-based user facts system until the upstream bug is fixed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
Summary
letta_api_key_secret_namesetting to load Letta API key from Prefect secretslearning()context manager for persistent memoryagentic-learningdependency to slackbotEach Slack user gets their own memory agent (
slackbot-{user_id}), enabling cross-session learning.Test plan
letta-api-keywith Letta API key🤖 Generated with Claude Code