feat(fable-mcp): add reset_today_briefing tool

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>
This commit is contained in:
2026-04-10 20:42:48 -04:00
parent 9eba6ac107
commit 7e0938fe7d
2 changed files with 52 additions and 4 deletions
+32 -4
View File
@@ -684,10 +684,9 @@ async def fable_trigger_briefing(slot: str = "compilation") -> dict:
"""Manually run a briefing slot for the current user.
Fires the same data refresh the scheduler does (RSS, weather),
runs the briefing pipeline (legacy or agentic based on the user's
``briefing_mode`` setting), and writes the result into today's
briefing conversation. Use this to test prompt changes without
waiting for the next scheduled slot.
runs the agentic briefing pipeline, and writes the result into
today's briefing conversation. Use this to test prompt changes
without waiting for the next scheduled slot.
Args:
slot: One of ``compilation`` (full morning, default), ``morning``,
@@ -699,6 +698,35 @@ async def fable_trigger_briefing(slot: str = "compilation") -> dict:
return await briefing.trigger_briefing(client, slot=slot)
@mcp.tool()
async def fable_reset_today_briefing(run_compilation: bool = True) -> dict:
"""Wipe today's briefing and (optionally) regenerate from scratch.
Deletes every message in today's briefing conversation — the
conversation row itself is kept so its id stays stable for any
open UI sessions. If ``run_compilation`` is True (the default),
immediately fires the compilation slot afterward so a fresh
briefing lands in place of the deleted content.
Use this when iterating on briefing prompts or tools and you want
to start from a clean slate rather than append another slot update
on top of stale output.
Args:
run_compilation: When True, fire ``POST /api/briefing/trigger``
for the ``compilation`` slot immediately after wiping.
Set False to only wipe without regenerating.
Returns a dict with ``reset`` (the delete result: deleted count +
conversation id) and ``triggered`` (the new message payload, or
null if regeneration was skipped).
"""
async with FableClient() as client:
return await briefing.reset_today_briefing(
client, run_compilation=run_compilation,
)
# ---------------------------------------------------------------------------
# Generic conversation access
# ---------------------------------------------------------------------------
+20
View File
@@ -67,6 +67,26 @@ async def trigger_briefing(
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(