A newer version of the Gradio SDK is available:
6.1.0
MVP 2 - Sprint 1: Define Prompt Ontology & Enhance KG for Prompts
Sprint Created: 2025-06-08
Builds Upon: MVP 1 (Successfully Completed - 100%)
Sprint Duration: 3-4 hours
Priority: HIGH (Foundation for all MVP 2 development)
Development Environment: Claude 4.0 + Cursor IDE
π― Sprint 1 Objectives
Primary Goals
- Define MCPPrompt Ontology - Create comprehensive data structure for prompt templates
- Create Rich Prompt Metadata - Build sample prompt dataset for testing and demonstration
- Extend InMemoryKG for Prompts - Add structured prompt storage and retrieval
- Implement Prompt Vector Indexing - Enable semantic search across prompt templates
- Update Application Initialization - Integrate prompt loading into startup process
Success Criteria
- MCPPrompt dataclass defined with comprehensive fields
- 4+ diverse prompt templates created in JSON format
- InMemoryKG enhanced for dual tool+prompt management
- Vector indexing supports both tools and prompts seamlessly
- Application startup includes prompt loading and indexing
- All new functionality covered by unit tests (20+ new tests)
- No regression in existing MVP 1 functionality
- All quality checks passing (lint, format, type-check, test)
π Task Breakdown
Task 1: Define MCPPrompt Ontology & Associated Tests
Estimated Time: 60-75 minutes
Priority: HIGH
Dependencies: None
Sub-Task 1.1: Create MCPPrompt Dataclass
- Status: Todo
- Estimated Time: 30-45 minutes
- Description: Define comprehensive MCPPrompt dataclass with all required fields
- Acceptance Criteria:
- MCPPrompt dataclass with proper type hints and defaults
- JSON serialization compatibility
- Validation for required fields
- Integration with existing ontology module
Claude/Cursor Prompt:
**TASK: Define MCPPrompt Dataclass and Initial Tests**
**Objective:** Create the foundational MCPPrompt dataclass and comprehensive unit tests.
**Action 1: Modify `kg_services/ontology.py`**
1. Open `@kg_services/ontology.py`
2. Add necessary imports if not present:
```python
from dataclasses import dataclass, field
from typing import List, Dict, Optional
- Below the existing
MCPTooldataclass, add a newMCPPromptdataclass with these fields:@dataclass class MCPPrompt: """Represents a prompt template for MCP tool usage.""" prompt_id: str name: str description: str target_tool_id: str # Links to MCPTool.tool_id template_string: str # Template with {{variable}} placeholders tags: List[str] = field(default_factory=list) input_variables: List[str] = field(default_factory=list) use_case: str = "" # Specific use case description difficulty_level: str = "beginner" # beginner, intermediate, advanced example_inputs: Dict[str, str] = field(default_factory=dict) # Example values def __post_init__(self): """Validate prompt data after initialization.""" if not self.prompt_id: raise ValueError("prompt_id cannot be empty") if not self.name: raise ValueError("name cannot be empty") if not self.target_tool_id: raise ValueError("target_tool_id cannot be empty") if not self.template_string: raise ValueError("template_string cannot be empty")
Action 2: Create/Update tests/kg_services/test_ontology.py
- Open or create
@tests/kg_services/test_ontology.py - Add comprehensive test methods:
def test_mcp_prompt_creation(): """Test MCPPrompt basic creation with all fields.""" prompt = MCPPrompt( prompt_id="test_prompt_v1", name="Test Prompt", description="A test prompt for validation", target_tool_id="test_tool_v1", template_string="Process this: {{input_text}}", tags=["test", "validation"], input_variables=["input_text"], use_case="Testing purposes", difficulty_level="beginner", example_inputs={"input_text": "sample text"} ) assert prompt.prompt_id == "test_prompt_v1" assert prompt.name == "Test Prompt" assert prompt.description == "A test prompt for validation" assert prompt.target_tool_id == "test_tool_v1" assert prompt.template_string == "Process this: {{input_text}}" assert prompt.tags == ["test", "validation"] assert prompt.input_variables == ["input_text"] assert prompt.use_case == "Testing purposes" assert prompt.difficulty_level == "beginner" assert prompt.example_inputs == {"input_text": "sample text"} def test_mcp_prompt_defaults(): """Test MCPPrompt creation with minimal required fields.""" prompt = MCPPrompt( prompt_id="minimal_prompt", name="Minimal Prompt", description="A minimal prompt", target_tool_id="tool_id", template_string="{{input}}" ) assert prompt.tags == [] assert prompt.input_variables == [] assert prompt.use_case == "" assert prompt.difficulty_level == "beginner" assert prompt.example_inputs == {} def test_mcp_prompt_validation(): """Test MCPPrompt validation in __post_init__.""" import pytest # Test empty prompt_id with pytest.raises(ValueError, match="prompt_id cannot be empty"): MCPPrompt(prompt_id="", name="Test", description="Test", target_tool_id="tool", template_string="{{input}}") # Test empty name with pytest.raises(ValueError, match="name cannot be empty"): MCPPrompt(prompt_id="test", name="", description="Test", target_tool_id="tool", template_string="{{input}}") # Test empty target_tool_id with pytest.raises(ValueError, match="target_tool_id cannot be empty"): MCPPrompt(prompt_id="test", name="Test", description="Test", target_tool_id="", template_string="{{input}}") # Test empty template_string with pytest.raises(ValueError, match="template_string cannot be empty"): MCPPrompt(prompt_id="test", name="Test", description="Test", target_tool_id="tool", template_string="")
Apply coding standards from @.cursor/rules/python_gradio_basic.mdc.
Generate the complete code for both files.
#### **Sub-Task 1.2: Create Rich Initial Prompt Metadata**
- **Status:** Todo
- **Estimated Time:** 45-60 minutes
- **Dependencies:** Sub-Task 1.1
- **Description:** Create comprehensive prompt dataset with diverse, high-quality templates
- **Acceptance Criteria:**
1. 6+ diverse prompt templates covering all MVP 1 tools
2. Multiple prompt styles per tool (concise, detailed, specialized)
3. Rich descriptions optimized for semantic embedding
4. Valid JSON structure matching MCPPrompt schema
**Claude/Cursor Prompt:**
```cursor
**TASK: Create Rich Initial Prompt Metadata**
**Objective:** Create a comprehensive `data/initial_prompts.json` file with diverse, high-quality prompt templates.
**Action: Create `data/initial_prompts.json`**
1. Create the file `@data/initial_prompts.json`
2. Structure as a JSON array containing 6 MCPPrompt objects
3. Ensure coverage of all tools from MVP 1:
- sentiment_analyzer_v1
- summarizer_v1
- image_caption_generator_stub_v1
- code_quality_linter_v1
4. Create multiple prompt styles for variety:
```json
[
{
"prompt_id": "sentiment_customer_feedback_v1",
"name": "Customer Feedback Sentiment Analysis",
"description": "Analyzes customer feedback for business insights, focusing on actionable sentiment patterns, emotional indicators, and customer satisfaction levels. Optimized for business decision-making.",
"target_tool_id": "sentiment_analyzer_v1",
"template_string": "Analyze the sentiment of this customer feedback and provide actionable business insights:\n\nCustomer Feedback: {{customer_feedback}}\n\nPlease provide:\n1. Overall sentiment (positive/negative/neutral) with confidence score\n2. Key emotional indicators and specific language patterns\n3. Actionable business insights and recommendations\n4. Areas for improvement based on the feedback",
"tags": ["sentiment", "customer", "business", "feedback", "analysis", "actionable"],
"input_variables": ["customer_feedback"],
"use_case": "Business customer feedback analysis for actionable insights",
"difficulty_level": "intermediate",
"example_inputs": {
"customer_feedback": "The product arrived late and the packaging was damaged, but the customer service team was very helpful in resolving the issue quickly. Overall satisfied but shipping needs improvement."
}
},
{
"prompt_id": "sentiment_social_media_v1",
"name": "Social Media Sentiment Monitor",
"description": "Quick sentiment analysis for social media posts, comments, and reviews. Focuses on immediate emotional tone detection and viral content assessment.",
"target_tool_id": "sentiment_analyzer_v1",
"template_string": "Analyze the sentiment of this social media content: {{social_content}}\n\nProvide: sentiment (positive/negative/neutral), intensity (low/medium/high), and key emotional words.",
"tags": ["sentiment", "social", "media", "quick", "viral", "emotions"],
"input_variables": ["social_content"],
"use_case": "Real-time social media monitoring and content moderation",
"difficulty_level": "beginner",
"example_inputs": {
"social_content": "Just tried the new coffee shop downtown - amazing latte art and perfect temperature! βοΈβ¨ #coffeelover"
}
},
{
"prompt_id": "summarizer_executive_v1",
"name": "Executive Summary Generator",
"description": "Creates concise executive summaries for business documents, reports, and lengthy content. Focuses on key decisions, financial impacts, and strategic recommendations.",
"target_tool_id": "summarizer_v1",
"template_string": "Create an executive summary of the following document:\n\n{{document_content}}\n\nExecutive Summary should include:\n- Key findings and conclusions\n- Critical decisions or recommendations\n- Financial or strategic impacts\n- Next steps or action items\n\nLimit to 3-4 bullet points maximum.",
"tags": ["summary", "executive", "business", "decisions", "strategic", "concise"],
"input_variables": ["document_content"],
"use_case": "Executive briefings and board presentations",
"difficulty_level": "advanced",
"example_inputs": {
"document_content": "Q3 Financial Report: Revenue increased 15% year-over-year to $2.3M, primarily driven by new product launches..."
}
},
{
"prompt_id": "summarizer_academic_v1",
"name": "Academic Research Summarizer",
"description": "Summarizes academic papers, research articles, and scholarly content with focus on methodology, findings, and implications for further research.",
"target_tool_id": "summarizer_v1",
"template_string": "Summarize this academic content with focus on research methodology and findings:\n\n{{research_content}}\n\nSummary should cover:\n1. Research question and methodology\n2. Key findings and data insights\n3. Implications and future research directions\n4. Limitations and considerations",
"tags": ["summary", "academic", "research", "methodology", "findings", "scholarly"],
"input_variables": ["research_content"],
"use_case": "Academic literature review and research synthesis",
"difficulty_level": "advanced",
"example_inputs": {
"research_content": "This study examined the impact of machine learning algorithms on natural language processing tasks using a dataset of 50,000 text samples..."
}
},
{
"prompt_id": "image_caption_detailed_v1",
"name": "Detailed Image Caption Generator",
"description": "Generates comprehensive, descriptive captions for images with focus on visual elements, composition, context, and accessibility. Suitable for detailed documentation and accessibility purposes.",
"target_tool_id": "image_caption_generator_stub_v1",
"template_string": "Generate a detailed, descriptive caption for this image:\n\nImage: {{image_reference}}\n\nInclude:\n- Main subjects and objects in the scene\n- Setting, lighting, and composition details\n- Colors, textures, and visual style\n- Any text or signage visible\n- Overall mood or atmosphere\n\nMake it accessible and informative for visually impaired users.",
"tags": ["image", "caption", "detailed", "accessibility", "descriptive", "visual", "documentation"],
"input_variables": ["image_reference"],
"use_case": "Accessibility compliance and detailed image documentation",
"difficulty_level": "intermediate",
"example_inputs": {
"image_reference": "A photograph of a busy coffee shop interior with customers at wooden tables"
}
},
{
"prompt_id": "code_review_security_v1",
"name": "Security-Focused Code Review",
"description": "Performs comprehensive code quality analysis with emphasis on security vulnerabilities, best practices, and maintainability. Provides actionable recommendations for improvement.",
"target_tool_id": "code_quality_linter_v1",
"template_string": "Review this code for quality and security issues:\n\n```{{programming_language}}\n{{code_content}}\n```\n\nProvide analysis for:\n1. Security vulnerabilities and potential exploits\n2. Code quality and maintainability issues\n3. Performance optimization opportunities\n4. Best practice violations\n5. Specific recommendations for improvement\n\nPrioritize security concerns and provide actionable fixes.",
"tags": ["code", "review", "security", "quality", "vulnerability", "best-practices", "maintainability"],
"input_variables": ["programming_language", "code_content"],
"use_case": "Security audits and code quality assurance for production systems",
"difficulty_level": "advanced",
"example_inputs": {
"programming_language": "python",
"code_content": "def authenticate_user(username, password):\n if username == 'admin' and password == 'password123':\n return True\n return False"
}
}
]
Ensure:
- All prompt_ids are unique
- All target_tool_ids match existing tools from MVP 1
- Descriptions are rich and suitable for semantic embedding
- Templates use clear {{variable}} syntax
- Example inputs are realistic and helpful
- Difficulty levels are appropriately assigned
---
### **Task 2: Extend InMemoryKG for Prompts (Structured & Vector Parts)**
**Estimated Time:** 90-120 minutes
**Priority:** HIGH
**Dependencies:** Task 1 completion
#### **Sub-Task 2.1: Add Prompt Storage and Retrieval (Structured)**
- **Status:** Todo
- **Estimated Time:** 45-60 minutes
- **Dependencies:** Sub-Task 1.2
- **Description:** Extend InMemoryKG to handle MCPPrompt objects for structured storage and retrieval
- **Acceptance Criteria:**
1. Prompt loading from JSON with error handling
2. Prompt retrieval by ID and by tool ID
3. Integration with existing KG structure
4. Comprehensive unit test coverage
**Claude/Cursor Prompt:**
```cursor
**TASK: Extend InMemoryKG for Structured Prompt Storage and Retrieval**
**Objective:** Modify `InMemoryKG` to handle loading, storing, and retrieving `MCPPrompt` objects alongside existing tool functionality.
**Action 1: Modify `kg_services/knowledge_graph.py`**
1. Open `@kg_services/knowledge_graph.py`
2. Add import for MCPPrompt:
```python
from .ontology import MCPTool, MCPPrompt
- In
InMemoryKG.__init__method, add:self.prompts: Dict[str, MCPPrompt] = {} - Add new method
load_prompts_from_json:def load_prompts_from_json(self, filepath: str) -> None: """Load MCPPrompt objects from JSON file.""" try: with open(filepath, 'r', encoding='utf-8') as f: prompts_data = json.load(f) self.prompts.clear() # Clear existing prompts for prompt_data in prompts_data: prompt = MCPPrompt(**prompt_data) self.prompts[prompt.prompt_id] = prompt print(f"Loaded {len(self.prompts)} prompts into structured KG.") except FileNotFoundError: print(f"Warning: Prompt file '{filepath}' not found. No prompts loaded.") except json.JSONDecodeError as e: print(f"Warning: Invalid JSON in prompt file '{filepath}': {e}. No prompts loaded.") except Exception as e: print(f"Warning: Error loading prompts from '{filepath}': {e}. No prompts loaded.") - Add new method
get_prompt_by_id:def get_prompt_by_id(self, prompt_id: str) -> Optional[MCPPrompt]: """Retrieve prompt by ID.""" return self.prompts.get(prompt_id) - Add new method
get_prompts_for_tool:def get_prompts_for_tool(self, tool_id: str) -> List[MCPPrompt]: """Get all prompts targeting a specific tool.""" return [prompt for prompt in self.prompts.values() if prompt.target_tool_id == tool_id]
Action 2: Update tests/kg_services/test_knowledge_graph.py
- Open
@tests/kg_services/test_knowledge_graph.py - Add import for MCPPrompt:
from kg_services.ontology import MCPTool, MCPPrompt - Add test methods:
def test_kg_initialization_includes_prompts(): """Test that InMemoryKG initializes with empty prompts dictionary.""" kg = InMemoryKG() assert isinstance(kg.prompts, dict) assert len(kg.prompts) == 0 def test_load_prompts_from_json_success(tmp_path): """Test successful loading of prompts from JSON.""" kg = InMemoryKG() # Create test prompt data test_prompts = [ { "prompt_id": "test_prompt_1", "name": "Test Prompt 1", "description": "First test prompt", "target_tool_id": "test_tool_1", "template_string": "Process: {{input}}", "tags": ["test"], "input_variables": ["input"] }, { "prompt_id": "test_prompt_2", "name": "Test Prompt 2", "description": "Second test prompt", "target_tool_id": "test_tool_2", "template_string": "Analyze: {{data}}", "tags": ["test", "analyze"], "input_variables": ["data"] } ] # Write test data to temporary file test_file = tmp_path / "test_prompts.json" test_file.write_text(json.dumps(test_prompts)) # Load prompts kg.load_prompts_from_json(str(test_file)) # Verify loading assert len(kg.prompts) == 2 assert "test_prompt_1" in kg.prompts assert "test_prompt_2" in kg.prompts prompt1 = kg.prompts["test_prompt_1"] assert prompt1.name == "Test Prompt 1" assert prompt1.target_tool_id == "test_tool_1" assert prompt1.template_string == "Process: {{input}}" def test_get_prompt_by_id(): """Test prompt retrieval by ID.""" kg = InMemoryKG() # Add test prompt directly test_prompt = MCPPrompt( prompt_id="test_id", name="Test Prompt", description="Test description", target_tool_id="tool_1", template_string="{{input}}" ) kg.prompts["test_id"] = test_prompt # Test existing ID retrieved = kg.get_prompt_by_id("test_id") assert retrieved is not None assert retrieved.name == "Test Prompt" # Test non-existent ID assert kg.get_prompt_by_id("non_existent") is None def test_get_prompts_for_tool(): """Test retrieving prompts by tool ID.""" kg = InMemoryKG() # Add test prompts for different tools prompt1 = MCPPrompt("p1", "Prompt 1", "Desc 1", "tool_a", "{{input}}") prompt2 = MCPPrompt("p2", "Prompt 2", "Desc 2", "tool_a", "{{data}}") prompt3 = MCPPrompt("p3", "Prompt 3", "Desc 3", "tool_b", "{{text}}") kg.prompts["p1"] = prompt1 kg.prompts["p2"] = prompt2 kg.prompts["p3"] = prompt3 # Test tool with multiple prompts tool_a_prompts = kg.get_prompts_for_tool("tool_a") assert len(tool_a_prompts) == 2 assert all(p.target_tool_id == "tool_a" for p in tool_a_prompts) # Test tool with single prompt tool_b_prompts = kg.get_prompts_for_tool("tool_b") assert len(tool_b_prompts) == 1 assert tool_b_prompts[0].prompt_id == "p3" # Test tool with no prompts assert kg.get_prompts_for_tool("tool_c") == [] def test_load_prompts_handles_file_not_found(capsys): """Test handling of missing prompt file.""" kg = InMemoryKG() kg.load_prompts_from_json("non_existent_file.json") assert len(kg.prompts) == 0 captured = capsys.readouterr() assert "Warning: Prompt file 'non_existent_file.json' not found" in captured.out def test_load_prompts_handles_invalid_json(tmp_path, capsys): """Test handling of invalid JSON in prompt file.""" kg = InMemoryKG() # Create file with invalid JSON test_file = tmp_path / "invalid.json" test_file.write_text("{ invalid json content") kg.load_prompts_from_json(str(test_file)) assert len(kg.prompts) == 0 captured = capsys.readouterr() assert "Warning: Invalid JSON" in captured.out
Apply coding standards from @.cursor/rules/python_gradio_basic.mdc.
Generate the complete modifications and test methods.
#### **Sub-Task 2.2: Extend Vector Indexing for Prompts**
- **Status:** Todo
- **Estimated Time:** 60-75 minutes
- **Dependencies:** Sub-Task 2.1
- **Description:** Add prompt embedding generation and semantic search capabilities
- **Acceptance Criteria:**
1. Prompt embeddings generated and stored alongside tool embeddings
2. Semantic search functionality for prompts
3. Integration with existing vector search infrastructure
4. Performance optimization for dual indexing
**Claude/Cursor Prompt:**
```cursor
**TASK: Extend InMemoryKG for Prompt Embedding Indexing and Search**
**Objective:** Enhance `InMemoryKG` to generate embeddings for prompts and enable semantic search across prompt templates.
**Action 1: Modify `kg_services/knowledge_graph.py` (InMemoryKG class)**
1. Open `@kg_services/knowledge_graph.py`
2. In `InMemoryKG.__init__`, add new attributes:
```python
# Existing tool embedding attributes remain...
# Add prompt embedding attributes
self.prompt_embeddings: List[List[float]] = []
self.prompt_ids_for_vectors: List[str] = []
- Modify
build_vector_indexmethod to include prompt processing:def build_vector_index(self, embedder: EmbeddingService) -> None: """Build vector index for both tools and prompts.""" # Clear existing embeddings self.tool_embeddings.clear() self.tool_ids_for_vectors.clear() self.prompt_embeddings.clear() self.prompt_ids_for_vectors.clear() # Index tools (existing logic) print(f"Indexing {len(self.tools)} tools...") for tool_id, tool in self.tools.items(): text_to_embed = f"{tool.name} - {tool.description} Tags: {', '.join(tool.tags)}" embedding = embedder.get_embedding(text_to_embed) if embedding is not None: self.tool_embeddings.append(embedding) self.tool_ids_for_vectors.append(tool_id) else: print(f"Warning: Could not generate embedding for tool {tool.name}") # Index prompts (new logic) print(f"Indexing {len(self.prompts)} prompts...") for prompt_id, prompt in self.prompts.items(): # Create rich text for embedding text_to_embed = self._create_prompt_embedding_text(prompt) embedding = embedder.get_embedding(text_to_embed) if embedding is not None: self.prompt_embeddings.append(embedding) self.prompt_ids_for_vectors.append(prompt_id) else: print(f"Warning: Could not generate embedding for prompt {prompt.name}") print(f"Vector index built: {len(self.tool_embeddings)} tools, {len(self.prompt_embeddings)} prompts indexed.") - Add helper method for prompt embedding text:
def _create_prompt_embedding_text(self, prompt: MCPPrompt) -> str: """Create descriptive text for prompt embedding.""" parts = [ prompt.name, prompt.description, f"Use case: {prompt.use_case}" if prompt.use_case else "", f"Tags: {', '.join(prompt.tags)}" if prompt.tags else "", f"Difficulty: {prompt.difficulty_level}", f"Variables: {', '.join(prompt.input_variables)}" if prompt.input_variables else "" ] return " - ".join(part for part in parts if part) - Add
find_similar_promptsmethod:def find_similar_prompts(self, query_embedding: List[float], top_k: int = 3) -> List[str]: """Find prompts similar to query using cosine similarity.""" if not self.prompt_embeddings or not query_embedding: return [] similarities = [] for i, prompt_embedding in enumerate(self.prompt_embeddings): similarity = self._cosine_similarity(query_embedding, prompt_embedding) similarities.append((similarity, self.prompt_ids_for_vectors[i])) # Sort by similarity (descending) and return top_k prompt IDs similarities.sort(key=lambda x: x[0], reverse=True) return [prompt_id for _, prompt_id in similarities[:top_k]]
Action 2: Update tests/kg_services/test_knowledge_graph.py
- Open
@tests/kg_services/test_knowledge_graph.py - Update existing
build_vector_indextests to include prompt verification - Add new prompt-specific tests:
def test_build_vector_index_includes_prompts(): """Test that build_vector_index processes both tools and prompts.""" kg = InMemoryKG() mock_embedder = MockEmbeddingService() # Add test tool test_tool = MCPTool("tool1", "Test Tool", "A test tool", ["test"]) kg.tools["tool1"] = test_tool # Add test prompt test_prompt = MCPPrompt( prompt_id="prompt1", name="Test Prompt", description="A test prompt", target_tool_id="tool1", template_string="{{input}}", tags=["test"], use_case="testing" ) kg.prompts["prompt1"] = test_prompt # Configure mock to return different embeddings mock_embedder.set_embedding_for_text( "Test Tool - A test tool Tags: test", [0.1, 0.2, 0.3] ) mock_embedder.set_embedding_for_text( "Test Prompt - A test prompt - Use case: testing - Tags: test - Difficulty: beginner", [0.4, 0.5, 0.6] ) kg.build_vector_index(mock_embedder) # Verify both tools and prompts are indexed assert len(kg.tool_embeddings) == 1 assert len(kg.prompt_embeddings) == 1 assert kg.tool_ids_for_vectors == ["tool1"] assert kg.prompt_ids_for_vectors == ["prompt1"] def test_create_prompt_embedding_text(): """Test prompt embedding text creation.""" kg = InMemoryKG() prompt = MCPPrompt( prompt_id="test", name="Test Prompt", description="A comprehensive test prompt", target_tool_id="tool1", template_string="{{input}}", tags=["test", "example"], input_variables=["input"], use_case="testing purposes", difficulty_level="intermediate" ) text = kg._create_prompt_embedding_text(prompt) expected = "Test Prompt - A comprehensive test prompt - Use case: testing purposes - Tags: test, example - Difficulty: intermediate - Variables: input" assert text == expected def test_find_similar_prompts_empty_index(): """Test find_similar_prompts with empty index.""" kg = InMemoryKG() result = kg.find_similar_prompts([0.1, 0.2, 0.3]) assert result == [] def test_find_similar_prompts_logic(): """Test find_similar_prompts similarity ranking.""" kg = InMemoryKG() # Manually set up prompt embeddings and IDs kg.prompt_embeddings = [ [1.0, 0.0, 0.0], # prompt_a [0.0, 1.0, 0.0], # prompt_b [0.0, 0.0, 1.0], # prompt_c ] kg.prompt_ids_for_vectors = ["prompt_a", "prompt_b", "prompt_c"] # Query most similar to prompt_a query_embedding = [0.9, 0.1, 0.0] results = kg.find_similar_prompts(query_embedding, top_k=2) # Should return prompt_a first, then prompt_b assert len(results) == 2 assert results[0] == "prompt_a" assert results[1] == "prompt_b" def test_find_similar_prompts_respects_top_k(): """Test that find_similar_prompts respects top_k parameter.""" kg = InMemoryKG() # Set up 3 prompt embeddings kg.prompt_embeddings = [[1, 0], [0, 1], [0.5, 0.5]] kg.prompt_ids_for_vectors = ["p1", "p2", "p3"] # Test different top_k values results_1 = kg.find_similar_prompts([1, 0], top_k=1) assert len(results_1) == 1 results_2 = kg.find_similar_prompts([1, 0], top_k=2) assert len(results_2) == 2 results_all = kg.find_similar_prompts([1, 0], top_k=10) assert len(results_all) == 3 # Can't return more than available
Apply coding standards from @.cursor/rules/python_gradio_basic.mdc.
Generate all code modifications and comprehensive test methods.
---
### **Task 3: Update Application Initialization**
**Estimated Time:** 20-30 minutes
**Priority:** MEDIUM
**Dependencies:** Task 2 completion
#### **Sub-Task 3.1: Integrate Prompt Loading in app.py**
- **Status:** Todo
- **Estimated Time:** 20-30 minutes
- **Dependencies:** Sub-Task 2.2
- **Description:** Update application startup to load prompts and include them in vector indexing
- **Acceptance Criteria:**
1. Prompts loaded during application startup
2. Vector index includes both tools and prompts
3. Proper error handling and logging
4. No breaking changes to existing functionality
**Claude/Cursor Prompt:**
```cursor
**TASK: Update app.py Initialization to Include Prompt Loading**
**Objective:** Modify the global service initialization in `app.py` to load prompts and include them in the vector indexing process.
**Action: Modify `app.py`**
1. Open `@app.py`
2. Locate the global service initialization section (around line 20-50)
3. After the line that loads tools, add prompt loading:
```python
# Existing tool loading
print("Loading tools from data/initial_tools.json...")
knowledge_graph_instance.load_tools_from_json("data/initial_tools.json")
print(f"β
Loaded {len(knowledge_graph_instance.tools)} tools.")
# Add prompt loading
print("Loading prompts from data/initial_prompts.json...")
knowledge_graph_instance.load_prompts_from_json("data/initial_prompts.json")
print(f"β
Loaded {len(knowledge_graph_instance.prompts)} prompts.")
- Update the vector index building message:
# Update existing message print("Building vector index for tools and prompts (may take a moment for first run)...") knowledge_graph_instance.build_vector_index(embedding_service_instance) print(f"β Vector index built successfully: {len(knowledge_graph_instance.tool_embeddings)} tools, {len(knowledge_graph_instance.prompt_embeddings)} prompts indexed.") - Ensure the initialization block has proper error handling that covers prompt loading:
try: # ... existing initialization code ... # Tool loading print("Loading tools from data/initial_tools.json...") knowledge_graph_instance.load_tools_from_json("data/initial_tools.json") print(f"β Loaded {len(knowledge_graph_instance.tools)} tools.") # Prompt loading print("Loading prompts from data/initial_prompts.json...") knowledge_graph_instance.load_prompts_from_json("data/initial_prompts.json") print(f"β Loaded {len(knowledge_graph_instance.prompts)} prompts.") # Vector indexing print("Building vector index for tools and prompts (may take a moment for first run)...") knowledge_graph_instance.build_vector_index(embedding_service_instance) print(f"β Vector index built successfully: {len(knowledge_graph_instance.tool_embeddings)} tools, {len(knowledge_graph_instance.prompt_embeddings)} prompts indexed.") # ... rest of initialization ... except FileNotFoundError as e: print(f"β FATAL: Data file not found: {e}") print("Please ensure both data/initial_tools.json and data/initial_prompts.json exist.") except Exception as e: print(f"β FATAL: Error during service initialization: {e}") print("The application may not function correctly.")
Verification Requirements:
- No changes to existing tool loading logic
- Prompt loading integrated seamlessly
- Enhanced logging for better debugging
- Proper error messages that mention both files
- No regression in MVP 1 functionality
Generate the modified initialization section with proper error handling and logging.
---
### **Task 4: Sprint Wrap-up & Final Checks**
**Estimated Time:** 30-45 minutes
**Priority:** HIGH
**Dependencies:** Task 3 completion
#### **Sub-Task 4.1: Dependencies and Environment Update**
- **Status:** Todo
- **Estimated Time:** 10-15 minutes
- **Description:** Update dependency files and regenerate lock file
- **Acceptance Criteria:**
1. requirements.lock updated and synchronized
2. No new runtime dependencies (this sprint adds no external libs)
3. Development environment properly configured
#### **Sub-Task 4.2: Comprehensive Quality Checks**
- **Status:** Todo
- **Estimated Time:** 15-20 minutes
- **Dependencies:** Sub-Task 4.1
- **Description:** Execute all quality assurance checks
- **Acceptance Criteria:**
1. All linting rules pass
2. Code properly formatted
3. Type checking passes
4. All unit tests pass (target: 60+ tests total)
#### **Sub-Task 4.3: Integration Testing**
- **Status:** Todo
- **Estimated Time:** 10-15 minutes
- **Dependencies:** Sub-Task 4.2
- **Description:** Manual verification of full integration
- **Acceptance Criteria:**
1. Application starts successfully
2. Both tools and prompts load correctly
3. Vector index builds for both types
4. No regressions in existing functionality
**Final Quality Check Commands:**
```bash
# Update dependencies
just lock
just install
# Run all quality checks
just lint
just format
just type-check
just test
# Manual integration test
python app.py
# Verify console output shows both tools and prompts loading
# Final commit
git add -A
python scripts/smart_commit.py "feat: implement MVP 2 Sprint 1 - MCPPrompt ontology and KG integration"
git push origin main
π Sprint 1 Success Metrics
Functional Metrics
- New Data Structures: 1 (MCPPrompt dataclass)
- New Data Files: 1 (initial_prompts.json with 6+ prompts)
- Enhanced KG Methods: 5 (load, retrieve, index, search for prompts)
- New Unit Tests: 20+ (comprehensive test coverage)
Technical Metrics
- Code Quality: A+ (maintained from MVP 1)
- Test Coverage: >80% for new code
- Type Safety: 100% (full type hints)
- Integration: Seamless with existing MVP 1 code
Performance Metrics
- Startup Time: <5 seconds (including prompt loading)
- Vector Index Build: <30 seconds (for 4 tools + 6 prompts)
- Memory Usage: <50MB increase (for prompt data)
- API Response Time: Maintained MVP 1 performance
π Risk Assessment
Technical Risks
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Prompt JSON Schema Changes | Low | Medium | Comprehensive validation in MCPPrompt.post_init |
| Vector Index Performance | Low | Low | Small dataset, proven embedding approach |
| Test Complexity | Medium | Low | Incremental testing, clear test separation |
Integration Risks
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| MVP 1 Regression | Low | High | Extensive existing test coverage, no changes to tool logic |
| Startup Time Increase | Medium | Low | Monitor startup performance, optimize if needed |
| Memory Usage Growth | Low | Low | Small prompt dataset, efficient storage |
π Sprint 1 Deliverables
Code Artifacts
- Enhanced kg_services/ontology.py - MCPPrompt dataclass with validation
- Rich data/initial_prompts.json - 6+ diverse, high-quality prompt templates
- Extended kg_services/knowledge_graph.py - Dual tool+prompt management
- Updated app.py - Integrated prompt loading in initialization
- Comprehensive Test Suite - 20+ new unit tests for all new functionality
Quality Assurance
- 100% Type Coverage - All new code with proper type hints
- Comprehensive Testing - Unit tests for all new methods and edge cases
- Documentation - Clear docstrings and inline comments
- Performance Validation - No regression in MVP 1 performance
- Integration Verification - End-to-end testing of enhanced system
π― Sprint 1 Definition of Done
Technical Completion
- MCPPrompt dataclass implemented with validation
- 6+ diverse prompt templates created and validated
- InMemoryKG enhanced for dual tool+prompt management
- Vector indexing supports semantic search across prompts
- Application initialization includes prompt loading
- All new functionality covered by unit tests
Quality Standards
- All quality checks passing (lint, format, type-check, test)
- No regressions in existing MVP 1 functionality
- Code follows project standards and conventions
- Comprehensive error handling and logging
- Performance targets maintained
Integration Readiness
- Application starts successfully with enhanced initialization
- Both tools and prompts load and index correctly
- System ready for Sprint 2 (enhanced planner development)
- All changes committed and CI pipeline green
π Post-Sprint 1 Review
What's Complete
- Foundational prompt ontology established
- Rich prompt metadata created for all MVP 1 tools
- Knowledge graph enhanced for dual tool+prompt management
- Vector indexing supports semantic search across both types
- Application initialization seamlessly includes prompts
- Comprehensive test coverage for all new functionality
What's Next (Sprint 2)
- Enhance SimplePlannerAgent to suggest tool+prompt pairs
- Implement intelligent prompt selection logic
- Create PlannedStep data structure
- Maintain backward compatibility with MVP 1 interface
Key Success Factors
- Solid Foundation - Comprehensive data structures and validation
- Rich Data - High-quality prompt templates for effective testing
- Seamless Integration - No disruption to existing MVP 1 functionality
- Quality First - Extensive testing and error handling
- Future Ready - Architecture prepared for advanced planning logic
Sprint 1 Start Date: TBD
Estimated Completion: 3-4 hours
Confidence Level: HIGH (building on proven MVP 1 architecture)
Risk Level: LOW (additive changes, no breaking modifications)
This comprehensive Sprint 1 plan provides the foundation for transforming KGraph-MCP from a tool discovery system into an intelligent tool+prompt suggestion platform.