7e0938fe7d
Wipes today's briefing messages (keeps the conversation row) and optionally re-fires the compilation slot to regenerate. Pairs with the new POST /api/briefing/reset-today backend route. Also drops the stale briefing_mode reference from trigger_briefing's docstring now that legacy mode is gone. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
99 lines
3.5 KiB
Python
99 lines
3.5 KiB
Python
"""MCP tools for Fable briefings and RSS feed management."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from fable_mcp.client import FableClient
|
|
|
|
|
|
# ── RSS feeds ────────────────────────────────────────────────────────────────
|
|
|
|
async def list_rss_feeds(client: FableClient) -> dict[str, Any]:
|
|
"""List the user's RSS feeds."""
|
|
return await client.get("/api/briefing/feeds")
|
|
|
|
|
|
async def add_rss_feed(
|
|
client: FableClient,
|
|
*,
|
|
url: str,
|
|
title: str | None = None,
|
|
category: str | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Add a new RSS feed. Title is optional — auto-populated from feed metadata."""
|
|
payload: dict[str, Any] = {"url": url}
|
|
if title:
|
|
payload["title"] = title
|
|
if category:
|
|
payload["category"] = category
|
|
return await client.post("/api/briefing/feeds", json=payload)
|
|
|
|
|
|
async def remove_rss_feed(client: FableClient, *, feed_id: int) -> dict[str, Any]:
|
|
"""Remove an RSS feed by ID."""
|
|
return await client.delete(f"/api/briefing/feeds/{feed_id}")
|
|
|
|
|
|
# ── Briefings ────────────────────────────────────────────────────────────────
|
|
|
|
async def list_briefing_conversations(client: FableClient) -> dict[str, Any]:
|
|
"""List the user's briefing conversations, newest first."""
|
|
return await client.get("/api/briefing/conversations")
|
|
|
|
|
|
async def get_today_briefing(client: FableClient) -> dict[str, Any]:
|
|
"""Fetch today's briefing conversation with all messages."""
|
|
return await client.get("/api/briefing/conversations/today")
|
|
|
|
|
|
async def get_briefing_messages(
|
|
client: FableClient,
|
|
*,
|
|
conversation_id: int,
|
|
) -> dict[str, Any]:
|
|
"""Fetch messages for a specific briefing conversation."""
|
|
return await client.get(f"/api/briefing/conversations/{conversation_id}/messages")
|
|
|
|
|
|
async def trigger_briefing(
|
|
client: FableClient,
|
|
*,
|
|
slot: str = "compilation",
|
|
) -> dict[str, Any]:
|
|
"""Manually trigger a briefing slot — fires data refresh and runs the pipeline.
|
|
|
|
Slot is one of: compilation (full morning), morning, midday, afternoon.
|
|
"""
|
|
return await client.post("/api/briefing/trigger", json={"slot": slot})
|
|
|
|
|
|
async def reset_today_briefing(
|
|
client: FableClient,
|
|
*,
|
|
run_compilation: bool = True,
|
|
) -> dict[str, Any]:
|
|
"""Delete all messages in today's briefing and optionally regenerate.
|
|
|
|
Wipes the messages in today's briefing conversation (keeping the
|
|
conversation row), then, if ``run_compilation`` is True, fires the
|
|
compilation slot so a fresh briefing lands in its place.
|
|
"""
|
|
reset = await client.post("/api/briefing/reset-today")
|
|
if not run_compilation:
|
|
return {"reset": reset, "triggered": None}
|
|
triggered = await client.post(
|
|
"/api/briefing/trigger", json={"slot": "compilation"}
|
|
)
|
|
return {"reset": reset, "triggered": triggered}
|
|
|
|
|
|
# ── Generic conversations ───────────────────────────────────────────────────
|
|
|
|
async def get_conversation(
|
|
client: FableClient,
|
|
*,
|
|
conversation_id: int,
|
|
) -> dict[str, Any]:
|
|
"""Fetch any conversation (chat or briefing) with all messages and tool calls."""
|
|
return await client.get(f"/api/chat/conversations/{conversation_id}")
|