mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-03-19 03:43:08 +00:00
feat: add structured questions (AskUserQuestion) to assistant chat
Add interactive multiple-choice question support to the project assistant, allowing it to present clickable options when clarification is needed. Backend changes: - Add ask_user MCP tool to feature_mcp.py with input validation - Add mcp__features__ask_user to assistant allowed tools list - Intercept ask_user tool calls in _query_claude() to yield question messages - Add answer WebSocket message handler in assistant_chat router - Document ask_user tool in assistant system prompt Frontend changes: - Add AssistantChatQuestionMessage type and update server message union - Add currentQuestions state and sendAnswer() to useAssistantChat hook - Handle question WebSocket messages by attaching to last assistant message - Render QuestionOptions component between messages and input area - Disable text input while structured questions are active Flow: Claude calls ask_user → backend intercepts → WebSocket question message → frontend renders QuestionOptions → user clicks options → answer sent back → Claude receives formatted answer and continues conversation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -984,5 +984,35 @@ def feature_set_dependencies(
|
||||
return json.dumps({"error": f"Failed to set dependencies: {str(e)}"})
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def ask_user(
|
||||
questions: Annotated[list[dict], Field(description="List of questions to ask, each with question, header, options (list of {label, description}), and multiSelect (bool)")]
|
||||
) -> str:
|
||||
"""Ask the user structured questions with selectable options.
|
||||
|
||||
Use this when you need clarification or want to offer choices to the user.
|
||||
Each question has a short header, the question text, and 2-4 clickable options.
|
||||
The user's selections will be returned as your next message.
|
||||
|
||||
Args:
|
||||
questions: List of questions, each with:
|
||||
- question (str): The question to ask
|
||||
- header (str): Short label (max 12 chars)
|
||||
- options (list): Each with label (str) and description (str)
|
||||
- multiSelect (bool): Allow multiple selections (default false)
|
||||
|
||||
Returns:
|
||||
Acknowledgment that questions were presented to the user
|
||||
"""
|
||||
# Validate input
|
||||
for i, q in enumerate(questions):
|
||||
if not all(key in q for key in ["question", "header", "options"]):
|
||||
return json.dumps({"error": f"Question at index {i} missing required fields"})
|
||||
if len(q["options"]) < 2 or len(q["options"]) > 4:
|
||||
return json.dumps({"error": f"Question at index {i} must have 2-4 options"})
|
||||
|
||||
return "Questions presented to the user. Their response will arrive as your next message."
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp.run()
|
||||
|
||||
Reference in New Issue
Block a user