"""Tool: read_briefing – read or list DB-backed handover briefings.""" from __future__ import annotations import json import os from typing import Optional from helpers.tool import Tool, Response from usr.plugins.a0_software_orchestrator.helpers.briefing_file import ( read_briefing as read_briefing_text, list_briefings_for, ) from usr.plugins.a0_software_orchestrator.helpers.db_state_store import get_briefing from usr.plugins.a0_software_orchestrator.helpers.exceptions import PluginDBError def _resolve_name(project_name: str = "", project_root: str = "") -> str: if project_name: return project_name.strip() if project_root: return os.path.basename(project_root.rstrip("/")) return os.path.basename(os.getcwd()) class ReadBriefing(Tool): """Read or list handover briefings created by handover_to_specialist. Args: action: "read" (default), "metadata", or "list". briefing_id: DB id returned by handover_to_specialist. project_name/project_root: used for action=list. specialist: optional filter for action=list. max_bytes: max bytes of markdown returned by action=read. format: "text" or "json". """ async def execute( self, action: str = "read", briefing_id: int = 0, project_name: str = "", project_root: str = "", specialist: Optional[str] = None, max_bytes: int = 32000, format: str = "text", **kwargs, ): try: if action == "list": name = _resolve_name(project_name, project_root) rows = list_briefings_for( project_name=name, project_root=project_root, specialist=specialist, limit=int(kwargs.get("limit", 50)), ) return Response( message=json.dumps(rows, indent=2, ensure_ascii=False, default=str), break_loop=False, ) if not briefing_id: return Response( message="ERROR: 'briefing_id' is required for action=read/metadata.", break_loop=False, ) if action == "metadata": rec = get_briefing(int(briefing_id)) if not rec: return Response(message=f"Briefing id={briefing_id} not found.", break_loop=False) rec = dict(rec) rec.pop("section_md", None) return Response( message=json.dumps(rec, indent=2, ensure_ascii=False, default=str), break_loop=False, ) if action == "read": text = read_briefing_text(int(briefing_id), max_bytes=max(1, int(max_bytes))) if not text: return Response(message=f"Briefing id={briefing_id} not found.", break_loop=False) if format == "json": return Response( message=json.dumps({"briefing_id": briefing_id, "section_md": text}, indent=2, ensure_ascii=False), break_loop=False, ) return Response(message=text, break_loop=False) return Response( message=f"Unknown action {action!r}. Supported: read, metadata, list", break_loop=False, ) except (ValueError, PluginDBError) as e: return Response(message=f"ERROR: {e}", break_loop=False)