LLM assistant for Python packages in REPLs and notebooks
Project description
LLM-powered assistant for every Python package!
Just add .sage.ask("your question") to talk to any module.
๐ง Sagely Agent
Sagely Agent automatically injects a .sage assistant into every package you import. Ask questions about the library you're using, get help with errors, and explore code with syntax-highlighted answers โ all powered by an LLM.
๐ฅ Demo (TODO!)
(Click to view full video)
https://github.com/superpandas-ai/sagely/assets/demo.gif
or
https://loom.com/share/sagely-demo-link
โ Why Sagely?
There are thousands of Python libraries, but their docs aren't always intuitive. Moreover, getting help about errors or finding usage requires (atleast) asking an LLM manually. With sagely, you can do all that right from the REPL or the jupyter notebook:
- You don't need to search Stack Overflow, or ask ChatGPT, every time you forget a method or run into an error.
- You get context-aware help, including recent exceptions and object summaries.
- It's built for exploration โ whether you're using a notebook, or REPL.
โจ Features
- ๐ง Ask any module
.sage.ask("How do I do X?")(prints the answer) - ๐ก Smart context: recent errors + object summaries
- ๐งฉ Auto-attaches to every import
- ๐พ Caches answers to avoid repeated API calls
- ๐ฆ Caches module analysis for faster subsequent queries
- ๐จ Syntax-highlighted output with
rich - ๐ง IPython magic:
%sagely pandas how to merge? - ๐ Real-time status updates showing agent flow progress
- ๐ Web search integration with multiple providers (OpenAI web-search, Tavily)
- ๐ LangSmith tracing for debugging and monitoring
- โ๏ธ Centralized configuration system for customizing agent behavior
- ๐๏ธ Direct configuration access via
sagely.config.attribute = value - ๐ Configurable line numbers in console display
- ๐ฐ Token usage tracking with model-specific breakdowns and persistent storage
- ๐ Usage analytics with session management and historical data
- ๐ Real-time usage display in status updates
๐ Getting Started
1. Install
pip install sagely
2. Set up OpenAI API Key
export OPENAI_API_KEY='your-api-key-here'
Note: Sagely currently uses OpenAI's models (gpt-4.1-mini by default), so you must have your OpenAI API key set in the environment. Later we plan to introduce other LLM providers.
3. Import It
import sagely
It hooks into all future module imports.
๐งช Usage Examples
Inline Python
import matplotlib
matplotlib.sage.ask("how to make a scatter plot?") # This will print the answer
In Jupyter / IPython
%load_ext sagely
%sagely numpy how to generate random numbers?
Programmatic
from sagely import agent
agent.ask("requests", "how do I send a POST request?") # Prints the answer
Status Outputs
The agent provides real-time feedback about what it's doing:
โน๏ธ Processing question about 'requests': How do I send a POST request?...
โน๏ธ Starting LangGraph workflow execution...
โน๏ธ Starting context analysis for module: requests
โน๏ธ Analyzing module 'requests'...
โ
Successfully analyzed module 'requests'
โ
Context analysis completed
๐ค Generating initial response...
โ
Initial response generated
๐ค Evaluating if web search is needed...
๐ Web search needed for comprehensive answer
๐ Starting web search for additional information...
๐ Web search 1/3: requests python How do I send a POST request?...
๐ Web search 2/3: requests documentation How do I send a POST request?...
๐ Web search 3/3: python requests best practices How do I send a POST request?...
โ
Web search completed with results
๐ค Generating final response with web search results...
โ
Final response generated successfully
๐ฆ Answer cached for future use
โ
Displaying final answer
โ๏ธ Configuration System
Sagely provides a centralized configuration system for customizing agent behavior, model selection, cache management, and more.
Direct Configuration Access (Recommended)
The easiest way to configure Sagely is through direct attribute assignment:
import sagely
# Direct configuration updates
sagely.config.enable_module_cache = False
sagely.config.show_line_numbers = False
sagely.config.model_name = "gpt-3.5-turbo"
sagely.config.web_search_provider = "tavily"
sagely.config.show_status_updates = False
# Changes take effect immediately and affect all future operations
Programmatic Configuration
from sagely import get_config, update_config, clear_caches, clear_module_cache, reset_config, SageAgent
# View current configuration
config = get_config()
print(config.to_dict())
# Update configuration (e.g., change model, disable status updates)
update_config(model_name="gpt-3.5-turbo", show_status_updates=False)
# Create a new agent with the updated model
agent = SageAgent(model_name=get_config().model_name)
# Reset configuration to defaults
reset_config()
Available Configuration Options
model_name: LLM model to use (default: "gpt-4.1-mini")show_status_updates: Show status outputs (default: True)show_line_numbers: Show line numbers in console display (default: True)enable_response_cache: Enable/disable response caching (default: True)enable_module_cache: Enable/disable module info caching (default: True)enable_web_search: Enable/disable web search (default: True)web_search_provider: Web search provider ("openai_websearch" or "tavily", default: "openai_websearch")web_search_timeout: Timeout for web search requests (default: 10)enable_langsmith_tracing: Enable LangSmith tracing (default: False)langsmith_project: LangSmith project name (default: None)
Cache Management
Sagely uses two types of caches to improve performance:
- Response Cache: Stores answers to questions to avoid repeated API calls
- Module Cache: Stores analyzed module information for faster subsequent queries
To manage caches, import the cache functions:
from sagely import clear_caches, clear_module_cache
# Clear all caches
clear_caches()
# Clear only response cache
clear_caches("response")
# Clear only module cache
clear_caches("module")
# Clear module cache for a specific module
clear_module_cache("json")
# Clear module cache for all modules
clear_module_cache()
Environment Variable Configuration
You can also configure Sagely using environment variables:
SAGELY_MODELSAGELY_SHOW_STATUSSAGELY_SHOW_LINE_NUMBERSSAGELY_ENABLE_RESPONSE_CACHESAGELY_ENABLE_MODULE_CACHESAGELY_ENABLE_WEB_SEARCHSAGELY_WEB_SEARCH_PROVIDERSAGELY_WEB_SEARCH_TIMEOUTSAGELY_ENABLE_LANGSMITHSAGELY_LANGSMITH_PROJECTTAVILY_API_KEY(for Tavily web search)OPENAI_API_KEY
Example:
export SAGELY_MODEL=gpt-4.1-mini
export SAGELY_SHOW_STATUS=false
export SAGELY_SHOW_LINE_NUMBERS=false
export SAGELY_ENABLE_WEB_SEARCH=true
export SAGELY_WEB_SEARCH_PROVIDER=tavily
export SAGELY_WEB_SEARCH_TIMEOUT=15
export TAVILY_API_KEY=your-tavily-api-key
Web Search Providers
Sagely supports multiple web search providers for up-to-date information:
OpenAI Web Search (Default)
- Uses OpenAI's built-in web search tool
- No additional API key required (uses your OpenAI API key)
- Set with:
sagely.config.web_search_provider = "openai_websearch"
Tavily Search
- Uses Tavily's search API for comprehensive web results
- Requires a Tavily API key:
export TAVILY_API_KEY=your-key - Set with:
sagely.config.web_search_provider = "tavily"
The agent automatically rebuilds its workflow when you change the web search provider.
Configuration Persistence
Sagely automatically creates a configuration file at ~/.sagely/config.json on first run with default settings. You can:
# Save current configuration to file
from sagely.config import save_config
save_config()
# Load configuration from file
from sagely.config import load_config
load_config()
# Or use the global functions
from sagely import save_config, load_config
save_config()
load_config()
The configuration file is automatically created with default settings if it doesn't exist.
๐ LangSmith Tracing
Sagely supports LangSmith for tracing and experiment tracking. To enable LangSmith tracing:
-
Install dependencies (already included):
langsmithlangchain-core
-
Set environment variables (in your shell or
.envfile):export LANGCHAIN_TRACING_V2=true export LANGCHAIN_API_KEY=your-langsmith-api-key export LANGCHAIN_PROJECT=your-project-name # optional
-
Enable tracing in configuration:
import sagely sagely.config.enable_langsmith_tracing = True sagely.config.langsmith_project = "my-sagely-project" # optional
-
Run your code as usual. All LangChain and LangGraph runs will be traced to your LangSmith dashboard.
For more details, see the LangSmith docs.
๐ง Direct Tool Access
You can access the built-in tools directly for custom implementations:
from sagely.langgraph_agent import analyze_module, get_error_context, web_search
# Analyze a module with comprehensive information
module_info = analyze_module.invoke({"module_name": "json"})
print(module_info)
# Output includes: documentation, functions with docstrings, classes, and submodules
# Get error context
error_info = get_error_context.invoke({})
print(error_info)
# Search the web
web_result = web_search.invoke({"query": "python pandas performance optimization"})
print(web_result)
๐ Prompt Customization
All prompts are available in the sagely.prompts module for customization:
from sagely.prompts import (
INITIAL_RESPONSE_PROMPT,
ORCHESTRATOR_EVALUATION_PROMPT,
FINAL_RESPONSE_WITH_WEB_PROMPT,
FINAL_RESPONSE_WITHOUT_WEB_PROMPT,
SYSTEM_MESSAGE_TEMPLATE
)
# Use prompts for custom implementations
system_msg = SYSTEM_MESSAGE_TEMPLATE.format(module_name="numpy")
initial_prompt = INITIAL_RESPONSE_PROMPT.format(
traceback="No errors",
context_summary="Working with arrays",
module_info="NumPy module info",
question="How to create arrays?"
)
๐ Token Usage Tracking
Sagely provides comprehensive token usage tracking to help you monitor your API costs and usage patterns. The system automatically tracks all LLM requests and stores detailed usage data both in-memory and in persistent JSON files.
๐ฏ Key Features
- Automatic Tracking: All LLM requests are automatically tracked
- Model-Specific Tracking: Usage is tracked separately for each LLM model
- Real-Time Display: Token usage is shown in status updates when enabled
- Persistent Storage: Usage data is saved to JSON files in
~/.sagely/usage_data/ - Session Management: Each session gets a unique file with timestamp
- Historical Analysis: Access to all previous session data
- Easy Integration: Ready for Streamlit app integration
๐ Quick Start
import sagely
# Check current session usage
print(f"Total tokens used: {sagely.usage_data.total_tokens:,}")
print(f"Session ID: {sagely.usage_data.session_id}")
# Make some requests (usage is tracked automatically)
import requests
requests.sage.ask("How do I send a POST request?")
# Check updated usage
print(f"Updated tokens: {sagely.usage_data.total_tokens:,}")
๐ Usage Data Access
Via sagely.usage_data (Recommended)
The easiest way to access usage information:
import sagely
# Basic usage information
print(f"Input tokens: {sagely.usage_data.input_tokens:,}")
print(f"Output tokens: {sagely.usage_data.output_tokens:,}")
print(f"Total tokens: {sagely.usage_data.total_tokens:,}")
print(f"Request count: {sagely.usage_data.request_count}")
# Session information
print(f"Session ID: {sagely.usage_data.session_id}")
print(f"File path: {sagely.usage_data.session_file_path}")
# Model-specific usage
for model_name, usage in sagely.usage_data.models.items():
print(f"{model_name}: {usage.total_tokens:,} tokens")
# Get usage for specific model
gpt4_usage = sagely.usage_data.get_model_usage("gpt-4")
print(f"gpt-4 usage: {gpt4_usage.total_tokens:,} tokens")
# Get recent usage for a model
recent = sagely.usage_data.get_model_recent_usage("gpt-4o", 3)
for usage in recent:
print(f"{usage.total_tokens} tokens ({usage.request_type})")
# Comprehensive summary
print(sagely.usage_data.summary)
Via Functions
from sagely import (
get_session_total,
get_session_summary,
get_model_usage,
get_all_model_usage,
get_session_id,
get_session_file_path
)
# Get total usage
total = get_session_total()
print(f"Total: {total.total_tokens:,} tokens")
# Get formatted summary
print(get_session_summary())
# Get model-specific usage
gpt4_usage = get_model_usage("gpt-4")
print(f"gpt-4: {gpt4_usage.total_tokens:,} tokens")
# Get all models
all_models = get_all_model_usage()
for model_name, usage in all_models.items():
print(f"{model_name}: {usage.total_tokens:,} tokens")
๐พ File-Based Storage
Usage data is automatically saved to JSON files in ~/.sagely/usage_data/ with the following structure:
~/.sagely/
โโโ config.json
โโโ usage_data/
โโโ usage_20250709_000629.json
โโโ usage_20250709_000607.json
โโโ usage_20250709_000557.json
โโโ ...
File Naming Convention
Files are named usage_YYYYMMDD_HHMMSS.json where:
YYYYMMDD= Date (Year-Month-Day)HHMMSS= Time (Hour-Minute-Second)
This ensures no data overwrites and provides chronological ordering.
JSON Structure
{
"session_id": "20250709_000629",
"session_start": "2025-07-09T00:06:29.375616",
"usage_history": [
{
"input_tokens": 150,
"output_tokens": 75,
"total_tokens": 225,
"timestamp": "2025-07-09T00:06:29.375696",
"model_name": "gpt-4",
"request_type": "initial_response"
}
],
"model_usage": {
"gpt-4": {
"input_tokens": 250,
"output_tokens": 125,
"total_tokens": 375,
"timestamp": "2025-07-09T00:06:29.375700",
"model_name": "gpt-4",
"request_type": ""
}
}
}
๐ Session Management
Working with Session Files
from sagely import (
get_all_session_files,
load_session_from_file,
load_latest_session
)
# Get all session files (sorted by date, newest first)
session_files = get_all_session_files()
for file_path in session_files[:5]: # Show first 5
print(f"Session: {file_path.name}")
# Load specific session
loaded_tracker = load_session_from_file(session_files[0])
print(f"Loaded tokens: {loaded_tracker.get_session_total().total_tokens:,}")
# Load latest session
latest = load_latest_session()
print(f"Latest session: {latest.get_session_id()}")
Session Summary Example
Session Token Usage:
Total input tokens: 1,234
Total output tokens: 567
Total tokens: 1,801
Session duration: 0:05:30
Total requests: 5
Model Breakdown:
gpt-4:
Input tokens: 800
Output tokens: 400
Total tokens: 1,200
Requests: 3
gpt-4o:
Input tokens: 434
Output tokens: 167
Total tokens: 601
Requests: 2
๐ Usage Management
Clearing Usage Data
from sagely import clear_usage_history, clear_model_history
# Clear all usage history
clear_usage_history()
# Clear history for specific model
clear_model_history("gpt-3.5-turbo")
Real-Time Status Updates
When show_status_updates is enabled, you'll see token usage in real-time:
๐ฐ Tokens used: 150 input, 75 output, 225 total
๐ฐ Tokens used: 200 input, 100 output, 300 total
๐ฐ Tokens used: 100 input, 50 output, 150 total
๐๏ธ Configuration
Token usage tracking can be configured through the main configuration system:
import sagely
# Enable/disable status updates (affects usage display)
sagely.config.show_status_updates = True
# The usage tracking itself is always enabled for data collection
# Status updates only control the display of usage information
๐ฑ Streamlit Integration
The file-based storage system is designed for easy integration with Streamlit apps:
- JSON Format: Easy to parse and analyze
- Historical Data: Access to all previous sessions
- Model Breakdown: Detailed model-specific usage
- Timestamp Data: Precise timing information
- Session Recovery: Load any previous session
Example Streamlit data loading:
import streamlit as st
import json
from pathlib import Path
# Load all session files
usage_dir = Path.home() / ".sagely" / "usage_data"
session_files = sorted(usage_dir.glob("usage_*.json"), reverse=True)
# Load and analyze data
for file_path in session_files:
with open(file_path, 'r') as f:
data = json.load(f)
st.write(f"Session: {data['session_id']}")
st.write(f"Total tokens: {sum(usage['total_tokens'] for usage in data['usage_history'])}")
๐ Advanced Usage
Custom Usage Analysis
from sagely import get_usage_tracker
# Get the usage tracker for advanced operations
tracker = get_usage_tracker()
# Get recent usage for specific model
recent_gpt4 = tracker.get_model_recent_usage("gpt-4", 10)
# Analyze usage patterns
for usage in recent_gpt4:
print(f"{usage.timestamp}: {usage.total_tokens} tokens ({usage.request_type})")
Usage Statistics
import sagely
# Quick usage check
if sagely.usage_data.total_tokens > 0:
print(f"โ
Session active with {sagely.usage_data.total_tokens:,} tokens")
else:
print("โน๏ธ No tokens used yet")
# Model comparison
models = sagely.usage_data.models
if len(models) > 1:
print("๐ Model usage comparison:")
for model_name, usage in models.items():
print(f" {model_name}: {usage.total_tokens:,} tokens")
๐ง Requirements
- OpenAI API key (set as
OPENAI_API_KEYenvironment variable) - Tavily API key (optional, for Tavily web search provider)
- LangSmith API key (optional, for tracing)
Dependencies
- openai
- ipywidgets
- rich
- ipython
- langgraph
- langchain-openai
- langchain-tavily (for Tavily web search)
- langchain-core
- requests
- langsmith (optional, for tracing)
(All dependencies are installed automatically.)
๐ง Project Structure
sagely/
โโโ src/sagely/
โ โโโ langgraph_agent.py # Main LangGraph-based agent
โ โโโ sage_agent.py # High-level agent interface
โ โโโ cache.py # Caching system
โ โโโ context.py # Context gathering
โ โโโ import_hook.py # Import hooking
โ โโโ ipython_magics.py # IPython magic commands
โ โโโ prompts.py # Prompt templates
โ โโโ tracing.py # LangSmith tracing
โ โโโ widgets.py # Display utilities
โ โโโ config.py # Centralized configuration system
โ โโโ usage_info.py # Token usage tracking system
โ โโโ __init__.py
โโโ tests/
โโโ examples/ # Usage examples in Jupyter notebooks
โโโ pyproject.toml
โโโ MANIFEST.in
โโโ README.md
๐ Data Storage
~/.sagely/
โโโ config.json # Configuration file
โโโ usage_data/ # Token usage data
โโโ usage_20250709_000629.json
โโโ usage_20250709_000607.json
โโโ ...
๐ค Contributing
Sagely is early-stage โ PRs and ideas welcome! ๐ฅ
We use Featurebase for product roadmap and feature requests/tracking
๐ Future Features
- Support for other LLM Providers
- Advanced caching and error tracing
- Auto-annotation of cells with answers
- Better prompts and prompt management
- Async & Parallel Context Gathering
- Streaming Response for Jupyter/REPL
- Improved context for large modules using RAG/Summarization/Selective filtering
- Enhanced web search capabilities
- Custom agent workflows
- Integration with more development tools
๐งท License
MIT ยฉ 2025 SuperPandas Ltd
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 sagely-0.1.1.tar.gz.
File metadata
- Download URL: sagely-0.1.1.tar.gz
- Upload date:
- Size: 47.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecd53ef14020a4e3878682494c37808273fe84997fa4245a11ff78542b8c4e4f
|
|
| MD5 |
a5d8a35c46fffd9c2fb91eb8a7721a05
|
|
| BLAKE2b-256 |
027b9384aa5f6c8619c18f2e9c9a95156e37e3c6cefe0a68b2ffa2b734ea2c4f
|
File details
Details for the file sagely-0.1.1-py3-none-any.whl.
File metadata
- Download URL: sagely-0.1.1-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b2576fa49d8458c5d4953c9b41a9336305c40669501da68a5eb742a44addc59
|
|
| MD5 |
b9bf6059fd3d8164b78d9d5116b98d18
|
|
| BLAKE2b-256 |
6d7c849d29906fec78ea9d9266941be692cf2666114dacd7f6ed80536ec4cb7f
|