Implement runtime agent loop and container hygiene
This commit is contained in:
126
app/exports/markdown.py
Normal file
126
app/exports/markdown.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""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)
|
||||
|
||||
# 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 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
|
||||
Reference in New Issue
Block a user