trafilatura.extract dispatched via run_in_executor isn't safe to run
concurrently — two parallel calls can crash the process with a
libxml2-level double free. The top-level Wikipedia+SearXNG gather is
fine; only the inner per-article extraction needs to stay sequential,
matching the pre-parallelization behavior.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Runs the Wikipedia summary and SearXNG search concurrently and returns
both when available, so current-event questions aren't masked by a
generic role article from Wikipedia. When the Wikipedia summary includes
a thumbnail, it is cached through the existing image pipeline and
surfaced as an embeddable markdown snippet alongside the extract.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
RSS is now off by default. When disabled:
- Scheduler skips RSS feed sync during compilation slot
- Briefing pipeline skips RSS item gathering
- RSS LLM tools (get_rss_items, add_rss_feed) are hidden
- API routes return empty results for feeds/news
- Frontend hides News nav link, RSS Feeds and News Preferences in settings
- Briefing view hides news sidebar section
Toggle in Settings > Briefing > RSS / News.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two related bugs where the server defaulted naive datetimes to UTC instead
of the configured user timezone, causing all-day events to land on the
previous day and briefings to "disappear" at UTC midnight.
- New services/tz.py helpers: get_user_tz, user_today, user_briefing_date
(the briefing day flips at 4am local to align with the compilation slot,
so the 00:00-04:00 local window still shows yesterday's briefing until
the new one is generated).
- calendar create/list/update tools now parse naive datetimes in the
user's TZ before converting to UTC for storage, and tool descriptions
tell the model to pass plain local dates.
- briefing_conversations.get_or_create_today_conversation and the
reset-today route use user_briefing_date so the in-progress briefing
doesn't get replaced at 19:00 NY / UTC midnight.
- _run_profile_closeout targets user-local "yesterday" for consistency.
Regression tests added for the TZ helpers and the calendar tool.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three related fixes uncovered while benchmarking qwen3:14b against 8b:
- pick_num_ctx was only counting message content, missing the ~15K
tokens of tool schemas. num_ctx=8192 was being selected while actual
prompt_tokens hit 14K+, causing silent prompt truncation on every
tool-using request. Now includes json.dumps(tools) in the estimate.
KV cache priming in app.py and routes/settings.py also fetches tools
so the primed num_ctx matches what real chat requests will use.
- _should_think's heuristic classifier was overriding explicit
think=true requests from the frontend toggle and MCP, gating on
message length and regex patterns. Now a pass-through — the caller
is the source of truth. quick_capture hardcodes think=False since
it's a fast classification path that was relying on the old gating.
- delete_note description only mentioned "note or task", so the model
refused to call it for entries created by save_person / save_place /
create_list. Description now explicitly lists all five note_types it
handles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge create_task into create_note (set status='todo' for tasks, omit
for notes), merge delete_task into delete_note, consolidate entity
tools (create/update_person → save_person, create/update_place →
save_place), rename get_note → read_note with clearer descriptions,
move calculate out of rag.py into utility.py, and extract shared
duplicate detection into check_duplicate() helper.
Updates all downstream references in generation_task.py, quick_capture.py,
ToolCallCard.vue, and WorkspaceView.vue.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split 2566-line tools.py into a tools/ package with @tool decorator
registration. Each tool's schema, metadata, and implementation live
together. Briefing eligibility is now a briefing=True flag instead of
a separate frozenset allowlist. Conditional inclusion (CalDAV, SearXNG)
uses requires= metadata. Public API (get_tools_for_user, execute_tool)
unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>