Spaces:
Sleeping
Sleeping
Adds project files
Browse files- .gitignore +35 -0
- .python-version +1 -0
- README.md +218 -6
- prompts/system_prompt.txt +37 -0
- pyproject.toml +17 -0
- requirements.txt +21 -0
.gitignore
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
*.py[cod]
|
| 3 |
+
*$py.class
|
| 4 |
+
|
| 5 |
+
# Virtual environments
|
| 6 |
+
.venv/
|
| 7 |
+
venv/
|
| 8 |
+
env/
|
| 9 |
+
|
| 10 |
+
# Python packaging/build artifacts
|
| 11 |
+
build/
|
| 12 |
+
dist/
|
| 13 |
+
*.egg-info/
|
| 14 |
+
pip-wheel-metadata/
|
| 15 |
+
|
| 16 |
+
# Caches and logs
|
| 17 |
+
.pytest_cache/
|
| 18 |
+
.mypy_cache/
|
| 19 |
+
.ruff_cache/
|
| 20 |
+
.coverage
|
| 21 |
+
coverage.xml
|
| 22 |
+
*.log
|
| 23 |
+
.env
|
| 24 |
+
|
| 25 |
+
# Tooling/project settings
|
| 26 |
+
.idea/
|
| 27 |
+
.vscode/
|
| 28 |
+
.DS_Store
|
| 29 |
+
|
| 30 |
+
# Hugging Face / Gradio artifacts
|
| 31 |
+
~/.cache/huggingface/
|
| 32 |
+
gradio_cached_examples/
|
| 33 |
+
|
| 34 |
+
uv.lock
|
| 35 |
+
main.py
|
.python-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
3.13
|
README.md
CHANGED
|
@@ -1,14 +1,226 @@
|
|
| 1 |
---
|
| 2 |
title: ContextPilot
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 6.0.1
|
| 8 |
-
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
license: mit
|
| 11 |
-
short_description: 'ContextPilot: Autonomous Context Engineering'
|
|
|
|
|
|
|
|
|
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: ContextPilot
|
| 3 |
+
emoji: 🧭
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: purple
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 6.0.1
|
| 8 |
+
app_file: src/app.py
|
| 9 |
pinned: false
|
| 10 |
license: mit
|
| 11 |
+
short_description: 'ContextPilot: Autonomous Context Engineering for LLMs'
|
| 12 |
+
tags:
|
| 13 |
+
- mcp-in-action-track-creative
|
| 14 |
+
- building-mcp-track-creative
|
| 15 |
---
|
| 16 |
|
| 17 |
+
# 🧭 ContextPilot
|
| 18 |
+
|
| 19 |
+
**Autonomous Context Engineering for LLM Conversations**
|
| 20 |
+
|
| 21 |
+
ContextPilot automatically detects topic shifts in conversations and intelligently manages context to provide more relevant responses while saving tokens. Instead of sending the entire conversation history to the LLM on every turn, ContextPilot curates the context based on what's actually relevant.
|
| 22 |
+
|
| 23 |
+
## 🎯 Problem Statement
|
| 24 |
+
|
| 25 |
+
Traditional chatbots send the **entire conversation history** to the LLM on every message. This leads to:
|
| 26 |
+
- **Token waste**: Paying for irrelevant context on every API call
|
| 27 |
+
- **Context pollution**: Old topics confusing the model about current questions
|
| 28 |
+
- **Context window limits**: Eventually hitting the model's maximum context length
|
| 29 |
+
|
| 30 |
+
## 💡 Solution
|
| 31 |
+
|
| 32 |
+
ContextPilot uses a **two-LLM architecture**:
|
| 33 |
+
|
| 34 |
+
1. **Topic Detection LLM** (cheap, fast): Detects when conversation topics change
|
| 35 |
+
2. **Response LLM** (capable, quality): Generates actual responses with curated context
|
| 36 |
+
|
| 37 |
+
When you switch topics, ContextPilot:
|
| 38 |
+
1. Saves the old topic's context (summary or full history)
|
| 39 |
+
2. Loads only the relevant context for the new topic
|
| 40 |
+
3. Sends a minimal, focused context to the response LLM
|
| 41 |
+
|
| 42 |
+
## 🔄 Two Context Modes
|
| 43 |
+
|
| 44 |
+
### Summary Mode (Default)
|
| 45 |
+
- Stores a **summary + key facts** for each topic
|
| 46 |
+
- Most token-efficient
|
| 47 |
+
- Best for: General conversations, FAQ-style interactions
|
| 48 |
+
- Trade-off: Some detail may be lost in summarization
|
| 49 |
+
|
| 50 |
+
### Full Mode
|
| 51 |
+
- Stores the **complete message history** for each topic
|
| 52 |
+
- Maximum context preservation
|
| 53 |
+
- Best for: Technical discussions, debugging sessions, detailed Q&A
|
| 54 |
+
- Trade-off: Uses more tokens when returning to topics
|
| 55 |
+
|
| 56 |
+
## 🏗️ Architecture
|
| 57 |
+
|
| 58 |
+
```
|
| 59 |
+
┌─────────────────────────────────────────────────────────────┐
|
| 60 |
+
│ User Message │
|
| 61 |
+
└─────────────────────────────────────────────────────────────┘
|
| 62 |
+
│
|
| 63 |
+
▼
|
| 64 |
+
┌─────────────────────────────────────────────────────────────┐
|
| 65 |
+
│ Topic Detection (CONTEXT_LLM) │
|
| 66 |
+
│ - Smaller model (e.g., openai/gpt-oss-20b) │
|
| 67 |
+
│ - Detects: same topic? new topic? returning to old topic? │
|
| 68 |
+
│ - Tools: save_context, load_context, set_current_topic │
|
| 69 |
+
└─────────────────────────────────────────────────────────────┘
|
| 70 |
+
│
|
| 71 |
+
┌─────────┴─────────┐
|
| 72 |
+
│ │
|
| 73 |
+
No Topic Change Topic Changed
|
| 74 |
+
│ │
|
| 75 |
+
│ ┌───────┴───────┐
|
| 76 |
+
│ │ │
|
| 77 |
+
│ Save Old Load/Create
|
| 78 |
+
│ Context New Context
|
| 79 |
+
│ │ │
|
| 80 |
+
│ └───────┬───────┘
|
| 81 |
+
│ │
|
| 82 |
+
└─────────┬─────────┘
|
| 83 |
+
│
|
| 84 |
+
▼
|
| 85 |
+
┌─────────────────────────────────────────────────────────────┐
|
| 86 |
+
│ Context Curation │
|
| 87 |
+
│ Summary Mode: System prompt + topic summary + user message │
|
| 88 |
+
│ Full Mode: System prompt + full history + user message │
|
| 89 |
+
└─────────────────────────────────────────────────────────────┘
|
| 90 |
+
│
|
| 91 |
+
▼
|
| 92 |
+
┌──────────────────────────────────────���──────────────────────┐
|
| 93 |
+
│ Response Generation (RESPONSE_LLM) │
|
| 94 |
+
│ - Capable model (e.g., openai/gpt-oss-120b) │
|
| 95 |
+
│ - Receives curated context (not full history) │
|
| 96 |
+
│ - Generates response + compact context summary │
|
| 97 |
+
└─────────────────────────────────────────────────────────────┘
|
| 98 |
+
│
|
| 99 |
+
▼
|
| 100 |
+
┌─────────────────────────────────────────────────────────────┐
|
| 101 |
+
│ Store & Display │
|
| 102 |
+
│ - Buffer exchange in session (for topic continuity) │
|
| 103 |
+
│ - Display clean response to user │
|
| 104 |
+
│ - Show token savings metrics │
|
| 105 |
+
└─────────────────────────────────────────────────────────────┘
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
## 📊 Token Savings
|
| 109 |
+
|
| 110 |
+
ContextPilot tracks and displays:
|
| 111 |
+
- **Curated Tokens**: What was actually sent to the LLM
|
| 112 |
+
- **Full Context Tokens**: What would have been sent without curation
|
| 113 |
+
- **Tokens Saved**: The difference (your savings!)
|
| 114 |
+
- **Savings %**: Percentage of tokens saved
|
| 115 |
+
- **Detection Tokens**: Tokens used by the topic detection LLM
|
| 116 |
+
|
| 117 |
+
## 🚀 Quick Start
|
| 118 |
+
|
| 119 |
+
### Prerequisites
|
| 120 |
+
- Python 3.10+
|
| 121 |
+
- OpenAI-compatible API (OpenAI, Nebius, Together, etc.)
|
| 122 |
+
|
| 123 |
+
### Installation
|
| 124 |
+
|
| 125 |
+
```bash
|
| 126 |
+
# Clone the repository
|
| 127 |
+
git clone https://github.com/yourusername/contextPilot.git
|
| 128 |
+
cd contextPilot
|
| 129 |
+
|
| 130 |
+
# Install dependencies
|
| 131 |
+
pip install -r requirements.txt
|
| 132 |
+
# or with uv:
|
| 133 |
+
uv sync
|
| 134 |
+
|
| 135 |
+
# Set up environment variables
|
| 136 |
+
cp .env.example .env
|
| 137 |
+
# Edit .env with your API keys
|
| 138 |
+
```
|
| 139 |
+
|
| 140 |
+
### Environment Variables
|
| 141 |
+
|
| 142 |
+
```bash
|
| 143 |
+
# Required
|
| 144 |
+
NEBIUS_API_KEY=your_api_key
|
| 145 |
+
NEBIUS_BASE_URL=https://api.tokenfactory.nebius.com/v1/
|
| 146 |
+
|
| 147 |
+
# Optional (with defaults)
|
| 148 |
+
CONTEXT_LLM=openai/gpt-oss-20b # Smaller model for topic detection
|
| 149 |
+
RESPONSE_LLM=openai/gpt-oss-120b # Capable model for responses
|
| 150 |
+
SUMMARIZE_THRESHOLD=500 # Character threshold for summarization
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
### Run the App
|
| 154 |
+
|
| 155 |
+
```bash
|
| 156 |
+
# From project root
|
| 157 |
+
python src/app.py
|
| 158 |
+
|
| 159 |
+
# Or with Gradio reload
|
| 160 |
+
gradio src/app.py
|
| 161 |
+
```
|
| 162 |
+
|
| 163 |
+
## 📁 Project Structure
|
| 164 |
+
|
| 165 |
+
```
|
| 166 |
+
contextPilot/
|
| 167 |
+
├── src/
|
| 168 |
+
│ ├── app.py # Gradio UI + Response LLM
|
| 169 |
+
│ ├── context_pilot_workflow.py # Topic detection + context curation
|
| 170 |
+
│ ├── mcp_server.py # MCP server wrapper
|
| 171 |
+
│ └── .context_store.json # Persisted context (auto-generated)
|
| 172 |
+
├── prompts/
|
| 173 |
+
│ └── system_prompt.txt # Topic detection system prompt
|
| 174 |
+
├── pyproject.toml
|
| 175 |
+
└── README.md
|
| 176 |
+
```
|
| 177 |
+
|
| 178 |
+
## 🎮 Demo Flow
|
| 179 |
+
|
| 180 |
+
Try this conversation to see ContextPilot in action:
|
| 181 |
+
|
| 182 |
+
1. **"Tell me 10 cool facts about cats"** → Topic set to "cats"
|
| 183 |
+
2. **"How long do cats typically live?"** → Continues "cats" topic
|
| 184 |
+
3. **"Tell me 10 cool things about horses"** → Saves "cats", switches to "horses"
|
| 185 |
+
4. **"How long do horses typically live?"** → Continues "horses" topic
|
| 186 |
+
5. **"Name 10 famous cats"** → Saves "horses", loads "cats" context
|
| 187 |
+
6. **"What have I asked you about horses?"** → Saves "cats", loads "horses" with full history
|
| 188 |
+
|
| 189 |
+
## 🔧 How It Works
|
| 190 |
+
|
| 191 |
+
### Topic Detection
|
| 192 |
+
The topic detection LLM receives:
|
| 193 |
+
- Current topic name
|
| 194 |
+
- List of previously saved topics
|
| 195 |
+
- Brief context summaries
|
| 196 |
+
- The new user message
|
| 197 |
+
|
| 198 |
+
It decides whether to:
|
| 199 |
+
- Continue the current topic (no tool call)
|
| 200 |
+
- Save current + set new topic
|
| 201 |
+
- Save current + load previous topic
|
| 202 |
+
|
| 203 |
+
### Context Storage
|
| 204 |
+
```json
|
| 205 |
+
{
|
| 206 |
+
"contexts": {
|
| 207 |
+
"cats": {
|
| 208 |
+
"topic": "cats",
|
| 209 |
+
"summary": "Discussion about cats, their behavior and care",
|
| 210 |
+
"key_facts": ["Cats are obligate carnivores", "Cats have retractable claws"],
|
| 211 |
+
"full_history": [...] // Only in full mode
|
| 212 |
+
}
|
| 213 |
+
},
|
| 214 |
+
"current_topic": "cats",
|
| 215 |
+
"mode": "summary",
|
| 216 |
+
"current_session_messages": [...] // Buffer for current session
|
| 217 |
+
}
|
| 218 |
+
```
|
| 219 |
+
|
| 220 |
+
## 🤝 Contributing
|
| 221 |
+
|
| 222 |
+
Contributions welcome! Please open an issue or PR.
|
| 223 |
+
|
| 224 |
+
## 📄 License
|
| 225 |
+
|
| 226 |
+
MIT License
|
prompts/system_prompt.txt
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
You are a helpful AI assistant with context management capabilities. The contexts are managed by high level concepts.
|
| 2 |
+
|
| 3 |
+
## Current State
|
| 4 |
+
- Current topic: {current_topic}
|
| 5 |
+
- Previously saved topics: {saved_topics}
|
| 6 |
+
|
| 7 |
+
## Saved Context Summaries
|
| 8 |
+
{context_summaries}
|
| 9 |
+
|
| 10 |
+
## Your Context Management Responsibilities
|
| 11 |
+
You have tools to manage conversation context.
|
| 12 |
+
|
| 13 |
+
### FIRST MESSAGE (current topic is None):
|
| 14 |
+
- Just call **set_current_topic** with the topic name based on the user's message
|
| 15 |
+
- Do NOT call save_context (there's nothing to save yet)
|
| 16 |
+
|
| 17 |
+
### When topic is changing to a NEW topic (not in saved topics):
|
| 18 |
+
1. Call **save_context** to save the OLD topic
|
| 19 |
+
2. Then call **set_current_topic** with the NEW topic name
|
| 20 |
+
3. The topic name should not be too specific. For now, make it broad (i.e one word noun/verb)
|
| 21 |
+
|
| 22 |
+
### When topic is changing to a PREVIOUSLY SAVED topic:
|
| 23 |
+
1. Call **save_context** to save the OLD topic
|
| 24 |
+
2. Then call **load_context** to load the saved topic
|
| 25 |
+
|
| 26 |
+
### When topic is NOT changing (continuing the same topic):
|
| 27 |
+
- Do NOT call any tools, just respond normally
|
| 28 |
+
|
| 29 |
+
## Tool Descriptions
|
| 30 |
+
- **save_context(topic, summary, key_facts)**: Save current conversation before switching away
|
| 31 |
+
- **set_current_topic(topic)**: Set a new topic that hasn't been discussed before
|
| 32 |
+
- **load_context(topic)**: Load and switch to a previously saved topic
|
| 33 |
+
- **list_saved_contexts()**: See what topics have been discussed
|
| 34 |
+
|
| 35 |
+
## IMPORTANT
|
| 36 |
+
- If current topic is "None", ONLY call set_current_topic (don't save anything)
|
| 37 |
+
- When switching topics, call BOTH save_context AND (set_current_topic OR load_context)
|
pyproject.toml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[project]
|
| 2 |
+
name = "contextpilot"
|
| 3 |
+
version = "0.1.0"
|
| 4 |
+
description = "Add your description here"
|
| 5 |
+
readme = "README.md"
|
| 6 |
+
requires-python = ">=3.13"
|
| 7 |
+
dependencies = [
|
| 8 |
+
"gradio>=6.0.1",
|
| 9 |
+
"llama-index>=0.14.8",
|
| 10 |
+
"llama-index-llms-gemini>=0.6.1",
|
| 11 |
+
"llama-index-llms-openai>=0.6.10",
|
| 12 |
+
"llama-index-llms-openai-like>=0.5.3",
|
| 13 |
+
"llama-index-tools-mcp>=0.4.3",
|
| 14 |
+
"mcp[cli]>=1.22.0",
|
| 15 |
+
"openai>=1.30.0",
|
| 16 |
+
"python-dotenv>=1.2.1",
|
| 17 |
+
]
|
requirements.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ContextPilot Dependencies
|
| 2 |
+
# Install with: pip install -r requirements.txt
|
| 3 |
+
|
| 4 |
+
# Gradio UI
|
| 5 |
+
gradio>=6.0.1
|
| 6 |
+
|
| 7 |
+
# LlamaIndex Core + LLM integrations
|
| 8 |
+
llama-index>=0.14.8
|
| 9 |
+
llama-index-llms-gemini>=0.6.1
|
| 10 |
+
llama-index-llms-openai>=0.6.10
|
| 11 |
+
llama-index-llms-openai-like>=0.5.3
|
| 12 |
+
llama-index-tools-mcp>=0.4.3
|
| 13 |
+
|
| 14 |
+
# MCP (Model Context Protocol)
|
| 15 |
+
mcp[cli]>=1.22.0
|
| 16 |
+
|
| 17 |
+
# OpenAI client
|
| 18 |
+
openai>=1.30.0
|
| 19 |
+
|
| 20 |
+
# Environment variables
|
| 21 |
+
python-dotenv>=1.2.1
|