Add strategy architect agent to daily planning committee
This commit is contained in:
@@ -24,7 +24,11 @@ from services.intelligence.agents.core_agent_framework import (
|
||||
BaseALwrityAgent, AgentAction, AgentPerformance, StrategyOrchestratorAgent
|
||||
)
|
||||
from services.intelligence.agents.specialized_agents import (
|
||||
ContentStrategyAgent, CompetitorResponseAgent, SEOOptimizationAgent, SocialAmplificationAgent
|
||||
ContentStrategyAgent,
|
||||
CompetitorResponseAgent,
|
||||
SEOOptimizationAgent,
|
||||
SocialAmplificationAgent,
|
||||
StrategyArchitectAgent,
|
||||
)
|
||||
from services.intelligence.agents.trend_surfer_agent import TrendSurferAgent
|
||||
from services.intelligence.agents.market_signal_detector import (
|
||||
@@ -141,6 +145,13 @@ class ALwrityAgentOrchestrator:
|
||||
if enabled_by_key.get("content_strategist", True):
|
||||
self.content_agent = ContentStrategyAgent(self.user_id, self.config.shared_llm, llm=self.llm)
|
||||
self.agents['content'] = self.content_agent
|
||||
|
||||
# Strategy Architect Agent
|
||||
if enabled_by_key.get("strategy_architect", True):
|
||||
from services.intelligence.txtai_service import TxtaiIntelligenceService
|
||||
intel_service = TxtaiIntelligenceService(self.user_id)
|
||||
self.strategy_agent = StrategyArchitectAgent(intel_service, self.user_id)
|
||||
self.agents['strategy'] = self.strategy_agent
|
||||
|
||||
# Competitor Response Agent
|
||||
if enabled_by_key.get("competitor_analyst", True):
|
||||
|
||||
@@ -279,10 +279,10 @@ async def generate_agent_enhanced_plan(db: Session, user_id: str, date: str) ->
|
||||
# Define agents to poll
|
||||
agents_to_poll = [
|
||||
orchestrator.agents.get('content'), # ContentStrategyAgent
|
||||
orchestrator.agents.get('strategy'), # StrategyArchitectAgent
|
||||
orchestrator.agents.get('seo'), # SEOOptimizationAgent
|
||||
orchestrator.agents.get('social'), # SocialAmplificationAgent
|
||||
orchestrator.agents.get('competitor'), # CompetitorResponseAgent
|
||||
# Add StrategyArchitect if available in orchestrator.agents
|
||||
]
|
||||
|
||||
# Filter out None agents (disabled/failed init)
|
||||
|
||||
@@ -20,6 +20,14 @@ class DummyActivity:
|
||||
return None
|
||||
|
||||
|
||||
class DummyMemoryService:
|
||||
def __init__(self, user_id, db):
|
||||
pass
|
||||
|
||||
async def filter_redundant_proposals(self, proposals):
|
||||
return proposals
|
||||
|
||||
|
||||
class DummyAgent:
|
||||
def __init__(self, proposals):
|
||||
self._proposals = proposals
|
||||
@@ -28,10 +36,11 @@ class DummyAgent:
|
||||
return self._proposals
|
||||
|
||||
|
||||
def _mock_orchestrator_with_agents(proposals):
|
||||
def _mock_orchestrator_with_agents(content_proposals=None, strategy_proposals=None):
|
||||
return SimpleNamespace(
|
||||
agents={
|
||||
"content": DummyAgent(proposals),
|
||||
"content": DummyAgent(content_proposals or []),
|
||||
"strategy": DummyAgent(strategy_proposals or []),
|
||||
"seo": None,
|
||||
"social": None,
|
||||
"competitor": None,
|
||||
@@ -55,7 +64,7 @@ async def test_generate_agent_enhanced_plan_preserves_full_committee_coverage(mo
|
||||
]
|
||||
|
||||
async def _get_orchestrator(user_id):
|
||||
return _mock_orchestrator_with_agents(proposals)
|
||||
return _mock_orchestrator_with_agents(content_proposals=proposals)
|
||||
|
||||
monkeypatch.setattr(svc, "build_grounding_context", lambda db, user_id, date: {})
|
||||
monkeypatch.setattr(svc.orchestration_service, "get_or_create_orchestrator", _get_orchestrator)
|
||||
@@ -74,7 +83,7 @@ async def test_generate_agent_enhanced_plan_backfills_missing_committee_pillars(
|
||||
]
|
||||
|
||||
async def _get_orchestrator(user_id):
|
||||
return _mock_orchestrator_with_agents(proposals)
|
||||
return _mock_orchestrator_with_agents(content_proposals=proposals)
|
||||
|
||||
monkeypatch.setattr(svc, "build_grounding_context", lambda db, user_id, date: {})
|
||||
monkeypatch.setattr(svc.orchestration_service, "get_or_create_orchestrator", _get_orchestrator)
|
||||
@@ -88,7 +97,7 @@ async def test_generate_agent_enhanced_plan_backfills_missing_committee_pillars(
|
||||
@pytest.mark.asyncio
|
||||
async def test_generate_agent_enhanced_plan_full_fallback_path_still_covers_all_pillars(monkeypatch):
|
||||
async def _get_orchestrator(user_id):
|
||||
return _mock_orchestrator_with_agents([])
|
||||
return _mock_orchestrator_with_agents()
|
||||
|
||||
monkeypatch.setattr(svc, "build_grounding_context", lambda db, user_id, date: {})
|
||||
monkeypatch.setattr(svc.orchestration_service, "get_or_create_orchestrator", _get_orchestrator)
|
||||
@@ -103,3 +112,55 @@ async def test_generate_agent_enhanced_plan_full_fallback_path_still_covers_all_
|
||||
|
||||
assert _covered_pillars(result) == set(svc.PILLAR_IDS)
|
||||
assert len(result["tasks"]) >= len(svc.PILLAR_IDS)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_generate_agent_enhanced_plan_strategy_plan_task_survives_dedupe_and_coverage(monkeypatch):
|
||||
content_proposals = [
|
||||
TaskProposal(
|
||||
"Review Strategic Goals",
|
||||
"desc",
|
||||
"plan",
|
||||
"medium",
|
||||
10,
|
||||
"ContentStrategyAgent",
|
||||
"why",
|
||||
{},
|
||||
"navigate",
|
||||
"/content-planning-dashboard",
|
||||
),
|
||||
]
|
||||
strategy_proposals = [
|
||||
TaskProposal(
|
||||
"Review Strategic Goals",
|
||||
"desc",
|
||||
"plan",
|
||||
"high",
|
||||
10,
|
||||
"StrategyArchitectAgent",
|
||||
"why",
|
||||
{},
|
||||
"navigate",
|
||||
"/content-planning-dashboard",
|
||||
),
|
||||
]
|
||||
|
||||
async def _get_orchestrator(user_id):
|
||||
return _mock_orchestrator_with_agents(
|
||||
content_proposals=content_proposals,
|
||||
strategy_proposals=strategy_proposals,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(svc, "build_grounding_context", lambda db, user_id, date: {})
|
||||
monkeypatch.setattr(svc.orchestration_service, "get_or_create_orchestrator", _get_orchestrator)
|
||||
monkeypatch.setattr(svc, "TaskMemoryService", DummyMemoryService)
|
||||
|
||||
result = await svc.generate_agent_enhanced_plan(db=None, user_id="u1", date="2026-01-01")
|
||||
|
||||
assert _covered_pillars(result) == set(svc.PILLAR_IDS)
|
||||
plan_tasks = [task for task in result["tasks"] if task["pillarId"] == "plan"]
|
||||
assert any(
|
||||
task["title"] == "Review Strategic Goals"
|
||||
and task["metadata"].get("source_agent") == "StrategyArchitectAgent"
|
||||
for task in plan_tasks
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user