Drop-in SDK for adding persistent memory and learning to any agent.
Project description
Agentic Learning SDK
Add continual learning to any LLM agent with one line of code. This SDK enables agents to learn from every conversation and recall context across sessions—making your agents truly stateful.
from openai import OpenAI
from agentic_learning import learning
client = OpenAI()
with learning(agent="my_agent"):
response = client.chat.completions.create(...) # LLM is now stateful!
Quick Start
Python Installation
pip install agentic-learning
TypeScript Installation
npm install @letta-ai/agentic-learning
Basic Usage (Python)
# Set your API keys
export OPENAI_API_KEY="your-openai-key"
export LETTA_API_KEY="your-letta-key"
from openai import OpenAI
from agentic_learning import learning
client = OpenAI()
# Add continual learning with one line
with learning(agent="my_assistant"):
# Your LLM call - conversation is automatically captured
response = client.chat.completions.create(
model="gpt-5",
messages=[{"role": "user", "content": "My name is Alice"}]
)
# Agent remembers prior context
response = client.chat.completions.create(
model="gpt-5",
messages=[{"role": "user", "content": "What's my name?"}]
)
# Returns: "Your name is Alice"
That's it - this SDK automatically:
- ✅ Learns from every conversation
- ✅ Recalls relevant context when needed
- ✅ Remembers across sessions
- ✅ Works with your existing LLM code
Basic Usage (TypeScript)
# Set your API keys
export OPENAI_API_KEY="your-openai-key"
export LETTA_API_KEY="your-letta-key"
import { learning } from '@letta-ai/agentic-learning';
import OpenAI from 'openai';
const client = new OpenAI();
// Add continual learning with one line
await learning({ agent: "my_assistant" }, async () => {
// Your LLM call - conversation is automatically captured
const response = await client.chat.completions.create({
model: "gpt-5",
messages: [{ role: "user", content: "My name is Alice" }]
});
// Agent remembers prior context
const response2 = await client.chat.completions.create({
model: "gpt-5",
messages: [{ role: "user", content: "What's my name?" }]
});
// Returns: "Your name is Alice"
});
Supported Providers
| Provider | Package | Status | Py Example | TS Example |
|---|---|---|---|---|
| Anthropic | anthropic |
✅ Stable | anthropic_example.py | anthropic_example.ts |
| Claude Agent SDK | @anthropic-ai/claude-agent-sdk |
✅ Stable | claude_example.py | claude_example.ts |
| OpenAI Chat Completions | openai |
✅ Stable | openai_example.py | openai_example.ts |
| OpenAI Responses API | openai |
✅ Stable | openai_responses_example.py | openai_responses_example.ts |
| Gemini | google-generativeai |
✅ Stable | gemini_example.py | gemini_example.ts |
| Vercel AI SDK | ai |
✅ Stable | N/A (TS only) | vercel_example.ts |
See examples/README.md for detailed documentation.
Core Concepts
Learning Context
Wrap any LLM calls in a learning() context to enable continual learning:
with learning(agent="agent_name"):
# All SDK calls inside this block have learning enabled
response = llm_client.generate(...)
Note: Learning is scoped by agent name. Each agent learns independently, so agent="sales_bot" and agent="support_bot" maintain separate memories.
Context Injection
The SDK automatically retrieves relevant context from past conversations:
# First session
with learning(agent="sales_bot", memory=["customer"]):
response = client.chat.completions.create(
messages=[{"role": "user", "content": "I'm interested in Product X"}]
)
# Later session - agent remembers any information related to "customer"
with learning(agent="sales_bot", memory=["customer"]):
response = client.chat.completions.create(
messages=[{"role": "user", "content": "Tell me more about that product"}]
)
# Agent knows you're asking about Product X
Capture-Only Mode
Store conversations without injecting context (useful for logging or background processing):
with learning(agent="agent_name", capture_only=True):
# Conversations saved for learning but not injected into prompts
response = client.chat.completions.create(...)
# Later, list entire conversation history
learning_client = AgenticLearning()
messages = learning_client.messages.list("agent_name")
Knowledge Search
Query what your agent has learned with semantic search:
# Search for relevant conversations
messages = learning_client.memory.search(
agent="agent_name",
query="What are my project requirements?"
)
How It Works
The SDK uses automatic interception of LLM SDK calls:
- Intercepts - Captures conversations automatically
- Learns - Extracts and stores knowledge from interactions
- Recalls - Retrieves relevant context when needed
- Injects - Seamlessly adds context to your prompts
┌─────────────────-┐
│ Your Code │
│ client.create() │
└────────┬────────-┘
│
▼
┌─────────────────-┐
│ Agentic Learning │ ← Intercepts call
│ Interceptor │ ← Injects context
└────────┬───────-─┘
│
▼
┌───────────────-──┐
│ LLM API │ ← Sees enriched prompt
│ (OpenAI, etc) │
└────────┬──────-──┘
│
▼
┌────────────────-─┐
│ Letta Server │ ← Stores conversation
│ (Persistent DB) │ ← Learning update
└─────────────────-┘
Architecture
Interceptors
The SDK provides interceptors for different integration patterns:
- API-Level Interceptors (OpenAI, Anthropic, Gemini) - Patch HTTP API methods
- Transport-Level Interceptors (Claude Agent SDK) - Patch subprocess transport layer
All interceptors share common logic through BaseAPIInterceptor, making it easy to add new providers.
Client Architecture
AgenticLearning()
├── agents # Agent management
│ ├── create()
│ ├── update()
│ ├── retrieve()
│ ├── list()
│ ├── delete()
│ └── sleeptime # Background memory processing
├── memory # Memory block management
│ ├── create()
│ ├── upsert()
│ ├── retrieve()
│ ├── list()
│ ├── search() # Semantic search
│ ├── remember() # Store memories
│ └── context # Memory context retrieval
└── messages # Message history
├── capture() # Save conversation turn
├── list()
└── create() # Send message to LLM
Requirements
Python
- Python 3.9+
- Letta API key (sign up at letta.com)
- At least one LLM SDK:
openai>=1.0.0anthropic>=0.18.0google-generativeai>=0.3.0@anthropic-ai/claude-agent-sdk>=0.1.0
TypeScript/JavaScript
- Node.js 18+
- Letta API key (sign up at letta.com)
- At least one LLM SDK:
openai>=4.0.0@anthropic-ai/sdk>=0.30.0@google/generative-ai>=0.21.0@anthropic-ai/claude-agent-sdk>=0.1.0ai>=3.0.0(Vercel AI SDK)
Local Development (Optional)
For local development, you can run Letta server locally:
# Install Letta
pip install letta
# Start server (default: http://localhost:8283)
letta server
See Letta documentation for more details.
Development Setup
Python Development
# Clone repository
git clone https://github.com/letta-ai/agentic_learning_sdk.git
cd agentic_learning_sdk
# Install in development mode
pip install -e python/
# Run tests
cd python
.venv/bin/python3 -m pytest tests/ -v
# Run examples
cd ../examples
python3 openai_example.py
TypeScript Development
# Clone repository
git clone https://github.com/letta-ai/agentic_learning_sdk.git
cd agentic_learning_sdk/typescript
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Run examples
cd ../examples
npx tsx openai_example.ts
Advanced Usage
Custom Letta Server URL
learning_client = AgenticLearning(base_url="http://custom-host:8283")
Agent Configuration
# Create agent with custom memory blocks
agent = learning_client.agents.create(
agent="my_agent",
memory=["human", "persona", "project_context"],
model="anthropic/claude-sonnet-4-20250514"
)
# Create custom memory block
learning_client.memory.create(
agent="my_agent",
label="user_preferences",
value="Prefers concise technical responses"
)
Async Support
from agentic_learning import learning_async, AsyncAgenticLearning
async_client = AsyncAgenticLearning()
async with learning_async(agent="my_agent", client=async_client):
response = await async_llm_client.generate(...)
Testing
This SDK includes comprehensive test suites for both Python and TypeScript:
Python Tests
- 36/36 tests passing (100%)
- Unit tests with mocked LLM HTTP calls
- Integration tests with real API calls
- See python/tests/README.md for details
TypeScript Tests
- 40/40 tests passing (100%)
- Unit tests with Jest mocks
- Integration tests with real API calls
- See typescript/tests/README.md for details
Both test suites cover all supported providers and validate:
- ✅ Conversation capture and storage
- ✅ Memory injection into prompts
- ✅ Capture-only mode
- ✅ Interceptor cleanup
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Adding a New Provider
- Create a new interceptor in
python/src/agentic_learning/interceptors/ - Extend
BaseAPIInterceptor(for API-level) orBaseInterceptor(for transport-level) - Implement SDK-specific methods:
extract_user_messages()extract_assistant_message()inject_memory_context()_build_response_from_chunks()
- Register in
__init__.py - Add example to
examples/
See existing interceptors for reference implementations.
License
Apache 2.0 - See LICENSE for details.
Links
Acknowledgments
Built with Letta - the leading platform for building stateful AI agents with long-term memory.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agentic_learning-0.4.0.tar.gz.
File metadata
- Download URL: agentic_learning-0.4.0.tar.gz
- Upload date:
- Size: 117.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.24
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a68f2f4c35d54a55429c14a2d555f8827d59bcb39573c9d09d0a6c9c6f25033b
|
|
| MD5 |
75440427a28f6facc3b228bdf08ce7f8
|
|
| BLAKE2b-256 |
0f695e218227eb9aace395eee134fe17e767e2ae4f745adfb9d6cf9850c193a1
|
File details
Details for the file agentic_learning-0.4.0-py3-none-any.whl.
File metadata
- Download URL: agentic_learning-0.4.0-py3-none-any.whl
- Upload date:
- Size: 35.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.24
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f32d853cd1c4f65ebe40e1a6e48eb63856106d439961cca41ddce73eaecfb2b6
|
|
| MD5 |
ed4531e8a803ac5109c6cada4fb0f09a
|
|
| BLAKE2b-256 |
2170ca13312829742dbccd3ef8faf43fefa335dc26699ba66ca052a4207b12b2
|