Coverage for .claude/hooks/moai/lib/agent_context.py: 0.00%
96 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-19 08:00 +0900
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-19 08:00 +0900
1#!/usr/bin/env python3
2"""Agent Context Engineering utilities
4Advanced JIT (Just-in-Time) Retrieval with Expert Agent Delegation
5Intelligently analyzes user prompts to recommend specialist agents and skills
6"""
8import json
9import re
10from pathlib import Path
11from typing import Any, Dict, List, Optional, Tuple
13from .context import get_jit_context
16def load_agent_skills_mapping() -> Dict[str, Any]:
17 """Load agent-skills mapping configuration
19 Returns:
20 Mapping configuration dictionary
21 """
22 try:
23 mapping_file = Path(__file__).parent.parent / "config" / "agent_skills_mapping.json"
24 if mapping_file.exists():
25 with open(mapping_file, 'r', encoding='utf-8') as f:
26 return json.load(f)
27 except Exception:
28 pass
30 return {
31 "agent_skills_mapping": {},
32 "prompt_patterns": {}
33 }
36def analyze_prompt_intent(prompt: str, mapping: Dict[str, Any]) -> Optional[Dict[str, Any]]:
37 """Analyze user prompt intent
39 Args:
40 prompt: User prompt
41 mapping: Agent-skills mapping
43 Returns:
44 Analyzed intent information or None
45 """
46 prompt_lower = prompt.lower()
48 # Calculate score for each pattern
49 pattern_scores = []
51 for pattern_name, pattern_config in mapping.get("prompt_patterns", {}).items():
52 score = 0
53 matched_keywords = []
55 # Keyword matching
56 for keyword in pattern_config.get("keywords", []):
57 if keyword.lower() in prompt_lower:
58 score += 1
59 matched_keywords.append(keyword)
61 # Regex pattern matching
62 if pattern_config.get("regex_patterns"):
63 for regex_pattern in pattern_config["regex_patterns"]:
64 if re.search(regex_pattern, prompt_lower):
65 score += 2 # Regex matching has higher weight
67 if score > 0:
68 pattern_scores.append({
69 "pattern": pattern_name,
70 "score": score,
71 "matched_keywords": matched_keywords,
72 "config": pattern_config
73 })
75 # Return pattern with highest score
76 if pattern_scores:
77 pattern_scores.sort(key=lambda x: x["score"], reverse=True)
78 best_match = pattern_scores[0]
80 return {
81 "intent": best_match["pattern"],
82 "confidence": min(best_match["score"] / 3.0, 1.0), # Maximum 3 keyword matches
83 "matched_keywords": best_match["matched_keywords"],
84 "primary_agent": best_match["config"].get("primary_agent"),
85 "secondary_agents": best_match["config"].get("secondary_agents", []),
86 "recommended_skills": best_match["config"].get("skills", []),
87 "context_files": best_match["config"].get("context_files", [])
88 }
90 return None
93def get_agent_delegation_context(prompt: str, cwd: str) -> Dict[str, Any]:
94 """Create agent delegation context based on prompt
96 Args:
97 prompt: User prompt
98 cwd: Current working directory
100 Returns:
101 Agent delegation context information
102 """
103 mapping = load_agent_skills_mapping()
104 intent_analysis = analyze_prompt_intent(prompt, mapping)
106 # Get existing JIT context
107 existing_context = get_jit_context(prompt, cwd)
109 # Agent delegation information
110 agent_context = {
111 "intent_detected": intent_analysis is not None,
112 "traditional_context": existing_context
113 }
115 if intent_analysis:
116 # Verify file existence
117 valid_context_files = []
118 cwd_path = Path(cwd)
120 for context_file in intent_analysis["context_files"]:
121 file_path = cwd_path / context_file
122 if file_path.exists():
123 valid_context_files.append(context_file)
125 # Create skills reference paths
126 skill_references = []
127 for skill in intent_analysis["recommended_skills"]:
128 skill_ref = f".claude/skills/{skill}/reference.md"
129 skill_path = cwd_path / skill_ref
130 if skill_path.exists():
131 skill_references.append(skill_ref)
133 agent_context.update({
134 "primary_agent": intent_analysis["primary_agent"],
135 "secondary_agents": intent_analysis["secondary_agents"],
136 "recommended_skills": intent_analysis["recommended_skills"],
137 "skill_references": skill_references,
138 "context_files": valid_context_files,
139 "confidence": intent_analysis["confidence"],
140 "intent": intent_analysis["intent"],
141 "matched_keywords": intent_analysis["matched_keywords"]
142 })
144 return agent_context
147def format_agent_delegation_message(context: Dict[str, Any]) -> Optional[str]:
148 """Format agent delegation message
150 Args:
151 context: Agent delegation context
153 Returns:
154 Formatted message or None
155 """
156 if not context.get("intent_detected"):
157 return None
159 messages = []
161 # Basic information
162 primary_agent = context.get("primary_agent")
163 confidence = context.get("confidence", 0)
164 intent = context.get("intent", "")
165 matched_keywords = context.get("matched_keywords", [])
167 if primary_agent and confidence > 0.5:
168 messages.append(f"🎯 Recommended Expert Agent: {primary_agent}")
169 messages.append(f"📋 Task Intent: {intent}")
171 if matched_keywords:
172 messages.append(f"🔍 Detected Keywords: {', '.join(matched_keywords)}")
174 # Recommended skills
175 skills = context.get("recommended_skills", [])
176 if skills:
177 messages.append(f"⚡ Recommended Skills: {', '.join(skills[:3])}") # Display max 3
179 # Secondary agents
180 secondary_agents = context.get("secondary_agents", [])
181 if secondary_agents:
182 messages.append(f"🤝 Collaboration Agents: {', '.join(secondary_agents[:2])}") # Display max 2
184 # Context files
185 context_files = context.get("context_files", [])
186 skill_references = context.get("skill_references", [])
188 all_files = context_files + skill_references
189 if all_files:
190 messages.append(f"📚 Auto-loaded Context: {len(all_files)} files")
192 return "\n".join(messages) if messages else None
195def get_enhanced_jit_context(prompt: str, cwd: str) -> Tuple[List[str], Optional[str]]:
196 """Get enhanced JIT context
198 Args:
199 prompt: User prompt
200 cwd: Current working directory
202 Returns:
203 (Context file list, system message)
204 """
205 agent_context = get_agent_delegation_context(prompt, cwd)
207 # Combine all context files
208 context_files = []
210 # Add existing context
211 traditional_context = agent_context.get("traditional_context", [])
212 context_files.extend(traditional_context)
214 # Add agent context files
215 agent_context_files = agent_context.get("context_files", [])
216 for file in agent_context_files:
217 if file not in context_files:
218 context_files.append(file)
220 # Add skills reference files
221 skill_references = agent_context.get("skill_references", [])
222 for skill_ref in skill_references:
223 if skill_ref not in context_files:
224 context_files.append(skill_ref)
226 # Generate system message
227 system_message = format_agent_delegation_message(agent_context)
229 return context_files, system_message
232__all__ = [
233 "load_agent_skills_mapping",
234 "analyze_prompt_intent",
235 "get_agent_delegation_context",
236 "format_agent_delegation_message",
237 "get_enhanced_jit_context"
238]