UX: queue bubbles, dashboard queuing, duplicate confirm buttons, short-note fix
- Dashboard chat: allow typing/sending during streaming (queued in store) placeholder updates to "Type to queue…" during generation - ChatView/WorkspaceView: replace queued chip with actual pending message bubbles — light grey, dashed border, "Queued" badge above content; clear button below the stack - ToolCallCard: when tool returns requires_confirmation=True, show "Similar content found" label (not "Error"), link to the similar note, and "Create Anyway" / "Don't Create" buttons that auto-send the reply - tools.py: fuzzy title match now returns requires_confirmation=True with similar_note data instead of a hard error, so numbered-series notes (Lore: X 0, Lore: X 1) can be created with one button click; semantic match responses also include similar_note for the link Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -823,7 +823,7 @@ async def execute_tool(user_id: int, tool_name: str, arguments: dict) -> dict:
|
||||
near, ratio = _fuzzy_title_match(task_title, candidates)
|
||||
if near is not None:
|
||||
item_type = "task" if near.status is not None else "note"
|
||||
return {"success": False, "error": f"A {item_type} with a very similar title '{near.title}' already exists (id: {near.id}, similarity: {ratio:.0%}). Use update_note to modify it instead of creating a duplicate."}
|
||||
return {"success": False, "requires_confirmation": True, "similar_note": {"id": near.id, "title": near.title}, "error": f"A {item_type} with a very similar title '{near.title}' already exists (similarity: {ratio:.0%}). Ask the user to confirm before creating a separate entry."}
|
||||
|
||||
if not arguments.get("confirmed") and len(task_body.strip()) >= 80:
|
||||
from fabledassistant.services.embeddings import semantic_search_notes as _ssn
|
||||
@@ -832,7 +832,7 @@ async def execute_tool(user_id: int, tool_name: str, arguments: dict) -> dict:
|
||||
if sem_hits:
|
||||
best_score, best_note = sem_hits[0]
|
||||
item_type = "task" if best_note.status is not None else "note"
|
||||
return {"success": False, "requires_confirmation": True, "error": f"A {item_type} with very similar content exists: '{best_note.title}' (id: {best_note.id}, semantic similarity: {best_score:.0%}). Ask the user: 'An existing {item_type} covers very similar ground. Shall I still create a separate task titled \"{task_title}\"?' Then retry with confirmed=true if they agree."}
|
||||
return {"success": False, "requires_confirmation": True, "similar_note": {"id": best_note.id, "title": best_note.title}, "error": f"A {item_type} with very similar content exists: '{best_note.title}' (semantic similarity: {best_score:.0%}). Ask the user to confirm before creating a separate entry."}
|
||||
|
||||
note = await create_note(
|
||||
user_id=user_id,
|
||||
@@ -901,7 +901,7 @@ async def execute_tool(user_id: int, tool_name: str, arguments: dict) -> dict:
|
||||
near, ratio = _fuzzy_title_match(note_title, candidates)
|
||||
if near is not None:
|
||||
item_type = "task" if near.status is not None else "note"
|
||||
return {"success": False, "error": f"A {item_type} with a very similar title '{near.title}' already exists (id: {near.id}, similarity: {ratio:.0%}). Use update_note to modify it instead of creating a duplicate."}
|
||||
return {"success": False, "requires_confirmation": True, "similar_note": {"id": near.id, "title": near.title}, "error": f"A {item_type} with a very similar title '{near.title}' already exists (similarity: {ratio:.0%}). Ask the user to confirm before creating a separate entry."}
|
||||
|
||||
if not arguments.get("confirmed") and len(note_body.strip()) >= 80:
|
||||
from fabledassistant.services.embeddings import semantic_search_notes as _ssn
|
||||
@@ -910,7 +910,7 @@ async def execute_tool(user_id: int, tool_name: str, arguments: dict) -> dict:
|
||||
if sem_hits:
|
||||
best_score, best_note = sem_hits[0]
|
||||
item_type = "task" if best_note.status is not None else "note"
|
||||
return {"success": False, "requires_confirmation": True, "error": f"A {item_type} with very similar content exists: '{best_note.title}' (id: {best_note.id}, semantic similarity: {best_score:.0%}). Ask the user: 'An existing {item_type} covers very similar ground. Shall I still create a separate note titled \"{note_title}\"?' Then retry with confirmed=true if they agree."}
|
||||
return {"success": False, "requires_confirmation": True, "similar_note": {"id": best_note.id, "title": best_note.title}, "error": f"A {item_type} with very similar content exists: '{best_note.title}' (semantic similarity: {best_score:.0%}). Ask the user to confirm before creating a separate entry."}
|
||||
|
||||
note = await create_note(
|
||||
user_id=user_id,
|
||||
|
||||
Reference in New Issue
Block a user