Files
signalscout-backend/app/agent/runner.py
T

83 lines
3.3 KiB
Python

from __future__ import annotations
import logging
from datetime import date
from typing import Optional
from sqlalchemy.orm import Session
from app.agent.report_writer import ReportWriter
from app.core.config import Settings
from app.db.repository import AgentRepository
from app.integrations.github_client import GitHubHotProjectClient
from app.integrations.news_search_client import NewsSearchClient
from app.llm.grok_client import GrokIntelligenceClient
from app.schemas.agent import RunResponse
logger = logging.getLogger(__name__)
class AgentRunner:
"""Coordinates source collection, persistence, and report writing."""
def __init__(self, db: Session, settings: Settings) -> None:
self.repo = AgentRepository(db)
self.db = db
self.github = GitHubHotProjectClient(settings)
self.news = NewsSearchClient(settings)
self.grok = GrokIntelligenceClient(settings)
self.writer = ReportWriter(settings.report_dir)
def run_daily(self, run_date: Optional[date] = None) -> RunResponse:
# Runner统一编排候选采集、模型研判和持久化,保证一次运行只有一种业务路径。
current_date = run_date or date.today()
request_payload = {
"run_date": current_date.isoformat(),
"mode": "grok_agent",
}
run = self.repo.create_run(request_payload=request_payload)
logger.info("agent_run_started run_id=%s run_date=%s mode=grok_agent", run.id, current_date)
try:
topics = self.repo.list_enabled_topics()
news_candidates = self.news.collect_ai_news(run_date=current_date)
github_projects = self.github.collect_hot_projects(run_date=current_date)
result = self.grok.collect_daily_intelligence(
topics=topics,
news_candidates=news_candidates,
github_projects=github_projects,
run_date=current_date,
)
signals = self.repo.save_signals(run=run, items=result.signals)
report_path = self.writer.write_daily_report(current_date, result.report_markdown)
self.repo.save_report(
run=run,
title=result.title,
content_md=result.report_markdown,
file_path=str(report_path),
)
self.repo.mark_run_complete(
run=run,
raw_response={
"mode": "grok_agent",
"topic_count": len(topics),
"news_candidate_count": len(news_candidates),
"github_project_count": len(github_projects),
"model": self.grok.settings.llm_model,
"model_response": result.raw_response,
},
)
self.db.commit()
logger.info(
"agent_run_completed run_id=%s signals=%s report_path=%s",
run.id,
len(signals),
report_path,
)
return RunResponse(run_id=run.id, status=run.status, report_path=str(report_path))
except Exception as exc:
self.repo.mark_run_failed(run=run, error=str(exc))
self.db.commit()
logger.exception("agent_run_failed run_id=%s error=%s", run.id, exc)
raise