| 1 | from __future__ import annotations |
| 2 | |
| 3 | from typing import Any |
| 4 | |
| 5 | from plugins._goal.tools import goal |
| 6 | |
| 7 | |
| 8 | def run(payload: dict[str, Any]) -> dict[str, Any]: |
| 9 | invocation = payload.get("invocation") or {} |
| 10 | raw_args = str(invocation.get("raw_arguments") or "").strip() |
| 11 | tokens = ((invocation.get("arguments") or {}).get("tokens") or []) |
| 12 | context_id = str((payload.get("context") or {}).get("context_id") or "").strip() |
| 13 | |
| 14 | if not context_id: |
| 15 | return _effects(_toast("Open or create a chat context first.", level="error")) |
| 16 | |
| 17 | action = str(tokens[0] if tokens else "").strip().lower() |
| 18 | |
| 19 | try: |
| 20 | if action in {"", "status", "show"}: |
| 21 | return _show_markdown("Goal", goal.summarize_goal(goal.get_goal(context_id))) |
| 22 | if action in {"pause", "paused"}: |
| 23 | current_goal = goal.update_goal(context_id, status="paused") |
| 24 | return _changed("Goal paused.", current_goal) |
| 25 | if action in {"resume", "start", "active"}: |
| 26 | current_goal = goal.update_goal(context_id, status="active") |
| 27 | return _changed("Goal resumed.", current_goal) |
| 28 | if action in {"delete", "clear", "remove"}: |
| 29 | goal.delete_goal(context_id) |
| 30 | return _changed("Goal deleted.", None) |
| 31 | if action in {"complete", "done"}: |
| 32 | current_goal = goal.update_goal(context_id, status="complete") |
| 33 | return _changed("Goal marked complete.", current_goal) |
| 34 | if action == "blocked": |
| 35 | note = raw_args.split(None, 1)[1].strip() if len(tokens) > 1 else "" |
| 36 | current_goal = goal.update_goal(context_id, status="blocked", note=note) |
| 37 | return _changed("Goal marked blocked.", current_goal) |
| 38 | if action == "edit": |
| 39 | objective = raw_args.split(None, 1)[1].strip() if len(tokens) > 1 else "" |
| 40 | current_goal = goal.update_goal(context_id, objective=objective, status="active") |
| 41 | return _changed("Goal updated.", current_goal) |
| 42 | if action in {"auto", "ask", "model"}: |
| 43 | hint = raw_args.split(None, 1)[1].strip() if len(tokens) > 1 else "" |
| 44 | return _auto_prompt(hint) |
| 45 | |
| 46 | current_goal = goal.create_goal(context_id, raw_args, created_by="user") |
| 47 | return _changed("Goal set.", current_goal, send_text=raw_args) |
| 48 | except FileNotFoundError: |
| 49 | return _effects(_toast("No goal is set for this chat.", level="error")) |
| 50 | except ValueError as error: |
| 51 | return _effects(_toast(str(error), level="error")) |
| 52 | |
| 53 | |
| 54 | def _auto_prompt(hint: str) -> dict[str, Any]: |
| 55 | prompt = ( |
| 56 | "Please create and manage a goal for this chat. Use the goal tools to inspect " |
| 57 | "any current goal, create a concise goal objective, and update it when the work " |
| 58 | "is complete or genuinely blocked." |
| 59 | ) |
| 60 | if hint: |
| 61 | prompt += f"\n\nUser hint: {hint}" |
| 62 | return {"text": prompt, "effects": []} |
| 63 | |
| 64 | |
| 65 | def _changed(message: str, current_goal: dict[str, Any] | None, *, send_text: str = "") -> dict[str, Any]: |
| 66 | return _effects( |
| 67 | _toast(message), |
| 68 | {"type": "goal_changed", "goal": goal.public_goal(current_goal)}, |
| 69 | {"type": "send_message", "text": send_text} if send_text else {}, |
| 70 | ) |
| 71 | |
| 72 | |
| 73 | def _effects(*effects: dict[str, Any]) -> dict[str, Any]: |
| 74 | return {"text": "", "effects": [effect for effect in effects if effect]} |
| 75 | |
| 76 | |
| 77 | def _toast(message: str, *, level: str = "success") -> dict[str, Any]: |
| 78 | return {"type": "toast", "message": message, "level": level} |
| 79 | |
| 80 | |
| 81 | def _show_markdown(title: str, content: str) -> dict[str, Any]: |
| 82 | return _effects({"type": "show_markdown", "title": title, "content": content}) |