File size: 8,663 Bytes
5655a42 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | """Schema for the generic `computer_use` tool (model-facing; value is byte-frozen β
the schema goes to the model every turn, so prompt-cache parity depends on it).
Model-agnostic: any tool-calling model can drive this. Vision-capable models
should prefer `capture(mode='som')` then `click(element=N)` β much more reliable
than pixel coordinates, which remain supported for models trained on them.
"""
from __future__ import annotations
from typing import Any, Dict
# One consolidated tool with an `action` discriminator keeps the schema compact
# and the per-turn token cost low. Property groups: capture (mode, app, pid,
# window_id) / targeting (element, coordinate, button, modifiers) / drag / scroll /
# set_value / type-key-wait / focus_app / delivery ladder / return shape.
_PROPERTIES: Dict[str, Any] = {
"action": {
"type": "string",
"enum": [
"capture",
"click",
"double_click",
"right_click",
"middle_click",
"drag",
"scroll",
"type",
"key",
"set_value",
"wait",
"list_apps",
"list_windows",
"focus_app",
],
"description": (
"Which action to perform. `capture` is free (no side effects). All other actions "
"require approval unless auto-approved. Use `set_value` for select/popup elements and "
"sliders β it selects the matching option directly without opening the native menu (no "
"focus steal)."
),
},
"mode": {
"type": "string",
"enum": ["som", "vision", "ax"],
"description": (
"Capture mode. `som` (default) is a screenshot with numbered overlays on every "
"interactable element plus the AX tree β best for vision models, lets you click by "
"element index. `vision` is a plain screenshot. `ax` is the accessibility tree only "
"(no image; useful for text-only models)."
),
},
"app": {
"type": "string",
"description": (
"Optional. Limit capture/action to one app (name e.g. 'Safari', or bundle ID). Omitted "
"= frontmost window. app='screen' = composited full-screen grab (image only, no "
"clickable elements); app='desktop' = the OS desktop/shell surface (wallpaper, icons, "
"taskbar) with its elements."
),
},
"pid": {
"type": "integer",
"description": (
"Optional exact process target for action='capture'. Pair with window_id when "
"discovery cannot resolve an X11 app."
),
},
"window_id": {
"type": "integer",
"description": (
"Optional exact native window target for action='capture'. Pair with pid when an "
"external cua-driver list_windows lookup has already identified the window."
),
},
"element": {
"type": "integer",
"description": (
"The 1-based SOM index returned by the last `capture(mode='som')` call. Strongly "
"preferred over raw coordinates."
),
},
"coordinate": {
"type": "array",
"items": {"type": "integer"},
"minItems": 2,
"maxItems": 2,
"description": (
"Pixel coordinates [x, y] relative to the captured window screenshot (top-left "
"origin). Only use this if no element index is available."
),
},
"button": {
"type": "string",
"enum": ["left", "right", "middle"],
"description": "Mouse button. Defaults to left.",
},
"modifiers": {
"type": "array",
"items": {
"type": "string",
"enum": [
"cmd",
"shift",
"option",
"alt",
"ctrl",
"fn",
"win",
"windows",
"super",
"meta",
],
},
"description": "Modifier keys held during the action.",
},
"from_element": {"type": "integer", "description": "Source element index (drag)."},
"to_element": {"type": "integer", "description": "Target element index (drag)."},
"from_coordinate": {
"type": "array",
"items": {"type": "integer"},
"minItems": 2,
"maxItems": 2,
"description": "Source [x,y] (drag; use when no element available).",
},
"to_coordinate": {
"type": "array",
"items": {"type": "integer"},
"minItems": 2,
"maxItems": 2,
"description": "Target [x,y] (drag; use when no element available).",
},
"direction": {"type": "string", "enum": ["up", "down", "left", "right"], "description": "Scroll direction."},
"amount": {"type": "integer", "description": "Scroll wheel ticks. Default 3."},
"value": {
"type": "string",
"description": (
"For action='set_value': the value to set on the element. For AXPopUpButton / select "
"dropdowns, pass the option's display label (e.g. 'Blue'). For sliders and other "
"AXValue-settable elements, pass the numeric or string value."
),
},
"text": {"type": "string", "description": "Text to type (respects the current layout)."},
"keys": {
"type": "string",
"description": (
"Key combo, e.g. 'cmd+s', 'ctrl+alt+t', 'return', 'escape', 'tab'. Use '+' to combine."
),
},
"seconds": {"type": "number", "description": "Seconds to wait. Max 30."},
"raise_window": {
"type": "boolean",
"description": (
"Only for action='focus_app'. If true, brings the window to front (DISRUPTS the user). "
"Default false β input is routed to the app without raising, matching the background "
"co-work model."
),
},
"delivery_mode": {
"type": "string",
"enum": ["background", "foreground"],
"description": (
"For input actions (click, type, key, drag, scroll). `background` (DEFAULT) delivers "
"without raising the window or stealing focus. `foreground` briefly fronts the window "
"then restores focus β a visible change needing its own approval; use it only when a "
"result's verdict tells you to escalate there. Each result's `verdict` carries the "
"next step; follow it rather than guessing."
),
},
"bring_to_front": {
"type": "boolean",
"description": (
"Optional and only valid with delivery_mode='foreground'. Explicitly invokes "
"cua-driver's standalone bring_to_front tool before the input; it is never passed as "
"an input property. This persistent focus change has a separate approval scope. "
"Default false."
),
},
"capture_after": {
"type": "boolean",
"description": (
"If true, take a follow-up capture after the action and include it in the response. "
"Saves a round-trip when you need to verify an action's effect."
),
},
}
COMPUTER_USE_SCHEMA: Dict[str, Any] = {
"name": "computer_use",
"description": (
"Drive the desktop via cua-driver β screenshots, mouse, keyboard, scroll, drag β on macOS, "
"Windows, and Linux. Input is background-FIRST, not background-only: the default delivery "
"routes to the target window without stealing the user's cursor or focus (works even on "
"hidden/minimized windows), and when a result's `verdict` says to escalate you climb β "
"pixel coordinates, or delivery_mode='foreground' (briefly fronts the window; separate "
"approval). Each result carries a `verdict` with the next step; follow it β never repeat "
"confirmed input, and re-capture to verify an unverifiable one before retrying. Workflow: "
"action='capture' (mode='som' gives numbered element overlays), then click by `element` "
"index; re-capture after state-changing actions (or pass capture_after=true). Image "
"captures include a shareable `screenshot_path`; deliver it via the platform's MEDIA "
"syntax when the user asks to see it β not for captures used only for control."
),
"parameters": {"type": "object", "properties": _PROPERTIES, "required": ["action"]},
}
def get_computer_use_schema() -> Dict[str, Any]:
"""Return the generic OpenAI function-calling schema."""
return COMPUTER_USE_SCHEMA
|