Skip to main content

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.

PyPI version Python 3.10+ License: MIT


๐ŸŽฏ What This Library Does

llm-context-toolkit solves two critical problems when building LLM-powered AI systems:

  1. Context Resolution - Converts short, contextual messages into complete standalone instructions
  2. 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 TurnContextCard objects
  • โœ… 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 question
  • follow_up_latest - Continues from latest result
  • follow_up_specific_turn - References a specific older turn
  • modify_previous_query - Modifies a previous result
  • suggestion_request - Asks for related suggestions
  • clarification_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


๐Ÿค Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_context_toolkit-0.1.2.tar.gz (58.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl (964.4 kB view details)

Uploaded CPython 3.11Windows x86-64

llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

File details

Details for the file llm_context_toolkit-0.1.2.tar.gz.

File metadata

  • Download URL: llm_context_toolkit-0.1.2.tar.gz
  • Upload date:
  • Size: 58.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_context_toolkit-0.1.2.tar.gz
Algorithm Hash digest
SHA256 66fd25818b3ee2a7165f971e0988a5cf0cbd858de4340afe5695de83fb4e4d25
MD5 19205e1e9b87eec681c91e5369e7ae8b
BLAKE2b-256 7ec320fe4672e86f1cfd433b763f965e2d7bde2ce5c5bfa035d81fcaa6b1ccca

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.2.tar.gz:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 15afe4fe50977155787fa8845fc38b129e9b61b565e0ad634696782b7183afde
MD5 54e2281256b23f9c49478a8570f09693
BLAKE2b-256 e3cfab71650b7e3dddd9d432d21304b1d4b98117327b97c56d024032af8fddb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.2-cp311-cp311-win_amd64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 77e073133c031ea5003580a857951193d2e60447151cb49839a4c37c8a09d4b7
MD5 7c264cf2811bfef27bb3702b83c9d601
BLAKE2b-256 1c57de295373236fd7132484c69347c6bbbab002f064ba69b01c66d66b969037

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f8d803f66da0d0bc3d48bfcb14a1ea3578bb1d7eef855b8baddc6ca0d6c1aa26
MD5 8a024dcff8b511c936d459c801233416
BLAKE2b-256 3c51acfb50e5ed1436f93bfe81bf153dc0cd2b8c697ebfda1380a499e12f9989

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.2-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 11262961b4dd41f0cabc04160a968c1d1b16729eedc553a6a6e5615eccd44ade
MD5 cd9d9fd8305ebe7f6ff2dc4ef3fa5907
BLAKE2b-256 ad208dede3ffc40e169009f95142ef2e62e7bc3eff5c96290e57a0b3590bf303

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.2-cp311-cp311-macosx_10_9_x86_64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page