The model was hallucinating project names from task/note content (e.g.
inferring "Vehicle Maintenance" from "purchase wheel bearings"). Added
explicit guidance to both project field descriptions: only set if the
user explicitly named a project, never infer from content.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- build_context: when conversation_type is 'briefing', inject a system
prompt instruction telling the model to answer from conversation history
and article context instead of searching the web
- Consolidate briefing conversation type detection to one DB query (was
being checked twice — once for the system prompt addition, once for
article context injection)
- ChatPanel: render a visual 'New Briefing Update' separator line before
2nd+ briefing slot messages (identified by metadata.rss_item_ids)
- types/chat.ts: add metadata field to Message interface
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the single monolithic research note with topic-driven section notes
plus an index note. Two new LLM calls: _generate_outline (JSON outline, 3-8
sections) and _synthesize_section (300-600 word focused note per section,
parallelised via asyncio.gather). Public signature of run_research_pipeline
unchanged; falls back to single-note synthesis on outline failure or if all
sections fail.
Also extracts _build_sources_block helper and adds full test suite.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Route now logs every synthesis request (char count, voice, speed)
- Route logs char count + text preview when the 8000-char limit is hit
- Route logs empty audio with preview (helps spot no-chunk-produced edge case)
- Route logs success with byte count and duration
- Kokoro synthesise() logs per-call: samples produced, elapsed, chars/s
- Kokoro synthesise() logs warning when zero audio chunks returned with preview
- Kokoro synthesise() catches and logs pipeline-internal errors with preview
- Frontend: console.warn now includes char count + 80-char preview on failure and retry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CONTENT_MAX_CHARS was removed from rss.py when the article content cap
was lifted. backfill_rss_article_content still referenced it, causing an
ImportError on startup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Account tab: SSO users see an info banner instead of email/password forms
- Briefing tab: remove Office Days section (work days now come from Profile)
- Remove unused toggleWorkDay function
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New Timezone section with text input + Detect button
- Detect auto-fills from browser Intl API
- Save calls PUT /api/settings (which now propagates to scheduler)
- Briefing tab firing timezone hint reads stored value instead of live browser API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When user_timezone is saved via PUT /api/settings, immediately call
update_user_schedule if briefing is enabled so the scheduler picks up
the new timezone without requiring a restart.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _add_user_jobs now accepts config dict and skips disabled slots
- _get_briefing_enabled_users returns 3-tuple (user_id, tz, config)
- update_user_schedule passes config through to _add_user_jobs
- _run_slot_for_user skips morning slot on non-work days via profile.work_schedule
- Add tests for slot gating and work-day gate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the custom classify_capture_intent + _process_note two-pass
approach. The LLM now picks the right tool directly via Ollama's native
tool_calls API (same path as the main chat pipeline). _should_think
decides whether extended reasoning is needed based on input length/
complexity. intent.py deleted — no longer needed.
Android app and response format unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
POST /api/briefing/articles/<id>/discuss injects stored article content
as a persisted read_article tool exchange before triggering generation.
The LLM sees the article as already read; follow-ups retain context via
the fixed history builder. Frontend Discuss button now calls the new
endpoint instead of inlining article text in the user message.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Needed by the Discuss endpoint to persist synthetic read_article
tool exchanges before triggering generation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>