feat(briefing): differentiated check-in slots — midday progress nudge, afternoon wrap-up
This commit is contained in:
@@ -369,26 +369,77 @@ async def _llm_synthesise(system_prompt: str, user_prompt: str, model: str, num_
|
||||
return ""
|
||||
|
||||
|
||||
def _unified_system_prompt(profile_body: str) -> str:
|
||||
return (
|
||||
"You are a personal assistant delivering a daily briefing. "
|
||||
def _unified_system_prompt(profile_body: str, slot: str = "compilation") -> str:
|
||||
base = (
|
||||
"You are a personal assistant. "
|
||||
"Speak naturally and conversationally — as if talking to the user, not writing a report. "
|
||||
"Use no markdown: no headers, no bullet points, no bold, no lists. Write in flowing prose. "
|
||||
"Weave together what matters today: mention the weather in a sentence, note any calendar "
|
||||
"events or tasks due today, and briefly reference one or two noteworthy news stories. "
|
||||
"Only mention projects if a task from one is specifically due today. "
|
||||
"Be warm, concise, and human — aim for 4 to 8 sentences.\n\n"
|
||||
"IMPORTANT: Be actionable, not just informational. For overdue or due-today tasks, "
|
||||
"suggest a concrete next step — offer to reschedule, mark in progress, or break it down. "
|
||||
"For upcoming events, mention if preparation might help. "
|
||||
"Be warm, concise, and human. "
|
||||
"The user can reply to act on your suggestions via tool calls.\n\n"
|
||||
+ (f"User profile:\n{profile_body}\n" if profile_body else "")
|
||||
)
|
||||
|
||||
if slot == "compilation":
|
||||
base += (
|
||||
"This is the MORNING BRIEFING — the full daily overview. "
|
||||
"Weave together what matters today: mention the weather, note calendar events and tasks, "
|
||||
"briefly reference one or two noteworthy news themes, and suggest a daily focus. "
|
||||
"Be actionable: for overdue or due-today tasks, suggest a concrete next step. "
|
||||
"Aim for 4 to 8 sentences.\n\n"
|
||||
)
|
||||
elif slot in ("morning", "midday"):
|
||||
base += (
|
||||
"This is a MIDDAY CHECK-IN — brief progress nudge, not a full briefing. "
|
||||
"Focus on what's been done and what hasn't been touched yet today. "
|
||||
"If weather conditions have changed, mention it briefly. "
|
||||
"Keep it to 2-3 sentences. Don't repeat news or the full task list.\n\n"
|
||||
)
|
||||
elif slot == "afternoon":
|
||||
base += (
|
||||
"This is the AFTERNOON WRAP-UP — help the user close out the day. "
|
||||
"Summarize what was accomplished today. Flag anything still overdue. "
|
||||
"Ask if there's anything to capture before tomorrow — notes, thoughts, follow-ups. "
|
||||
"Keep it to 2-4 sentences. Reflective and encouraging tone.\n\n"
|
||||
)
|
||||
|
||||
if profile_body:
|
||||
base += f"User profile:\n{profile_body}\n"
|
||||
return base
|
||||
|
||||
|
||||
def _unified_user_prompt(internal_data: dict, external_data: dict, slot: str, temp_unit: str = "C") -> str:
|
||||
lines = [f"Date: {internal_data['date']}", f"Slot: {slot}", ""]
|
||||
|
||||
# For check-in slots, build a slimmer prompt
|
||||
if slot in ("morning", "midday"):
|
||||
# Just tasks status + any weather changes
|
||||
if internal_data.get("due_today"):
|
||||
lines.append("TASKS DUE TODAY (note which are still untouched):")
|
||||
lines.extend(f" - {t}" for t in internal_data["due_today"])
|
||||
lines.append("")
|
||||
if internal_data.get("overdue_tasks"):
|
||||
lines.append(f"STILL OVERDUE: {len(internal_data['overdue_tasks'])} task(s)")
|
||||
lines.append("")
|
||||
if internal_data.get("calendar_events"):
|
||||
lines.append("REMAINING EVENTS TODAY:")
|
||||
lines.extend(f" - {e}" for e in internal_data["calendar_events"])
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
if slot == "afternoon":
|
||||
if internal_data.get("due_today"):
|
||||
lines.append("TASKS THAT WERE DUE TODAY:")
|
||||
lines.extend(f" - {t}" for t in internal_data["due_today"])
|
||||
lines.append("")
|
||||
if internal_data.get("overdue_tasks"):
|
||||
overdue = internal_data["overdue_tasks"]
|
||||
lines.append(f"OVERDUE ({len(overdue)} remaining):")
|
||||
lines.extend(f" - {t}" for t in overdue[:3])
|
||||
lines.append("")
|
||||
lines.append("Ask the user if there's anything to capture before tomorrow — a note, a thought, a follow-up task.")
|
||||
return "\n".join(lines)
|
||||
|
||||
# ── Full compilation prompt below ──────────────────────────────────────────
|
||||
|
||||
# Weather (brief — card handles detail)
|
||||
weather = external_data.get("weather") or []
|
||||
if weather:
|
||||
@@ -590,7 +641,7 @@ async def run_compilation(
|
||||
}
|
||||
|
||||
briefing_text = await _llm_synthesise(
|
||||
_unified_system_prompt(profile_context),
|
||||
_unified_system_prompt(profile_context, slot),
|
||||
_unified_user_prompt(internal_data_filtered, external_data_filtered, slot, temp_unit),
|
||||
model,
|
||||
num_ctx=8192,
|
||||
|
||||
Reference in New Issue
Block a user