multimodalart HF Staff commited on
Commit
afb04d6
·
verified ·
1 Parent(s): e1e5979

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ examples/linux_take_photo.png filter=lfs diff=lfs merge=lfs -text
37
+ examples/vscode_split_editor.png filter=lfs diff=lfs merge=lfs -text
38
+ examples/windows_mute.png filter=lfs diff=lfs merge=lfs -text
39
+ examples/word_redo.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,45 @@
1
  ---
2
- title: Groundgui
3
- emoji: 🌖
4
- colorFrom: red
5
- colorTo: purple
6
  sdk: gradio
7
  sdk_version: 6.30.0
8
- python_version: '3.12'
9
  app_file: app.py
10
- pinned: false
 
 
 
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: GroundGUI GUI Grounding
3
+ emoji: 🖱️
4
+ colorFrom: pink
5
+ colorTo: blue
6
  sdk: gradio
7
  sdk_version: 6.30.0
 
8
  app_file: app.py
9
+ short_description: Ground click coordinates on any GUI screenshot.
10
+ python_version: "3.12"
11
+ startup_duration_timeout: 1h
12
+ license: apache-2.0
13
+ models:
14
+ - PrentisAI/GroundGUI-8B
15
  ---
16
 
17
+ # GroundGUI · GUI Grounding
18
+
19
+ This demo runs [PrentisAI/GroundGUI-8B](https://huggingface.co/PrentisAI/GroundGUI-8B),
20
+ an 8B GUI-grounding vision-language model fine-tuned from Qwen3-VL-8B-Instruct via
21
+ high-quality data curation and distillation-to-reinforcement learning.
22
+
23
+ Give it a GUI screenshot plus a short instruction, and it emits the click action
24
+ as a tool call with coordinates in a **normalized 0–1000 space** —
25
+ `{"name": "computer_use", "arguments": {"action": "left_click", "coordinate": [x, y]}}`.
26
+ The demo maps the coordinates back onto your original image and marks the
27
+ predicted click point with a crosshair.
28
+
29
+ The system prompt is the exact frozen per-platform grounding prompt the model was
30
+ trained with (`scalecua_toolcall`): pick **desktop**, **web**, or **mobile** to
31
+ serve the matching tool schema (`computer_use` / `browser_use` / `mobile_use`).
32
+ Inference is greedy (`do_sample=False`), matching the paper's evaluation.
33
+
34
+ - Paper: [GroundGUI: GUI Grounding by High-Quality Data and Distillation-to-Reinforcement Learning](https://huggingface.co/papers/2610.19100)
35
+ - Code & data: [github.com/PrentisAI/GroundGUI](https://github.com/PrentisAI/GroundGUI)
36
+ - Model: [PrentisAI/GroundGUI-8B](https://huggingface.co/PrentisAI/GroundGUI-8B)
37
+
38
+ **Benchmark results** (from the paper): 95.2 ScreenSpot-v2 · 63.9 ScreenSpot-Pro ·
39
+ 86.8 MMBench-GUI L2 · 38.3 UI-Vision · 65.4 OSWorld-G.
40
+
41
+ ## Example screenshots
42
+
43
+ The bundled example screenshots come from
44
+ [likaixin/ScreenSpot-Pro](https://huggingface.co/datasets/likaixin/ScreenSpot-Pro)
45
+ (MIT license), a professional high-resolution GUI grounding benchmark.
app.py ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces # MUST come before torch / transformers (ZeroGPU)
2
+
3
+ import json
4
+ import os
5
+ import re
6
+ import time
7
+
8
+ import gradio as gr
9
+ import torch
10
+ from PIL import Image, ImageDraw
11
+ from transformers import AutoModelForImageTextToText, AutoProcessor
12
+
13
+ # GroundGUI-8B: a Qwen3-VL-8B derivative trained for GUI grounding with the
14
+ # ScaleCUA-recipe per-platform tool-call system prompts (frozen verbatim in
15
+ # prompts.json, extracted from ScaleCUAToolCallPrompt._GROUNDING_SYSTEM in
16
+ # github.com/PrentisAI/GroundGUI eval/prompts.py).
17
+ MODEL = "PrentisAI/GroundGUI-8B"
18
+
19
+ # Eval-side image budget (run_eval.sh: MAX_IMAGE_PIXELS=16777216). Larger
20
+ # screenshots are downscaled with smart_resize (factor = patch 16 * merge 2 =
21
+ # 32, the Qwen3-VL grid) before encoding; the predicted point is mapped back
22
+ # onto the ORIGINAL image afterwards, so the overlay is unaffected.
23
+ FACTOR = 32
24
+ MAX_PIXELS = 16_777_216
25
+
26
+ HERE = os.path.dirname(os.path.abspath(__file__))
27
+ with open(os.path.join(HERE, "prompts.json"), encoding="utf-8") as f:
28
+ GROUNDING_SYSTEM = json.load(f)
29
+
30
+ TOOL_CALL_OPEN = chr(60) + "tool_call" + chr(62)
31
+ TOOL_CALL_CLOSE = chr(60) + "/" + "tool_call" + chr(62)
32
+
33
+
34
+ def smart_resize(h, w, factor=FACTOR, min_pixels=56 * 56, max_pixels=MAX_PIXELS):
35
+ """Qwen3-VL smart_resize: snap sides to the factor grid under a pixel budget.
36
+
37
+ Mirrors qwen_vl_utils.smart_resize as used by the GroundGUI eval
38
+ (IMAGE_FACTOR=32, MAX_IMAGE_PIXELS=16777216).
39
+ """
40
+ h_bar = round(h / factor) * factor
41
+ w_bar = round(w / factor) * factor
42
+ if h_bar * w_bar > max_pixels:
43
+ beta = (h * w / max_pixels) ** 0.5
44
+ h_bar = round(h / beta / factor) * factor
45
+ w_bar = round(w / beta / factor) * factor
46
+ if h_bar * w_bar < min_pixels:
47
+ beta2 = (min_pixels / (h * w)) ** 0.5
48
+ h_bar = round(h * beta2 / factor) * factor
49
+ w_bar = round(w * beta2 / factor) * factor
50
+ return max(h_bar, factor), max(w_bar, factor)
51
+
52
+
53
+ def fit(image):
54
+ """Downscale a screenshot to the eval's vision budget (factor-32 grid)."""
55
+ w, h = image.size
56
+ nh, nw = smart_resize(h, w)
57
+ if (nh, nw) != (h, w):
58
+ image = image.resize((nw, nh), Image.LANCZOS)
59
+ return image
60
+
61
+
62
+ def extract_point(response):
63
+ """Parse the model's tool_call block into a [x, y] point in 0-1000 space.
64
+
65
+ Follows the official eval parse (Qwen3VLPrompt.extract_coordinates):
66
+ the JSON object inside the tool-call tags, terminate/abstain -> [-1, -1],
67
+ falling back to the GUI-Owl "(x, y)" then "[x, y]" regexes (last match).
68
+
69
+ Returns (point, refusal, tool_name, action_name) where point is None if
70
+ nothing parsed.
71
+ """
72
+ if ('"action": "terminate"' in response or '"status": "failure"' in response
73
+ or '"action": "abstain"' in response):
74
+ return None, True, "", ""
75
+ blobs = re.findall(
76
+ re.escape(TOOL_CALL_OPEN) + r"\s*(\{.*?\})\s*" + re.escape(TOOL_CALL_CLOSE),
77
+ response, re.DOTALL,
78
+ )
79
+ for blob in reversed(blobs):
80
+ try:
81
+ obj = json.loads(blob)
82
+ except json.JSONDecodeError:
83
+ continue
84
+ name = obj.get("name") or ""
85
+ args = obj.get("arguments") or {}
86
+ if args.get("action") in ("terminate", "abstain"):
87
+ return None, True, name, args.get("action")
88
+ coord = args.get("coordinate")
89
+ if isinstance(coord, (list, tuple)) and len(coord) >= 2:
90
+ try:
91
+ return [float(coord[0]), float(coord[1])], False, name, args.get("action")
92
+ except (TypeError, ValueError):
93
+ continue
94
+ matches = re.findall(r"\((\d+),\s*(\d+)\)", response)
95
+ if not matches:
96
+ matches = re.findall(r"\[(\d+),\s*(\d+)\]", response)
97
+ if not matches:
98
+ return None, False, "", ""
99
+ x, y = matches[-1]
100
+ return [int(x), int(y)], False, "", ""
101
+
102
+
103
+ def norm_to_pixels(point, width, height):
104
+ """Map a 0-1000 normalized point onto image pixels (GUIOwlPrompt.calculate_metrics)."""
105
+ return round(point[0] / 1000.0 * width), round(point[1] / 1000.0 * height)
106
+
107
+
108
+ def draw_marker(image, point):
109
+ """Draw a crosshair + circle at the predicted click point.
110
+
111
+ A white underlay keeps the marker visible on both light and dark UIs.
112
+ """
113
+ out = image.copy()
114
+ d = ImageDraw.Draw(out)
115
+ x, y = point
116
+ r = max(10, min(out.width, out.height) // 60)
117
+ # white underlay, then orange marker on top
118
+ d.ellipse([x - r, y - r, x + r, y + r], outline=(255, 255, 255), width=6)
119
+ d.ellipse([x - r, y - r, x + r, y + r], outline=(255, 64, 0), width=3)
120
+ for (x0, y0, x1, y1) in [
121
+ (x - r * 1.8, y, x + r * 1.8, y), # horizontal
122
+ (x, y - r * 1.8, x, y + r * 1.8), # vertical
123
+ ]:
124
+ d.line([x0, y0, x1, y1], fill=(255, 255, 255), width=9)
125
+ d.line([x0, y0, x1, y1], fill=(255, 64, 0), width=4)
126
+ return out
127
+
128
+
129
+ processor = AutoProcessor.from_pretrained(MODEL)
130
+ model = (
131
+ AutoModelForImageTextToText.from_pretrained(
132
+ MODEL, dtype=torch.bfloat16, attn_implementation="sdpa"
133
+ )
134
+ .eval()
135
+ .to("cuda")
136
+ )
137
+
138
+
139
+ @spaces.GPU(duration=120)
140
+ def predict(instruction: str, screenshot, platform: str = "desktop", max_new_tokens: int = 256):
141
+ """Locate a UI element in a screenshot.
142
+
143
+ Args:
144
+ instruction: referring expression naming the element to find,
145
+ e.g. "the redo button".
146
+ screenshot: a GUI screenshot (desktop, web, or mobile).
147
+ platform: one of "desktop", "web", "mobile" -- selects the
148
+ per-platform grounding tool schema the model was trained with
149
+ (computer_use / browser_use / mobile_use).
150
+ max_new_tokens: generation length cap for the emitted tool call.
151
+
152
+ Returns:
153
+ Tuple of (annotated screenshot with the predicted click point,
154
+ raw model output, predicted action, coordinates on the original
155
+ image, inference seconds).
156
+ """
157
+ if screenshot is None:
158
+ raise gr.Error("Please provide a GUI screenshot first.")
159
+ if not instruction or not instruction.strip():
160
+ raise gr.Error("Please enter an instruction, e.g. 'the redo button'.")
161
+ platform = platform if platform in GROUNDING_SYSTEM else "desktop"
162
+
163
+ if screenshot.mode != "RGB":
164
+ screenshot = screenshot.convert("RGB")
165
+ orig_w, orig_h = screenshot.size
166
+
167
+ # Eval-order prompt: system = frozen per-platform grounding prompt,
168
+ # user = image first, then the bare instruction (scalecua_toolcall).
169
+ messages = [
170
+ {"role": "system", "content": GROUNDING_SYSTEM[platform]},
171
+ {
172
+ "role": "user",
173
+ "content": [
174
+ {"type": "image"},
175
+ {"type": "text", "text": instruction.strip()},
176
+ ],
177
+ },
178
+ ]
179
+ prompt = processor.apply_chat_template(
180
+ messages, tokenize=False, add_generation_prompt=True
181
+ )
182
+ inputs = processor(
183
+ text=[prompt], images=[fit(screenshot)], return_tensors="pt"
184
+ ).to(model.device)
185
+
186
+ t0 = time.perf_counter()
187
+ with torch.inference_mode():
188
+ output = model.generate(
189
+ **inputs,
190
+ max_new_tokens=int(max_new_tokens),
191
+ do_sample=False,
192
+ use_cache=True,
193
+ )
194
+ elapsed = time.perf_counter() - t0
195
+
196
+ response = processor.decode(
197
+ output[0, inputs["input_ids"].shape[1]:], skip_special_tokens=True
198
+ ).strip()
199
+
200
+ # Unwrap the chat-template's tool-call rendering (skip_special_tokens=True
201
+ # keeps the non-special tool-call tags, which the parser strips itself).
202
+ body = response
203
+ if TOOL_CALL_OPEN in body:
204
+ body = body.split(TOOL_CALL_OPEN, 1)[1]
205
+ if TOOL_CALL_CLOSE in body:
206
+ body = body.split(TOOL_CALL_CLOSE, 1)[0]
207
+ body = body.strip()
208
+
209
+ point, refusal, tool_name, action_name = extract_point(body)
210
+ if refusal or point is None:
211
+ note = "Model abstained: element not found on screen." if refusal else "No coordinates parsed from the model output."
212
+ return screenshot.copy(), body, "abstain" if refusal else "", note, f"{elapsed:.1f}s"
213
+
214
+ px = norm_to_pixels(point, orig_w, orig_h)
215
+ clipped = (max(0, min(orig_w - 1, px[0])), max(0, min(orig_h - 1, px[1])))
216
+ annotated = draw_marker(screenshot, clipped)
217
+ coords_text = f"click point ({clipped[0]}, {clipped[1]}) px on {orig_w}x{orig_h} image; model space [{point[0]:g}, {point[1]:g}] / 1000"
218
+ action_text = (tool_name or "?") + "." + (action_name or "?") + f" -> ({clipped[0]}, {clipped[1]})"
219
+ return annotated, body, action_text, coords_text, f"{elapsed:.1f}s"
220
+
221
+
222
+ CSS = """
223
+ #col-container { max-width: 1400px; margin: 0 auto; }
224
+ .dark .gradio-container { color: var(--body-text-color); }
225
+ """
226
+
227
+ with gr.Blocks() as demo:
228
+ with gr.Column(elem_id="col-container"):
229
+ gr.Markdown(
230
+ """
231
+ # :mag: GroundGUI · GUI Grounding
232
+
233
+ **GroundGUI-8B** ([PrentisAI/GroundGUI-8B](https://huggingface.co/PrentisAI/GroundGUI-8B))
234
+ is an 8B GUI-grounding vision-language model fine-tuned from Qwen3-VL-8B-Instruct with
235
+ high-quality grounding data and distillation-to-reinforcement learning.
236
+ Give it a GUI screenshot and a short instruction, and it emits the click
237
+ action with coordinates in a **normalized 0–1000 space**, which are mapped onto
238
+ your original image and marked with a crosshair.
239
+
240
+ Paper: [GroundGUI: GUI Grounding by High-Quality Data and Distillation-to-Reinforcement Learning](https://huggingface.co/papers/2610.19100) ·
241
+ Code: [github.com/PrentisAI/GroundGUI](https://github.com/PrentisAI/GroundGUI)
242
+
243
+ Benchmarks: **95.2** ScreenSpot-v2 · **63.9** ScreenSpot-Pro · **86.8** MMBench-GUI L2 ·
244
+ **38.3** UI-Vision · **65.4** OSWorld-G.
245
+ """
246
+ )
247
+ with gr.Row():
248
+ with gr.Column(scale=1):
249
+ screenshot_in = gr.Image(
250
+ type="pil", label="GUI screenshot", height=420,
251
+ sources=["upload", "clipboard"],
252
+ )
253
+ instruction = gr.Textbox(
254
+ label="Instruction",
255
+ placeholder="e.g. the redo button",
256
+ lines=2,
257
+ )
258
+ platform = gr.Radio(
259
+ ["desktop", "web", "mobile"], value="desktop",
260
+ label="Platform (tool schema used in the system prompt)",
261
+ )
262
+ run_btn = gr.Button("Ground it", variant="primary")
263
+ with gr.Accordion("Advanced", open=False):
264
+ max_new_tokens = gr.Slider(
265
+ 64, 512, value=256, step=32, label="Max new tokens",
266
+ )
267
+ with gr.Column(scale=1):
268
+ screenshot_out = gr.Image(
269
+ type="pil", label="Annotated screenshot (predicted click point)",
270
+ height=420,
271
+ )
272
+ action_out = gr.Textbox(label="Predicted action", lines=1)
273
+ coords_out = gr.Textbox(label="Coordinates", lines=2)
274
+ raw_out = gr.Textbox(label="Raw model output", lines=6)
275
+ time_out = gr.Textbox(label="Inference time", lines=1)
276
+
277
+ gr.Examples(
278
+ examples=[
279
+ ["redo", "examples/word_redo.png", "desktop"],
280
+ ["Split editor.", "examples/vscode_split_editor.png", "desktop"],
281
+ ["mute", "examples/windows_mute.png", "desktop"],
282
+ ["take a photo", "examples/linux_take_photo.png", "desktop"],
283
+ ],
284
+ inputs=[instruction, screenshot_in, platform],
285
+ fn=predict,
286
+ outputs=[screenshot_out, raw_out, action_out, coords_out, time_out],
287
+ cache_examples=True,
288
+ cache_mode="lazy",
289
+ )
290
+
291
+ run_btn.click(
292
+ predict,
293
+ inputs=[instruction, screenshot_in, platform, max_new_tokens],
294
+ outputs=[screenshot_out, raw_out, action_out, coords_out, time_out],
295
+ api_name="predict",
296
+ )
297
+
298
+ if __name__ == "__main__":
299
+ demo.launch(mcp_server=True, theme=gr.themes.Citrus(), css=CSS)
examples/linux_take_photo.png ADDED

Git LFS Details

  • SHA256: 053614804586d7ca6b8a21d349a171c0b8c48d2474512cf3aae37e82d5577113
  • Pointer size: 132 Bytes
  • Size of remote file: 1.88 MB
examples/vscode_split_editor.png ADDED

Git LFS Details

  • SHA256: ac641bb2497372333c9cdb2bd8d0533ac7e9b5c361d1983504c43292c20d96b2
  • Pointer size: 131 Bytes
  • Size of remote file: 704 kB
examples/windows_mute.png ADDED

Git LFS Details

  • SHA256: 3e1838a9bb65cf4840790443e1a48f17e10efcd2fe1a6132750d1ce3effd6faa
  • Pointer size: 132 Bytes
  • Size of remote file: 1.48 MB
examples/word_redo.png ADDED

Git LFS Details

  • SHA256: 2a0c8931ec1db48fe0cfe27b43671dbc474d7da960291b428adce49d1c0b256a
  • Pointer size: 132 Bytes
  • Size of remote file: 3.4 MB
prompts.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "desktop": "You are an autonomous GUI agent capable of operating on desktops, mobile devices, and web browsers. Your primary function is to analyze a screen capture, locate the target UI element, and issue the single appropriate action that fulfills the given instruction.\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>\n{\"type\": \"function\", \"function\": {\"name\": \"computer_use\", \"description\": \"Use a mouse and keyboard to interact with a computer, and take screenshots.\\n* This is an interface to a desktop GUI. You do not have access to a terminal or applications menu. You must click on desktop icons to start applications.\\n* Some applications may take time to start or process actions, so you may need to wait and take successive screenshots to see the results of your actions. E.g. if you click on Firefox and a window doesn't open, try wait and taking another screenshot.\\n* The screen's resolution is 1000x1000.\\n* Make sure to click any buttons, links, icons, etc with the cursor tip in the center of the element. Don't click boxes on their edges unless asked.\", \"parameters\": {\"properties\": {\"action\": {\"description\": \"The action to perform. The available actions are:\\n* `mouse_move`: Move the cursor to a specified (x, y) pixel coordinate on the screen.\\n* `left_click`: Click the left mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `left_click_drag`: Press the left mouse button at the start point with coordinate (x, y), drag to the end point with coordinate2 (x2, y2), and release.\\n* `right_click`: Click the right mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `middle_click`: Click the middle mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `double_click`: Double-click the left mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `triple_click`: Triple-click the left mouse button at a specified (x, y) pixel coordinate on the screen.\", \"enum\": [\"mouse_move\", \"left_click\", \"left_click_drag\", \"right_click\", \"middle_click\", \"double_click\", \"triple_click\"], \"type\": \"string\"}, \"coordinate\": {\"description\": \"(x, y): The x (pixels from the left edge) and y (pixels from the top edge) coordinates to move the mouse to. Required only by `action=mouse_move`, `action=left_click`, `action=left_click_drag`, `action=right_click`, `action=middle_click`, `action=double_click`, and `action=triple_click`.\", \"type\": \"array\"}, \"coordinate2\": {\"description\": \"(x, y): The x (pixels from the left edge) and y (pixels from the top edge) coordinates to drag the cursor to. Required only by `action=left_click_drag`.\", \"type\": \"array\"}}, \"required\": [\"action\"], \"type\": \"object\"}}}\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call>\n\n## Input Specification\n- A screenshot of the current screen + an instruction describing the action to perform.\n\n## Output Format\n- Emit exactly one <tool_call></tool_call> block containing a single JSON object with the function name and its arguments.\n- Coordinates are integers in a 1000x1000 space (x measured from the left edge, y from the top edge).\n\n## Note\n- Choose exactly one function whose name and arguments are defined in the tool schema above.\n- Do not output anything other than the <tool_call></tool_call> block.",
3
+ "mobile": "You are an autonomous GUI agent capable of operating on desktops, mobile devices, and web browsers. Your primary function is to analyze a screen capture, locate the target UI element, and issue the single appropriate action that fulfills the given instruction.\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>\n{\"type\": \"function\", \"function\": {\"name\": \"mobile_use\", \"description\": \"Use a touchscreen to interact with a mobile device, and take screenshots.\\n* This is an interface to a mobile device with touchscreen. You can perform actions like clicking, typing, swiping, etc.\\n* Some applications may take time to start or process actions, so you may need to wait and take successive screenshots to see the results of your actions.\\n* The screen's resolution is 1000x1000.\\n* Make sure to click any buttons, links, icons, etc with the cursor tip in the center of the element. Don't click boxes on their edges unless asked.\", \"parameters\": {\"properties\": {\"action\": {\"description\": \"The action to perform. The available actions are:\\n* `click`: Click the point on the screen with coordinate (x, y).\\n* `long_press`: Press the point on the screen with coordinate (x, y) for specified seconds.\", \"enum\": [\"click\", \"long_press\"], \"type\": \"string\"}, \"coordinate\": {\"description\": \"(x, y): the point on the screen the action acts on — the element to touch, the region to scroll, or the object to start dragging. x is measured from the left edge and y from the top edge, both on a 0-1000 scale, so y gets larger toward the bottom of the screen. Required only by `action=click` and `action=long_press`.\", \"type\": \"array\"}, \"time\": {\"description\": \"The seconds to wait. Required only by `action=long_press`.\", \"type\": \"number\"}}, \"required\": [\"action\"], \"type\": \"object\"}}}\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call>\n\n## Input Specification\n- A screenshot of the current screen + an instruction describing the action to perform.\n\n## Output Format\n- Emit exactly one <tool_call></tool_call> block containing a single JSON object with the function name and its arguments.\n- Coordinates are integers in a 1000x1000 space (x measured from the left edge, y from the top edge).\n\n## Note\n- Choose exactly one function whose name and arguments are defined in the tool schema above.\n- Do not output anything other than the <tool_call></tool_call> block.",
4
+ "web": "You are an autonomous GUI agent capable of operating on desktops, mobile devices, and web browsers. Your primary function is to analyze a screen capture, locate the target UI element, and issue the single appropriate action that fulfills the given instruction.\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>\n{\"type\": \"function\", \"function\": {\"name\": \"browser_use\", \"description\": \"Use a mouse and keyboard to interact with a web browser, and take screenshots.\\n* This is an interface to a web browser. You interact with the rendered web page by clicking, typing, scrolling, selecting options and navigating between pages.\\n* Some pages may take time to load or process actions, so you may need to wait and take successive screenshots to see the results of your actions.\\n* The screen's resolution is 1000x1000.\\n* Make sure to click any buttons, links, icons, etc with the cursor tip in the center of the element. Don't click boxes on their edges unless asked.\", \"parameters\": {\"properties\": {\"action\": {\"description\": \"The action to perform. The available actions are:\\n* `mouse_move`: Move the cursor to a specified (x, y) pixel coordinate on the screen.\\n* `left_click`: Click the left mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `left_click_drag`: Press the left mouse button at the start point with coordinate (x, y), drag to the end point with coordinate2 (x2, y2), and release.\\n* `right_click`: Click the right mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `middle_click`: Click the middle mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `double_click`: Double-click the left mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `triple_click`: Triple-click the left mouse button at a specified (x, y) pixel coordinate on the screen.\\n* `select`: Select an option in a dropdown or list element at the specified (x, y) coordinate; the option to choose is given by text.\", \"enum\": [\"mouse_move\", \"left_click\", \"left_click_drag\", \"right_click\", \"middle_click\", \"double_click\", \"triple_click\", \"select\"], \"type\": \"string\"}, \"coordinate\": {\"description\": \"(x, y): The x (pixels from the left edge) and y (pixels from the top edge) coordinates to move the mouse to. Required only by `action=mouse_move`, `action=left_click`, `action=left_click_drag`, `action=right_click`, `action=middle_click`, `action=double_click`, `action=triple_click`, and `action=select`.\", \"type\": \"array\"}, \"coordinate2\": {\"description\": \"(x, y): The x (pixels from the left edge) and y (pixels from the top edge) coordinates to drag the cursor to. Required only by `action=left_click_drag`.\", \"type\": \"array\"}, \"text\": {\"description\": \"Required only by `action=select`.\", \"type\": \"string\"}}, \"required\": [\"action\"], \"type\": \"object\"}}}\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call>\n\n## Input Specification\n- A screenshot of the current screen + an instruction describing the action to perform.\n\n## Output Format\n- Emit exactly one <tool_call></tool_call> block containing a single JSON object with the function name and its arguments.\n- Coordinates are integers in a 1000x1000 space (x measured from the left edge, y from the top edge).\n\n## Note\n- Choose exactly one function whose name and arguments are defined in the tool schema above.\n- Do not output anything other than the <tool_call></tool_call> block."
5
+ }
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ transformers==5.19.0
2
+ accelerate
3
+ torchvision==0.26.0
4
+ pillow