Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ condaEnvPython/
logs/
chroma_db/
newTestPython/
/venv
112 changes: 112 additions & 0 deletions MCP_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Model Context Protocol (MCP) Implementation for Angel Stylus Coding Assistant

## Overview

This document describes the Model Context Protocol (MCP) implementation in the Angel Stylus Coding Assistant. MCP enables the assistant to maintain context across multiple interactions, providing more coherent and contextually-aware responses to user queries.

## What is MCP?

Model Context Protocol (MCP) is a framework that allows AI models to understand and process context effectively across interactions. It ensures that models can:

- **Remember past interactions** - Maintaining conversation history to provide consistent responses
- **Connect related information** - Understanding references to previously mentioned topics
- **Provide personalized responses** - Tailoring answers based on the user's conversation history
- **Enhance continuity** - Creating a more natural, flowing conversation experience

## How MCP is Implemented in Angel Stylus

### Core Components

1. **MCPHandler Class** (`mcp_handler.py`)
- Manages conversation sessions and context storage
- Provides methods to create, retrieve, and update conversation contexts
- Handles conversation history formatting for LLM prompts

2. **Session Management**
- Each conversation is assigned a unique session ID
- Context is maintained across multiple messages within a session
- Sessions can be created, retrieved, and updated via the API

3. **Context Storage**
- Contexts are stored both in memory (for fast access) and on disk (for persistence)
- JSON-based storage format for easy debugging and portability
- Automatic context retrieval when continuing a conversation

4. **API Integration**
- REST API endpoints support session-based conversations
- Session IDs can be provided by clients or generated automatically
- Response includes the session ID for future interactions

## Usage

### API Usage

```python
# Example API request with session ID
import requests
import json

# First request (no session ID)
response1 = requests.post(
"http://localhost:8001/stylus-chat",
json={
"model": "llama3.1:8b",
"prompt": "What is Stylus?"
}
).json()

# Get the session ID from the response
session_id = response1["session_id"]
print(f"Response: {response1['response']}")

# Second request (with session ID)
response2 = requests.post(
"http://localhost:8001/stylus-chat",
json={
"model": "llama3.1:8b",
"prompt": "What programming languages can I use with it?",
"session_id": session_id
}
).json()

print(f"Response: {response2['response']}")

# Get conversation history
history = requests.get(f"http://localhost:8001/conversation-history/{session_id}").json()
print(f"Conversation history: {history['history']}")
```

### Web Interface

The Streamlit web interface automatically manages MCP sessions:

1. Each browser session gets a unique MCP session ID
2. Conversation history is maintained as you chat
3. The "New Conversation" button in the sidebar clears the history and starts a new session

## Testing

To test the MCP implementation, run:

```bash
python test_mcp.py
```

This script simulates a conversation with multiple turns and displays the conversation history maintained by MCP.

## Limitations

1. **Session Expiration**: Currently, sessions are stored indefinitely. In production, consider adding session expiration.
2. **Memory Usage**: For production use with many users, consider optimizing the in-memory cache.
3. **Token Limits**: Very long conversations may exceed the LLM's context window. The system currently limits to the 5 most recent interactions.

## Future Improvements

1. **Session Expiration**: Add automatic expiration for inactive sessions
2. **Advanced Context Management**: Implement smarter context selection beyond the recent message limit
3. **User Authentication**: Add user authentication to associate sessions with specific users
4. **Context Compression**: Implement techniques to compress context for more efficient storage and retrieval

## Conclusion

The MCP implementation enhances the Angel Stylus Coding Assistant by enabling it to maintain context across interactions, providing a more natural and helpful conversation experience. Users can now refer to previous questions and answers without needing to repeat information, making the assistant more efficient and user-friendly.
151 changes: 151 additions & 0 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Quick Start Guide - Angel Stylus Coding Assistant with MCP

Get the MCP-enabled Angel Stylus Coding Assistant up and running in minutes!

## Prerequisites

