feat(rag): RAG scoping and context isolation controls
- Migration 0030: add conversations.rag_project_id (NULL=orphan-only, -1=all notes, positive=project), projects.auto_summary and projects.summary_updated_at - Three-value scope semantics thread from build_context() → semantic search and keyword fallback via orphan_only + effective_project_id - Project summarization background job (generate_project_summary, backfill_project_summaries) called via Ollama; triggered on project update and note saves (debounced 1h); runs at startup - New LLM tools: search_projects (SequenceMatcher scoring on title+description+auto_summary) and set_rag_scope (persists to DB, workspace-guarded, emits new_rag_scope in SSE done event) - execute_tool() accepts conv_id + workspace_project_id; generation_task passes both and captures scope changes for SSE done enrichment - Frontend: Conversation type gets rag_project_id; chat store adds ragProjectId computed + updateRagScope(); SSE done handler syncs scope - ChatView: replace sidebar ProjectSelector with a scope chip pill above the input bar, animated dropdown, pulse on model-driven scope change Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -115,13 +115,15 @@ async def delete_conversation_route(conv_id: int):
|
||||
@chat_bp.route("/conversations/<int:conv_id>", methods=["PATCH"])
|
||||
@login_required
|
||||
async def update_conversation_route(conv_id: int):
|
||||
from fabledassistant.services.chat import _UNSET
|
||||
uid = get_current_user_id()
|
||||
data = await request.get_json()
|
||||
title = data.get("title")
|
||||
model = data.get("model")
|
||||
if title is None and model is None:
|
||||
return jsonify({"error": "title or model is required"}), 400
|
||||
conv = await update_conversation(uid, conv_id, title=title, model=model)
|
||||
rag_project_id = data.get("rag_project_id", _UNSET)
|
||||
if title is None and model is None and rag_project_id is _UNSET:
|
||||
return jsonify({"error": "title, model, or rag_project_id is required"}), 400
|
||||
conv = await update_conversation(uid, conv_id, title=title, model=model, rag_project_id=rag_project_id)
|
||||
if conv is None:
|
||||
return not_found("Conversation")
|
||||
return jsonify(conv.to_dict())
|
||||
|
||||
Reference in New Issue
Block a user