""" Curated read-only tool subset for agentic briefings. The main chat pipeline exposes 40+ tools via ``tools.get_tools_for_user``, including mutating tools (``create_task``, ``delete_note``) and external-search tools (``search_images``, ``search_web``). Neither is appropriate for a scheduled background job that generates briefings — briefings are read-only and should not reach out to the internet on the user's behalf, and leaving high-noise tools in the list increases the chance of spurious calls (e.g. ``search_images`` firing on "what meeting?"). This module maintains an explicit allowlist. New tools added to ``tools.py`` are not automatically exposed to briefings — they must be opted in by name here. """ import logging from fabledassistant.services.tools import get_tools_for_user logger = logging.getLogger(__name__) # Explicit allowlist — tools a briefing is permitted to call. Read-only only. # Any tool not listed here is invisible to the briefing model. BRIEFING_TOOL_NAMES: frozenset[str] = frozenset({ # Tasks — what's actionable today, overdue, or high priority "list_tasks", # Calendar — internal event store and CalDAV (if configured) "list_events", "search_events", # Weather — today's forecast for the user's configured locations "get_weather", # News — RSS items filtered by user preferences "get_rss_items", # Projects — context for prioritization and narrative continuity "list_projects", "search_projects", "get_project", # Notes — surface recent captures for "pick up where you left off" "list_notes", "get_note", }) async def get_briefing_tools(user_id: int) -> list[dict]: """Return the tool schemas a briefing run is permitted to call. Builds the user's full tool list (so user-specific gating such as CalDAV availability still applies) and filters it down to the briefing allowlist. """ all_tools = await get_tools_for_user(user_id) filtered = [ t for t in all_tools if t.get("function", {}).get("name") in BRIEFING_TOOL_NAMES ] logger.debug( "Briefing tools for user %d: %d of %d selected", user_id, len(filtered), len(all_tools), ) return filtered