from __future__ import annotations from src.game_state import get_state TOOL_SCHEMAS = [ { "type": "function", "function": { "name": "start_timer", "description": ( "Start the user's focus timer. Use this when they want to begin a work " "session, Pomodoro, or free-flow focus block." ), "parameters": { "type": "object", "properties": { "duration_minutes": { "type": "integer", "description": "Duration in minutes (1-180). Ignored in freeflow mode.", "default": 25, }, "mode": { "type": "string", "enum": ["pomodoro", "freeflow"], "description": ( "'pomodoro' counts down from duration_minutes; " "'freeflow' counts up indefinitely." ), "default": "pomodoro", }, }, "required": [], }, }, }, { "type": "function", "function": { "name": "stop_timer", "description": "Pause/stop the currently running timer without resetting it.", "parameters": { "type": "object", "properties": {}, "required": [], }, }, }, { "type": "function", "function": { "name": "reset_timer", "description": "Stop and reset the timer back to zero, clearing the current session.", "parameters": { "type": "object", "properties": {}, "required": [], }, }, }, { "type": "function", "function": { "name": "add_todo", "description": "Add a new task (quest) to the user's todo list.", "parameters": { "type": "object", "properties": { "task": { "type": "string", "description": "The task description to add.", }, }, "required": ["task"], }, }, }, { "type": "function", "function": { "name": "complete_todo", "description": ( "Mark an existing task as done. Identify it by its id (preferred, shown " "as id=N in the quest list) or by matching task text." ), "parameters": { "type": "object", "properties": { "todo_id": { "type": "integer", "description": "The id of the task to complete.", }, "task": { "type": "string", "description": "Task text to match if the id is unknown.", }, }, "required": [], }, }, }, { "type": "function", "function": { "name": "remove_todo", "description": ( "Delete a task from the list entirely. Identify it by its id (preferred) " "or by matching task text." ), "parameters": { "type": "object", "properties": { "todo_id": { "type": "integer", "description": "The id of the task to remove.", }, "task": { "type": "string", "description": "Task text to match if the id is unknown.", }, }, "required": [], }, }, }, ] def _find_todo(state, arguments: dict) -> dict | None: """Resolve a todo from a tool's arguments by id (preferred) or task text.""" tid = arguments.get("todo_id") if tid is not None: try: tid = int(tid) for t in state.todos: if t["id"] == tid: return t except (ValueError, TypeError): pass task = (arguments.get("task") or "").strip().lower() if task: for t in state.todos: if task in t["task"].lower(): return t return None def execute_tool(name: str, arguments: dict) -> tuple[str, str | None]: """Execute a tool by name. Returns (text_result, js_command_or_None).""" state = get_state() if name == "start_timer": duration = max(1, min(180, int(arguments.get("duration_minutes") or 25))) mode = arguments.get("mode", "pomodoro") if mode not in ("pomodoro", "freeflow"): mode = "pomodoro" state.timer_state.update({ "running": True, "mode": mode, "duration_minutes": duration, "phase": "work", }) label = f"{duration}-minute {mode}" if mode == "pomodoro" else "free-flow" js = f"timerStart({duration}, '{mode}')" return f"Timer started: {label} session.", js if name == "stop_timer": state.timer_state["running"] = False return "Timer stopped.", "timerStop()" if name == "reset_timer": state.timer_state.update({"running": False, "phase": "work"}) return "Timer reset.", "timerReset()" if name == "add_todo": task = (arguments.get("task") or "").strip() if not task: return "I couldn't tell what task to add.", None state.add_todo(task) return f"Added quest: {task}", None if name == "complete_todo": t = _find_todo(state, arguments) if not t: return "I couldn't find that quest on your list.", None if t["done"]: return f"'{t['task']}' is already complete.", None state.mark_done(t["id"]) return f"Marked '{t['task']}' complete. +{state.XP_PER_TODO} XP! 🎉", "avatarPlay('questDone')" if name == "remove_todo": t = _find_todo(state, arguments) if not t: return "I couldn't find that quest on your list.", None task = t["task"] state.remove_todo(t["id"]) return f"Removed quest: {task}", None return f"Unknown tool: {name}", None