docs: clear briefing remnants and document journal system
The Briefing system was retired weeks ago and replaced with the conversational Journal, but several current-state docs still described it as live. Updates: architecture.md - settings keys: briefing_enabled / briefing_locations / office_days → journal_config (JSON: locations, temp_unit, prep schedule) - conversation_type: chat/briefing/mcp → chat/journal/mcp - briefing_date column → day_date on Conversation - "Briefing-Related Tables" section: dropped rss_feeds + rss_items rows (retired with PR #43); kept weather_cache and clarified that lat/lon now live in journal_config.locations, not on the cache row - routes/chat.py description: dropped trailing "briefing conversation routes" mention - routes/briefing.py → routes/journal.py with the current endpoint shape (config / today / day / days / weather / moments / trigger- prep) - services/briefing_pipeline + scheduler + conversations + profile → services/journal_prep + journal_pipeline + journal_scheduler + journal_search/moments + user_profile.build_profile_context features.md - "Daily Briefing" section rewritten as "Daily Journal": conversational, single morning prep, right rail with weather + upcoming events, profile-tab configuration, "what the assistant has learned" framing - Settings table: dropped Briefing tab row, added Profile tab row, fixed Notifications row's stale briefing-push reference api-reference.md - /api/briefing/* endpoints replaced with /api/journal/* — config, today/day/days, trigger-prep, weather (cached/current/refresh/ geocode), moments Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+13
-14
@@ -145,23 +145,22 @@ All endpoints require login (session cookie or `Authorization: Bearer <api-key>`
|
|||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/search` | Semantic + keyword search across notes and tasks. Params: `q`, `type` (`note`/`task`/`all`), `limit` |
|
| GET | `/api/search` | Semantic + keyword search across notes and tasks. Params: `q`, `type` (`note`/`task`/`all`), `limit` |
|
||||||
|
|
||||||
## Briefing
|
## Journal
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/briefing/config` | Get briefing configuration |
|
| GET | `/api/journal/config` | Get journal configuration (locations, temp_unit, prep schedule) |
|
||||||
| PUT | `/api/briefing/config` | Save briefing configuration |
|
| PUT | `/api/journal/config` | Save journal configuration; live-reschedules the prep job |
|
||||||
| GET | `/api/briefing/feeds` | List RSS feeds |
|
| GET | `/api/journal/today` | Get/create today's journal conversation + messages |
|
||||||
| POST | `/api/briefing/feeds` | Add RSS feed `{url, name?, category?}` |
|
| GET | `/api/journal/day/:iso` | Get a specific day's journal conversation (read-only) |
|
||||||
| DELETE | `/api/briefing/feeds/:id` | Delete feed |
|
| GET | `/api/journal/days` | List dates with journal content, newest first |
|
||||||
| POST | `/api/briefing/feeds/refresh` | Trigger immediate feed refresh → `{feeds_refreshed, new_items}` |
|
| POST | `/api/journal/trigger-prep` | Force-regenerate today's prep (or `{date}` for a specific day) |
|
||||||
| GET | `/api/briefing/weather` | Get weather configuration |
|
| GET | `/api/journal/weather` | Cached weather rows; auto-refreshes stale rows in the background |
|
||||||
| PUT | `/api/briefing/weather` | Save weather locations |
|
| GET | `/api/journal/weather/current` | Live current conditions for the primary configured location |
|
||||||
| POST | `/api/briefing/weather/geocode` | Geocode address `{query}` → `{lat, lon, label}` |
|
| POST | `/api/journal/weather/refresh` | Manual refresh of all configured locations |
|
||||||
| POST | `/api/briefing/trigger` | Manually fire a briefing slot `{slot}` |
|
| POST | `/api/journal/weather/geocode` | Geocode place name `{query}` → `{lat, lon, label}` |
|
||||||
| GET | `/api/briefing/conversations` | List past briefing conversations |
|
| POST | `/api/journal/moments/:id/update` | Update a recorded moment |
|
||||||
| GET | `/api/briefing/conversations/today` | Get/create today's briefing conversation |
|
| DELETE | `/api/journal/moments/:id` | Delete a moment |
|
||||||
| GET | `/api/briefing/conversations/:id/messages` | Get messages for a briefing conversation |
|
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
|
|||||||
+13
-14
@@ -133,11 +133,11 @@ Indexes: GIN on `tags`, B-tree on `status`, B-tree on `title`.
|
|||||||
|
|
||||||
### Settings
|
### Settings
|
||||||
|
|
||||||
Composite PK `(user_id, key)`. Per-user key-value store. CRUD via `services/settings.py`. Used for: `default_model`, `assistant_name`, `briefing_enabled`, `briefing_locations`, `office_days`, etc.
|
Composite PK `(user_id, key)`. Per-user key-value store. CRUD via `services/settings.py`. Used for: `default_model`, `assistant_name`, `journal_config` (JSON: locations, temp_unit, prep schedule), `user_timezone`, `voice_*`, etc.
|
||||||
|
|
||||||
### Conversations / Messages
|
### Conversations / Messages
|
||||||
|
|
||||||
`conversations`: `id`, `title`, `model`, `user_id`, `conversation_type` (`chat`/`briefing`/`mcp`), `briefing_date`, `rag_project_id` (nullable int — RAG scope: NULL=orphan-only, -1=all, positive=project), `created_at`, `updated_at`.
|
`conversations`: `id`, `title`, `model`, `user_id`, `conversation_type` (`chat`/`journal`/`mcp`), `day_date` (YYYY-MM-DD for journal conversations), `rag_project_id` (nullable int — RAG scope: NULL=orphan-only, -1=all, positive=project), `created_at`, `updated_at`.
|
||||||
`messages`: `id`, `conversation_id` FK CASCADE, `role` (`user`/`assistant`), `content`, `status` (`done`/`generating`), `created_at`.
|
`messages`: `id`, `conversation_id` FK CASCADE, `role` (`user`/`assistant`), `content`, `status` (`done`/`generating`), `created_at`.
|
||||||
|
|
||||||
Title auto-generated by LLM on first exchange, re-generated every 10th message.
|
Title auto-generated by LLM on first exchange, re-generated every 10th message.
|
||||||
@@ -155,11 +155,9 @@ Title auto-generated by LLM on first exchange, re-generated every 10th message.
|
|||||||
|
|
||||||
Permission resolution is centralised in `services/access.py`. `get_project_permission(uid, project_id)` checks ownership → direct share → group-based share → note→project inheritance, returning the highest applicable permission.
|
Permission resolution is centralised in `services/access.py`. `get_project_permission(uid, project_id)` checks ownership → direct share → group-based share → note→project inheritance, returning the highest applicable permission.
|
||||||
|
|
||||||
### Briefing-Related Tables
|
### Journal-Related Tables
|
||||||
|
|
||||||
`rss_feeds`: `id`, `user_id`, `url`, `name`, `category`, `last_fetched_at`.
|
`weather_cache`: per-user, per-`location_key` cache. Columns: `user_id`, `location_key` (`home`/`work`/etc.), `location_label`, `forecast_json` (Open-Meteo response), `previous_json` (last forecast, used to detect changes), `fetched_at`. Lat/lon are *not* stored on the cache row — they live in the user's `journal_config.locations.{home|work}` setting and are used at refresh time.
|
||||||
`rss_items`: `id`, `feed_id` FK, `guid`, `title`, `url`, `summary`, `pub_date`.
|
|
||||||
`weather_cache`: per-user cache with `lat`, `lon`, `location_name`, `forecast_json`, `fetched_at`.
|
|
||||||
|
|
||||||
### API Keys
|
### API Keys
|
||||||
|
|
||||||
@@ -188,14 +186,14 @@ Permission resolution is centralised in `services/access.py`. `get_project_permi
|
|||||||
| `routes/api.py` | `/api` blueprint; `GET /api/health` (public) |
|
| `routes/api.py` | `/api` blueprint; `GET /api/health` (public) |
|
||||||
| `routes/auth.py` | Register, login, logout, me, password/email change, password reset, invite registration, OAuth login+callback; rate limiting; `LOCAL_AUTH_ENABLED` guards |
|
| `routes/auth.py` | Register, login, logout, me, password/email change, password reset, invite registration, OAuth login+callback; rate limiting; `LOCAL_AUTH_ENABLED` guards |
|
||||||
| `routes/admin.py` | Backup, restore, user management, registration toggle, invitations, base URL, SMTP (admin only) |
|
| `routes/admin.py` | Backup, restore, user management, registration toggle, invitations, base URL, SMTP (admin only) |
|
||||||
| `routes/chat.py` | Conversations CRUD; SSE generation stream; model pull/delete/list/warm; briefing conversation routes |
|
| `routes/chat.py` | Conversations CRUD; SSE generation stream; model pull/delete/list/warm |
|
||||||
| `routes/notes.py` | Notes CRUD + wikilinks + backlinks + assist + link suggestions + version history + drafts |
|
| `routes/notes.py` | Notes CRUD + wikilinks + backlinks + assist + link suggestions + version history + drafts |
|
||||||
| `routes/tasks.py` | Tasks CRUD; `POST` accepts `project` name string (resolved to `project_id`) |
|
| `routes/tasks.py` | Tasks CRUD; `POST` accepts `project` name string (resolved to `project_id`) |
|
||||||
| `routes/task_logs.py` | Task work log CRUD (`GET/POST/DELETE /api/tasks/:id/logs`) |
|
| `routes/task_logs.py` | Task work log CRUD (`GET/POST/DELETE /api/tasks/:id/logs`) |
|
||||||
| `routes/projects.py` | Projects CRUD + summary endpoint |
|
| `routes/projects.py` | Projects CRUD + summary endpoint |
|
||||||
| `routes/milestones.py` | Milestones CRUD under `/api/projects/:id/milestones` |
|
| `routes/milestones.py` | Milestones CRUD under `/api/projects/:id/milestones` |
|
||||||
| `routes/settings.py` | Per-user settings key-value (`GET/PUT /api/settings/:key`) |
|
| `routes/settings.py` | Per-user settings key-value (`GET/PUT /api/settings/:key`) |
|
||||||
| `routes/briefing.py` | Briefing conversation + reply + history; RSS feed management |
|
| `routes/journal.py` | Journal config CRUD; today/day/days conversation accessors; weather endpoints (cached/current/refresh/geocode); moments CRUD; trigger-prep |
|
||||||
| `routes/groups.py` | Group CRUD + membership management (admin) |
|
| `routes/groups.py` | Group CRUD + membership management (admin) |
|
||||||
| `routes/shares.py` | Share project/note with user or group; revoke; list incoming shares |
|
| `routes/shares.py` | Share project/note with user or group; revoke; list incoming shares |
|
||||||
| `routes/in_app_notifications.py` | In-app notification list + mark-read + count |
|
| `routes/in_app_notifications.py` | In-app notification list + mark-read + count |
|
||||||
@@ -227,10 +225,11 @@ Permission resolution is centralised in `services/access.py`. `get_project_permi
|
|||||||
| `services/groups.py` | Group CRUD; membership management |
|
| `services/groups.py` | Group CRUD; membership management |
|
||||||
| `services/notifications.py` | Create/read/mark-read in-app notifications |
|
| `services/notifications.py` | Create/read/mark-read in-app notifications |
|
||||||
| `services/task_logs.py` | Append/list/delete work log entries on tasks |
|
| `services/task_logs.py` | Append/list/delete work log entries on tasks |
|
||||||
| `services/briefing_pipeline.py` | Two-lane parallel gather → LLM synthesis → `GenerationBuffer` stream |
|
| `services/journal_prep.py` | Deterministic data gather (tasks/events/weather/projects/recent moments/open threads) → LLM prose opener; persisted as the first assistant message of today's journal Conversation |
|
||||||
| `services/briefing_scheduler.py` | APScheduler `BackgroundScheduler`; slots with catch-up logic; async-safe via `asyncio.create_task` |
|
| `services/journal_pipeline.py` | System-prompt builder for journal conversations; calls `build_profile_context()` so the LLM sees the user's profile + learned summary |
|
||||||
| `services/briefing_conversations.py` | Briefing conversation persistence and history queries |
|
| `services/journal_scheduler.py` | APScheduler `BackgroundScheduler`; per-user prep job; live-reschedule via `update_user_schedule()`; catch-up logic for missed runs |
|
||||||
| `services/briefing_profile.py` | Per-user profile note that the assistant updates over time |
|
| `services/journal_search.py`, `services/moments.py` | Moment recording + search across journal history |
|
||||||
|
| `services/user_profile.py` | `build_profile_context()` consolidates profile + observations + learned_summary into a system-prompt block |
|
||||||
| `services/research.py` | SearXNG research pipeline: sub-queries → parallel fetch → outline → section synthesis → executive summary → index note with linked section notes |
|
| `services/research.py` | SearXNG research pipeline: sub-queries → parallel fetch → outline → section synthesis → executive summary → index note with linked section notes |
|
||||||
| `services/events.py` | Internal events CRUD: `list_events`, `create_event`, `update_event`, `delete_event`, `get_event`; source of truth for all event LLM tools |
|
| `services/events.py` | Internal events CRUD: `list_events`, `create_event`, `update_event`, `delete_event`, `get_event`; source of truth for all event LLM tools |
|
||||||
| `routes/events.py` | `/api/events` — event CRUD routes |
|
| `routes/events.py` | `/api/events` — event CRUD routes |
|
||||||
@@ -293,8 +292,8 @@ Permission resolution is centralised in `services/access.py`. `get_project_permi
|
|||||||
| `services/generation_task.py` | SSE streaming, tool-call loop, GenerationBuffer management |
|
| `services/generation_task.py` | SSE streaming, tool-call loop, GenerationBuffer management |
|
||||||
| `services/tools/` | LLM tool implementations (38 tools across 11 modules); decorator-based registry |
|
| `services/tools/` | LLM tool implementations (38 tools across 11 modules); decorator-based registry |
|
||||||
| `services/embeddings.py` | `upsert_note_embedding()`, `semantic_search_notes()` |
|
| `services/embeddings.py` | `upsert_note_embedding()`, `semantic_search_notes()` |
|
||||||
| `services/briefing_pipeline.py` | Two-lane parallel gather → LLM synthesis → briefing output |
|
| `services/journal_prep.py` | Data gather → LLM prose opener; persisted into today's journal conversation |
|
||||||
| `services/briefing_scheduler.py` | APScheduler integration, catch-up logic for missed slots |
|
| `services/journal_scheduler.py` | APScheduler integration, per-user prep job, catch-up for missed runs |
|
||||||
| `services/backup.py` | Full and per-user backup export/restore (version 2 format) |
|
| `services/backup.py` | Full and per-user backup export/restore (version 2 format) |
|
||||||
| `services/weather.py` | Nominatim geocoding + Open-Meteo forecast fetch + DB cache |
|
| `services/weather.py` | Nominatim geocoding + Open-Meteo forecast fetch + DB cache |
|
||||||
| `services/rss.py` | feedparser-based fetch, per-feed DB cache, prune-to-100 |
|
| `services/rss.py` | feedparser-based fetch, per-feed DB cache, prune-to-100 |
|
||||||
|
|||||||
+12
-9
@@ -52,19 +52,22 @@ Full conversation history with SSE streaming. Features:
|
|||||||
- **Bulk delete** — Select and delete multiple conversations.
|
- **Bulk delete** — Select and delete multiple conversations.
|
||||||
- **Retention** — Conversations auto-pruned after configurable days (default 90).
|
- **Retention** — Conversations auto-pruned after configurable days (default 90).
|
||||||
|
|
||||||
## Daily Briefing
|
## Daily Journal
|
||||||
|
|
||||||
`/briefing` is a scheduled, dialogue-based morning briefing. The assistant compiles tasks, calendar events, projects, weather forecast, and RSS digest at configurable times, then checks in throughout the day. You can reply interactively.
|
`/journal` is a conversational daily surface — each day is a chat-style conversation seeded with an LLM-generated daily prep as the first assistant message. The prep pulls together today's tasks, calendar events, weather, recent moments, and active projects in flowing prose, then invites the user to continue the conversation throughout the day.
|
||||||
|
|
||||||
**Schedule** — Configurable slots: morning (default 4am compile), midday (8am check-in), evening (12pm check-in), night (4pm). Scheduler catches up missed slots on startup.
|
**Schedule** — Daily prep generates at a configurable time (default 5:00am). The "day rollover hour" controls when the journal switches to a new day (default 4am — late-night entries 1–3am still count as the previous day). Scheduler catches up missed runs on startup.
|
||||||
|
|
||||||
**Configuration** — Settings → Briefing: enable toggle, location geocoding, office days, time slot toggles, RSS feed management, push notification toggle.
|
**Right rail** — The journal view shows current weather conditions and upcoming events for the next two weeks alongside the conversation. Both surfaces draw from the same data the prep references.
|
||||||
|
|
||||||
**RSS feeds** — Add feed URLs with optional name and category. Feeds are fetched and cached; the briefing digest includes recent items. Category badges shown in the UI. Feeds can be manually refreshed.
|
**Configuration** — Settings → Profile:
|
||||||
|
- *Locations* section: home and work place-name inputs (geocoded on blur via Nominatim) and a temperature unit toggle (C/F)
|
||||||
|
- *Journal* section: prep auto-generate toggle, prep generation time, day rollover hour
|
||||||
|
- *About You* / *Interests* / *Work Schedule* / *Response Preferences* feed personalization into the prep's system prompt
|
||||||
|
|
||||||
**Weather** — Location-based forecast via Open-Meteo. Multiple locations supported (home, work, or any city name). Geocoding via Nominatim.
|
**Weather** — Location-based forecast via Open-Meteo. Up to two named locations (home, work). Cached rows auto-refresh in the background when the journal page loads.
|
||||||
|
|
||||||
**Profile note** — The assistant maintains a profile note for each user that it updates based on briefing conversations, improving personalisation over time.
|
**What the assistant has learned** — The assistant maintains a per-user observation log + consolidated summary, generated from journal and chat conversations. The summary is included in the journal's system prompt so the daily prep can reference what it knows about you over time.
|
||||||
|
|
||||||
## Web Research
|
## Web Research
|
||||||
|
|
||||||
@@ -115,10 +118,10 @@ Settings are tabbed:
|
|||||||
|-----|----------|
|
|-----|----------|
|
||||||
| General | Assistant name, default model, model management (pull/delete) |
|
| General | Assistant name, default model, model management (pull/delete) |
|
||||||
| Account | Email change, password change, session invalidation |
|
| Account | Email change, password change, session invalidation |
|
||||||
| Notifications | Push notification subscription, briefing push toggle |
|
| Notifications | Push notification subscription, journal prep push toggle |
|
||||||
|
| Profile | About you, response preferences, interests, work schedule, locations + temperature unit, journal prep schedule, learned observations |
|
||||||
| Integrations | CalDAV configuration, SearXNG status |
|
| Integrations | CalDAV configuration, SearXNG status |
|
||||||
| Data | Personal export, backup/restore (admin) |
|
| Data | Personal export, backup/restore (admin) |
|
||||||
| Briefing | Enable, location, office days, slots, RSS feeds, weather |
|
|
||||||
| API Keys | Create/revoke API keys, Fable MCP download and install |
|
| API Keys | Create/revoke API keys, Fable MCP download and install |
|
||||||
| Config (admin) | Base URL, SMTP, OIDC settings |
|
| Config (admin) | Base URL, SMTP, OIDC settings |
|
||||||
| Users (admin) | User list, invite links, registration toggle |
|
| Users (admin) | User list, invite links, registration toggle |
|
||||||
|
|||||||
Reference in New Issue
Block a user