Add tool confirmation UI with Accept/Decline for write operations
Before executing any write tool (create/update/delete), the backend now pauses with an asyncio.Future and emits a tool_pending SSE event. The frontend displays a ToolConfirmCard with Accept and Decline buttons. Clicking Accept resolves the Future and proceeds; Decline records a declined tool_call chip and falls through to regular streaming. Typing single-word yes/no responses (e.g. "yes", "cancel") also works as confirmation. 120s timeout auto-declines if no response. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -187,6 +187,28 @@ async def generation_stream_route(conv_id: int):
|
||||
)
|
||||
|
||||
|
||||
@chat_bp.route("/conversations/<int:conv_id>/generation/confirm", methods=["POST"])
|
||||
@login_required
|
||||
async def confirm_generation_route(conv_id: int):
|
||||
"""Resolve a pending tool confirmation (accept or decline)."""
|
||||
uid = get_current_user_id()
|
||||
conv = await get_conversation(uid, conv_id)
|
||||
if conv is None:
|
||||
return jsonify({"error": "Conversation not found"}), 404
|
||||
|
||||
buf = get_buffer(conv_id)
|
||||
if buf is None or buf.state != GenerationState.RUNNING:
|
||||
return jsonify({"error": "No active generation"}), 404
|
||||
|
||||
if buf.confirmation_future is None or buf.confirmation_future.done():
|
||||
return jsonify({"error": "No pending tool confirmation"}), 409
|
||||
|
||||
data = await request.get_json(force=True, silent=True) or {}
|
||||
decision = bool(data.get("confirmed", False))
|
||||
buf.confirmation_future.set_result(decision)
|
||||
return jsonify({"status": "ok", "confirmed": decision})
|
||||
|
||||
|
||||
@chat_bp.route("/conversations/<int:conv_id>/generation/cancel", methods=["POST"])
|
||||
@login_required
|
||||
async def cancel_generation_route(conv_id: int):
|
||||
|
||||
Reference in New Issue
Block a user