|
# retoor <retoor@molodetz.nl>
|
|
|
|
from __future__ import annotations
|
|
|
|
from .spec import Action, Param
|
|
|
|
|
|
def arg(name: str, description: str, required: bool = False, kind: str = "string") -> Param:
|
|
return Param(name=name, location="body", description=description, required=required, type=kind)
|
|
|
|
|
|
CLIENT = (
|
|
"Runs in the user's own browser through the web terminal. Only effective in the web "
|
|
"interface with a live connection; elsewhere it reports that no browser is attached."
|
|
)
|
|
|
|
CLIENT_ACTIONS: tuple[Action, ...] = (
|
|
Action(
|
|
name="get_page_context",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Read the user's current page: URL, title, viewport, scroll, selected text, visible headings, and whether they are signed in",
|
|
description=CLIENT + " Use this to understand where the user is and what they are looking at before acting or guiding them.",
|
|
handler="client",
|
|
requires_auth=False,
|
|
),
|
|
Action(
|
|
name="run_js",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Execute JavaScript in the user's browser and return its result",
|
|
description=(
|
|
CLIENT + " The code is the body of an async function; use 'return value' to return a "
|
|
"JSON-serializable result. You have full access to window and document. Use this for "
|
|
"anything not covered by the dedicated tools: read or change the DOM, drive a live "
|
|
"demo, inspect state, or update the screen. Prefer the dedicated tools "
|
|
"(highlight_element, show_toast, scroll_to_element, navigate_to, reload_page) when they fit."
|
|
),
|
|
handler="client",
|
|
requires_auth=False,
|
|
params=(
|
|
arg("code", "JavaScript to run as an async function body. Return a JSON-serializable value.", required=True),
|
|
),
|
|
),
|
|
Action(
|
|
name="highlight_element",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Highlight an element on screen with an outline and an optional callout label, for live tutorials",
|
|
description=CLIENT + " Scrolls the element into view and draws an attention outline. Call clear_highlights to remove it.",
|
|
handler="client",
|
|
requires_auth=False,
|
|
params=(
|
|
arg("selector", "CSS selector, or the element's exact visible text (e.g. a heading or link label).", required=True),
|
|
arg("label", "Optional callout text shown next to the element."),
|
|
),
|
|
),
|
|
Action(
|
|
name="clear_highlights",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Remove all highlights and callouts placed by highlight_element",
|
|
description=CLIENT,
|
|
handler="client",
|
|
requires_auth=False,
|
|
),
|
|
Action(
|
|
name="show_toast",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Show a brief on-screen message (toast) to the user",
|
|
description=CLIENT,
|
|
handler="client",
|
|
requires_auth=False,
|
|
params=(
|
|
arg("text", "Message to display.", required=True),
|
|
arg("duration_ms", "How long to show it, in milliseconds (default 4000).", kind="integer"),
|
|
),
|
|
),
|
|
Action(
|
|
name="scroll_to_element",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Smoothly scroll an element into view",
|
|
description=CLIENT,
|
|
handler="client",
|
|
requires_auth=False,
|
|
params=(arg("selector", "CSS selector, or the element's exact visible text.", required=True),),
|
|
),
|
|
Action(
|
|
name="navigate_to",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Send the user's browser to a URL",
|
|
description=(
|
|
CLIENT + " Use a same-origin path like /feed or /docs/index.html, or a full URL. The "
|
|
"page reloads; the user's Devii session and conversation persist and reconnect automatically."
|
|
),
|
|
handler="client",
|
|
requires_auth=False,
|
|
params=(arg("url", "Path or URL to navigate to.", required=True),),
|
|
),
|
|
Action(
|
|
name="reload_page",
|
|
method="LOCAL",
|
|
path="",
|
|
summary="Refresh the user's current page, e.g. after something changed",
|
|
description=CLIENT + " The Devii session and conversation persist and reconnect automatically.",
|
|
handler="client",
|
|
requires_auth=False,
|
|
),
|
|
)
|