526 lines
21 KiB
Python
526 lines
21 KiB
Python
"""Multi-perspective analysis agents for YouTube video analysis."""
|
|
|
|
import asyncio
|
|
import json
|
|
import logging
|
|
from typing import Dict, List, Optional, Any
|
|
from datetime import datetime
|
|
|
|
from ..core.exceptions import ServiceError
|
|
from .deepseek_service import DeepSeekService
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class BaseAnalysisAgent:
|
|
"""Base class for analysis agents."""
|
|
|
|
def __init__(self, agent_id: str, name: str, ai_service: Optional[DeepSeekService] = None):
|
|
"""Initialize the base analysis agent.
|
|
|
|
Args:
|
|
agent_id: Unique identifier for the agent
|
|
name: Human-readable name for the agent
|
|
ai_service: DeepSeek AI service instance
|
|
"""
|
|
self.agent_id = agent_id
|
|
self.name = name
|
|
self.ai_service = ai_service or DeepSeekService()
|
|
self.capabilities = self._get_capabilities()
|
|
|
|
def _get_capabilities(self) -> List[str]:
|
|
"""Get agent capabilities. Override in subclasses."""
|
|
return []
|
|
|
|
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Execute agent analysis. Override in subclasses."""
|
|
raise NotImplementedError("Subclasses must implement execute method")
|
|
|
|
def get_capabilities(self) -> List[str]:
|
|
"""Get list of agent capabilities."""
|
|
return self.capabilities
|
|
|
|
|
|
class TechnicalAnalysisAgent(BaseAnalysisAgent):
|
|
"""Technical Analysis Agent for analyzing technical concepts and implementation details."""
|
|
|
|
def __init__(self, ai_service: Optional[DeepSeekService] = None):
|
|
"""Initialize the Technical Analysis Agent.
|
|
|
|
Args:
|
|
ai_service: DeepSeek AI service instance
|
|
"""
|
|
super().__init__(
|
|
agent_id="technical_analyst",
|
|
name="Technical Analysis Agent",
|
|
ai_service=ai_service
|
|
)
|
|
|
|
def _get_capabilities(self) -> List[str]:
|
|
"""Get technical analysis capabilities."""
|
|
return [
|
|
"technical_analysis",
|
|
"architecture_review",
|
|
"code_quality_assessment",
|
|
"performance_analysis",
|
|
"security_evaluation",
|
|
"scalability_assessment",
|
|
"technology_evaluation",
|
|
"implementation_guidance"
|
|
]
|
|
|
|
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Execute technical analysis of video content."""
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Extract content from state
|
|
transcript = state.get("transcript", "")
|
|
video_id = state.get("video_id", "")
|
|
video_title = state.get("video_title", "")
|
|
|
|
if not transcript:
|
|
raise ServiceError("No transcript provided for technical analysis")
|
|
|
|
# Create technical analysis prompt
|
|
prompt = f"""
|
|
As a Technical Analyst, analyze this video content focusing on:
|
|
|
|
**Technical Concepts**: Identify and explain technical topics, technologies, frameworks, tools
|
|
**Architecture & Design**: Evaluate architectural patterns, design decisions, system design
|
|
**Implementation Details**: Analyze code examples, best practices, implementation strategies
|
|
**Performance & Scalability**: Assess performance implications and scalability considerations
|
|
**Security Aspects**: Identify security-related topics and considerations
|
|
|
|
Video: {video_title}
|
|
Transcript: {transcript[:4000]}...
|
|
|
|
Provide analysis in this JSON format:
|
|
{{
|
|
"summary": "Technical summary of the video content",
|
|
"key_insights": ["insight1", "insight2", "insight3", "insight4", "insight5"],
|
|
"focus_areas": ["area1", "area2", "area3"],
|
|
"recommendations": ["rec1", "rec2", "rec3"],
|
|
"confidence_score": 0.85,
|
|
"technical_concepts": ["concept1", "concept2", "concept3"],
|
|
"implementation_notes": "Key implementation considerations"
|
|
}}
|
|
"""
|
|
|
|
# Generate technical analysis
|
|
response = await self.ai_service.generate_response(
|
|
prompt,
|
|
temperature=0.3,
|
|
max_tokens=1500
|
|
)
|
|
|
|
# Parse JSON response
|
|
try:
|
|
analysis_data = json.loads(response)
|
|
except json.JSONDecodeError:
|
|
# Fallback parsing if JSON is malformed
|
|
analysis_data = {
|
|
"summary": response[:500] + "..." if len(response) > 500 else response,
|
|
"key_insights": ["Technical analysis completed"],
|
|
"focus_areas": ["Technical implementation"],
|
|
"recommendations": ["Review technical details"],
|
|
"confidence_score": 0.7,
|
|
"technical_concepts": ["General technical content"],
|
|
"implementation_notes": "Analysis completed"
|
|
}
|
|
|
|
# Calculate processing time
|
|
processing_time = (datetime.now() - start_time).total_seconds()
|
|
|
|
# Build result
|
|
result = {
|
|
"status": "success",
|
|
"analysis_results": {
|
|
"technical": {
|
|
"agent_type": "technical",
|
|
"agent_id": self.agent_id,
|
|
"summary": analysis_data.get("summary", ""),
|
|
"key_insights": analysis_data.get("key_insights", []),
|
|
"focus_areas": analysis_data.get("focus_areas", []),
|
|
"recommendations": analysis_data.get("recommendations", []),
|
|
"confidence_score": analysis_data.get("confidence_score", 0.8),
|
|
"technical_concepts": analysis_data.get("technical_concepts", []),
|
|
"implementation_notes": analysis_data.get("implementation_notes", ""),
|
|
"processing_time_seconds": processing_time
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.info(f"Technical analysis completed for video {video_id} in {processing_time:.2f}s")
|
|
return result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in technical analysis: {e}")
|
|
return {
|
|
"status": "error",
|
|
"error": str(e),
|
|
"agent_id": self.agent_id
|
|
}
|
|
|
|
|
|
class BusinessAnalysisAgent(BaseAnalysisAgent):
|
|
"""Business Analysis Agent for analyzing business value and strategic implications."""
|
|
|
|
def __init__(self, ai_service: Optional[DeepSeekService] = None):
|
|
"""Initialize the Business Analysis Agent.
|
|
|
|
Args:
|
|
ai_service: DeepSeek AI service instance
|
|
"""
|
|
super().__init__(
|
|
agent_id="business_analyst",
|
|
name="Business Analysis Agent",
|
|
ai_service=ai_service
|
|
)
|
|
|
|
def _get_capabilities(self) -> List[str]:
|
|
"""Get business analysis capabilities."""
|
|
return [
|
|
"business_value_assessment",
|
|
"market_analysis",
|
|
"roi_evaluation",
|
|
"strategic_planning",
|
|
"competitive_analysis",
|
|
"cost_benefit_analysis",
|
|
"business_case_development",
|
|
"stakeholder_analysis"
|
|
]
|
|
|
|
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Execute business analysis of video content."""
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Extract content from state
|
|
transcript = state.get("transcript", "")
|
|
video_id = state.get("video_id", "")
|
|
video_title = state.get("video_title", "")
|
|
|
|
if not transcript:
|
|
raise ServiceError("No transcript provided for business analysis")
|
|
|
|
# Create business analysis prompt
|
|
prompt = f"""
|
|
As a Business Analyst, analyze this video content focusing on:
|
|
|
|
**Business Value**: Identify business opportunities, value propositions, market potential
|
|
**Strategic Implications**: Evaluate strategic impact, competitive advantages, market positioning
|
|
**ROI & Metrics**: Assess return on investment, key performance indicators, success metrics
|
|
**Market Analysis**: Analyze target markets, customer segments, market trends
|
|
**Risk Assessment**: Identify business risks, challenges, mitigation strategies
|
|
|
|
Video: {video_title}
|
|
Transcript: {transcript[:4000]}...
|
|
|
|
Provide analysis in this JSON format:
|
|
{{
|
|
"summary": "Business summary of the video content",
|
|
"key_insights": ["insight1", "insight2", "insight3", "insight4", "insight5"],
|
|
"focus_areas": ["area1", "area2", "area3"],
|
|
"recommendations": ["rec1", "rec2", "rec3"],
|
|
"confidence_score": 0.85,
|
|
"business_opportunities": ["opp1", "opp2", "opp3"],
|
|
"strategic_notes": "Key strategic considerations"
|
|
}}
|
|
"""
|
|
|
|
# Generate business analysis
|
|
response = await self.ai_service.generate_response(
|
|
prompt,
|
|
temperature=0.4,
|
|
max_tokens=1500
|
|
)
|
|
|
|
# Parse JSON response
|
|
try:
|
|
analysis_data = json.loads(response)
|
|
except json.JSONDecodeError:
|
|
# Fallback parsing if JSON is malformed
|
|
analysis_data = {
|
|
"summary": response[:500] + "..." if len(response) > 500 else response,
|
|
"key_insights": ["Business analysis completed"],
|
|
"focus_areas": ["Business strategy"],
|
|
"recommendations": ["Review business implications"],
|
|
"confidence_score": 0.7,
|
|
"business_opportunities": ["General business value"],
|
|
"strategic_notes": "Analysis completed"
|
|
}
|
|
|
|
# Calculate processing time
|
|
processing_time = (datetime.now() - start_time).total_seconds()
|
|
|
|
# Build result
|
|
result = {
|
|
"status": "success",
|
|
"analysis_results": {
|
|
"business": {
|
|
"agent_type": "business",
|
|
"agent_id": self.agent_id,
|
|
"summary": analysis_data.get("summary", ""),
|
|
"key_insights": analysis_data.get("key_insights", []),
|
|
"focus_areas": analysis_data.get("focus_areas", []),
|
|
"recommendations": analysis_data.get("recommendations", []),
|
|
"confidence_score": analysis_data.get("confidence_score", 0.8),
|
|
"business_opportunities": analysis_data.get("business_opportunities", []),
|
|
"strategic_notes": analysis_data.get("strategic_notes", ""),
|
|
"processing_time_seconds": processing_time
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.info(f"Business analysis completed for video {video_id} in {processing_time:.2f}s")
|
|
return result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in business analysis: {e}")
|
|
return {
|
|
"status": "error",
|
|
"error": str(e),
|
|
"agent_id": self.agent_id
|
|
}
|
|
|
|
|
|
class UserExperienceAgent(BaseAnalysisAgent):
|
|
"""User Experience Agent for analyzing usability and user-centric aspects."""
|
|
|
|
def __init__(self, ai_service: Optional[DeepSeekService] = None):
|
|
"""Initialize the User Experience Agent.
|
|
|
|
Args:
|
|
ai_service: DeepSeek AI service instance
|
|
"""
|
|
super().__init__(
|
|
agent_id="ux_analyst",
|
|
name="User Experience Agent",
|
|
ai_service=ai_service
|
|
)
|
|
|
|
def _get_capabilities(self) -> List[str]:
|
|
"""Get user experience analysis capabilities."""
|
|
return [
|
|
"user_experience_evaluation",
|
|
"usability_assessment",
|
|
"accessibility_analysis",
|
|
"user_journey_mapping",
|
|
"interaction_design_review",
|
|
"user_research_insights",
|
|
"conversion_optimization",
|
|
"user_feedback_analysis"
|
|
]
|
|
|
|
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Execute user experience analysis of video content."""
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Extract content from state
|
|
transcript = state.get("transcript", "")
|
|
video_id = state.get("video_id", "")
|
|
video_title = state.get("video_title", "")
|
|
|
|
if not transcript:
|
|
raise ServiceError("No transcript provided for UX analysis")
|
|
|
|
# Create UX analysis prompt
|
|
prompt = f"""
|
|
As a User Experience Analyst, analyze this video content focusing on:
|
|
|
|
**User Experience**: Evaluate user-centric design, usability principles, user satisfaction
|
|
**Accessibility**: Assess accessibility considerations, inclusive design, universal access
|
|
**User Journey**: Analyze user workflows, interaction patterns, user pain points
|
|
**Interface Design**: Evaluate UI/UX design principles, visual design, interaction design
|
|
**User Research**: Identify user needs, behaviors, preferences, feedback
|
|
|
|
Video: {video_title}
|
|
Transcript: {transcript[:4000]}...
|
|
|
|
Provide analysis in this JSON format:
|
|
{{
|
|
"summary": "UX summary of the video content",
|
|
"key_insights": ["insight1", "insight2", "insight3", "insight4", "insight5"],
|
|
"focus_areas": ["area1", "area2", "area3"],
|
|
"recommendations": ["rec1", "rec2", "rec3"],
|
|
"confidence_score": 0.85,
|
|
"usability_factors": ["factor1", "factor2", "factor3"],
|
|
"accessibility_notes": "Key accessibility considerations"
|
|
}}
|
|
"""
|
|
|
|
# Generate UX analysis
|
|
response = await self.ai_service.generate_response(
|
|
prompt,
|
|
temperature=0.4,
|
|
max_tokens=1500
|
|
)
|
|
|
|
# Parse JSON response
|
|
try:
|
|
analysis_data = json.loads(response)
|
|
except json.JSONDecodeError:
|
|
# Fallback parsing if JSON is malformed
|
|
analysis_data = {
|
|
"summary": response[:500] + "..." if len(response) > 500 else response,
|
|
"key_insights": ["UX analysis completed"],
|
|
"focus_areas": ["User experience"],
|
|
"recommendations": ["Review user-centric design"],
|
|
"confidence_score": 0.7,
|
|
"usability_factors": ["General usability"],
|
|
"accessibility_notes": "Analysis completed"
|
|
}
|
|
|
|
# Calculate processing time
|
|
processing_time = (datetime.now() - start_time).total_seconds()
|
|
|
|
# Build result
|
|
result = {
|
|
"status": "success",
|
|
"analysis_results": {
|
|
"user_experience": {
|
|
"agent_type": "user_experience",
|
|
"agent_id": self.agent_id,
|
|
"summary": analysis_data.get("summary", ""),
|
|
"key_insights": analysis_data.get("key_insights", []),
|
|
"focus_areas": analysis_data.get("focus_areas", []),
|
|
"recommendations": analysis_data.get("recommendations", []),
|
|
"confidence_score": analysis_data.get("confidence_score", 0.8),
|
|
"usability_factors": analysis_data.get("usability_factors", []),
|
|
"accessibility_notes": analysis_data.get("accessibility_notes", ""),
|
|
"processing_time_seconds": processing_time
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.info(f"UX analysis completed for video {video_id} in {processing_time:.2f}s")
|
|
return result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in UX analysis: {e}")
|
|
return {
|
|
"status": "error",
|
|
"error": str(e),
|
|
"agent_id": self.agent_id
|
|
}
|
|
|
|
|
|
class SynthesisAgent(BaseAnalysisAgent):
|
|
"""Synthesis Agent for combining multiple perspective analyses into unified insights."""
|
|
|
|
def __init__(self, ai_service: Optional[DeepSeekService] = None):
|
|
"""Initialize the Synthesis Agent.
|
|
|
|
Args:
|
|
ai_service: DeepSeek AI service instance
|
|
"""
|
|
super().__init__(
|
|
agent_id="synthesis_agent",
|
|
name="Synthesis Agent",
|
|
ai_service=ai_service
|
|
)
|
|
|
|
def _get_capabilities(self) -> List[str]:
|
|
"""Get synthesis capabilities."""
|
|
return [
|
|
"multi_perspective_synthesis",
|
|
"insight_integration",
|
|
"cross_domain_analysis",
|
|
"pattern_identification",
|
|
"recommendation_consolidation",
|
|
"holistic_evaluation",
|
|
"strategic_synthesis",
|
|
"unified_reporting"
|
|
]
|
|
|
|
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Execute synthesis of multiple perspective analyses."""
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Extract content from state
|
|
analysis_results = state.get("analysis_results", {})
|
|
transcript = state.get("transcript", "")
|
|
video_id = state.get("video_id", "")
|
|
video_title = state.get("video_title", "")
|
|
|
|
if not analysis_results:
|
|
raise ServiceError("No analysis results provided for synthesis")
|
|
|
|
# Create synthesis prompt
|
|
prompt = f"""
|
|
As a Synthesis Agent, combine these multiple perspective analyses into unified insights:
|
|
|
|
Video: {video_title}
|
|
|
|
Analysis Results:
|
|
{json.dumps(analysis_results, indent=2)}
|
|
|
|
Provide synthesis in this JSON format:
|
|
{{
|
|
"summary": "Unified summary combining all perspectives",
|
|
"unified_insights": ["insight1", "insight2", "insight3", "insight4", "insight5", "insight6", "insight7", "insight8"],
|
|
"cross_cutting_themes": ["theme1", "theme2", "theme3"],
|
|
"recommendations": ["rec1", "rec2", "rec3", "rec4", "rec5"],
|
|
"confidence_score": 0.85,
|
|
"perspective_alignment": "How well the different perspectives align",
|
|
"key_takeaways": ["takeaway1", "takeaway2", "takeaway3"]
|
|
}}
|
|
"""
|
|
|
|
# Generate synthesis
|
|
response = await self.ai_service.generate_response(
|
|
prompt,
|
|
temperature=0.3,
|
|
max_tokens=2000
|
|
)
|
|
|
|
# Parse JSON response
|
|
try:
|
|
analysis_data = json.loads(response)
|
|
except json.JSONDecodeError:
|
|
# Fallback parsing if JSON is malformed
|
|
analysis_data = {
|
|
"summary": response[:500] + "..." if len(response) > 500 else response,
|
|
"unified_insights": ["Synthesis analysis completed"],
|
|
"cross_cutting_themes": ["General themes"],
|
|
"recommendations": ["Review combined analysis"],
|
|
"confidence_score": 0.7,
|
|
"perspective_alignment": "Analysis completed",
|
|
"key_takeaways": ["Combined insights available"]
|
|
}
|
|
|
|
# Calculate processing time
|
|
processing_time = (datetime.now() - start_time).total_seconds()
|
|
|
|
# Build result
|
|
result = {
|
|
"status": "success",
|
|
"analysis_results": {
|
|
"synthesis": {
|
|
"agent_type": "synthesis",
|
|
"agent_id": self.agent_id,
|
|
"summary": analysis_data.get("summary", ""),
|
|
"unified_insights": analysis_data.get("unified_insights", []),
|
|
"cross_cutting_themes": analysis_data.get("cross_cutting_themes", []),
|
|
"recommendations": analysis_data.get("recommendations", []),
|
|
"confidence_score": analysis_data.get("confidence_score", 0.8),
|
|
"perspective_alignment": analysis_data.get("perspective_alignment", ""),
|
|
"key_takeaways": analysis_data.get("key_takeaways", []),
|
|
"processing_time_seconds": processing_time
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.info(f"Synthesis completed for video {video_id} in {processing_time:.2f}s")
|
|
return result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in synthesis: {e}")
|
|
return {
|
|
"status": "error",
|
|
"error": str(e),
|
|
"agent_id": self.agent_id
|
|
} |