llm-context-toolkit
Version: 0.1.0
Author: sreeyenan
License: MIT
Python: 3.10+
A comprehensive toolkit for LLM context management with intelligent metadata selection and contextual question resolution.
🎯 What This Library Does
llm-context-toolkit solves two critical problems when building LLM-powered AI systems:
- Context Resolution - Converts short, contextual messages into complete standalone instructions
- Metadata Selection - Intelligently selects only relevant metadata from large catalogs
The Problem
When building Text-to-SQL, RAG systems, or dashboard AI assistants, you face these challenges:
- Contextual questions are hard to understand: "make it monthly", "what else?", "same for payments"
- Full metadata catalogs are too large: Sending 50+ tables with 500+ columns to an LLM wastes tokens, increases cost, and reduces accuracy
- Chat history grows unbounded: Passing full conversation history is expensive and often unnecessary
The Solution
from llm_context_toolkit import resolve_and_select
# One line to resolve context + select metadata
resolution, selection = resolve_and_select(
current_question="make it monthly",
metadata_catalog=tenant_catalog,
context_cards=[previous_turn_card],
database="client_db"
)
# Result:
# - Resolved question: "Show monthly revenue by region for last 6 months"
# - Selected metadata: 1 table, 3 columns (from 42 tables, 890 columns)
# - Token reduction: 95.5% (47000 → 2100 tokens)
🚀 Key Features
Context Resolution
- ✅ Converts contextual messages into standalone questions
- ✅ Detects follow-ups, modifications, fresh questions, and suggestion requests
- ✅ Maintains state using compact
TurnContextCardobjects - ✅ No full chat history needed (90%+ memory reduction)
- ✅ Rule-based resolution (no API calls required)
- ✅ Optional LLM fallback for ambiguous cases
Metadata Selection
- ✅ Selects only relevant tables and columns from large catalogs
- ✅ 90-98% token reduction for LLM prompts
- ✅ Multiple strategies: lexical, TF-IDF, embeddings, hybrid
- ✅ No API key required for core functionality
- ✅ Supports business metadata (synonyms, descriptions, roles)
- ✅ Works with any database schema (SQL, NoSQL, graph, etc.)
Framework-Agnostic
- ✅ Works with any LLM (OpenAI, Anthropic, Gemini, Groq, local models)
- ✅ Works with any SQL engine (PostgreSQL, MySQL, ClickHouse, etc.)
- ✅ Works with any framework (FastAPI, Flask, Django, etc.)
- ✅ Works with any vector database for RAG
- ✅ Pure Python with zero required dependencies
📦 Installation
Minimal Installation (Pure Python)
pip install llm-context-toolkit
With Optional Enhanced Features
# TF-IDF strategy for better lexical matching
pip install llm-context-toolkit[tfidf]
# Local embedding support for semantic matching
pip install llm-context-toolkit[embeddings]
# Everything
pip install llm-context-toolkit[all]
🎓 Quick Start
1. Basic Context Resolution
from llm_context_toolkit import ContextResolver, TurnContextCard
# Previous conversation turn
previous_card = TurnContextCard(
turn_id=1,
user_question="Show total revenue by region",
resolved_question="Show total revenue by region",
query_state={
"active_tables": ["sales_orders"],
"metrics": ["revenue"],
"group_by": ["region"],
}
)
# Resolve a contextual follow-up
resolver = ContextResolver()
resolution = resolver.resolve(
current_question="make it monthly",
context_cards=[previous_card]
)
print(resolution.resolved_question)
# "Show monthly revenue by region"
print(resolution.metadata_search_query)
# "monthly revenue region order_date sales_orders"
2. Basic Metadata Selection
from llm_context_toolkit import MetadataSelector
catalog = {
"database": "client_db",
"tables": [
{
"table_name": "sales_orders",
"columns": [
{"name": "revenue", "role": "metric", "synonyms": ["sales", "income"]},
{"name": "region", "role": "dimension", "synonyms": ["zone", "area"]},
{"name": "order_date", "role": "date"},
]
}
]
}
selector = MetadataSelector()
result = selector.select(
question="Show total sales by region for last 6 months",
catalog=catalog
)
print(result.selected_metadata)
# Only relevant table and columns selected
print(result.metrics.summary())
# "tables 42 → 1 (97.6% cut), columns 890 → 3 (99.7% cut), tokens ~47000 → ~500 (98.9% cut)"
3. Combined Workflow (Recommended)
from llm_context_toolkit import resolve_and_select, TurnContextCard
# One call to handle both resolution and selection
resolution, selection = resolve_and_select(
current_question="consider monthly?",
metadata_catalog=tenant_catalog,
context_cards=[previous_card],
database="client_abc_db"
)
# Handle clarification requests
if resolution.route == "clarify":
return {"message": resolution.clarification_question}
# Now pass to your LLM
prompt = f"""
Question: {resolution.resolved_question}
Available Schema:
{selection.selected_metadata}
Generate SQL for this question.
"""
# Send to OpenAI, Anthropic, Gemini, etc.
sql = your_llm.generate(prompt)
🔄 Typical Pipeline
User Message: "make it monthly"
↓
ContextResolver
↓
Resolved: "Show monthly revenue by region for last 6 months"
Search Query: "monthly revenue region order_date"
↓
MetadataSelector
↓
Selected: 1 table (sales_orders), 3 columns (revenue, region, order_date)
Token Reduction: 47000 → 2100 tokens (95.5% reduction)
↓
LLM Prompt
↓
SQL/Config/Answer Generation
↓
Save new TurnContextCard
📖 Use Cases
Text-to-SQL
# User: "Show revenue by region"
# → SQL: SELECT region, sum(revenue) FROM sales_orders GROUP BY region
# User: "make it monthly"
# → SQL: SELECT toStartOfMonth(order_date) AS month, region, sum(revenue)
# FROM sales_orders GROUP BY month, region
Text-to-Query-Config
# User: "Show revenue by region as a bar chart"
# → Config: {"type": "bar", "x": "region", "y": "sum(revenue)"}
RAG / Document Q&A
# Previous: "What are the compliance requirements?"
# User: "what about privacy only?"
# → Resolved: "What are the privacy-specific compliance requirements?"
Dashboard AI Assistant
# User: "what else can we analyze?"
# → Suggestions: ["Revenue by product category", "Monthly trend analysis", "Top 10 regions"]
🏗️ Architecture
Context Resolution Flow
User Message
↓
Detect explicit references (turn #3, chart 2, etc.)
↓
Rank recent context cards by relevance
↓
Classify: fresh | follow-up | modify | suggest | clarify
↓
Extract intent delta (granularity, filters, etc.)
↓
Compose resolved question + metadata search query
↓
Output: ContextResolution
Metadata Selection Flow
Question + Full Catalog (42 tables, 890 columns)
↓
Parse intent (metrics, dates, grouping, trends)
↓
Score tables (lexical + TF-IDF + embeddings)
↓
Select top K tables (default: 3)
↓
Score columns within selected tables
↓
Select top N columns per table (default: 25)
↓
Include relationships between selected tables
↓
Output: Selected metadata (1-3 tables, 5-30 columns)
🎯 Core Concepts
TurnContextCard
Compact memory object storing structured context from a previous AI turn.
TurnContextCard(
turn_id=1,
user_question="Show revenue by region",
resolved_question="Show total revenue by region for last 6 months",
task_type="text_to_sql",
artifact_type="sql",
topic_keywords=["revenue", "region", "sales"],
entities=["sales_orders", "revenue", "region"],
query_state={
"active_tables": ["sales_orders"],
"metrics": ["revenue"],
"dimensions": ["region"],
"filters": [{"column": "order_date", "operation": "last_6_months"}],
},
sql="SELECT region, sum(revenue) FROM sales_orders WHERE order_date >= ...",
)
Why not store full chat history?
- Full history: 1000+ tokens per turn × 10 turns = 10,000+ tokens
- Context cards: ~200 tokens per turn × 10 turns = 2,000 tokens
- 80% reduction before metadata selection even starts
ContextType
Classification of how the current question relates to previous context:
fresh_question- New independent questionfollow_up_latest- Continues from latest resultfollow_up_specific_turn- References a specific older turnmodify_previous_query- Modifies a previous resultsuggestion_request- Asks for related suggestionsclarification_needed- Too ambiguous to resolve
Selection Strategies
- lexical - Pure Python keyword matching (no dependencies)
- tfidf - TF-IDF scoring (requires scikit-learn)
- embedding - Semantic similarity (requires sentence-transformers)
- hybrid - Combines all available strategies (recommended)
🔧 Configuration
Resolver Configuration
from llm_context_toolkit import ResolverConfig, ContextResolver
config = ResolverConfig(
max_recent_cards=10, # How many recent cards to consider
min_confidence_threshold=0.75, # Minimum confidence to resolve
allow_llm_fallback=False, # Use LLM for ambiguous cases
enable_debug=True, # Include debug information
)
resolver = ContextResolver(config=config)
Selector Configuration
from llm_context_toolkit import SelectorConfig, MetadataSelector
config = SelectorConfig(
strategy="hybrid", # lexical | tfidf | embedding | hybrid
top_k_tables=3, # Max tables to select
max_columns_per_table=25, # Max columns per table
max_output_chars=10000, # Budget limit for output
use_embeddings_if_available=True, # Use embeddings if installed
embedding_model_name_or_path="./models/all-MiniLM-L6-v2", # Local model
include_debug=True, # Include scoring details
)
selector = MetadataSelector(config=config)
📊 Real-World Results
Token Reduction Examples
| Scenario | Input Tokens | Output Tokens | Reduction |
|---|---|---|---|
| Small catalog (5 tables, 50 cols) | ~3,000 | ~400 | 86.7% |
| Medium catalog (20 tables, 200 cols) | ~12,000 | ~800 | 93.3% |
| Large catalog (50 tables, 500 cols) | ~30,000 | ~1,200 | 96.0% |
| Very large (100 tables, 1000 cols) | ~60,000 | ~1,500 | 97.5% |
Cost Impact
Assuming GPT-4 pricing ($10/1M input tokens):
- Large catalog: 30,000 tokens → 1,200 tokens = $0.30 → $0.012 per query (96% cost reduction)
- 10,000 queries/month: $3,000 → $120/month savings = $34,560/year
🔬 Advanced Usage
Custom LLM Fallback for Ambiguous Cases
from llm_context_toolkit import ContextResolver
def my_llm_fallback(question, card_summaries, preliminary):
# Call your LLM to resolve ambiguous cases
prompt = f"Question: {question}\nContext: {card_summaries}\nResolve this."
response = your_llm_client.generate(prompt)
return {"resolved_question": response["question"], ...}
resolver = ContextResolver(llm_fallback=my_llm_fallback)
Multi-Tenant Isolation
# Always pass database override from your tenant resolver
client_id = request.headers["X-Client-ID"]
database = tenant_resolver.get_database(client_id)
resolution, selection = resolve_and_select(
current_question=user_question,
metadata_catalog=tenant_catalogs[client_id],
database=database, # Ensures LLM only sees this tenant's data
)
State Extraction for Next Turn
# After generating SQL/config, extract state for next turn
from llm_context_toolkit import TurnContextCard
next_card = TurnContextCard(
turn_id=current_turn_id + 1,
user_question=resolution.current_question,
resolved_question=resolution.resolved_question,
query_state={
"active_tables": [t["table_name"] for t in selection.selected_metadata["tables"]],
"metrics": extract_metrics_from_sql(generated_sql),
"dimensions": extract_dimensions_from_sql(generated_sql),
# ... extract other state
},
sql=generated_sql,
)
# Store for next turn
context_store.save(session_id, next_card)
🧪 Testing
# Run tests
pytest
# Run with coverage
pytest --cov=llm_context_toolkit
# Run specific test
pytest tests/test_context_resolver.py::test_fresh_question
📚 Documentation
- Full User Manual - Complete reference guide
- Context Resolver Guide - Detailed context resolution documentation
- Metadata Selector Guide - Detailed metadata selection documentation
- Examples - Code examples for common use cases
🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
This library was built to solve real-world problems in multi-tenant analytics systems with Text-to-SQL, dashboard AI assistants, and natural language query interfaces.
📧 Support
Made with ❤️ by sreeyenan
Metadata
Release files for llm-context-toolkit 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| llm_context_toolkit-0.1.2.tar.gz | 58.3 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
| llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.17+ x86-64 | Details |
| llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl | CPython 3.11 | CPython 3.11 | macOS 11.0+ ARM64 | Details |
| llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl | CPython 3.11 | CPython 3.11 | macOS 10.9+ x86-64 | Details |
Total release size: 6.6 MB
Release files / llm_context_toolkit-0.1.2.tar.gz
| Download URL | llm_context_toolkit-0.1.2.tar.gz |
|---|---|
| Size | 58.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
66fd25818b3ee2a7165f971e0988a5cf0cbd858de4340afe5695de83fb4e4d25
|
|
BLAKE2b-256 checksum How to use checksums |
7ec320fe4672e86f1cfd433b763f965e2d7bde2ce5c5bfa035d81fcaa6b1ccca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logRelease files / llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl
| Download URL | llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 964.4 kB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
15afe4fe50977155787fa8845fc38b129e9b61b565e0ad634696782b7183afde
|
|
BLAKE2b-256 checksum How to use checksums |
e3cfab71650b7e3dddd9d432d21304b1d4b98117327b97c56d024032af8fddb9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logRelease files / llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
| Download URL | llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
|---|---|
| Size | 3.5 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
77e073133c031ea5003580a857951193d2e60447151cb49839a4c37c8a09d4b7
|
|
BLAKE2b-256 checksum How to use checksums |
1c57de295373236fd7132484c69347c6bbbab002f064ba69b01c66d66b969037
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logRelease files / llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.0 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f8d803f66da0d0bc3d48bfcb14a1ea3578bb1d7eef855b8baddc6ca0d6c1aa26
|
|
BLAKE2b-256 checksum How to use checksums |
3c51acfb50e5ed1436f93bfe81bf153dc0cd2b8c697ebfda1380a499e12f9989
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logRelease files / llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl
| Download URL | llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.11 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
11262961b4dd41f0cabc04160a968c1d1b16729eedc553a6a6e5615eccd44ade
|
|
BLAKE2b-256 checksum How to use checksums |
ad208dede3ffc40e169009f95142ef2e62e7bc3eff5c96290e57a0b3590bf303
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency log