Remove CalDAV todo tools; overhaul quick-capture
- Remove all 6 CalDAV todo tools (create/list/update/complete/delete/search_todos) from tools.py definitions, imports, execute_tool branches, intent routing rules, generation_task labels/actions, and llm.py system prompt hints. CalDAV event tools remain. Todo functions still exist in caldav.py but are no longer exposed. - Quick-capture now uses a dedicated classify_capture_intent() with a focused _CAPTURE_SYSTEM_PROMPT that always routes to a tool (never null). Tool set expanded: create_note/task/event + update_note + research_topic. - research_topic in quick-capture calls run_research_pipeline() directly (no SSE buffer). run_research_pipeline() now accepts buf=None; all buf.append_event calls are guarded so status events are skipped when no buffer is provided. - Fallback note now always sets body=text (was empty for texts ≤80 chars). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,15 +26,16 @@ async def run_research_pipeline(
|
||||
user_id: int,
|
||||
model: str,
|
||||
intent_model: str,
|
||||
buf,
|
||||
buf=None,
|
||||
) -> Note:
|
||||
"""Full research pipeline: search → fetch → synthesize → create note.
|
||||
|
||||
Emits status events via buf.append_event throughout.
|
||||
Emits status events via buf.append_event throughout (when buf is provided).
|
||||
Returns the created Note.
|
||||
"""
|
||||
# Step 1: Generate sub-queries
|
||||
buf.append_event("status", {"status": "Generating search queries..."})
|
||||
if buf is not None:
|
||||
buf.append_event("status", {"status": "Generating search queries..."})
|
||||
queries = await _generate_sub_queries(topic, intent_model)
|
||||
logger.info("Research: generated %d sub-queries for topic '%s'", len(queries), topic)
|
||||
|
||||
@@ -42,7 +43,8 @@ async def run_research_pipeline(
|
||||
async def _search_with_stagger(i: int, query: str) -> tuple[str, list[dict]]:
|
||||
if i > 0:
|
||||
await asyncio.sleep(0.2 * i)
|
||||
buf.append_event("status", {"status": f"Searching: {query}..."})
|
||||
if buf is not None:
|
||||
buf.append_event("status", {"status": f"Searching: {query}..."})
|
||||
results = await _search_searxng(query)
|
||||
logger.info("Research: query '%s' → %d results", query, len(results))
|
||||
return query, results
|
||||
@@ -64,7 +66,8 @@ async def run_research_pipeline(
|
||||
# Fetch all unique URLs in parallel
|
||||
async def _fetch_source(url: str, result: dict, query: str) -> dict:
|
||||
title = result.get("title", url)
|
||||
buf.append_event("status", {"status": f"Reading: {title[:60]}..."})
|
||||
if buf is not None:
|
||||
buf.append_event("status", {"status": f"Reading: {title[:60]}..."})
|
||||
content = await fetch_url_content(url)
|
||||
return {
|
||||
"url": url,
|
||||
@@ -98,11 +101,13 @@ async def run_research_pipeline(
|
||||
)
|
||||
|
||||
# Step 4: Synthesize (streams tokens into chat as the note is being written)
|
||||
buf.append_event("status", {"status": f"Synthesizing report from {len(synthesis_sources)} sources..."})
|
||||
if buf is not None:
|
||||
buf.append_event("status", {"status": f"Synthesizing report from {len(synthesis_sources)} sources..."})
|
||||
title, body = await _synthesize_note(topic, synthesis_sources, model, buf)
|
||||
|
||||
# Step 5: Create note
|
||||
buf.append_event("status", {"status": "Saving note..."})
|
||||
if buf is not None:
|
||||
buf.append_event("status", {"status": "Saving note..."})
|
||||
note = await create_note(
|
||||
user_id=user_id,
|
||||
title=title,
|
||||
|
||||
Reference in New Issue
Block a user