143 lines
4.8 KiB
Python
143 lines
4.8 KiB
Python
"""Markdown export functionality for stream ledgers."""
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
from app.config import settings
|
|
from app.memory.database import get_session
|
|
from app.memory.repository import Repository
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class MarkdownExporter:
|
|
"""Exports stream session data as markdown ledgers."""
|
|
|
|
def __init__(self, export_path: str | None = None):
|
|
"""
|
|
Initialize exporter.
|
|
|
|
Args:
|
|
export_path: Directory to export ledgers to (defaults to settings.EXPORT_PATH)
|
|
"""
|
|
self.export_path = Path(export_path or settings.EXPORT_PATH)
|
|
self.export_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
async def export_session(self, session_id: str) -> str:
|
|
"""
|
|
Export a session as a markdown ledger.
|
|
|
|
Args:
|
|
session_id: Session ID to export
|
|
|
|
Returns:
|
|
Markdown content
|
|
"""
|
|
async for db_session in get_session():
|
|
repo = Repository(db_session)
|
|
|
|
session = await repo.get_session(session_id)
|
|
if not session:
|
|
logger.warning(f"Session {session_id} not found")
|
|
return ""
|
|
|
|
# Gather data
|
|
messages = await repo.get_recent_messages(session_id, limit=1000)
|
|
actions = await repo.get_session_actions(session_id)
|
|
clips = await repo.get_clip_candidates(session_id)
|
|
seeds = await repo.get_blog_seeds(session_id)
|
|
dashboard = await repo.get_dashboard(session_id)
|
|
|
|
dashboard_data = Repository.serialize_dashboard(dashboard)
|
|
|
|
# Build markdown
|
|
date = session.started_at.strftime("%Y-%m-%d")
|
|
ledger = f"# Sanctum Ledger — {date}\n\n"
|
|
ledger += f"**Channel:** {session.channel_name}\n"
|
|
ledger += f"**Started:** {session.started_at.isoformat()}\n"
|
|
if session.ended_at:
|
|
ledger += f"**Ended:** {session.ended_at.isoformat()}\n"
|
|
ledger += "\n"
|
|
|
|
# Stream Theme
|
|
ledger += "## Stream Theme\n"
|
|
if dashboard_data:
|
|
if dashboard_data.get("stream_title"):
|
|
ledger += f"**Title:** {dashboard_data['stream_title']}\n"
|
|
if dashboard_data.get("game"):
|
|
ledger += f"**Game:** {dashboard_data['game']}\n"
|
|
if dashboard_data.get("mood"):
|
|
ledger += f"**Mood:** {dashboard_data['mood']}\n"
|
|
if dashboard_data.get("content_angle"):
|
|
ledger += f"**Content Angle:** {dashboard_data['content_angle']}\n"
|
|
if dashboard_data.get("session_goals"):
|
|
ledger += "\n**Session Goals**\n"
|
|
for goal in dashboard_data["session_goals"]:
|
|
ledger += f"- {goal}\n"
|
|
elif session.theme:
|
|
ledger += f"{session.theme}\n"
|
|
else:
|
|
ledger += "*No theme recorded*\n"
|
|
ledger += "\n"
|
|
|
|
# Notable Discussion
|
|
ledger += "## Notable Discussion\n"
|
|
if messages:
|
|
for msg in messages[:20]: # Latest 20 messages
|
|
ledger += f"- **{msg.username}:** {msg.content[:100]}\n"
|
|
else:
|
|
ledger += "*No messages recorded*\n"
|
|
ledger += "\n"
|
|
|
|
# Agent Actions
|
|
ledger += "## Agent Actions\n"
|
|
if actions:
|
|
for action in actions:
|
|
ledger += f"- **{action.mode}** ({action.action_type}): {action.description}\n"
|
|
else:
|
|
ledger += "*No agent actions recorded*\n"
|
|
ledger += "\n"
|
|
|
|
# Clip Candidates
|
|
ledger += "## Clip Candidates\n"
|
|
if clips:
|
|
for clip in clips:
|
|
ledger += f"- {clip.reason}\n"
|
|
else:
|
|
ledger += "*No clip candidates identified*\n"
|
|
ledger += "\n"
|
|
|
|
# Blog Seeds
|
|
ledger += "## Blog Seeds\n"
|
|
if seeds:
|
|
for seed in seeds:
|
|
ledger += f"- **{seed.topic}:** {seed.description}\n"
|
|
else:
|
|
ledger += "*No blog seeds proposed*\n"
|
|
ledger += "\n"
|
|
|
|
logger.info(f"Generated ledger for session {session_id}")
|
|
return ledger
|
|
|
|
async def save_session_ledger(self, session_id: str) -> Path:
|
|
"""
|
|
Export session and save to file.
|
|
|
|
Args:
|
|
session_id: Session ID
|
|
|
|
Returns:
|
|
Path to saved file
|
|
"""
|
|
ledger = await self.export_session(session_id)
|
|
|
|
date = datetime.utcnow().strftime("%Y-%m-%d")
|
|
filename = f"ledger_{date}_{session_id[:8]}.md"
|
|
filepath = self.export_path / filename
|
|
|
|
filepath.write_text(ledger, encoding="utf-8")
|
|
logger.info(f"Saved ledger to {filepath}")
|
|
|
|
return filepath
|