"""UI-only "ask the user to pick a branch" tool.

收窄定位:**方案/分支确认**,不是通用提问器。模型在「需要用户在 2-4 个互斥方向
间拍板、且该选择会实质改变后续动作」时调用,前端把 question + options 渲成一组可点击
选项卡。用户点某项即作为其回复继续,也可不点直接用文字讨论。

与 task_progress 同属「虚拟工具」:结果体极小(只是占位),真正给前端用的内容全在
assistant tool_call 的 arguments 里(question/options),供 Web 渲染。loop 检测到本步
调用了本工具就提前结束本轮,等用户响应(见 core/loop.py)。
"""
from __future__ import annotations

import json
from typing import Any

from .base import Tool


class AskUserTool(Tool):
    name = "ask_user"
    description = (
        "在需要用户在 2-4 个互斥方向间拍板、且该选择会实质改变你接下来动作时,展示一组可点击"
        "选项让用户选。典型:确认实施方案、在多条候选路线里选一条、在明确的取舍间二选一。"
        "用户点某个选项即作为其回复继续,也可不点直接用文字与你讨论。"
        "不要用于:信息缺失的开放性提问(直接用文字问)、你能自己合理默认就推进的决定、"
        "单纯的是/否确认、给用户播报进度。每轮最多用一次,且只在真正的分叉点用;"
        "调用本工具后你的发言即结束、等待用户,不要再继续动作。"
    )
    parameters = {
        "type": "object",
        "additionalProperties": False,
        "properties": {
            "question": {
                "type": "string",
                "description": "要用户拍板的问题,一句话讲清在选什么。",
            },
            "options": {
                "type": "array",
                "description": "2-4 个互斥选项。",
                "minItems": 2,
                "maxItems": 4,
                "items": {
                    "type": "object",
                    "additionalProperties": False,
                    "properties": {
                        "label": {
                            "type": "string",
                            "description": "选项短标题,用户点击后即作为其回复原文发出,写成可直接当回复的一句话。",
                        },
                        "description": {
                            "type": "string",
                            "description": "可选,一句话说明该选项的取舍 / 后果。",
                        },
                    },
                    "required": ["label"],
                },
            },
        },
        "required": ["question", "options"],
    }

    def execute(self, **kwargs: Any) -> str:
        options = kwargs.get("options")
        n = len(options) if isinstance(options, list) else 0
        return json.dumps(
            {
                "ok": True,
                "shown": True,
                "n_options": n,
                "note": "已向用户展示选项,等待其点选或继续讨论。",
            },
            ensure_ascii=False,
            separators=(",", ":"),
        )