1. **Python 3.9+** - [Download here](https://python.org/downloads/)
2. **Ollama** (optional, for LLM functionality) - [Download here](https://ollama.ai/)

## Quick Setup (Automatic)

### Option 1: One-Click Start (Recommended)

**For Linux/macOS:**
```bash
./start.sh
```

**For Windows:**
```batch
start.bat
```

### Option 2: Manual Python Run
```bash
python3 run_mcp_assistant.py
```

This will automatically:
- ✅ Check Python version
- ✅ Install dependencies
- ✅ Set up required directories
- ✅ Initialize the ChromaDB database
- ✅ Check Ollama installation
- 🎯 Present menu options to run the assistant

## What You'll See

```
🤖 Angel Stylus Coding Assistant with MCP Support
============================================================
✅ Python version: 3.11.x
✅ Created directory: mcp_contexts
✅ Created directory: logs
✅ Created directory: chroma_db
📦 Installing dependencies...
✅ Dependencies installed successfully!
🗄️ Setting up database...
✅ Database setup completed
✅ Ollama is installed and running
Available models:
- llama3.1:8b
- deepseek-r1:7b

============================================================
🎯 What would you like to do?
1. Run API server (http://localhost:8001)
2. Run web interface (http://localhost:8501)
3. Run both API server and web interface
4. Test MCP functionality
5. Run API client example
6. Exit
```

## Usage Options

### 1. Web Interface (Easiest)
- Choose option **2** or **3**
- Open browser to `http://localhost:8501`
- Start chatting with the MCP-enabled assistant!

### 2. API Server
- Choose option **1** or **3**
- API available at `http://localhost:8001`
- Use the provided client examples or your own HTTP client

### 3. Test MCP Functionality
- Choose option **4**
- Runs automated tests to verify MCP context retention works

## First Conversation Example

**User:** "What is Stylus?"

**Assistant:** "Stylus is a framework for writing Arbitrum smart contracts in Rust..."

**User:** "How do I install it?" *(Note: Assistant remembers the previous context)*

**Assistant:** "To install Stylus (which we just discussed), you can..."

The assistant now remembers your conversation and provides contextual responses!

## Manual Setup (If Needed)

If the automatic setup doesn't work:

1. **Install dependencies:**
```bash
pip install -r requirements_mcp.txt
```

2. **Setup database:**
```bash
python setup_database.py
```

3. **Install Ollama models:**
```bash
ollama pull llama3.1:8b
ollama pull deepseek-r1:7b
```

4. **Run the assistant:**
```bash
python main.py # For API server
# OR
streamlit run pages/assistant.py # For web interface
```

## Troubleshooting

### "Ollama not found"
- Install Ollama from https://ollama.ai/
- Pull at least one model: `ollama pull llama3.1:8b`

### "Module not found" errors
- Run: `pip install -r requirements_mcp.txt`
- Ensure you're using Python 3.9+

### Database issues
- Delete `chroma_db` folder and run setup again
- Run: `python setup_database.py`

### Port already in use
- Change ports in the startup script
- Or kill existing processes on ports 8001/8501

## What Makes This Special?

🧠 **Memory**: Unlike regular chatbots, this assistant remembers your conversation
🔄 **Context**: References to "it", "that", "the previous example" work perfectly
📚 **Knowledge**: Built on official Stylus documentation
🔧 **Flexible**: Use via web interface, API, or integrate into your own apps

## Next Steps

- Read [MCP_README.md](MCP_README.md) for detailed MCP implementation
- Check [README.md](README.md) for complete project documentation
- Explore the API with [mcp_api_client.py](mcp_api_client.py)

Happy coding with Stylus! 🚀
22 changes: 21 additions & 1 deletion chroma_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,30 @@
from analyze_prompt import get_filters_wrapper
from logger import log_info

class OllamaEmbeddingFunction:
"""Custom embedding function for ChromaDB using Ollama."""

def __call__(self, input):
"""Generate embeddings for input texts."""
import ollama

if isinstance(input, str):
input = [input]

embeddings = []
for text in input:
result = ollama.embeddings(model="nomic-embed-text", prompt=text)
embeddings.append(result["embedding"])
return embeddings

chroma_client = chromadb.PersistentClient(path="./chroma_db")

collection = chroma_client.get_or_create_collection(name="stylus_data")
# Use the same embedding function as setup_database.py
embedding_function = OllamaEmbeddingFunction()
collection = chroma_client.get_or_create_collection(
name="stylus_data",
embedding_function=embedding_function
)

def get_prompt_embedding(user_prompt):
return ollama.embeddings(model="nomic-embed-text", prompt=user_prompt)["embedding"]
Expand Down
37 changes: 19 additions & 18 deletions llm_main_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def join_chunks_limited(chunks, max_chars=10000):
combined += chunk + "\n\n"
return combined.strip()

def stylus_request_with_llm(model, user_prompt):
def stylus_request_with_llm(model, user_prompt, conversation_history=""):
docs = get_chroma_documents(user_prompt)

if not docs:
Expand All @@ -20,11 +20,13 @@ def stylus_request_with_llm(model, user_prompt):
The user asked: "{user_prompt}"

No relevant content was retrieved for this question — either because:
– The docs dont cover this topic yet
– The docs don't cover this topic yet
– The question was too vague
– Or it's outside the scope of Stylus (e.g. generic Solidity, unrelated tooling, etc.)

⚠️ You are not keeping track of any previous messages. If the user's question seems to refer to something from earlier, let them know you don't have access to that context and ask them to clarify.
⚠️ You are keeping track of previous messages using MCP (Model Context Protocol). If the user's question seems to reference something from earlier, check the conversation history provided below.

{conversation_history}

Keep your response short and direct.

Expand All @@ -33,25 +35,34 @@ def stylus_request_with_llm(model, user_prompt):
– Which tool they're using (Rust SDK, Rust CLI, etc.)
– The actual command or error they're dealing with

If they already provided enough detail and we just dont have docs for it yet, tell them that clearly. Suggest they rephrase or check back later — the docs are still growing.
If they already provided enough detail and we just don't have docs for it yet, tell them that clearly. Suggest they rephrase or check back later — the docs are still growing.

⚠️ Do **not** make anything up. If it's not in the docs, just say that.
"""

return call_llm(fallback_prompt, user_prompt, model)
response = call_llm(fallback_prompt, user_prompt, model)
return response, []

context = join_chunks_limited(docs)

formatted_prompt = f"""
You are a developer assistant for Stylus (Arbitrum), helping users by answering technical questions based strictly on the official documentation.

This is a Retrieval-Augmented Generation (RAG) system. The information provided below was automatically retrieved from the official Stylus documentation, based on the user's question.

Only use the information in the context below. Do **not** rely on any prior knowledge or external sources. If the context includes a URL, you may include it in your response — otherwise, never guess or generate links.

⚠️ Important:
- You are using MCP (Model Context Protocol) to maintain conversation context across interactions
- Previous conversation history is provided below, use it to provide coherent responses
- If the user refers to something from a previous message, check the conversation history

--- CONVERSATION HISTORY ---
{conversation_history}
--- END OF CONVERSATION HISTORY ---

If the context doesn't contain the necessary information to answer the question, say:
"I'm sorry, I couldnt find specific information to help with that right now. The docs are still evolving — feel free to check back later."
"I'm sorry, I couldn't find specific information to help with that right now. The docs are still evolving — feel free to check back later."

Your tone should be direct, clear, and practical — like a developer helping another developer. No fluff, no guessing.

Expand All @@ -60,15 +71,5 @@ def stylus_request_with_llm(model, user_prompt):
--- END OF CONTEXT ---
"""



#response = call_llm(formatted_prompt, user_prompt,"qwen2.5:32b")
#log_info("calling llm now")
response = call_llm(formatted_prompt, user_prompt, model)
return response


#print(plan_trip_with_llm("what information is available for traveling with a dog to France namely about Documents?"))
#print(plan_trip_with_llm("I'll be travelling to France with my cat what usefull tips can you give me?"))
#print(plan_trip_with_llm("Can I travel by ferry from uk to france with my cat?"))
#print(plan_trip_with_llm("I will travel to france with my cat is there any concerns regarding border stuff?"))
return response, docs
Loading