{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2025-09-23-smol2operator-post-training-gui-agents-for-computer-use/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "**TL;DR:** This work shows how a lightweight vision–language model can acquire GUI-grounded skills and evolve into an agentic GUI coder. We release all training recipes, data-processing tools, resulting model, demo and datasets to enable full reproducibility and foster further research 🫡. Find the collection [here](https://huggingface.co/collections/smolagents/smol2operator-release-68d288e87d3fa8f551d2ce2e).\n\n* * *\n\nThis video demonstrates the model obtained through the recipe described below, executing a task end-to-end.\n\n* * *\n\n## Table of Contents\n\n- [Introduction](https://huggingface.co/blog/smol2operator#introduction)\n- [1\\. Data Transformation and Unified Action Space](https://huggingface.co/blog/smol2operator#1-data-transformation-and-unified-action-space)\n  - [The Challenge of Inconsistent Action Spaces](https://huggingface.co/blog/smol2operator#the-challenge-of-inconsistent-action-spaces)\n  - [Our Unified Approach](https://huggingface.co/blog/smol2operator#our-unified-approach)\n  - [Example Data Transformation](https://huggingface.co/blog/smol2operator#example-data-transformation)\n  - [Custom Action Space Adaptation with Action Space Converter](https://huggingface.co/blog/smol2operator#bonus-custom-action-space-adaptation-with-action-space-converter)\n  - [Key Features](https://huggingface.co/blog/smol2operator#key-features)\n  - [Usage Example](https://huggingface.co/blog/smol2operator#usage-example)\n  - [Transformed and Released Datasets](https://huggingface.co/blog/smol2operator#transformed-and-released-datasets)\n- [2\\. Phase 1: From Zero to Perception](https://huggingface.co/blog/smol2operator#2-phase-1-from-zero-to-perception)\n  - [Training Data](https://huggingface.co/blog/smol2operator#training-data)\n  - [Optimization Experiments](https://huggingface.co/blog/smol2operator#optimization-experiments)\n  - [Image Resolution and Coordinate System Analysis](https://huggingface.co/blog/smol2operator#image-resolution-and-coordinate-system-analysis)\n  - [Key Findings](https://huggingface.co/blog/smol2operator#key-findings)\n  - [Phase 1 Results](https://huggingface.co/blog/smol2operator#phase-1-results)\n- [3\\. Phase 2: From Perception to Cognition](https://huggingface.co/blog/smol2operator#3-phase-2-from-perception-to-cognition)\n  - [Training Data](https://huggingface.co/blog/smol2operator#training-data-1)\n  - [Phase 2 Results](https://huggingface.co/blog/smol2operator#phase-2-results)\n- [4\\. All you need is Open Source](https://huggingface.co/blog/smol2operator#4-all-you-need-is-open-source)\n- [5\\. Conclusion](https://huggingface.co/blog/smol2operator#5-conclusion)\n- [What's Next?](https://huggingface.co/blog/smol2operator#whats-next)\n\n## Introduction\n\nGraphical User Interface (GUI) automation is one of the most challenging frontiers in computer vision. Developing models that see and interact with user interfaces enables AI agents to navigate mobile, desktop, and web platforms. This will reshape the future of digital interaction.\n\nIn this blog post, we present a comprehensive approach to training vision-language models for GUI automation through a multi-phase training strategy. We demonstrate how to transform a model with zero grounding capabilities into an agentic coder capable of understanding and interacting with graphical interfaces.\n\nRather than aiming for a SOTA model, our goal is to demonstrate the entire process, from data processing to model training, and, in doing so, show how to unlock GUI-grounding capabilities in VLMs.\n\n[![GUI capabilities combine understanding of the interface and precise element localization. These abilities enable the model to translate high-level tasks into low-level GUI actions such as clicking, typing, …](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/google.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/google.png)\n\n*GUI capabilities combine understanding of the interface and precise element localization. These abilities enable the model to translate high-level tasks into low-level GUI actions such as clicking, typing, …*\n\nOur approach leverages [**SmolVLM2-2.2B-Instruct**](https://huggingface.co/HuggingFaceTB/SmolVLM2-2.2B-Instruct) as the baseline model, a small powerful vision-language model that initially has no grounding capabilities for GUI tasks. This makes it an ideal candidate to demonstrate the effectiveness of our training methodology. Through our two-phase training process, we first instill grounding capabilities in the model, then enhance it with agentic reasoning abilities using Supervised Fine-Tuning (SFT).\n\nWe evaluate our approach on an established perception benchmark: [**ScreenSpot-v2**](https://huggingface.co/datasets/HongxinLi/ScreenSpot_v2), which tests the model’s ability to understand and locate elements within screenshots. Our process is inspired by the [AGUVIS](https://huggingface.co/papers/2412.04454) paper, and we leverage their carefully curated datasets to build upon their foundational work.\n\n[![Evolution of ScreenSpot-v2 performance during the training phase of the base model SmolVLM2-2.2B-Instruct.](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/screenspot-v2.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/screenspot-v2.png)\n\n*Evolution of ScreenSpot-v2 performance during the training phase of the base model **SmolVLM2-2.2B-Instruct**.*\n\n## 1. Data Transformation and Unified Action Space\n\n*This section explains how we **convert heterogeneous GUI actions format from multiple datasets into a single unified format**. By standardizing function names, signatures, and parameters, we create consistent, high-quality data that forms the foundation for effective model training.*\n\n### The Challenge of Inconsistent Action Spaces\n\nOne of the primary challenges when working with multiple GUI automation datasets is the lack of standardization in action representations. Different datasets use varying function signatures, parameter naming conventions, and action taxonomies, making it difficult to train a unified model across diverse data sources.\n\n### Our Unified Approach\n\nWe took the open-source datasets ([xlangai/aguvis-stage1](https://huggingface.co/datasets/xlangai/aguvis-stage1), [xlangai/aguvis-stage2](https://huggingface.co/datasets/xlangai/aguvis-stage2)), originally used by [AGUVIS](https://huggingface.co/papers/2412.04454), and implemented a comprehensive data transformation pipeline to create a unified action space. Our approach involved:\n\n1. **Function Parsing and Normalization**: We developed a function parser (see `utils/function_parser.py`) that can extract and parse function calls from various formats across all datasets. This parser supports any function signature format, handles complex parameter structures, and can reconstruct function calls with proper parameter ordering.\n2. **Action Space Unification**: We implemented a comprehensive action conversion system (see `preprocessing/action_conversion.py`) that transforms all original action representations into a standardized function naming and argument structure. This process highlighted the significant inconsistencies in function signatures across different datasets and allowed us to:\n   - Remove undesired or redundant actions\n   - Standardize parameter naming conventions\n   - Create a cohesive action vocabulary\n3. **(Bonus) Flexible Adaptation Framework**: Our transformation pipeline includes utilities that allow users to:\n   - Adapt the entire dataset to their own action space naming conventions using the `utils/action_space_converter.py` tool\n   - Extract and analyze the current action space structure\n\n### Example Data Transformation\n\nHere are real examples from our action conversion system (`preprocessing/action_conversion.py`) showing how we transform heterogeneous action representations into our unified format (grounding coordinates normalized to \\[0,1\\]):\n\n**Before (Original Action Dataset Formats):**\n\n```python\n# Mobile Actions\nmobile.home()\nmobile.open_app(app_name='drupe')\nmobile.swipe(from_coord=[0.581, 0.898], to_coord=[0.601, 0.518])\nmobile.long_press(x=0.799, y=0.911)\nmobile.terminate(status='success')\n# Desktop Actions\npyautogui.click(x=0.8102, y=0.9463)\npyautogui.doubleClick(x=0.8102, y=0.9463)\npyautogui.hotkey(keys=['ctrl', 'c'])\npyautogui.scroll(page=-0.1)\npyautogui.write(message='bread buns')\npyautogui.dragTo(from_coord=[0.87, 0.423], to_coord=[0.8102, 0.9463])\n```\n\n**After (Unified Action Dataset Formats):**\n\n```python\n# Unified Mobile Actions\nnavigate_home()\nopen_app(app_name='drupe')\nswipe(from_coord=[0.581, 0.898], to_coord=[0.601, 0.518])\nlong_press(x=0.799, y=0.911)\nfinal_answer('success')\n# Unified Desktop Actions\nclick(x=0.8102, y=0.9463)\ndouble_click(x=0.8102, y=0.9463)\npress(keys=['ctrl', 'c'])\nscroll(direction='up', amount=10)  # Smart direction detection\ntype(text='bread buns')\ndrag(from_coord=[0.87, 0.423], to_coord=[0.8102, 0.9463])\n```\n\nThis unification process was essential for creating coherent training data that allows the model to learn consistent action patterns across diverse GUI environments.\n\n**💡 Why Normalized Coordinates?** \\\n Using raw pixel coordinates in text-action datapoint (e.g. `click(x=302, y=63)`) ties them to a single image size. Vision Language Models (VLMs) often resize images, causing pixel coordinates to break and require adjustment. Normalized coordinates (relative to image size) remain valid at any resolution and keep the dataset consistent.\n\n### (Bonus) Custom Action Space Adaptation with Action Space Converter\n\nTo maximize flexibility for different use cases, we developed the **Action Space Converter** (`utils/action_space_converter.py`), a tool that allows users to easily adapt from an action space to their own custom action vocabularies and naming conventions.\n\nYou can use this tool to transform one action signature (function names, parameter names, and parameter value changes, ...) into another:\n\n**Before**\n\n```python\nassistant_message: \"Action: click(x=0.5, y=0.3)\"\n```\n\n**After**\n\n```python\nassistant_message: \"Action: touch(x_coord=200, y_coord=300)\"\n```\n\n### Key Features\n\nThe Action Space Converter provides:\n\n1. **Configurable Mappings**: Define custom mappings between unified actions and your preferred action names\n2. **Parameter Transformation**: Rename parameters, apply value transformations, and set default values\n3. **Flexible Architecture**: Support for both simple parameter mappings and complex custom transformation functions\n4. **Validation**: Built-in validation to ensure mapping configurations are valid\n\n### Usage Example\n\n```python\nfrom utils.action_space_converter import ActionSpaceConverter, ActionMapping, ParameterMapping\nfrom utils.function_parser import parse_function_call\n\n# Create custom mappings\nmappings = [\n    ActionMapping(\n        source_function=\"click\",\n        target_function=\"touch\",\n        parameter_mappings=[\n            ParameterMapping(source_name=\"x\", target_name=\"x_coord\"),\n            ParameterMapping(source_name=\"y\", target_name=\"y_coord\")\n        ],\n        description=\"Touch screen at coordinates\"    ),\n    ActionMapping(\n        source_function=\"type\", # source_function is the name of the function in the original function call\n        target_function=\"write\", # target_function is the name of the function in the target function call        \n        parameter_mappings=[\n            ParameterMapping(source_name=\"text\", target_name=\"content\")\n            # source_name is the name of the parameter in the original function call            \n            # target_name is the name of the parameter in the target function call        \n        ],\n        description=\"Input text\"    \n    )\n]\n\nassistant_message = \"I'll interact at those coordinates for you. click(x=0.5, y=0.3) Now I'll input the text. type(text='hello world')\"\n\n# Parse function calls\nparsed_function_calls = parse_function_call(text)\n\n# Initialize converter\nconverter = ActionSpaceConverter(mappings)\n\n# Convert actions\nconverted_actions = converter.convert_actions(parsed_function_calls)\nfor new_function_call, old_function_call in zip(converted_actions, parsed_function_calls):\n    text = text.replace(old_function_call.to_string(), new_function_call.to_string())\n\nprint(text)\n# Output: I'll interact at those coordinates for you. touch(x_coord=0.5, y_coord=0.3) Now I'll input the text. write(content='hello world')\n```\n\nThis tool enables researchers and practitioners to:\n\n- **Customize Training Data**: Adapt the dataset to match their specific action vocabulary requirements\n- **Domain Adaptation**: Transform actions for different platforms (mobile vs. desktop vs. web)\n- **Framework Integration**: Easily align training data with existing automation frameworks\n- **Rapid Experimentation**: Quickly test different action space configurations\n- **Release Preparation**: Standardize action spaces for production deployment with consistent naming conventions\n\nThe Action Space Converter is particularly valuable for preparing datasets for training, as it ensures consistent action vocabularies across different deployment environments while maintaining compatibility with existing automation frameworks.\n\n### Transformed and Released Datasets\n\nThrough this pipeline, we transform the open-source datasets [xlangai/aguvis-stage1](https://huggingface.co/datasets/xlangai/aguvis-stage1), [xlangai/aguvis-stage2](https://huggingface.co/datasets/xlangai/aguvis-stage2) into our unified action space (see [here](https://www.notion.so/Smol2Operator-Post-Training-GUI-Agents-for-Computer-Use-Draft-Blog-Post-2701384ebcac8035bbaad69b5b32ed99?pvs=21)). The output of this process is released as two new fully formatted datasets: [smolagents/aguvis-stage-1](https://huggingface.co/datasets/smolagents/aguvis-stage-1) and [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2).\n\n## 2. Phase 1: From Zero to Perception\n\n### Training Data\n\nPhase 1 leverages the [smolagents/aguvis-stage-1](https://huggingface.co/datasets/smolagents/aguvis-stage-1) dataset, which introduces **GUI grounding** by pairing low-level instructions with diverse executable actions (expressed in code form). For example, a user/assistant turn in [smolagents/aguvis-stage-1](https://huggingface.co/datasets/smolagents/aguvis-stage-1) follows the structure:\n\n```json\n{\n  \"user\": \"click on more button\",\n  \"assistant\": \"click(x=0.8875, y=0.2281)\",\n}\n```\n\nEach sample links a screenshot with multi-turn user/assistant interactions, enabling the model to learn fine-grained action grounding across dialogue turns. During fine-tuning, the data collator masks everything except the assistant’s answers when computing the loss.\n\n### Optimization Experiments\n\nBefore proceeding with full-scale Phase 1 training, we conducted comprehensive ablation studies to determine optimal training configurations\n\n### Image Resolution and Coordinate System Analysis\n\nWe experimented with different image sizes and coordinate representation systems to identify the optimal configuration for SmolVLM2:\n\n- **Image Sizes Tested**: 384px, 768px, 1152px\n- **Coordinate Systems**: Pixel coordinates vs. normalized coordinates (0-1 range)\n- **Training Data**: 400K samples from Aguvis datasets\n\n> Some SOTA GUI VLMs (e.g., Qwen-VL) appear also to use a different normalized range (0–1000), which was not tested in this experiment.\n\n| Configuration (coords / image size) | Screenspot-v2 (%) |\n| ----------------------------------- | ----------------- |\n| *Normalized coordinates*            |                   |\n| Base / –                            | 0.47              |\n| 384                                 | 31.28             |\n| 764                                 | 32.32             |\n| 1152                                | **33.72**         |\n| *Pixel coordinates*                 |                   |\n| Base / –                            | 0.55              |\n| 384                                 | 1.17              |\n| 764                                 | 2.67              |\n| 1152                                | 4.32              |\n\n**Table 1:** *Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct (400k samples, aguvis-stage-1). Higher is better.*\n\n*As demonstrated in our benchmark results, SmolVLM2-2.2B-Instruct base initially achieved 0% performance on perception benchmarks like ScreenSpot-v2. This complete lack of grounding capability provided us with a clean slate to evaluate the effectiveness of our training methodology.*\n\n### Key Findings\n\nFrom our experiments, we determined that:\n\n- **Image Size**: 1152px\n- **Coordinate System**: Normalized coordinates (0-1 range) proved most effective for SmolVLM2\n- Note: The optimal choice between pixel and normalized coordinates may vary depending on the base model’s pre-training approach\n\n### Phase 1 Results\n\nUsing the optimal configuration (1152px resolution with normalized coordinates), we trained for 2 epochs on the smolagents/aguvis-stage-1 dataset. The results were remarkable, **+41% improvement over baseline on ScreenSpot-v2**\n\nThis dramatic improvement demonstrates that our Phase 1 training successfully instilled fundamental grounding capabilities in the model, enabling it to understand and locate visual elements within screenshots.\n\n| Configuration (coords / image size) | Screenspot-v2 (%) |\n| ----------------------------------- | ----------------- |\n| Normalized coordinates / 1152       | 41.27             |\n\n**Table 2:** *Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct (2 epochs, aguvis-stage-1).*\n\n## 3. Phase 2: From Perception to Cognition\n\nWhereas Phase 1 provided grounding capabilities, Phase 2 targets **agentic reasoning,** the ability to deliberate and plan before acting. This stage transforms the model from a reactive system identifying GUI elements into a proactive agent capable of executing complex, multi-step interactions.\n\n### Training Data\n\nPhase 2 uses the [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2) dataset, which introduces agentic scenarios:\n\n- **Explicit reasoning** about upcoming actions\n\n- **Context consistency** across multiple interaction steps\n\n- **High-level instructions** require multi-step, low-level actions.\n\nFor example, the [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2) chat message is like this:\n\n```json\n{\n  \"system\": \"You are a helpful GUI agent. ...\",\n  \"user\": \"Please generate the next move according to the UI screenshot, instruction and previous actions.\\n\\nInstruction: What information does the site provide about Judith Lauand's career, works and exhibitions?\\n\\nPrevious actions:\\nNone\",\n  \"assistant\": \"<think>\\nClick on the link labeled 'Judith Lauand: Brazilian 1922-2022' to explore more about her career and exhibitions.\\n</think>\\n<code>\\nclick(x=0.41, y=0.178)\\n</code>\",\n}\n```\n\nEach sample links a screenshot with a system/user/assistant turn. During fine-tuning, the data collator masks everything except the assistant’s answers when computing the loss.\n\n### Phase 2 Results\n\nStarting from the Phase 1 checkpoint (1152 px resolution, normalized coordinates), we fine-tuned the model for two epochs on [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2). The accuracy on **ScreenSpot-v2 increased from 41% to 61%**, indicating that explicit reasoning improves GUI grounding performance.\n\n| Configuration (coords / image size) | Screenspot-v2 (%) |\n| ----------------------------------- | ----------------- |\n| Normalized coordinates / 1152       | 61.71             |\n\n**Table 2:** *Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct after Phase 1 finetuning (2 epochs, aguvis-stage-1).*\n\n💡 *We also reproduced the two-phase training on a much smaller VLM (nanoVLM-460M). Despite its reduced capacity, the model achieved **\\~58% on ScreenSpot-v2**, demonstrating that the training strategy scales down effectively, **making it SOTA on ScreenSpot-v2 for this model size (460M parameters)**. In addition, aguvis-stage-1 is already included in [FineVision Dataset](https://huggingface.co/datasets/HuggingFaceM4/FineVision)!*\n\n## 4. All you need is Open Source\n\nAll training code, data processing pipelines, datasets and model are open-source!\n\n1. **Training Recipe** ([`recipe.ipynb`](https://github.com/huggingface/smol2operator/blob/main/recipe.ipynb)): Complete training pipeline for both Phase 1 and Phase 2, including dataset mixture configurations and training orchestration. We leverage the [TRL](https://huggingface.co/docs/trl/en/index) library to train our models.\n2. **Datasets** ([`smolagents/aguvis-stage-1`](https://huggingface.co/datasets/smolagents/aguvis-stage-1), [`smolagents/aguvis-stage-2`](https://huggingface.co/datasets/smolagents/aguvis-stage-2)): all datasets used are open-source.\n3. **Model** ([`smolagents/SmolVLM2-2.2B-Instruct-Agentic-GUI`](https://huggingface.co/smolagents/SmolVLM2-2.2B-Instruct-Agentic-GUI)): the model produced by applying the training recipe described above.\n4. **Preprocessing Tools:**\n   - **Function Parser** ([`utils/function_parser.py`](https://github.com/huggingface/smol2operator/blob/main/utils/function_parser.py)): Utilities for parsing, normalizing, and reconstructing function calls from diverse dataset formats. Supports complex parameter structures, positional arguments, and multiple function call extraction.\n   - **Action Conversion System** ([`preprocessing/action_conversion.py`](https://github.com/huggingface/smol2operator/blob/main/preprocessing/action_conversion.py)): Core unification engine transforming mobile and PyAutoGUI desktop actions into a standardized API format. Features smart coordinate handling, direction detection for scroll actions, and comprehensive parameter normalization.\n   - **Action Space Converter** ([`utils/action_space_converter.py`](https://github.com/huggingface/smol2operator/blob/main/utils/action_space_converter.py)): Flexible tool for adapting the unified action space to custom vocabularies and naming conventions. Enables domain-specific customization through configurable parameter mappings.\n\n💡 We’ve also released a Space to try the model’s agentic grounding capabilities: [A-Mahla/Smol2Operator](https://huggingface.co/spaces/A-Mahla/Smol2Operator)\n\n## 5. Conclusion\n\nOur experiments demonstrate that high-quality, reasoning-oriented data can substantially improve GUI grounding, even for small VLMs, using only supervised fine-tuning (SFT). Beyond raw performance gains, these results show that the GUI grounding capabilities are largely determined by the quality of the data. Carefully curated datasets teach models the structure and semantics of user interfaces, providing the grounding needed for accurate action prediction.\n\nTo support the development of GUI agents, we’re open-sourcing everything: our complete pipeline, datasets, and trained model. You can reproduce our results, experiment with different models and architectures, or adapt our approach to new domains. The future of agentic AI depends on researchers like you pushing these boundaries further!\n\n## What's Next?\n\nWhile SFT excels at supervised tasks, emerging methods such as Reinforcement Learning (RL) or Direct Preference Optimization (DPO) help develop stronger reasoning capabilities and enable real-time adaptation. These advances point toward a new generation of GUI agents that learn and improve through interaction rather than relying solely on static datasets.\n\nLet’s build the future of GUI agents together 🤗\n",
  "authors": [],
  "captured_at": "2026-10-04T12:50:30.804479567+00:00",
  "category": "ai",
  "content_html": "<p><strong>TL;DR:</strong> This work shows how a lightweight vision–language model can acquire GUI-grounded skills and evolve into an agentic GUI coder. We release all training recipes, data-processing tools, resulting model, demo and datasets to enable full reproducibility and foster further research 🫡. Find the collection <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/collections/smolagents/smol2operator-release-68d288e87d3fa8f551d2ce2e\">here</a>.</p>\n<hr />\n<p>This video demonstrates the model obtained through the recipe described below, executing a task end-to-end.</p>\n<hr />\n<h2>Table of Contents</h2>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#introduction\">Introduction</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#1-data-transformation-and-unified-action-space\">1. Data Transformation and Unified Action Space</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#the-challenge-of-inconsistent-action-spaces\">The Challenge of Inconsistent Action Spaces</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#our-unified-approach\">Our Unified Approach</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#example-data-transformation\">Example Data Transformation</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#bonus-custom-action-space-adaptation-with-action-space-converter\">Custom Action Space Adaptation with Action Space Converter</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#key-features\">Key Features</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#usage-example\">Usage Example</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#transformed-and-released-datasets\">Transformed and Released Datasets</a></li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#2-phase-1-from-zero-to-perception\">2. Phase 1: From Zero to Perception</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#training-data\">Training Data</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#optimization-experiments\">Optimization Experiments</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#image-resolution-and-coordinate-system-analysis\">Image Resolution and Coordinate System Analysis</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#key-findings\">Key Findings</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#phase-1-results\">Phase 1 Results</a></li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#3-phase-2-from-perception-to-cognition\">3. Phase 2: From Perception to Cognition</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#training-data-1\">Training Data</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#phase-2-results\">Phase 2 Results</a></li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#4-all-you-need-is-open-source\">4. All you need is Open Source</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#5-conclusion\">5. Conclusion</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/smol2operator#whats-next\">What's Next?</a></li>\n</ul>\n<h2>Introduction</h2>\n<p>Graphical User Interface (GUI) automation is one of the most challenging frontiers in computer vision. Developing models that see and interact with user interfaces enables AI agents to navigate mobile, desktop, and web platforms. This will reshape the future of digital interaction.</p>\n<p>In this blog post, we present a comprehensive approach to training vision-language models for GUI automation through a multi-phase training strategy. We demonstrate how to transform a model with zero grounding capabilities into an agentic coder capable of understanding and interacting with graphical interfaces.</p>\n<p>Rather than aiming for a SOTA model, our goal is to demonstrate the entire process, from data processing to model training, and, in doing so, show how to unlock GUI-grounding capabilities in VLMs.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/google.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/google.png\" alt=\"GUI capabilities combine understanding of the interface and precise element localization. These abilities enable the model to translate high-level tasks into low-level GUI actions such as clicking, typing, …\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<p><em>GUI capabilities combine understanding of the interface and precise element localization. These abilities enable the model to translate high-level tasks into low-level GUI actions such as clicking, typing, …</em></p>\n<p>Our approach leverages <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/HuggingFaceTB/SmolVLM2-2.2B-Instruct\"><strong>SmolVLM2-2.2B-Instruct</strong></a> as the baseline model, a small powerful vision-language model that initially has no grounding capabilities for GUI tasks. This makes it an ideal candidate to demonstrate the effectiveness of our training methodology. Through our two-phase training process, we first instill grounding capabilities in the model, then enhance it with agentic reasoning abilities using Supervised Fine-Tuning (SFT).</p>\n<p>We evaluate our approach on an established perception benchmark: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/HongxinLi/ScreenSpot_v2\"><strong>ScreenSpot-v2</strong></a>, which tests the model’s ability to understand and locate elements within screenshots. Our process is inspired by the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/papers/2412.04454\">AGUVIS</a> paper, and we leverage their carefully curated datasets to build upon their foundational work.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/screenspot-v2.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/screenspot-v2.png\" alt=\"Evolution of ScreenSpot-v2 performance during the training phase of the base model SmolVLM2-2.2B-Instruct.\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<p><em>Evolution of ScreenSpot-v2 performance during the training phase of the base model <strong>SmolVLM2-2.2B-Instruct</strong>.</em></p>\n<h2>1. Data Transformation and Unified Action Space</h2>\n<p><em>This section explains how we <strong>convert heterogeneous GUI actions format from multiple datasets into a single unified format</strong>. By standardizing function names, signatures, and parameters, we create consistent, high-quality data that forms the foundation for effective model training.</em></p>\n<h3>The Challenge of Inconsistent Action Spaces</h3>\n<p>One of the primary challenges when working with multiple GUI automation datasets is the lack of standardization in action representations. Different datasets use varying function signatures, parameter naming conventions, and action taxonomies, making it difficult to train a unified model across diverse data sources.</p>\n<h3>Our Unified Approach</h3>\n<p>We took the open-source datasets (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/xlangai/aguvis-stage1\">xlangai/aguvis-stage1</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/xlangai/aguvis-stage2\">xlangai/aguvis-stage2</a>), originally used by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/papers/2412.04454\">AGUVIS</a>, and implemented a comprehensive data transformation pipeline to create a unified action space. Our approach involved:</p>\n<ol>\n<li><strong>Function Parsing and Normalization</strong>: We developed a function parser (see <code>utils/function_parser.py</code>) that can extract and parse function calls from various formats across all datasets. This parser supports any function signature format, handles complex parameter structures, and can reconstruct function calls with proper parameter ordering.</li>\n<li><strong>Action Space Unification</strong>: We implemented a comprehensive action conversion system (see <code>preprocessing/action_conversion.py</code>) that transforms all original action representations into a standardized function naming and argument structure. This process highlighted the significant inconsistencies in function signatures across different datasets and allowed us to:\n<ul>\n<li>Remove undesired or redundant actions</li>\n<li>Standardize parameter naming conventions</li>\n<li>Create a cohesive action vocabulary</li>\n</ul>\n</li>\n<li><strong>(Bonus) Flexible Adaptation Framework</strong>: Our transformation pipeline includes utilities that allow users to:\n<ul>\n<li>Adapt the entire dataset to their own action space naming conventions using the <code>utils/action_space_converter.py</code> tool</li>\n<li>Extract and analyze the current action space structure</li>\n</ul>\n</li>\n</ol>\n<h3>Example Data Transformation</h3>\n<p>Here are real examples from our action conversion system (<code>preprocessing/action_conversion.py</code>) showing how we transform heterogeneous action representations into our unified format (grounding coordinates normalized to [0,1]):</p>\n<p><strong>Before (Original Action Dataset Formats):</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Mobile Actions\n</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mobile</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">home</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mobile</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">open_app</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">app_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">drupe<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mobile</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">swipe</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">from_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>581</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>898</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">to_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>601</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>518</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mobile</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">long_press</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">x</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>799</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">y</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>911</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mobile</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">terminate</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">status</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">success<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Desktop Actions\n</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pyautogui</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">click</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">x</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>8102</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">y</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>9463</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pyautogui</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">doubleClick</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">x</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>8102</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">y</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>9463</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pyautogui</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">hotkey</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">keys</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">ctrl<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">c<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pyautogui</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">scroll</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">page</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>1</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pyautogui</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">write</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">message</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">bread buns<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pyautogui</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">dragTo</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">from_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>87</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>423</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">to_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>8102</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>9463</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>After (Unified Action Dataset Formats):</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Unified Mobile Actions\n</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">navigate_home</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">open_app</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">app_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">drupe<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">swipe</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">from_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>581</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>898</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">to_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>601</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>518</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">long_press</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">x</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>799</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">y</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>911</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">final_answer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">success<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Unified Desktop Actions\n</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">click</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">x</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>8102</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">y</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>9463</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">double_click</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">x</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>8102</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">y</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>9463</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">press</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">keys</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">ctrl<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">c<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">scroll</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">direction</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">up<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">amount</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">10</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Smart direction detection\n</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">type</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">text</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">bread buns<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">drag</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">from_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>87</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>423</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">to_coord</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>8102</span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>9463</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>This unification process was essential for creating coherent training data that allows the model to learn consistent action patterns across diverse GUI environments.</p>\n<p><strong>💡 Why Normalized Coordinates?</strong><br />\nUsing raw pixel coordinates in text-action datapoint (e.g. <code>click(x=302, y=63)</code>) ties them to a single image size. Vision Language Models (VLMs) often resize images, causing pixel coordinates to break and require adjustment. Normalized coordinates (relative to image size) remain valid at any resolution and keep the dataset consistent.</p>\n<h3>(Bonus) Custom Action Space Adaptation with Action Space Converter</h3>\n<p>To maximize flexibility for different use cases, we developed the <strong>Action Space Converter</strong> (<code>utils/action_space_converter.py</code>), a tool that allows users to easily adapt from an action space to their own custom action vocabularies and naming conventions.</p>\n<p>You can use this tool to transform one action signature (function names, parameter names, and parameter value changes, ...) into another:</p>\n<p><strong>Before</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">assistant_message</span></span><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-variable syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Action: click(x=0.5, y=0.3)<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n</span></span></code></pre>\n<p><strong>After</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">assistant_message</span></span><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-variable syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Action: touch(x_coord=200, y_coord=300)<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n</span></span></code></pre>\n<h3>Key Features</h3>\n<p>The Action Space Converter provides:</p>\n<ol>\n<li><strong>Configurable Mappings</strong>: Define custom mappings between unified actions and your preferred action names</li>\n<li><strong>Parameter Transformation</strong>: Rename parameters, apply value transformations, and set default values</li>\n<li><strong>Flexible Architecture</strong>: Support for both simple parameter mappings and complex custom transformation functions</li>\n<li><strong>Validation</strong>: Built-in validation to ensure mapping configurations are valid</li>\n</ol>\n<h3>Usage Example</h3>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">utils</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-import-name syntax-python\">action_space_converter</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">ActionSpaceConverter</span><span class=\"syntax-punctuation syntax-separator syntax-import-list syntax-python\">,</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">ActionMapping</span><span class=\"syntax-punctuation syntax-separator syntax-import-list syntax-python\">,</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">ParameterMapping</span></span>\n<span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">utils</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-import-name syntax-python\">function_parser</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">parse_function_call</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Create custom mappings\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mappings</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ActionMapping</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n        <span class=\"syntax-variable syntax-parameter syntax-python\">source_function</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">click<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">target_function</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">touch<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">parameter_mappings</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n            <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ParameterMapping</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">source_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">x<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">target_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">x_coord<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n            <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ParameterMapping</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">source_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">y<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">target_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">y_coord<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">description</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Touch screen at coordinates<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>    </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ActionMapping</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n        <span class=\"syntax-variable syntax-parameter syntax-python\">source_function</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">type<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> source_function is the name of the function in the original function call\n</span>        <span class=\"syntax-variable syntax-parameter syntax-python\">target_function</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">write<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> target_function is the name of the function in the target function call        \n</span>        <span class=\"syntax-variable syntax-parameter syntax-python\">parameter_mappings</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n            <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ParameterMapping</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">source_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">text<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">target_name</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">content<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n            <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> source_name is the name of the parameter in the original function call            \n</span>            <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> target_name is the name of the parameter in the target function call        \n</span>        <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">description</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Input text<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>    \n    </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">assistant_message</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">I&#39;ll interact at those coordinates for you. click(x=0.5, y=0.3) Now I&#39;ll input the text. type(text=&#39;hello world&#39;)<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Parse function calls\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">parsed_function_calls</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">parse_function_call</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Initialize converter\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">converter</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ActionSpaceConverter</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mappings</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Convert actions\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">converted_actions</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">converter</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">convert_actions</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">parsed_function_calls</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-statement syntax-for syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-python\">for</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">new_function_call</span><span class=\"syntax-punctuation syntax-separator syntax-target-list syntax-python\">,</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">old_function_call</span> <span class=\"syntax-meta syntax-statement syntax-for syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-in syntax-python\">in</span></span></span><span class=\"syntax-meta syntax-statement syntax-for syntax-python\"> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">zip</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">converted_actions</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">parsed_function_calls</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-for syntax-python\">:</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">replace</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">old_function_call</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to_string</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">new_function_call</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to_string</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">print</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Output: I&#39;ll interact at those coordinates for you. touch(x_coord=0.5, y_coord=0.3) Now I&#39;ll input the text. write(content=&#39;hello world&#39;)\n</span></span></span></code></pre>\n<p>This tool enables researchers and practitioners to:</p>\n<ul>\n<li><strong>Customize Training Data</strong>: Adapt the dataset to match their specific action vocabulary requirements</li>\n<li><strong>Domain Adaptation</strong>: Transform actions for different platforms (mobile vs. desktop vs. web)</li>\n<li><strong>Framework Integration</strong>: Easily align training data with existing automation frameworks</li>\n<li><strong>Rapid Experimentation</strong>: Quickly test different action space configurations</li>\n<li><strong>Release Preparation</strong>: Standardize action spaces for production deployment with consistent naming conventions</li>\n</ul>\n<p>The Action Space Converter is particularly valuable for preparing datasets for training, as it ensures consistent action vocabularies across different deployment environments while maintaining compatibility with existing automation frameworks.</p>\n<h3>Transformed and Released Datasets</h3>\n<p>Through this pipeline, we transform the open-source datasets <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/xlangai/aguvis-stage1\">xlangai/aguvis-stage1</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/xlangai/aguvis-stage2\">xlangai/aguvis-stage2</a> into our unified action space (see <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.notion.so/Smol2Operator-Post-Training-GUI-Agents-for-Computer-Use-Draft-Blog-Post-2701384ebcac8035bbaad69b5b32ed99?pvs=21\">here</a>). The output of this process is released as two new fully formatted datasets: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-1\">smolagents/aguvis-stage-1</a> and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-2\">smolagents/aguvis-stage-2</a>.</p>\n<h2>2. Phase 1: From Zero to Perception</h2>\n<h3>Training Data</h3>\n<p>Phase 1 leverages the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-1\">smolagents/aguvis-stage-1</a> dataset, which introduces <strong>GUI grounding</strong> by pairing low-level instructions with diverse executable actions (expressed in code form). For example, a user/assistant turn in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-1\">smolagents/aguvis-stage-1</a> follows the structure:</p>\n<pre><code class=\"language-json\"><span class=\"code-snippet\" data-language=\"JSON\"><span class=\"syntax-source syntax-json\"><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-begin syntax-json\">{</span>\n  <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>user<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>click on more button<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n  <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>assistant<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>click(x=0.8875, y=0.2281)<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n<span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-end syntax-json\">}</span></span>\n</span></span></code></pre>\n<p>Each sample links a screenshot with multi-turn user/assistant interactions, enabling the model to learn fine-grained action grounding across dialogue turns. During fine-tuning, the data collator masks everything except the assistant’s answers when computing the loss.</p>\n<h3>Optimization Experiments</h3>\n<p>Before proceeding with full-scale Phase 1 training, we conducted comprehensive ablation studies to determine optimal training configurations</p>\n<h3>Image Resolution and Coordinate System Analysis</h3>\n<p>We experimented with different image sizes and coordinate representation systems to identify the optimal configuration for SmolVLM2:</p>\n<ul>\n<li><strong>Image Sizes Tested</strong>: 384px, 768px, 1152px</li>\n<li><strong>Coordinate Systems</strong>: Pixel coordinates vs. normalized coordinates (0-1 range)</li>\n<li><strong>Training Data</strong>: 400K samples from Aguvis datasets</li>\n</ul>\n<blockquote>\n<p>Some SOTA GUI VLMs (e.g., Qwen-VL) appear also to use a different normalized range (0–1000), which was not tested in this experiment.</p>\n</blockquote>\n<table>\n<thead>\n<tr>\n<th>Configuration (coords / image size)</th>\n<th>Screenspot-v2 (%)</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><em>Normalized coordinates</em></td>\n<td></td>\n</tr>\n<tr>\n<td>Base / –</td>\n<td>0.47</td>\n</tr>\n<tr>\n<td>384</td>\n<td>31.28</td>\n</tr>\n<tr>\n<td>764</td>\n<td>32.32</td>\n</tr>\n<tr>\n<td>1152</td>\n<td><strong>33.72</strong></td>\n</tr>\n<tr>\n<td><em>Pixel coordinates</em></td>\n<td></td>\n</tr>\n<tr>\n<td>Base / –</td>\n<td>0.55</td>\n</tr>\n<tr>\n<td>384</td>\n<td>1.17</td>\n</tr>\n<tr>\n<td>764</td>\n<td>2.67</td>\n</tr>\n<tr>\n<td>1152</td>\n<td>4.32</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Table 1:</strong> <em>Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct (400k samples, aguvis-stage-1). Higher is better.</em></p>\n<p><em>As demonstrated in our benchmark results, SmolVLM2-2.2B-Instruct base initially achieved 0% performance on perception benchmarks like ScreenSpot-v2. This complete lack of grounding capability provided us with a clean slate to evaluate the effectiveness of our training methodology.</em></p>\n<h3>Key Findings</h3>\n<p>From our experiments, we determined that:</p>\n<ul>\n<li><strong>Image Size</strong>: 1152px</li>\n<li><strong>Coordinate System</strong>: Normalized coordinates (0-1 range) proved most effective for SmolVLM2</li>\n<li>Note: The optimal choice between pixel and normalized coordinates may vary depending on the base model’s pre-training approach</li>\n</ul>\n<h3>Phase 1 Results</h3>\n<p>Using the optimal configuration (1152px resolution with normalized coordinates), we trained for 2 epochs on the smolagents/aguvis-stage-1 dataset. The results were remarkable, <strong>+41% improvement over baseline on ScreenSpot-v2</strong></p>\n<p>This dramatic improvement demonstrates that our Phase 1 training successfully instilled fundamental grounding capabilities in the model, enabling it to understand and locate visual elements within screenshots.</p>\n<table>\n<thead>\n<tr>\n<th>Configuration (coords / image size)</th>\n<th>Screenspot-v2 (%)</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Normalized coordinates / 1152</td>\n<td>41.27</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Table 2:</strong> <em>Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct (2 epochs, aguvis-stage-1).</em></p>\n<h2>3. Phase 2: From Perception to Cognition</h2>\n<p>Whereas Phase 1 provided grounding capabilities, Phase 2 targets <strong>agentic reasoning,</strong> the ability to deliberate and plan before acting. This stage transforms the model from a reactive system identifying GUI elements into a proactive agent capable of executing complex, multi-step interactions.</p>\n<h3>Training Data</h3>\n<p>Phase 2 uses the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-2\">smolagents/aguvis-stage-2</a> dataset, which introduces agentic scenarios:</p>\n<ul>\n<li>\n<p><strong>Explicit reasoning</strong> about upcoming actions</p>\n</li>\n<li>\n<p><strong>Context consistency</strong> across multiple interaction steps</p>\n</li>\n<li>\n<p><strong>High-level instructions</strong> require multi-step, low-level actions.</p>\n</li>\n</ul>\n<p>For example, the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-2\">smolagents/aguvis-stage-2</a> chat message is like this:</p>\n<pre><code class=\"language-json\"><span class=\"code-snippet\" data-language=\"JSON\"><span class=\"syntax-source syntax-json\"><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-begin syntax-json\">{</span>\n  <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>system<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>You are a helpful GUI agent. ...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n  <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>user<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>Please generate the next move according to the UI screenshot, instruction and previous actions.<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span><span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>Instruction: What information does the site provide about Judith Lauand&#39;s career, works and exhibitions?<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span><span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>Previous actions:<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>None<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n  <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>assistant<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>&lt;think&gt;<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>Click on the link labeled &#39;Judith Lauand: Brazilian 1922-2022&#39; to explore more about her career and exhibitions.<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>&lt;/think&gt;<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>&lt;code&gt;<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>click(x=0.41, y=0.178)<span class=\"syntax-constant syntax-character syntax-escape syntax-json\">\\n</span>&lt;/code&gt;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n<span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-end syntax-json\">}</span></span>\n</span></span></code></pre>\n<p>Each sample links a screenshot with a system/user/assistant turn. During fine-tuning, the data collator masks everything except the assistant’s answers when computing the loss.</p>\n<h3>Phase 2 Results</h3>\n<p>Starting from the Phase 1 checkpoint (1152 px resolution, normalized coordinates), we fine-tuned the model for two epochs on <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-2\">smolagents/aguvis-stage-2</a>. The accuracy on <strong>ScreenSpot-v2 increased from 41% to 61%</strong>, indicating that explicit reasoning improves GUI grounding performance.</p>\n<table>\n<thead>\n<tr>\n<th>Configuration (coords / image size)</th>\n<th>Screenspot-v2 (%)</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Normalized coordinates / 1152</td>\n<td>61.71</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Table 2:</strong> <em>Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct after Phase 1 finetuning (2 epochs, aguvis-stage-1).</em></p>\n<p>💡 <em>We also reproduced the two-phase training on a much smaller VLM (nanoVLM-460M). Despite its reduced capacity, the model achieved <strong>~58% on ScreenSpot-v2</strong>, demonstrating that the training strategy scales down effectively, <strong>making it SOTA on ScreenSpot-v2 for this model size (460M parameters)</strong>. In addition, aguvis-stage-1 is already included in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/HuggingFaceM4/FineVision\">FineVision Dataset</a>!</em></p>\n<h2>4. All you need is Open Source</h2>\n<p>All training code, data processing pipelines, datasets and model are open-source!</p>\n<ol>\n<li><strong>Training Recipe</strong> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/smol2operator/blob/main/recipe.ipynb\"><code>recipe.ipynb</code></a>): Complete training pipeline for both Phase 1 and Phase 2, including dataset mixture configurations and training orchestration. We leverage the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/docs/trl/en/index\">TRL</a> library to train our models.</li>\n<li><strong>Datasets</strong> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-1\"><code>smolagents/aguvis-stage-1</code></a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/smolagents/aguvis-stage-2\"><code>smolagents/aguvis-stage-2</code></a>): all datasets used are open-source.</li>\n<li><strong>Model</strong> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/smolagents/SmolVLM2-2.2B-Instruct-Agentic-GUI\"><code>smolagents/SmolVLM2-2.2B-Instruct-Agentic-GUI</code></a>): the model produced by applying the training recipe described above.</li>\n<li><strong>Preprocessing Tools:</strong>\n<ul>\n<li><strong>Function Parser</strong> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/smol2operator/blob/main/utils/function_parser.py\"><code>utils/function_parser.py</code></a>): Utilities for parsing, normalizing, and reconstructing function calls from diverse dataset formats. Supports complex parameter structures, positional arguments, and multiple function call extraction.</li>\n<li><strong>Action Conversion System</strong> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/smol2operator/blob/main/preprocessing/action_conversion.py\"><code>preprocessing/action_conversion.py</code></a>): Core unification engine transforming mobile and PyAutoGUI desktop actions into a standardized API format. Features smart coordinate handling, direction detection for scroll actions, and comprehensive parameter normalization.</li>\n<li><strong>Action Space Converter</strong> (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/smol2operator/blob/main/utils/action_space_converter.py\"><code>utils/action_space_converter.py</code></a>): Flexible tool for adapting the unified action space to custom vocabularies and naming conventions. Enables domain-specific customization through configurable parameter mappings.</li>\n</ul>\n</li>\n</ol>\n<p>💡 We’ve also released a Space to try the model’s agentic grounding capabilities: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/spaces/A-Mahla/Smol2Operator\">A-Mahla/Smol2Operator</a></p>\n<h2>5. Conclusion</h2>\n<p>Our experiments demonstrate that high-quality, reasoning-oriented data can substantially improve GUI grounding, even for small VLMs, using only supervised fine-tuning (SFT). Beyond raw performance gains, these results show that the GUI grounding capabilities are largely determined by the quality of the data. Carefully curated datasets teach models the structure and semantics of user interfaces, providing the grounding needed for accurate action prediction.</p>\n<p>To support the development of GUI agents, we’re open-sourcing everything: our complete pipeline, datasets, and trained model. You can reproduce our results, experiment with different models and architectures, or adapt our approach to new domains. The future of agentic AI depends on researchers like you pushing these boundaries further!</p>\n<h2>What's Next?</h2>\n<p>While SFT excels at supervised tasks, emerging methods such as Reinforcement Learning (RL) or Direct Preference Optimization (DPO) help develop stronger reasoning capabilities and enable real-time adaptation. These advances point toward a new generation of GUI agents that learn and improve through interaction rather than relying solely on static datasets.</p>\n<p>Let’s build the future of GUI agents together 🤗</p>\n",
  "content_markdown": "**TL;DR:** This work shows how a lightweight vision–language model can acquire GUI-grounded skills and evolve into an agentic GUI coder. We release all training recipes, data-processing tools, resulting model, demo and datasets to enable full reproducibility and foster further research 🫡. Find the collection [here](https://huggingface.co/collections/smolagents/smol2operator-release-68d288e87d3fa8f551d2ce2e).\n\n* * *\n\nThis video demonstrates the model obtained through the recipe described below, executing a task end-to-end.\n\n* * *\n\n## Table of Contents\n\n- [Introduction](https://huggingface.co/blog/smol2operator#introduction)\n- [1\\. Data Transformation and Unified Action Space](https://huggingface.co/blog/smol2operator#1-data-transformation-and-unified-action-space)\n  - [The Challenge of Inconsistent Action Spaces](https://huggingface.co/blog/smol2operator#the-challenge-of-inconsistent-action-spaces)\n  - [Our Unified Approach](https://huggingface.co/blog/smol2operator#our-unified-approach)\n  - [Example Data Transformation](https://huggingface.co/blog/smol2operator#example-data-transformation)\n  - [Custom Action Space Adaptation with Action Space Converter](https://huggingface.co/blog/smol2operator#bonus-custom-action-space-adaptation-with-action-space-converter)\n  - [Key Features](https://huggingface.co/blog/smol2operator#key-features)\n  - [Usage Example](https://huggingface.co/blog/smol2operator#usage-example)\n  - [Transformed and Released Datasets](https://huggingface.co/blog/smol2operator#transformed-and-released-datasets)\n- [2\\. Phase 1: From Zero to Perception](https://huggingface.co/blog/smol2operator#2-phase-1-from-zero-to-perception)\n  - [Training Data](https://huggingface.co/blog/smol2operator#training-data)\n  - [Optimization Experiments](https://huggingface.co/blog/smol2operator#optimization-experiments)\n  - [Image Resolution and Coordinate System Analysis](https://huggingface.co/blog/smol2operator#image-resolution-and-coordinate-system-analysis)\n  - [Key Findings](https://huggingface.co/blog/smol2operator#key-findings)\n  - [Phase 1 Results](https://huggingface.co/blog/smol2operator#phase-1-results)\n- [3\\. Phase 2: From Perception to Cognition](https://huggingface.co/blog/smol2operator#3-phase-2-from-perception-to-cognition)\n  - [Training Data](https://huggingface.co/blog/smol2operator#training-data-1)\n  - [Phase 2 Results](https://huggingface.co/blog/smol2operator#phase-2-results)\n- [4\\. All you need is Open Source](https://huggingface.co/blog/smol2operator#4-all-you-need-is-open-source)\n- [5\\. Conclusion](https://huggingface.co/blog/smol2operator#5-conclusion)\n- [What's Next?](https://huggingface.co/blog/smol2operator#whats-next)\n\n## Introduction\n\nGraphical User Interface (GUI) automation is one of the most challenging frontiers in computer vision. Developing models that see and interact with user interfaces enables AI agents to navigate mobile, desktop, and web platforms. This will reshape the future of digital interaction.\n\nIn this blog post, we present a comprehensive approach to training vision-language models for GUI automation through a multi-phase training strategy. We demonstrate how to transform a model with zero grounding capabilities into an agentic coder capable of understanding and interacting with graphical interfaces.\n\nRather than aiming for a SOTA model, our goal is to demonstrate the entire process, from data processing to model training, and, in doing so, show how to unlock GUI-grounding capabilities in VLMs.\n\n[![GUI capabilities combine understanding of the interface and precise element localization. These abilities enable the model to translate high-level tasks into low-level GUI actions such as clicking, typing, …](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/google.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/google.png)\n\n*GUI capabilities combine understanding of the interface and precise element localization. These abilities enable the model to translate high-level tasks into low-level GUI actions such as clicking, typing, …*\n\nOur approach leverages [**SmolVLM2-2.2B-Instruct**](https://huggingface.co/HuggingFaceTB/SmolVLM2-2.2B-Instruct) as the baseline model, a small powerful vision-language model that initially has no grounding capabilities for GUI tasks. This makes it an ideal candidate to demonstrate the effectiveness of our training methodology. Through our two-phase training process, we first instill grounding capabilities in the model, then enhance it with agentic reasoning abilities using Supervised Fine-Tuning (SFT).\n\nWe evaluate our approach on an established perception benchmark: [**ScreenSpot-v2**](https://huggingface.co/datasets/HongxinLi/ScreenSpot_v2), which tests the model’s ability to understand and locate elements within screenshots. Our process is inspired by the [AGUVIS](https://huggingface.co/papers/2412.04454) paper, and we leverage their carefully curated datasets to build upon their foundational work.\n\n[![Evolution of ScreenSpot-v2 performance during the training phase of the base model SmolVLM2-2.2B-Instruct.](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/screenspot-v2.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smol2operator/screenspot-v2.png)\n\n*Evolution of ScreenSpot-v2 performance during the training phase of the base model **SmolVLM2-2.2B-Instruct**.*\n\n## 1. Data Transformation and Unified Action Space\n\n*This section explains how we **convert heterogeneous GUI actions format from multiple datasets into a single unified format**. By standardizing function names, signatures, and parameters, we create consistent, high-quality data that forms the foundation for effective model training.*\n\n### The Challenge of Inconsistent Action Spaces\n\nOne of the primary challenges when working with multiple GUI automation datasets is the lack of standardization in action representations. Different datasets use varying function signatures, parameter naming conventions, and action taxonomies, making it difficult to train a unified model across diverse data sources.\n\n### Our Unified Approach\n\nWe took the open-source datasets ([xlangai/aguvis-stage1](https://huggingface.co/datasets/xlangai/aguvis-stage1), [xlangai/aguvis-stage2](https://huggingface.co/datasets/xlangai/aguvis-stage2)), originally used by [AGUVIS](https://huggingface.co/papers/2412.04454), and implemented a comprehensive data transformation pipeline to create a unified action space. Our approach involved:\n\n1. **Function Parsing and Normalization**: We developed a function parser (see `utils/function_parser.py`) that can extract and parse function calls from various formats across all datasets. This parser supports any function signature format, handles complex parameter structures, and can reconstruct function calls with proper parameter ordering.\n2. **Action Space Unification**: We implemented a comprehensive action conversion system (see `preprocessing/action_conversion.py`) that transforms all original action representations into a standardized function naming and argument structure. This process highlighted the significant inconsistencies in function signatures across different datasets and allowed us to:\n   - Remove undesired or redundant actions\n   - Standardize parameter naming conventions\n   - Create a cohesive action vocabulary\n3. **(Bonus) Flexible Adaptation Framework**: Our transformation pipeline includes utilities that allow users to:\n   - Adapt the entire dataset to their own action space naming conventions using the `utils/action_space_converter.py` tool\n   - Extract and analyze the current action space structure\n\n### Example Data Transformation\n\nHere are real examples from our action conversion system (`preprocessing/action_conversion.py`) showing how we transform heterogeneous action representations into our unified format (grounding coordinates normalized to \\[0,1\\]):\n\n**Before (Original Action Dataset Formats):**\n\n```python\n# Mobile Actions\nmobile.home()\nmobile.open_app(app_name='drupe')\nmobile.swipe(from_coord=[0.581, 0.898], to_coord=[0.601, 0.518])\nmobile.long_press(x=0.799, y=0.911)\nmobile.terminate(status='success')\n# Desktop Actions\npyautogui.click(x=0.8102, y=0.9463)\npyautogui.doubleClick(x=0.8102, y=0.9463)\npyautogui.hotkey(keys=['ctrl', 'c'])\npyautogui.scroll(page=-0.1)\npyautogui.write(message='bread buns')\npyautogui.dragTo(from_coord=[0.87, 0.423], to_coord=[0.8102, 0.9463])\n```\n\n**After (Unified Action Dataset Formats):**\n\n```python\n# Unified Mobile Actions\nnavigate_home()\nopen_app(app_name='drupe')\nswipe(from_coord=[0.581, 0.898], to_coord=[0.601, 0.518])\nlong_press(x=0.799, y=0.911)\nfinal_answer('success')\n# Unified Desktop Actions\nclick(x=0.8102, y=0.9463)\ndouble_click(x=0.8102, y=0.9463)\npress(keys=['ctrl', 'c'])\nscroll(direction='up', amount=10)  # Smart direction detection\ntype(text='bread buns')\ndrag(from_coord=[0.87, 0.423], to_coord=[0.8102, 0.9463])\n```\n\nThis unification process was essential for creating coherent training data that allows the model to learn consistent action patterns across diverse GUI environments.\n\n**💡 Why Normalized Coordinates?** \\\n Using raw pixel coordinates in text-action datapoint (e.g. `click(x=302, y=63)`) ties them to a single image size. Vision Language Models (VLMs) often resize images, causing pixel coordinates to break and require adjustment. Normalized coordinates (relative to image size) remain valid at any resolution and keep the dataset consistent.\n\n### (Bonus) Custom Action Space Adaptation with Action Space Converter\n\nTo maximize flexibility for different use cases, we developed the **Action Space Converter** (`utils/action_space_converter.py`), a tool that allows users to easily adapt from an action space to their own custom action vocabularies and naming conventions.\n\nYou can use this tool to transform one action signature (function names, parameter names, and parameter value changes, ...) into another:\n\n**Before**\n\n```python\nassistant_message: \"Action: click(x=0.5, y=0.3)\"\n```\n\n**After**\n\n```python\nassistant_message: \"Action: touch(x_coord=200, y_coord=300)\"\n```\n\n### Key Features\n\nThe Action Space Converter provides:\n\n1. **Configurable Mappings**: Define custom mappings between unified actions and your preferred action names\n2. **Parameter Transformation**: Rename parameters, apply value transformations, and set default values\n3. **Flexible Architecture**: Support for both simple parameter mappings and complex custom transformation functions\n4. **Validation**: Built-in validation to ensure mapping configurations are valid\n\n### Usage Example\n\n```python\nfrom utils.action_space_converter import ActionSpaceConverter, ActionMapping, ParameterMapping\nfrom utils.function_parser import parse_function_call\n\n# Create custom mappings\nmappings = [\n    ActionMapping(\n        source_function=\"click\",\n        target_function=\"touch\",\n        parameter_mappings=[\n            ParameterMapping(source_name=\"x\", target_name=\"x_coord\"),\n            ParameterMapping(source_name=\"y\", target_name=\"y_coord\")\n        ],\n        description=\"Touch screen at coordinates\"    ),\n    ActionMapping(\n        source_function=\"type\", # source_function is the name of the function in the original function call\n        target_function=\"write\", # target_function is the name of the function in the target function call        \n        parameter_mappings=[\n            ParameterMapping(source_name=\"text\", target_name=\"content\")\n            # source_name is the name of the parameter in the original function call            \n            # target_name is the name of the parameter in the target function call        \n        ],\n        description=\"Input text\"    \n    )\n]\n\nassistant_message = \"I'll interact at those coordinates for you. click(x=0.5, y=0.3) Now I'll input the text. type(text='hello world')\"\n\n# Parse function calls\nparsed_function_calls = parse_function_call(text)\n\n# Initialize converter\nconverter = ActionSpaceConverter(mappings)\n\n# Convert actions\nconverted_actions = converter.convert_actions(parsed_function_calls)\nfor new_function_call, old_function_call in zip(converted_actions, parsed_function_calls):\n    text = text.replace(old_function_call.to_string(), new_function_call.to_string())\n\nprint(text)\n# Output: I'll interact at those coordinates for you. touch(x_coord=0.5, y_coord=0.3) Now I'll input the text. write(content='hello world')\n```\n\nThis tool enables researchers and practitioners to:\n\n- **Customize Training Data**: Adapt the dataset to match their specific action vocabulary requirements\n- **Domain Adaptation**: Transform actions for different platforms (mobile vs. desktop vs. web)\n- **Framework Integration**: Easily align training data with existing automation frameworks\n- **Rapid Experimentation**: Quickly test different action space configurations\n- **Release Preparation**: Standardize action spaces for production deployment with consistent naming conventions\n\nThe Action Space Converter is particularly valuable for preparing datasets for training, as it ensures consistent action vocabularies across different deployment environments while maintaining compatibility with existing automation frameworks.\n\n### Transformed and Released Datasets\n\nThrough this pipeline, we transform the open-source datasets [xlangai/aguvis-stage1](https://huggingface.co/datasets/xlangai/aguvis-stage1), [xlangai/aguvis-stage2](https://huggingface.co/datasets/xlangai/aguvis-stage2) into our unified action space (see [here](https://www.notion.so/Smol2Operator-Post-Training-GUI-Agents-for-Computer-Use-Draft-Blog-Post-2701384ebcac8035bbaad69b5b32ed99?pvs=21)). The output of this process is released as two new fully formatted datasets: [smolagents/aguvis-stage-1](https://huggingface.co/datasets/smolagents/aguvis-stage-1) and [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2).\n\n## 2. Phase 1: From Zero to Perception\n\n### Training Data\n\nPhase 1 leverages the [smolagents/aguvis-stage-1](https://huggingface.co/datasets/smolagents/aguvis-stage-1) dataset, which introduces **GUI grounding** by pairing low-level instructions with diverse executable actions (expressed in code form). For example, a user/assistant turn in [smolagents/aguvis-stage-1](https://huggingface.co/datasets/smolagents/aguvis-stage-1) follows the structure:\n\n```json\n{\n  \"user\": \"click on more button\",\n  \"assistant\": \"click(x=0.8875, y=0.2281)\",\n}\n```\n\nEach sample links a screenshot with multi-turn user/assistant interactions, enabling the model to learn fine-grained action grounding across dialogue turns. During fine-tuning, the data collator masks everything except the assistant’s answers when computing the loss.\n\n### Optimization Experiments\n\nBefore proceeding with full-scale Phase 1 training, we conducted comprehensive ablation studies to determine optimal training configurations\n\n### Image Resolution and Coordinate System Analysis\n\nWe experimented with different image sizes and coordinate representation systems to identify the optimal configuration for SmolVLM2:\n\n- **Image Sizes Tested**: 384px, 768px, 1152px\n- **Coordinate Systems**: Pixel coordinates vs. normalized coordinates (0-1 range)\n- **Training Data**: 400K samples from Aguvis datasets\n\n> Some SOTA GUI VLMs (e.g., Qwen-VL) appear also to use a different normalized range (0–1000), which was not tested in this experiment.\n\n| Configuration (coords / image size) | Screenspot-v2 (%) |\n| ----------------------------------- | ----------------- |\n| *Normalized coordinates*            |                   |\n| Base / –                            | 0.47              |\n| 384                                 | 31.28             |\n| 764                                 | 32.32             |\n| 1152                                | **33.72**         |\n| *Pixel coordinates*                 |                   |\n| Base / –                            | 0.55              |\n| 384                                 | 1.17              |\n| 764                                 | 2.67              |\n| 1152                                | 4.32              |\n\n**Table 1:** *Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct (400k samples, aguvis-stage-1). Higher is better.*\n\n*As demonstrated in our benchmark results, SmolVLM2-2.2B-Instruct base initially achieved 0% performance on perception benchmarks like ScreenSpot-v2. This complete lack of grounding capability provided us with a clean slate to evaluate the effectiveness of our training methodology.*\n\n### Key Findings\n\nFrom our experiments, we determined that:\n\n- **Image Size**: 1152px\n- **Coordinate System**: Normalized coordinates (0-1 range) proved most effective for SmolVLM2\n- Note: The optimal choice between pixel and normalized coordinates may vary depending on the base model’s pre-training approach\n\n### Phase 1 Results\n\nUsing the optimal configuration (1152px resolution with normalized coordinates), we trained for 2 epochs on the smolagents/aguvis-stage-1 dataset. The results were remarkable, **+41% improvement over baseline on ScreenSpot-v2**\n\nThis dramatic improvement demonstrates that our Phase 1 training successfully instilled fundamental grounding capabilities in the model, enabling it to understand and locate visual elements within screenshots.\n\n| Configuration (coords / image size) | Screenspot-v2 (%) |\n| ----------------------------------- | ----------------- |\n| Normalized coordinates / 1152       | 41.27             |\n\n**Table 2:** *Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct (2 epochs, aguvis-stage-1).*\n\n## 3. Phase 2: From Perception to Cognition\n\nWhereas Phase 1 provided grounding capabilities, Phase 2 targets **agentic reasoning,** the ability to deliberate and plan before acting. This stage transforms the model from a reactive system identifying GUI elements into a proactive agent capable of executing complex, multi-step interactions.\n\n### Training Data\n\nPhase 2 uses the [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2) dataset, which introduces agentic scenarios:\n\n- **Explicit reasoning** about upcoming actions\n\n- **Context consistency** across multiple interaction steps\n\n- **High-level instructions** require multi-step, low-level actions.\n\nFor example, the [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2) chat message is like this:\n\n```json\n{\n  \"system\": \"You are a helpful GUI agent. ...\",\n  \"user\": \"Please generate the next move according to the UI screenshot, instruction and previous actions.\\n\\nInstruction: What information does the site provide about Judith Lauand's career, works and exhibitions?\\n\\nPrevious actions:\\nNone\",\n  \"assistant\": \"<think>\\nClick on the link labeled 'Judith Lauand: Brazilian 1922-2022' to explore more about her career and exhibitions.\\n</think>\\n<code>\\nclick(x=0.41, y=0.178)\\n</code>\",\n}\n```\n\nEach sample links a screenshot with a system/user/assistant turn. During fine-tuning, the data collator masks everything except the assistant’s answers when computing the loss.\n\n### Phase 2 Results\n\nStarting from the Phase 1 checkpoint (1152 px resolution, normalized coordinates), we fine-tuned the model for two epochs on [smolagents/aguvis-stage-2](https://huggingface.co/datasets/smolagents/aguvis-stage-2). The accuracy on **ScreenSpot-v2 increased from 41% to 61%**, indicating that explicit reasoning improves GUI grounding performance.\n\n| Configuration (coords / image size) | Screenspot-v2 (%) |\n| ----------------------------------- | ----------------- |\n| Normalized coordinates / 1152       | 61.71             |\n\n**Table 2:** *Baseline on HuggingFaceTB/SmolVLM2-2.2B-Instruct after Phase 1 finetuning (2 epochs, aguvis-stage-1).*\n\n💡 *We also reproduced the two-phase training on a much smaller VLM (nanoVLM-460M). Despite its reduced capacity, the model achieved **\\~58% on ScreenSpot-v2**, demonstrating that the training strategy scales down effectively, **making it SOTA on ScreenSpot-v2 for this model size (460M parameters)**. In addition, aguvis-stage-1 is already included in [FineVision Dataset](https://huggingface.co/datasets/HuggingFaceM4/FineVision)!*\n\n## 4. All you need is Open Source\n\nAll training code, data processing pipelines, datasets and model are open-source!\n\n1. **Training Recipe** ([`recipe.ipynb`](https://github.com/huggingface/smol2operator/blob/main/recipe.ipynb)): Complete training pipeline for both Phase 1 and Phase 2, including dataset mixture configurations and training orchestration. We leverage the [TRL](https://huggingface.co/docs/trl/en/index) library to train our models.\n2. **Datasets** ([`smolagents/aguvis-stage-1`](https://huggingface.co/datasets/smolagents/aguvis-stage-1), [`smolagents/aguvis-stage-2`](https://huggingface.co/datasets/smolagents/aguvis-stage-2)): all datasets used are open-source.\n3. **Model** ([`smolagents/SmolVLM2-2.2B-Instruct-Agentic-GUI`](https://huggingface.co/smolagents/SmolVLM2-2.2B-Instruct-Agentic-GUI)): the model produced by applying the training recipe described above.\n4. **Preprocessing Tools:**\n   - **Function Parser** ([`utils/function_parser.py`](https://github.com/huggingface/smol2operator/blob/main/utils/function_parser.py)): Utilities for parsing, normalizing, and reconstructing function calls from diverse dataset formats. Supports complex parameter structures, positional arguments, and multiple function call extraction.\n   - **Action Conversion System** ([`preprocessing/action_conversion.py`](https://github.com/huggingface/smol2operator/blob/main/preprocessing/action_conversion.py)): Core unification engine transforming mobile and PyAutoGUI desktop actions into a standardized API format. Features smart coordinate handling, direction detection for scroll actions, and comprehensive parameter normalization.\n   - **Action Space Converter** ([`utils/action_space_converter.py`](https://github.com/huggingface/smol2operator/blob/main/utils/action_space_converter.py)): Flexible tool for adapting the unified action space to custom vocabularies and naming conventions. Enables domain-specific customization through configurable parameter mappings.\n\n💡 We’ve also released a Space to try the model’s agentic grounding capabilities: [A-Mahla/Smol2Operator](https://huggingface.co/spaces/A-Mahla/Smol2Operator)\n\n## 5. Conclusion\n\nOur experiments demonstrate that high-quality, reasoning-oriented data can substantially improve GUI grounding, even for small VLMs, using only supervised fine-tuning (SFT). Beyond raw performance gains, these results show that the GUI grounding capabilities are largely determined by the quality of the data. Carefully curated datasets teach models the structure and semantics of user interfaces, providing the grounding needed for accurate action prediction.\n\nTo support the development of GUI agents, we’re open-sourcing everything: our complete pipeline, datasets, and trained model. You can reproduce our results, experiment with different models and architectures, or adapt our approach to new domains. The future of agentic AI depends on researchers like you pushing these boundaries further!\n\n## What's Next?\n\nWhile SFT excels at supervised tasks, emerging methods such as Reinforcement Learning (RL) or Direct Preference Optimization (DPO) help develop stronger reasoning capabilities and enable real-time adaptation. These advances point toward a new generation of GUI agents that learn and improve through interaction rather than relying solely on static datasets.\n\nLet’s build the future of GUI agents together 🤗\n",
  "dateCreated": "2026-10-04T12:50:30.804479567+00:00",
  "date_created": "2025-09-23T00:00:00+00:00",
  "date_modified": "2025-09-23T00:00:00+00:00",
  "date_published": "2025-09-23T00:00:00+00:00",
  "description": "TL;DR: This work shows how a lightweight vision–language model can acquire GUI-grounded skills and evolve into an agentic GUI coder. We release all training recipes, data-processing tools, resulting model, demo and datasets to enable full…",
  "external_url": "https://huggingface.co/blog/smol2operator",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/huggingface-co/2025/09/2025-09-23-smol2operator-post-training-gui-agents-for-computer-use.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/huggingface-co/2025/09/2025-09-23-smol2operator-post-training-gui-agents-for-computer-use.md"
  },
  "id": "urn:aggr:item:0c229480e01259c2210ed1cc6575f5b23c770c5d",
  "isBasedOn": {
    "@id": "https://huggingface.co/blog/smol2operator"
  },
  "mainEntity": {
    "@id": "https://huggingface.co/blog/smol2operator",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2025-09-23-smol2operator-post-training-gui-agents-for-computer-use/#webpage"
    },
    "dateModified": "2025-09-23T00:00:00+00:00",
    "datePublished": "2025-09-23T00:00:00+00:00",
    "headline": "Smol2Operator: Post-Training GUI Agents for Computer Use",
    "timeRequired": "PT11M",
    "url": "https://huggingface.co/blog/smol2operator",
    "wordCount": 2451
  },
  "name": "Archived snapshot: Smol2Operator: Post-Training GUI Agents for Computer Use",
  "preview": null,
  "reading_minutes": 11,
  "replicated_at": null,
  "source": "huggingface-co",
  "source_name": "Hugging Face - Blog",
  "summary": null,
  "tags": [],
  "temporalCoverage": "2026-10-04T12:50:30.804479567+00:00",
  "title": "Smol2Operator: Post-Training GUI Agents for Computer Use",
  "url": "https://aggr.aymericbeaumet.com/items/huggingface-co/2025-09-23-smol2operator-post-training-gui-agents-for-computer-use/",
  "word_count": 2451
}