Initial commit
This commit is contained in:
234
skills/meta-automation-architect/scripts/cost_estimator.py
Normal file
234
skills/meta-automation-architect/scripts/cost_estimator.py
Normal file
@@ -0,0 +1,234 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cost & Performance Estimator
|
||||
Provides transparent estimates for automation operations
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import Dict, List
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
@dataclass
|
||||
class AgentEstimate:
|
||||
"""Estimate for a single agent"""
|
||||
agent_name: str
|
||||
description: str
|
||||
estimated_tokens: int
|
||||
estimated_minutes: int
|
||||
priority: str # high, medium, low
|
||||
purpose: str
|
||||
|
||||
@dataclass
|
||||
class AutomationEstimate:
|
||||
"""Complete automation estimate"""
|
||||
mode: str # quick, focused, comprehensive
|
||||
total_agents: int
|
||||
agents: List[AgentEstimate]
|
||||
total_tokens_min: int
|
||||
total_tokens_max: int
|
||||
total_minutes_min: int
|
||||
total_minutes_max: int
|
||||
total_cost_min: float
|
||||
total_cost_max: float
|
||||
recommendations: List[str]
|
||||
|
||||
class CostEstimator:
|
||||
"""Estimates cost and time for automation"""
|
||||
|
||||
# Token costs (as of Jan 2025, Claude Sonnet)
|
||||
TOKEN_COST_INPUT = 0.000003 # $3 per 1M input tokens
|
||||
TOKEN_COST_OUTPUT = 0.000015 # $15 per 1M output tokens
|
||||
|
||||
# Approximate tokens per agent type
|
||||
AGENT_TOKEN_ESTIMATES = {
|
||||
'project-analyzer': {'input': 2000, 'output': 1500, 'minutes': 3},
|
||||
'structure-analyzer': {'input': 1000, 'output': 800, 'minutes': 2},
|
||||
'security-analyzer': {'input': 1500, 'output': 1000, 'minutes': 3},
|
||||
'performance-analyzer': {'input': 1500, 'output': 1000, 'minutes': 4},
|
||||
'test-coverage-analyzer': {'input': 1200, 'output': 800, 'minutes': 3},
|
||||
'latex-structure-analyzer': {'input': 1000, 'output': 800, 'minutes': 3},
|
||||
'citation-analyzer': {'input': 800, 'output': 600, 'minutes': 2},
|
||||
'link-validator': {'input': 1000, 'output': 700, 'minutes': 2},
|
||||
}
|
||||
|
||||
# Default estimate for unknown agents
|
||||
DEFAULT_ESTIMATE = {'input': 1000, 'output': 800, 'minutes': 3}
|
||||
|
||||
def estimate_agent(self, agent_name: str, priority: str = 'medium', purpose: str = '') -> AgentEstimate:
|
||||
"""
|
||||
Estimate cost/time for a single agent
|
||||
|
||||
Args:
|
||||
agent_name: Name of the agent
|
||||
priority: high, medium, or low
|
||||
purpose: What this agent does
|
||||
|
||||
Returns:
|
||||
AgentEstimate object
|
||||
"""
|
||||
estimate = self.AGENT_TOKEN_ESTIMATES.get(agent_name, self.DEFAULT_ESTIMATE)
|
||||
|
||||
total_tokens = estimate['input'] + estimate['output']
|
||||
minutes = estimate['minutes']
|
||||
|
||||
return AgentEstimate(
|
||||
agent_name=agent_name,
|
||||
description=purpose or f"Analyzes {agent_name.replace('-', ' ')}",
|
||||
estimated_tokens=total_tokens,
|
||||
estimated_minutes=minutes,
|
||||
priority=priority,
|
||||
purpose=purpose
|
||||
)
|
||||
|
||||
def estimate_quick_mode(self) -> AutomationEstimate:
|
||||
"""Estimate for quick analysis mode"""
|
||||
agents = [
|
||||
self.estimate_agent('project-analyzer', 'high', 'Intelligent project analysis'),
|
||||
]
|
||||
|
||||
return self._calculate_total_estimate('quick', agents, [
|
||||
'Fastest way to understand your project',
|
||||
'Low cost, high value',
|
||||
'Can expand to full automation after'
|
||||
])
|
||||
|
||||
def estimate_focused_mode(self, focus_areas: List[str]) -> AutomationEstimate:
|
||||
"""Estimate for focused automation mode"""
|
||||
# Map focus areas to agents
|
||||
area_to_agents = {
|
||||
'security': ['security-analyzer'],
|
||||
'testing': ['test-coverage-analyzer'],
|
||||
'performance': ['performance-analyzer'],
|
||||
'structure': ['structure-analyzer'],
|
||||
'latex': ['latex-structure-analyzer', 'citation-analyzer'],
|
||||
'links': ['link-validator'],
|
||||
}
|
||||
|
||||
agents = [self.estimate_agent('project-analyzer', 'high', 'Initial analysis')]
|
||||
|
||||
for area in focus_areas:
|
||||
for agent_name in area_to_agents.get(area, []):
|
||||
agents.append(self.estimate_agent(agent_name, 'high', f'Analyze {area}'))
|
||||
|
||||
return self._calculate_total_estimate('focused', agents, [
|
||||
'Targeted automation for your specific needs',
|
||||
'Medium cost, high relevance',
|
||||
'Focuses on what matters most to you'
|
||||
])
|
||||
|
||||
def estimate_comprehensive_mode(self, project_type: str) -> AutomationEstimate:
|
||||
"""Estimate for comprehensive automation mode"""
|
||||
agents = [
|
||||
self.estimate_agent('project-analyzer', 'high', 'Project analysis'),
|
||||
self.estimate_agent('structure-analyzer', 'high', 'Structure analysis'),
|
||||
]
|
||||
|
||||
# Add type-specific agents
|
||||
if project_type in ['programming', 'web_app', 'cli']:
|
||||
agents.extend([
|
||||
self.estimate_agent('security-analyzer', 'high', 'Security audit'),
|
||||
self.estimate_agent('performance-analyzer', 'medium', 'Performance check'),
|
||||
self.estimate_agent('test-coverage-analyzer', 'high', 'Test coverage'),
|
||||
])
|
||||
|
||||
elif project_type in ['academic_writing', 'research']:
|
||||
agents.extend([
|
||||
self.estimate_agent('latex-structure-analyzer', 'high', 'LaTeX structure'),
|
||||
self.estimate_agent('citation-analyzer', 'high', 'Citations & bibliography'),
|
||||
self.estimate_agent('link-validator', 'medium', 'Link validation'),
|
||||
])
|
||||
|
||||
return self._calculate_total_estimate('comprehensive', agents, [
|
||||
'Complete automation system',
|
||||
'Highest cost, most comprehensive',
|
||||
'Full agent suite, skills, commands, hooks'
|
||||
])
|
||||
|
||||
def _calculate_total_estimate(self, mode: str, agents: List[AgentEstimate], recommendations: List[str]) -> AutomationEstimate:
|
||||
"""Calculate total estimates from agent list"""
|
||||
total_tokens = sum(a.estimated_tokens for a in agents)
|
||||
total_minutes = max(5, sum(a.estimated_minutes for a in agents) // 2) # Parallel execution
|
||||
|
||||
# Add buffer (20-50% uncertainty)
|
||||
tokens_min = total_tokens
|
||||
tokens_max = int(total_tokens * 1.5)
|
||||
minutes_min = total_minutes
|
||||
minutes_max = int(total_minutes * 1.3)
|
||||
|
||||
# Calculate costs (rough approximation: 60% input, 40% output)
|
||||
cost_min = (tokens_min * 0.6 * self.TOKEN_COST_INPUT) + (tokens_min * 0.4 * self.TOKEN_COST_OUTPUT)
|
||||
cost_max = (tokens_max * 0.6 * self.TOKEN_COST_INPUT) + (tokens_max * 0.4 * self.TOKEN_COST_OUTPUT)
|
||||
|
||||
return AutomationEstimate(
|
||||
mode=mode,
|
||||
total_agents=len(agents),
|
||||
agents=agents,
|
||||
total_tokens_min=tokens_min,
|
||||
total_tokens_max=tokens_max,
|
||||
total_minutes_min=minutes_min,
|
||||
total_minutes_max=minutes_max,
|
||||
total_cost_min=round(cost_min, 3),
|
||||
total_cost_max=round(cost_max, 3),
|
||||
recommendations=recommendations
|
||||
)
|
||||
|
||||
def format_estimate(self, estimate: AutomationEstimate) -> str:
|
||||
"""Format estimate for display"""
|
||||
lines = []
|
||||
|
||||
lines.append(f"╔══════════════════════════════════════════════════╗")
|
||||
lines.append(f"║ Automation Estimate - {estimate.mode.upper()} Mode")
|
||||
lines.append(f"╚══════════════════════════════════════════════════╝")
|
||||
lines.append("")
|
||||
|
||||
# Agent list
|
||||
for agent in estimate.agents:
|
||||
priority_icon = "⭐" if agent.priority == "high" else "•"
|
||||
lines.append(f"{priority_icon} {agent.agent_name}")
|
||||
lines.append(f" {agent.description}")
|
||||
lines.append(f" ⏱️ ~{agent.estimated_minutes} min | 💰 ~{agent.estimated_tokens} tokens")
|
||||
lines.append("")
|
||||
|
||||
lines.append("────────────────────────────────────────────────────")
|
||||
|
||||
# Totals
|
||||
lines.append(f"Total Agents: {estimate.total_agents}")
|
||||
lines.append(f"Estimated Time: {estimate.total_minutes_min}-{estimate.total_minutes_max} minutes")
|
||||
lines.append(f"Estimated Tokens: {estimate.total_tokens_min:,}-{estimate.total_tokens_max:,}")
|
||||
lines.append(f"Estimated Cost: ${estimate.total_cost_min:.3f}-${estimate.total_cost_max:.3f}")
|
||||
|
||||
lines.append("")
|
||||
lines.append("💡 Notes:")
|
||||
for rec in estimate.recommendations:
|
||||
lines.append(f" • {rec}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
def export_estimate(self, estimate: AutomationEstimate, output_path: str = None) -> Dict:
|
||||
"""Export estimate as JSON"""
|
||||
data = asdict(estimate)
|
||||
|
||||
if output_path:
|
||||
with open(output_path, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
return data
|
||||
|
||||
# Example usage
|
||||
if __name__ == '__main__':
|
||||
estimator = CostEstimator()
|
||||
|
||||
print("1. QUICK MODE ESTIMATE")
|
||||
print("="*60)
|
||||
quick = estimator.estimate_quick_mode()
|
||||
print(estimator.format_estimate(quick))
|
||||
|
||||
print("\n\n2. FOCUSED MODE ESTIMATE (Security + Testing)")
|
||||
print("="*60)
|
||||
focused = estimator.estimate_focused_mode(['security', 'testing'])
|
||||
print(estimator.format_estimate(focused))
|
||||
|
||||
print("\n\n3. COMPREHENSIVE MODE ESTIMATE (Programming Project)")
|
||||
print("="*60)
|
||||
comprehensive = estimator.estimate_comprehensive_mode('programming')
|
||||
print(estimator.format_estimate(comprehensive))
|
||||
Reference in New Issue
Block a user