refactor(briefing)!: remove legacy one-shot synthesis, agentic-only

Deletes ~760 lines of legacy briefing code: format_task, compute_task_hash,
upsert_task_snapshots, _gather_internal, _gather_weekly_review,
_llm_synthesise, and the unified prompt helpers. run_compilation and
run_slot_injection are now agentic-tool-use-loop only.

briefing_scheduler and user_profile migrated from the deleted helper to
services.llm.generate_completion (retry + keep_alive baked in).

routes/briefing.manual_trigger now persists agentic tool-call receipts
via _persist_agentic_messages (previously silently dropped them) and
adds POST /api/briefing/reset-today to wipe today's briefing messages.

BREAKING: briefing_mode setting no longer honored; no legacy fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 20:42:42 -04:00
parent 66f906a629
commit 9eba6ac107
4 changed files with 87 additions and 785 deletions
+39 -1
View File
@@ -308,14 +308,52 @@ async def manual_trigger():
logger.warning("Pre-trigger refresh failed for user %d", g.user.id, exc_info=True)
from fabledassistant.services.briefing_pipeline import run_compilation
from fabledassistant.services.briefing_scheduler import _persist_agentic_messages
model = await get_setting(g.user.id, "default_model", "")
conv = await get_or_create_today_conversation(g.user.id, model)
text, metadata = await run_compilation(g.user.id, slot, model)
msg = await post_message(conv.id, "assistant", text, metadata=metadata)
await _persist_agentic_messages(conv.id, slot, metadata)
final_meta = {k: v for k, v in metadata.items() if k != "agentic_messages"}
final_meta["briefing_slot"] = slot
msg = await post_message(conv.id, "assistant", text, metadata=final_meta)
return jsonify({"conversation_id": conv.id, "message_id": msg.id, "slot": slot})
@briefing_bp.route("/reset-today", methods=["POST"])
@_REQUIRE
async def reset_today_briefing():
"""Delete all messages in today's briefing conversation.
The conversation row itself is kept so its id stays stable for any
open UI sessions. Intended for "wipe and start fresh" workflows
driven from the MCP when iterating on prompts. Pair with
``POST /api/briefing/trigger`` to immediately regenerate.
"""
from datetime import date as _date
from sqlalchemy import delete as _delete
today = _date.today()
async with async_session() as session:
result = await session.execute(
select(Conversation).where(
Conversation.user_id == g.user.id,
Conversation.conversation_type == "briefing",
Conversation.briefing_date == today,
)
)
conv = result.scalars().first()
if conv is None:
return jsonify({"deleted": 0, "conversation_id": None})
deleted_result = await session.execute(
_delete(Message).where(Message.conversation_id == conv.id)
)
await session.commit()
deleted = deleted_result.rowcount or 0
return jsonify({"deleted": deleted, "conversation_id": conv.id})
# ── RSS Reactions ──────────────────────────────────────────────────────────────
@briefing_bp.route("/rss-reactions", methods=["POST"])