scripts-agent-expert
""" Agent Type Expert
Specializes in understanding what makes a document an "agent" document. Agent docs define AI agent personas, capabilities, and system prompts.
Key characteristics:
- "You are" or persona-defining language
- Capabilities/responsibilities lists
- Tool/integration specifications
- Context/memory requirements
- Behavioral guidelines """
import re from typing import Dict, List from pathlib import Path import sys
sys.path.insert(0, str(Path(file).parent.parent)) from core.models import Document, AnalystVote from .base import TypeExpert, TypeAnalysis, ContentEnhancement
class AgentExpert(TypeExpert): """Expert in identifying and enhancing agent documents."""
expert_type = "agent"
strong_indicators = [
r'you are\b',
r'your role',
r'as an? (?:ai|agent)',
r'responsible for',
r'capabilities',
r'you (?:can|will|should|must)',
r'system prompt',
r'persona',
]
analyst_expectations = {
'metadata': ["type: agent in frontmatter", "component_type: agent"],
'content': ["Persona definition", "Capabilities list", "Tool specifications"],
'structural': ["Path contains /agents/", "Agent-style filename"],
'semantic': ["Second-person directives", "Role-defining language"],
'pattern': ["Filename matches agent patterns", "Title defines a role"],
}
def analyze(
self,
document: Document,
analyst_votes: List[AnalystVote]
) -> TypeAnalysis:
"""Analyze if document is truly an agent definition."""
content = document.body or document.content
headings = self.extract_headings(content)
h2_texts = [h[1].lower() for h in headings if h[0] == 2]
evidence_for = []
evidence_against = []
# Check strong indicators
for indicator in self.strong_indicators:
if re.search(indicator, content, re.I):
evidence_for.append(f"Contains agent indicator: '{indicator}'")
# Check for persona definition (critical for agents)
if re.search(r'^you are\b', content, re.I | re.MULTILINE):
evidence_for.append("Has 'You are' persona definition")
# Check for capabilities section
if any('capabilit' in h for h in h2_texts):
evidence_for.append("Has capabilities section")
if any('responsibilit' in h for h in h2_texts):
evidence_for.append("Has responsibilities section")
if any('tool' in h for h in h2_texts):
evidence_for.append("Has tools section")
# Check for behavioral guidelines
if re.search(r'you (?:must|should|will)\b', content, re.I):
evidence_for.append("Contains behavioral directives")
# Check for second-person throughout
you_count = len(re.findall(r'\byou\b', content, re.I))
if you_count >= 5:
evidence_for.append(f"Heavy use of second-person ({you_count} occurrences)")
# Check path
if '/agent' in str(document.path).lower():
evidence_for.append("Located in agents directory")
# Evidence against
if any('step' in h for h in h2_texts):
evidence_against.append("Has step sections - might be guide")
if any('api' in h or 'reference' in h for h in h2_texts):
evidence_against.append("Has API/reference sections - might be reference doc")
if re.search(r'how to\b', content, re.I) and not re.search(r'you are', content, re.I):
evidence_against.append("Uses instructional language without persona - might be guide")
confidence = min(0.98, len(evidence_for) * 0.14)
if evidence_against:
confidence -= len(evidence_against) * 0.1
is_agent = len(evidence_for) >= 2 and confidence > 0.5
# Missing signals
missing = []
if not re.search(r'you are\b', content, re.I):
missing.append('persona')
if not any('capabilit' in h or 'responsibilit' in h for h in h2_texts):
missing.append('capabilities')
if not any('tool' in h for h in h2_texts):
missing.append('tools')
if not re.search(r'context|memory', content, re.I):
missing.append('context_requirements')
disagreeing = self.identify_disagreeing_analysts(analyst_votes, 'agent')
analysts_to_sway = {
name: f"Needs more agent signals (persona, capabilities) to classify as agent"
for name in disagreeing
}
return TypeAnalysis(
is_this_type=is_agent,
confidence=max(0, confidence),
evidence_for=evidence_for,
evidence_against=evidence_against,
semantic_purpose=self.analyze_semantic_purpose(document),
missing_signals=missing,
recommended_changes=[],
analysts_to_sway=analysts_to_sway,
expert_type=self.expert_type
)
def generate_enhancements(
self,
document: Document,
analysis: TypeAnalysis
) -> List[ContentEnhancement]:
"""Generate contextual agent enhancements."""
enhancements = []
content = document.body or document.content
title = document.frontmatter.get('title', 'AI Agent')
# Extract potential role from content
role = self._infer_role(content, title)
if 'persona' in analysis.missing_signals:
enhancements.append(ContentEnhancement(
signal_type='persona',
content=self._generate_persona(role, content),
insertion_point='after_frontmatter',
reason="Agent docs need clear persona definition",
expected_analyst_boost={'semantic': 0.20, 'content': 0.15},
priority=1
))
if 'capabilities' in analysis.missing_signals:
capabilities = self._infer_capabilities(content)
enhancements.append(ContentEnhancement(
signal_type='capabilities',
content=self._generate_capabilities(capabilities),
insertion_point='after_persona',
reason="Agent docs need explicit capabilities list",
expected_analyst_boost={'content': 0.15, 'structural': 0.10},
priority=1
))
if 'tools' in analysis.missing_signals:
tools = self._infer_tools(content)
enhancements.append(ContentEnhancement(
signal_type='tools',
content=self._generate_tools(tools),
insertion_point='after_capabilities',
reason="Agent docs should specify available tools",
expected_analyst_boost={'content': 0.10, 'semantic': 0.10},
priority=2
))
if 'context_requirements' in analysis.missing_signals:
enhancements.append(ContentEnhancement(
signal_type='context_requirements',
content=self._generate_context_requirements(role),
insertion_point='before_end',
reason="Agent docs benefit from context/memory specifications",
expected_analyst_boost={'content': 0.10, 'pattern': 0.05},
priority=3
))
return enhancements
def _infer_role(self, content: str, title: str) -> str:
"""Infer the agent's role from content."""
# Look for role patterns
role_match = re.search(r'(?:you are|role|as) (?:a|an|the) ([^.]+)', content, re.I)
if role_match:
return role_match.group(1).strip()
# Fall back to title
return title.replace('-', ' ').replace('_', ' ')
def _infer_capabilities(self, content: str) -> List[str]:
"""Infer capabilities from document content."""
capabilities = []
# Look for can/able patterns
can_patterns = re.findall(r'(?:can|able to|capable of) ([^.]+)', content, re.I)
capabilities.extend(can_patterns[:5])
# Look for bullet points that describe actions
bullets = re.findall(r'^[-*]\s+(.+)$', content, re.MULTILINE)
for bullet in bullets[:5]:
if any(word in bullet.lower() for word in ['analyze', 'create', 'manage', 'review', 'generate', 'coordinate']):
capabilities.append(bullet)
if not capabilities:
capabilities = [
"Analyze and process input",
"Generate appropriate responses",
"Coordinate with other components"
]
return capabilities[:5]
def _infer_tools(self, content: str) -> List[str]:
"""Infer tools from content."""
tools = []
# Common tool patterns
tool_keywords = ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'Task', 'WebSearch', 'WebFetch']
for tool in tool_keywords:
if tool.lower() in content.lower():
tools.append(tool)
if not tools:
tools = ['Read', 'Write', 'Bash']
return tools
def _generate_persona(self, role: str, content: str) -> str:
"""Generate persona definition."""
return f"""
Agent Identity
You are a specialized {role}. Your purpose is to assist with tasks related to this domain, providing expert guidance and execution support.
Core Mission
Deliver high-quality assistance while adhering to established guidelines and best practices. """
def _generate_capabilities(self, capabilities: List[str]) -> str:
"""Generate capabilities section."""
items = "\n".join(f"- {cap}" for cap in capabilities)
return f"""
Capabilities
This agent can: {items} """
def _generate_tools(self, tools: List[str]) -> str:
"""Generate tools section."""
items = "\n".join(f"- `{tool}` - Access to {tool.lower()} operations" for tool in tools)
return f"""
Available Tools
{items} """
def _generate_context_requirements(self, role: str) -> str:
"""Generate context requirements section."""
return f"""
Context Requirements
Required Context
- Access to relevant project files and documentation
- Understanding of current task objectives
Memory Considerations
- Maintain context across related operations
- Track decisions and rationale for audit trails """