import re from random import SystemRandom _rng = SystemRandom() _NOTATION_RE = re.compile(r"^\s*(\d*)d(\d+)\s*(?:([+-])\s*(\d+))?\s*$", re.IGNORECASE) TOOL_SCHEMA = { "name": "roll_dice", "description": ( "Roll dice using standard D&D notation (e.g. '1d20+5', '2d6', 'd8-1'). " "Always use this tool for any dice roll that affects the game — never invent or guess a result yourself." ), "parameters": { "type": "object", "properties": { "notation": { "type": "string", "description": "Dice notation, e.g. '1d20+5'", }, "reason": { "type": "string", "description": "Short reason for the roll, e.g. 'Geschicklichkeitsrettung, Schwierigkeit 13'", }, }, "required": ["notation"], }, } def roll(notation: str) -> dict: match = _NOTATION_RE.match(notation) if not match: raise ValueError(f"Invalid dice notation: {notation!r}") count_str, sides_str, sign, modifier_str = match.groups() count = int(count_str) if count_str else 1 sides = int(sides_str) if not (1 <= count <= 100) or not (2 <= sides <= 1000): raise ValueError(f"Dice notation out of allowed range: {notation!r}") modifier = int(modifier_str) if modifier_str else 0 if sign == "-": modifier = -modifier rolls = [_rng.randint(1, sides) for _ in range(count)] total = sum(rolls) + modifier return {"notation": notation, "rolls": rolls, "modifier": modifier, "total": total}