personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Replace daily_news agent with morning_briefing

Five-section entity-informed briefing (your day, yesterday, needs
attention, forward look, reading) that synthesizes all daily agent
outputs. Adds `sol call sol briefing` for day-keyed storage under
sol/briefing/{day}.md. Deletes daily_news.md entirely.

+169 -71
-50
muse/daily_news.md
··· 1 - { 2 - "type": "cogitate", 3 - 4 - "title": "Daily News Briefing", 5 - "description": "Creates a crisp TL;DR briefing highlighting the day's top activities across all facets, delivered as a journal entry", 6 - "color": "#1565c0", 7 - "schedule": "daily", 8 - "priority": 45, 9 - "instructions": {"system": "journal", "facets": true, "now": true, "day": true} 10 - 11 - } 12 - 13 - You are the Daily News Briefing Generator for $agent_name. Your mission is to create a crisp, scannable TL;DR-style briefing that highlights the day's most notable activities across all facets and delivers it as a journal entry. 14 - 15 - ## Goals 16 - 17 - 1. **Be Concise**: Target 150 words or less total 18 - 2. **Be Scannable**: Should grasp the day in under 60 seconds 19 - 3. **Be Selective**: Focus on impact and significance, not exhaustive coverage 20 - 4. **Be Conversational**: Engaging and human, not robotic or formal 21 - 5. **Be Actionable**: Surface anything urgent or requiring attention 22 - 23 - ## Approach 24 - 25 - **Gather facet newsletters:** 26 - - Get the list of available facets using `sol call journal facets` 27 - - For each facet, retrieve its newsletter for the target day using `sol call journal news FACET` 28 - - If no facets have news, return early 29 - 30 - **Extract and synthesize:** 31 - - Identify the most significant activities from each facet 32 - - Skip routine or minor updates unless they're notably impactful 33 - - Flag any urgent items or blockers mentioned 34 - 35 - **Compose and deliver:** 36 - - Create a tight, bullet-focused briefing 37 - - Return the briefing as the agent's response 38 - 39 - ## Constraints 40 - 41 - - Use bullets only, no paragraphs 42 - - Limit to 2-3 highlights per active facet 43 - - Include a brief opening line that captures the day's character 44 - - Users can read individual facet newsletters for details – your job is the highlight reel 45 - 46 - ## Tools 47 - 48 - - `sol call journal news FACET` – Read facet newsletter 49 - 50 - This is the "morning coffee read" – a quick catch-up on the day's key activities. Design your briefing format and structure to best serve this goal.
+96
muse/morning_briefing.md
··· 1 + { 2 + "type": "cogitate", 3 + 4 + "title": "Morning Briefing", 5 + "description": "Synthesizes all daily agent outputs into a structured five-section morning briefing with entity intelligence", 6 + "color": "#1565c0", 7 + "schedule": "daily", 8 + "priority": 50, 9 + "instructions": {"system": "journal", "facets": true, "now": true, "day": true} 10 + 11 + } 12 + 13 + You are generating the morning briefing for $agent_name — a structured daily digest that synthesizes all agent outputs, calendar, todos, and entity intelligence into an actionable start-of-day view. 14 + 15 + This is not a conversation. Gather data, synthesize, write the briefing, done. 16 + 17 + ## Phase 1: Gather data 18 + 19 + Call all sources upfront. Some may return empty — that's expected, especially early in a journal's life. 20 + 21 + 1. `sol call journal facets` — list active facets 22 + 2. For each facet: `sol call journal news FACET --day $day_YYYYMMDD` — facet newsletter 23 + 3. `sol call calendar list $day_YYYYMMDD` — today's events with participants 24 + 4. `sol call todos list` — pending action items across all facets 25 + 5. `sol call sol pulse` — current pulse narrative and needs-you items 26 + 6. `sol call journal search "" -d $day_YYYYMMDD -a followups -n 10` — follow-up items from today 27 + 7. `sol call journal search "" --day-from $day_YYYYMMDD -a anticipation -n 5` — forward-looking anticipations 28 + 8. For each of the next 7 days after today: `sol call calendar list YYYYMMDD` — upcoming events for forward look 29 + 30 + For each person appearing in today's calendar events, also run: 31 + 9. `sol call entities intelligence PERSON` — relationship context, recent interactions, observations 32 + 33 + ## Phase 2: Synthesize 34 + 35 + Build five sections from the gathered data. **Omit any section entirely if it has no content** — do not include empty headings or placeholders. 36 + 37 + ### Section rules 38 + 39 + **Your Day** — What's ahead today. Lead with calendar events in chronological order. For each meeting, include who's attending and one line of entity-informed context (e.g., "last met 2 weeks ago, discussed product roadmap"). Include relevant todos due today. If no calendar events exist, lead with the highest-priority todos. 40 + 41 + **Yesterday** — What happened. Draw from facet newsletters and pulse. Highlight accomplishments, decisions made, and notable interactions. Keep to 3-5 bullets max. Only include if facet newsletters have content for the analysis day. 42 + 43 + **Needs Attention** — Ranked action list. Synthesize from all sources into a single prioritized list: 44 + 1. Overdue commitments (todos past due, missed follow-ups) 45 + 2. Pending follow-ups (items flagged by the followups agent) 46 + 3. Relationship maintenance (entities not contacted recently who are relevant) 47 + 4. Unscheduled todos (action items with no calendar time blocked) 48 + 49 + **Forward Look** — What's coming. Draw from anticipation agent output and upcoming calendar events (next 7 days). Note preparation needed for upcoming meetings or deadlines. 50 + 51 + **Reading** — Curated links and content. Surface any articles, links, or reading material mentioned in facet newsletters or agent outputs. Only include if there is actual reading material to surface. 52 + 53 + ## Phase 3: Write output 54 + 55 + Compose the briefing as markdown with YAML frontmatter and write it via: 56 + 57 + ```bash 58 + cat <<'EOF' | sol call sol briefing --write 59 + --- 60 + type: morning_briefing 61 + date: $day_YYYYMMDD 62 + generated: [ISO 8601 datetime of generation, e.g. 2026-03-27T06:30:00] 63 + --- 64 + 65 + ## Your Day 66 + 67 + [content] 68 + 69 + ## Yesterday 70 + 71 + [content] 72 + 73 + ## Needs Attention 74 + 75 + [content] 76 + 77 + ## Forward Look 78 + 79 + [content] 80 + 81 + ## Reading 82 + 83 + [content] 84 + EOF 85 + ``` 86 + 87 + Remember: omit sections with no content entirely. Do not write empty sections. 88 + 89 + ## Guidelines 90 + 91 + - Be concise and scannable. This is a morning read, not a report. 92 + - Lead each section with the most important item. 93 + - Use bullets, not paragraphs. 94 + - Entity intelligence should inform context, not be dumped raw — weave it naturally into the relevant section. 95 + - Don't include greetings, sign-offs, or meta-commentary about being an AI. 96 + - On a quiet day with minimal data, produce only the sections that have content. A briefing with just "Your Day" listing a few todos is perfectly valid.
+11 -11
tests/baselines/api/agents/agents-day.json
··· 55 55 "title": "Coder", 56 56 "type": "cogitate" 57 57 }, 58 - "daily_news": { 59 - "app": null, 60 - "color": "#1565c0", 61 - "description": "Creates a crisp TL;DR briefing highlighting the day's top activities across all facets, delivered as a journal entry", 62 - "multi_facet": false, 63 - "output_format": null, 64 - "schedule": "daily", 65 - "source": "system", 66 - "title": "Daily News Briefing", 67 - "type": "cogitate" 68 - }, 69 58 "daily_schedule": { 70 59 "app": null, 71 60 "color": "#455a64", ··· 307 296 "source": "system", 308 297 "title": "Messaging Summary", 309 298 "type": "generate" 299 + }, 300 + "morning_briefing": { 301 + "app": null, 302 + "color": "#1565c0", 303 + "description": "Synthesizes all daily agent outputs into a structured five-section morning briefing with entity intelligence", 304 + "multi_facet": false, 305 + "output_format": null, 306 + "schedule": "daily", 307 + "source": "system", 308 + "title": "Morning Briefing", 309 + "type": "cogitate" 310 310 }, 311 311 "naming": { 312 312 "app": null,
+8 -8
tests/baselines/api/settings/providers.json
··· 103 103 "tier": 2, 104 104 "type": "cogitate" 105 105 }, 106 - "muse.system.daily_news": { 107 - "disabled": false, 108 - "group": "Think", 109 - "label": "Daily News Briefing", 110 - "schedule": "daily", 111 - "tier": 2, 112 - "type": "cogitate" 113 - }, 114 106 "muse.system.daily_schedule": { 115 107 "disabled": false, 116 108 "group": "Think", ··· 255 247 "schedule": "activity", 256 248 "tier": 2, 257 249 "type": "generate" 250 + }, 251 + "muse.system.morning_briefing": { 252 + "disabled": false, 253 + "group": "Think", 254 + "label": "Morning Briefing", 255 + "schedule": "daily", 256 + "tier": 2, 257 + "type": "cogitate" 258 258 }, 259 259 "muse.system.naming": { 260 260 "disabled": false,
+54 -2
think/tools/sol.py
··· 4 4 """CLI commands for sol/ identity directory. 5 5 6 6 Provides read and write access to ``{journal}/sol/self.md``, 7 - ``{journal}/sol/agency.md``, and ``{journal}/sol/pulse.md`` — sol's 7 + ``{journal}/sol/agency.md``, ``{journal}/sol/pulse.md``, and 8 + ``{journal}/sol/briefing/{day}.md`` — sol's 8 9 identity and initiative files. 9 10 10 11 Mounted by ``think.call`` as ``sol call sol ...``. ··· 16 17 17 18 from think.awareness import ensure_sol_directory, update_self_md_section 18 19 19 - app = typer.Typer(help="Sol identity directory — self.md, agency.md, and pulse.md.") 20 + app = typer.Typer( 21 + help="Sol identity directory — self.md, agency.md, pulse.md, and briefing." 22 + ) 20 23 21 24 22 25 def _sol_dir(): ··· 117 120 typer.echo("pulse.md not found.", err=True) 118 121 raise typer.Exit(1) 119 122 typer.echo(pulse_path.read_text(encoding="utf-8")) 123 + 124 + 125 + @app.command("briefing") 126 + def briefing_cmd( 127 + write: bool = typer.Option( 128 + False, "--write", "-w", help="Write briefing from stdin." 129 + ), 130 + day: str | None = typer.Option( 131 + None, "--day", "-d", help="Specific day YYYYMMDD." 132 + ), 133 + ) -> None: 134 + """Read or write sol/briefing/{day}.md.""" 135 + import os 136 + 137 + sol_dir = _sol_dir() 138 + briefing_dir = sol_dir / "briefing" 139 + 140 + if write: 141 + target_day = day or os.environ.get("SOL_DAY") 142 + if not target_day: 143 + typer.echo("Error: --day required (or set SOL_DAY).", err=True) 144 + raise typer.Exit(1) 145 + content = sys.stdin.read() 146 + if not content.strip(): 147 + typer.echo("Error: no content provided on stdin.", err=True) 148 + raise typer.Exit(1) 149 + briefing_dir.mkdir(parents=True, exist_ok=True) 150 + (briefing_dir / f"{target_day}.md").write_text(content, encoding="utf-8") 151 + typer.echo(f"Briefing for {target_day} saved.") 152 + return 153 + 154 + # Read mode 155 + if day: 156 + path = briefing_dir / f"{day}.md" 157 + if not path.exists(): 158 + typer.echo("No briefing found.", err=True) 159 + raise typer.Exit(1) 160 + typer.echo(path.read_text(encoding="utf-8")) 161 + return 162 + 163 + # No day specified — find most recent 164 + if not briefing_dir.exists(): 165 + typer.echo("No briefing found.", err=True) 166 + raise typer.Exit(1) 167 + files = sorted(briefing_dir.glob("*.md"), reverse=True) 168 + if not files: 169 + typer.echo("No briefing found.", err=True) 170 + raise typer.Exit(1) 171 + typer.echo(files[0].read_text(encoding="utf-8"))