feat: Implement Today's Workflow and Agent Huddle enhancements

This commit is contained in:
ajaysi
2026-03-01 20:15:31 +05:30
parent 62d9c2e836
commit f8f7ddeb2a
25 changed files with 1852 additions and 272 deletions

View File

@@ -155,7 +155,7 @@ def track_agent_usage_sync(user_id: str, model_name: str, prompt: str, response_
db.execute(log_query, {
'user_id': user_id,
'provider': provider_enum.name, # Use name (GEMINI) not value (gemini) for SQLAlchemy Enum
'provider': provider_enum.value, # Use value (gemini) not name (GEMINI) for consistency
'endpoint': 'agent_action',
'method': 'GENERATE',
'model_used': model_name,

View File

@@ -107,6 +107,20 @@ class AgentAction:
if self.created_at is None:
self.created_at = datetime.utcnow().isoformat()
@dataclass
class TaskProposal:
"""Represents a daily task proposed by an agent"""
title: str
description: str
pillar_id: str # plan, generate, publish, analyze, engage, remarket
priority: str # high, medium, low
estimated_time: int # minutes
source_agent: str
reasoning: str
context_data: Optional[Dict[str, Any]] = None
action_type: str = "navigate"
action_url: Optional[str] = None
@dataclass
class MarketSignal:
"""Represents a market change or opportunity"""
@@ -833,6 +847,13 @@ class BaseALwrityAgent(ABC):
self.performance.success_rate = (
self.performance.successful_actions / self.performance.total_actions
)
async def propose_daily_tasks(self, context: Dict[str, Any]) -> List[TaskProposal]:
"""
Propose daily tasks based on the agent's domain and context.
Must be implemented by specialized agents.
"""
return []
# Calculate efficiency score (0.0 to 1.0)
# Based on success rate and response time

View File

@@ -11,7 +11,7 @@ from typing import List, Dict, Any, Optional
from datetime import datetime
from loguru import logger
from ..txtai_service import TxtaiIntelligenceService
from services.intelligence.agents.core_agent_framework import BaseALwrityAgent, AgentAction
from services.intelligence.agents.core_agent_framework import BaseALwrityAgent, AgentAction, TaskProposal
from services.seo_tools.content_strategy_service import ContentStrategyService
from services.analytics import PlatformAnalyticsService
from services.intelligence.sif_agents import SharedLLMWrapper, LocalLLMWrapper
@@ -122,6 +122,56 @@ class StrategyArchitectAgent(SIFBaseAgent):
# Simple confidence based on cluster size - larger clusters are more reliable
return min(1.0, len(cluster_indices) / 10.0)
async def propose_daily_tasks(self, context: Dict[str, Any]) -> List[TaskProposal]:
"""Propose PLAN pillar tasks based on semantic analysis."""
proposals = []
# 1. Pillar Health Check
try:
# We use a shorter timeout or cached check if possible, but discover_pillars is fairly fast
pillars = await self.discover_pillars()
if not pillars:
proposals.append(TaskProposal(
title="Establish Content Pillars",
description="Your content strategy lacks defined pillars. Let's analyze your niche to find core topics.",
pillar_id="plan",
priority="high",
estimated_time=15,
source_agent="StrategyArchitectAgent",
reasoning="No content pillars detected via SIF clustering.",
action_type="navigate",
action_url="/content-planning-dashboard"
))
elif len(pillars) < 3:
proposals.append(TaskProposal(
title="Expand Content Pillars",
description=f"You only have {len(pillars)} active pillars. Consider diversifying your strategy.",
pillar_id="plan",
priority="medium",
estimated_time=20,
source_agent="StrategyArchitectAgent",
reasoning=f"Low pillar diversity ({len(pillars)} detected).",
action_type="navigate",
action_url="/content-planning-dashboard"
))
except Exception as e:
logger.warning(f"[{self.__class__.__name__}] Error checking pillars for proposals: {e}")
# 2. Strategy Review (Generic fallback)
proposals.append(TaskProposal(
title="Review Strategic Goals",
description="Ensure your content output aligns with your quarterly business goals.",
pillar_id="plan",
priority="low",
estimated_time=10,
source_agent="StrategyArchitectAgent",
reasoning="Routine strategy maintenance.",
action_type="navigate",
action_url="/content-planning-dashboard"
))
return proposals
async def find_semantic_gaps(self, competitor_indices: List[int]) -> List[Dict[str, Any]]:
"""Compare user content vs competitor content to find missing topics."""
self._log_agent_operation("Finding semantic content gaps", competitor_count=len(competitor_indices))
@@ -856,6 +906,38 @@ class ContentStrategyAgent(BaseALwrityAgent):
self.sif_service = SIFIntegrationService(user_id)
except Exception as e:
logger.warning(f"Failed to initialize SIF service for ContentStrategyAgent: {e}")
async def propose_daily_tasks(self, context: Dict[str, Any]) -> List[TaskProposal]:
"""Propose GENERATE pillar tasks."""
proposals = []
# 1. Content Gap Analysis
proposals.append(TaskProposal(
title="Analyze Content Gaps",
description="Identify missing topics in your strategy compared to competitors.",
pillar_id="generate",
priority="high",
estimated_time=30,
source_agent="ContentStrategyAgent",
reasoning="Regular gap analysis ensures competitive relevance.",
action_type="navigate",
action_url="/content-planning-dashboard"
))
# 2. Draft New Content
proposals.append(TaskProposal(
title="Draft New Blog Post",
description="Create a new article targeting your primary keywords.",
pillar_id="generate",
priority="medium",
estimated_time=45,
source_agent="ContentStrategyAgent",
reasoning="Maintain publishing consistency.",
action_type="navigate",
action_url="/blog-writer"
))
return proposals
def _create_txtai_agent(self) -> Agent:
"""Create Content Strategy Agent using txtai native framework"""
@@ -1274,7 +1356,26 @@ class CompetitorResponseAgent(BaseALwrityAgent):
self.sif_service = SIFIntegrationService(user_id)
except Exception as e:
logger.warning(f"Failed to initialize SIF service for CompetitorResponseAgent: {e}")
async def propose_daily_tasks(self, context: Dict[str, Any]) -> List[TaskProposal]:
"""Propose REMARKET pillar tasks."""
proposals = []
# 1. Competitor Monitoring
proposals.append(TaskProposal(
title="Monitor Competitor Activity",
description="Check for new moves from your key competitors.",
pillar_id="remarket",
priority="medium",
estimated_time=15,
source_agent="CompetitorResponseAgent",
reasoning="Stay ahead of market changes.",
action_type="navigate",
action_url="/seo-dashboard"
))
return proposals
def _create_txtai_agent(self) -> Agent:
"""Create Competitor Response Agent using txtai native framework"""
if not TXTAI_AVAILABLE:
@@ -1463,7 +1564,39 @@ class SEOOptimizationAgent(BaseALwrityAgent):
self.sif_service = SIFIntegrationService(user_id)
except Exception as e:
logger.warning(f"Failed to initialize SIF service for SEOOptimizationAgent: {e}")
async def propose_daily_tasks(self, context: Dict[str, Any]) -> List[TaskProposal]:
"""Propose ANALYZE pillar tasks."""
proposals = []
# 1. Technical Audit
proposals.append(TaskProposal(
title="Review SEO Health",
description="Check for critical technical issues affecting your search visibility.",
pillar_id="analyze",
priority="high",
estimated_time=20,
source_agent="SEOOptimizationAgent",
reasoning="Regular health checks prevent traffic drops.",
action_type="navigate",
action_url="/seo-dashboard"
))
# 2. Keyword Opportunities
proposals.append(TaskProposal(
title="Optimize Underperforming Keywords",
description="Identify keywords where you rank on page 2 and optimize content to boost them.",
pillar_id="analyze",
priority="medium",
estimated_time=40,
source_agent="SEOOptimizationAgent",
reasoning="Low-hanging fruit for traffic growth.",
action_type="navigate",
action_url="/seo-dashboard"
))
return proposals
def _create_txtai_agent(self) -> Agent:
"""Create SEO Optimization Agent using txtai native framework"""
if not TXTAI_AVAILABLE:
@@ -2101,7 +2234,39 @@ class SocialAmplificationAgent(BaseALwrityAgent):
self.sif_service = SIFIntegrationService(user_id)
except Exception as e:
logger.warning(f"Failed to initialize SIF service for SocialAmplificationAgent: {e}")
async def propose_daily_tasks(self, context: Dict[str, Any]) -> List[TaskProposal]:
"""Propose PUBLISH and ENGAGE pillar tasks."""
proposals = []
# 1. Publish Task
proposals.append(TaskProposal(
title="Schedule Social Content",
description="Plan and schedule your posts for the week to maintain consistent presence.",
pillar_id="publish",
priority="high",
estimated_time=20,
source_agent="SocialAmplificationAgent",
reasoning="Consistency is key for algorithm growth.",
action_type="navigate",
action_url="/scheduler-dashboard"
))
# 2. Engage Task
proposals.append(TaskProposal(
title="Engage with Community",
description="Respond to comments and interact with industry leaders' posts.",
pillar_id="engage",
priority="medium",
estimated_time=15,
source_agent="SocialAmplificationAgent",
reasoning="Community building increases reach.",
action_type="navigate",
action_url="/social-dashboard"
))
return proposals
def _create_txtai_agent(self) -> Agent:
"""Create Social Amplification Agent using txtai native framework"""
if not TXTAI_AVAILABLE: