UI-TARS-desktop插件开发API:扩展功能的编程接口详解

UI-TARS-desktop插件开发API:扩展功能的编程接口详解

【免费下载链接】UI-TARS-desktop A GUI Agent application based on UI-TARS(Vision-Lanuage Model) that allows you to control your computer using natural language. 【免费下载链接】UI-TARS-desktop 项目地址: https://gitcode.com/GitHub_Trending/ui/UI-TARS-desktop

引言:释放UI-TARS-desktop的扩展能力

你是否在使用UI-TARS-desktop时遇到功能局限?是否需要定制化界面交互或集成专有系统?本文将系统解析UI-TARS-desktop插件开发API,帮助开发者构建强大的扩展功能。通过本文,你将掌握:

  • 核心API架构:理解GUIAgent、Operator和UITarsModel的协作机制
  • 插件开发全流程:从环境搭建到功能发布的完整步骤
  • 高级扩展技术:自定义操作器、模型集成和错误处理策略
  • 实战案例解析:通过NutJSOperator实现跨平台桌面控制

核心API架构解析

UI-TARS-desktop插件系统基于三层架构设计,通过松耦合的接口实现高度可扩展性。

类关系模型

mermaid

核心组件职责

组件职责关键方法
GUIAgent协调核心工作流run()pause()resume()stop()
Operator处理系统交互screenshot()execute()
UITarsModel管理模型交互invoke()reset()

工作流程时序

mermaid

开发环境搭建

环境准备清单

工具版本要求用途
Node.js≥16.0.0运行环境
npm/yarn≥8.0.0包管理
TypeScript≥5.0.0类型检查
@rslib/core≥0.5.4构建工具
vitest≥3.0.0单元测试

初始化项目

mkdir ui-tars-plugin && cd ui-tars-plugin
npm init -y

修改package.json配置:

{
  "name": "ui-tars-custom-operator",
  "version": "1.0.0",
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "scripts": {
    "dev": "rslib build --watch",
    "build": "rsbuild",
    "test": "vitest"
  },
  "peerDependencies": {
    "@ui-tars/sdk": "^1.2.0-beta.17"
  },
  "devDependencies": {
    "@ui-tars/sdk": "^1.2.0-beta.17",
    "@rslib/core": "^0.5.4",
    "typescript": "^5.7.2",
    "vitest": "^3.0.2"
  }
}

基础插件开发

创建自定义Operator

Operator是插件开发的核心,需要实现屏幕捕获和动作执行两大核心能力。

import { Operator, ScreenshotOutput, ExecuteParams, ExecuteOutput } from '@ui-tars/sdk';

export class CustomOperator implements Operator {
  // 定义动作空间描述
  static MANUAL = {
    ACTION_SPACES: [
      'click(start_box="") # 点击指定坐标区域',
      'type(content="") # 输入文本内容',
      'scroll(direction="") # 滚动页面',
      'finished() # 完成任务'
    ]
  };

  async screenshot(): Promise<ScreenshotOutput> {
    // 实现屏幕捕获逻辑
    return {
      base64: 'data:image/png;base64,...', // 实际项目中替换为真实截图
      scaleFactor: window.devicePixelRatio || 1
    };
  }

  async execute(params: ExecuteParams): Promise<ExecuteOutput> {
    const { parsedPrediction } = params;
    
    switch (parsedPrediction.action_type) {
      case 'click':
        return this.handleClick(parsedPrediction.action_inputs);
      case 'type':
        return this.handleType(parsedPrediction.action_inputs);
      case 'finished':
        return { status: 'END' };
      default:
        throw new Error(`不支持的动作类型: ${parsedPrediction.action_type}`);
    }
  }

  private handleClick(inputs: Record<string, any>): ExecuteOutput {
    // 实现点击逻辑
    const { start_box } = inputs;
    const [x, y] = start_box.match(/\d+/g)?.map(Number) || [0, 0];
    
    // 实际点击操作实现...
    
    return { status: 'SUCCESS' };
  }

  private handleType(inputs: Record<string, any>): ExecuteOutput {
    // 实现文本输入逻辑
    const { content } = inputs;
    
    // 实际输入操作实现...
    
    return { status: 'SUCCESS' };
  }
}

集成自定义Operator到GUIAgent

import { GUIAgent } from '@ui-tars/sdk';
import { CustomOperator } from './CustomOperator';

// 配置模型参数
const modelConfig = {
  baseURL: 'https://your-model-endpoint.com',
  apiKey: 'your-api-key',
  model: 'ui-tars-13b'
};

// 创建GUIAgent实例
const agent = new GUIAgent({
  model: modelConfig,
  operator: new CustomOperator(),
  systemPrompt: `
    你是一个UI自动化助手,能够通过以下动作控制界面:
    ${CustomOperator.MANUAL.ACTION_SPACES.join('\n')}
  `,
  onData: ({ data }) => {
    console.log('Agent状态更新:', data.status);
  },
  onError: ({ error }) => {
    console.error('Agent错误:', error);
  },
  maxLoopCount: 30 // 最大循环次数限制
});

// 启动Agent
agent.run('打开浏览器并访问https://example.com');

// 5秒后暂停Agent
setTimeout(() => {
  agent.pause();
  console.log('Agent已暂停');
  
  // 3秒后恢复Agent
  setTimeout(() => {
    agent.resume();
    console.log('Agent已恢复');
  }, 3000);
}, 5000);

高级功能开发

自定义模型集成

通过扩展UITarsModel类实现自定义模型集成:

import { UITarsModel, InvokeParams } from '@ui-tars/sdk';

class CustomVisionModel extends UITarsModel {
  constructor(private config: { apiKey: string }) {
    super(config);
  }

  async invoke(params: InvokeParams): Promise<any> {
    // 实现自定义模型调用逻辑
    const response = await fetch('https://your-custom-model.com/v1/invoke', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.config.apiKey}`
      },
      body: JSON.stringify({
        prompt: params.prompt,
        images: params.images,
        screenContext: params.screenContext
      })
    });

    const result = await response.json();
    
    // 转换结果为UI-TARS期望的格式
    return {
      prediction: result.action,
      parsedPredictions: [{
        action_type: result.actionType,
        action_inputs: result.actionParams,
        thought: result.thoughtProcess,
        reflection: result.reflection
      }]
    };
  }
}

// 使用自定义模型
const customModel = new CustomVisionModel({
  apiKey: 'your-custom-model-api-key'
});

const agent = new GUIAgent({
  model: customModel,
  operator: new CustomOperator(),
  // ...其他配置
});

错误处理与重试机制

UI-TARS SDK内置多层次错误处理机制,可通过配置实现健壮的插件:

const agent = new GUIAgent({
  // ...其他配置
  retry: {
    screenshot: {
      maxRetries: 3,
      onRetry: (error, attempt) => {
        console.log(`截图重试 ${attempt}/3: ${error.message}`);
      }
    },
    execute: {
      maxRetries: 2,
      minTimeout: 2000
    }
  },
  onError: ({ data, error }) => {
    switch (error.type) {
      case 'SCREENSHOT_RETRY_ERROR':
        console.error('截图失败超过最大重试次数');
        // 实现恢复策略...
        break;
      case 'EXECUTE_RETRY_ERROR':
        console.error('执行动作失败超过最大重试次数');
        // 实现恢复策略...
        break;
      default:
        console.error(`Agent错误: ${error.message}`);
    }
  }
});

状态管理与生命周期控制

GUIAgent提供完整的生命周期管理接口:

// 状态流转图
![mermaid](https://web-api.gitcode.com/mermaid/svg/eNorLkksSXXJTEwvSszVLTPiUgCCaK1YBV1dOwVPP88QsACIARYJCvXz8_Rzt1IoKs3T0ATLQYXA0gGOocGuLlYKBYmlxalQeYgYmu7U4tLcVCwGBIf4BwSATCguyS_AIu8aFOQfZKXwcsrMF-vXP-2f-HzKfLAasDhYBdDtYBGoSShiyCYBxawUnuze_bRr4dN1Pc86JgAAk8VL1g)

```typescript
// 完整的生命周期控制示例
const abortController = new AbortController();

const agent = new GUIAgent({
  // ...其他配置
  signal: abortController.signal,
  onData: ({ data }) => {
    console.log('当前状态:', data.status);
    
    // 监听状态变化
    if (data.status === 'MAX_LOOP') {
      console.log('达到最大循环次数');
      agent.stop();
    }
  }
});

// 启动任务
agent.run('复杂的自动化任务...');

// 监听用户输入终止任务
process.on('SIGINT', () => {
  abortController.abort();
  // 或者调用agent.stop()
  agent.stop();
});

实战案例:跨平台自动化操作器

NutJSOperator实现分析

NutJSOperator是UI-TARS-desktop提供的默认操作器,基于nut.js实现跨平台桌面控制:

import { Operator } from '@ui-tars/sdk';
import { mouse, keyboard, screen, Point } from '@nut-tree/nut-js';

export class NutJSOperator implements Operator {
  static MANUAL = {
    ACTION_SPACES: [
      'click(start_box="(x,y)") # 点击坐标(x,y)',
      'double_click(start_box="(x,y)") # 双击坐标(x,y)',
      'right_click(start_box="(x,y)") # 右键点击坐标(x,y)',
      'type(content="text") # 输入文本',
      'hotkey(keys="ctrl+c") # 按下热键组合',
      'scroll(direction="up|down", amount=10) # 滚动页面'
    ]
  };

  async screenshot(): Promise<ScreenshotOutput> {
    // 获取主屏幕
    const mainScreen = await screen.grab();
    const imageBuffer = await mainScreen.toBuffer();
    
    return {
      base64: `data:image/png;base64,${imageBuffer.toString('base64')}`,
      scaleFactor: screen.scaleFactor
    };
  }

  async execute(params: ExecuteParams): Promise<ExecuteOutput> {
    const { parsedPrediction, screenWidth, screenHeight, scaleFactor } = params;
    
    // 坐标转换:模型输出坐标 -> 实际屏幕坐标
    const convertCoordinates = (box: string): Point => {
      const [x, y] = box.match(/\d+/g)?.map(Number) || [0, 0];
      return new Point(x / scaleFactor, y / scaleFactor);
    };

    switch (parsedPrediction.action_type) {
      case 'click':
        const clickPoint = convertCoordinates(parsedPrediction.action_inputs.start_box);
        await mouse.move(clickPoint);
        await mouse.click();
        return { status: 'SUCCESS' };
        
      case 'type':
        await keyboard.type(parsedPrediction.action_inputs.content);
        return { status: 'SUCCESS' };
        
      case 'hotkey':
        const keys = parsedPrediction.action_inputs.keys.split('+');
        await keyboard.pressKey(...keys);
        await keyboard.releaseKey(...keys);
        return { status: 'SUCCESS' };
        
      // 其他动作实现...
      
      default:
        return { status: 'UNKNOWN_ACTION' };
    }
  }
}

自定义操作器开发指南

开发自定义操作器需遵循以下最佳实践:

  1. 接口兼容性

    • 严格实现Operator接口的screenshot()execute()方法
    • 确保返回类型符合ScreenshotOutputExecuteOutput定义
  2. 错误处理

    • 实现动作执行的重试机制
    • 提供详细的错误信息以便调试
  3. 性能优化

    • 截图操作使用高效编码
    • 坐标转换考虑多屏幕和DPI适配
  4. 安全性

    • 验证所有输入参数
    • 实现操作沙箱限制危险动作

插件测试与调试

单元测试策略

import { describe, it, expect, vi } from 'vitest';
import { CustomOperator } from './CustomOperator';

describe('CustomOperator', () => {
  const operator = new CustomOperator();
  
  it('should generate correct action spaces', () => {
    expect(CustomOperator.MANUAL.ACTION_SPACES).toContain(
      'click(start_box="") # 点击指定坐标区域'
    );
  });
  
  it('should handle click action', async () => {
    // Mock实现
    operator['handleClick'] = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
    
    const result = await operator.execute({
      parsedPrediction: {
        action_type: 'click',
        action_inputs: { start_box: '(100,200)' },
        thought: '',
        reflection: null
      },
      // 其他必要参数...
    });
    
    expect(result.status).toBe('SUCCESS');
    expect(operator['handleClick']).toHaveBeenCalled();
  });
});

集成测试与调试

// agent.test.ts
import { describe, it, expect, vi } from 'vitest';
import { GUIAgent } from '@ui-tars/sdk';
import { CustomOperator } from './CustomOperator';

describe('GUIAgent with CustomOperator', () => {
  it('should complete task successfully', async () => {
    const mockOperator = new CustomOperator();
    mockOperator.screenshot = vi.fn().mockResolvedValue({
      base64: 'data:image/png;base64,mock',
      scaleFactor: 1
    });
    
    mockOperator.execute = vi.fn().mockResolvedValue({
      status: 'END' // 模拟任务完成
    });
    
    const onData = vi.fn();
    
    const agent = new GUIAgent({
      model: {
        baseURL: 'https://mock-model.com',
        apiKey: 'test-key',
        model: 'test-model'
      },
      operator: mockOperator,
      onData
    });
    
    // Mock模型调用
    agent['model'].invoke = vi.fn().mockResolvedValue({
      prediction: 'finished()',
      parsedPredictions: [{
        action_type: 'finished',
        action_inputs: {},
        thought: '',
        reflection: null
      }]
    });
    
    await agent.run('测试任务');
    
    expect(onData).toHaveBeenCalledWith(
      expect.objectContaining({
        data: expect.objectContaining({
          status: 'END'
        })
      })
    );
  });
});

发布与分发

插件打包规范

{
  "name": "@your-org/ui-tars-custom-operator",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": ["dist", "README.md"],
  "keywords": ["ui-tars", "plugin", "operator"],
  "peerDependencies": {
    "@ui-tars/sdk": "^1.2.0-beta.17"
  },
  "publishConfig": {
    "access": "public"
  }
}

发布流程

  1. 构建项目

    npm run build
    
  2. 版本管理

    npm version patch  # 或 minor/major
    
  3. 发布到npm

    npm publish
    

总结与展望

UI-TARS-desktop插件开发API为扩展应用功能提供了强大而灵活的框架。通过本文介绍的API架构、开发流程和实战案例,开发者可以构建各种自定义扩展,满足特定业务需求。

未来,UI-TARS-desktop插件系统将支持更多功能:

  • 更丰富的生命周期钩子:提供更多扩展点
  • 插件市场:简化插件发现和安装
  • 可视化开发工具:降低插件开发门槛
  • 高级权限控制:细粒度的操作权限管理

立即开始探索UI-TARS-desktop插件开发,释放自动化控制的无限可能!

附录:API参考速查表

GUIAgent配置选项

参数类型描述默认值
modelModelConfig \| UITarsModel模型配置或实例必需
operatorOperator操作器实例必需
systemPromptstring系统提示词默认模板
maxLoopCountnumber最大循环次数25
signalAbortSignal终止信号-
loggerLogger日志记录器console
onData(data) => void数据回调-
onError(error) => void错误回调-

Operator接口定义

interface Operator {
  screenshot(): Promise<ScreenshotOutput>;
  execute(params: ExecuteParams): Promise<ExecuteOutput>;
}

interface ScreenshotOutput {
  base64: string;
  scaleFactor: number;
}

interface ExecuteParams {
  prediction: string;
  parsedPrediction: {
    action_type: string;
    action_inputs: Record<string, any>;
    thought: string;
    reflection: string | null;
  };
  screenWidth: number;
  screenHeight: number;
  scaleFactor: number;
  factors: [number, number];
}

错误类型参考

错误类型描述处理策略
SCREENSHOT_RETRY_ERROR截图失败检查系统权限
EXECUTE_RETRY_ERROR动作执行失败验证动作参数
MODEL_SERVICE_ERROR模型服务错误检查网络连接
REACH_MAXLOOP_ERROR达到最大循环优化任务步骤

点赞+收藏+关注,获取UI-TARS-desktop插件开发最新动态!下一期将带来《插件安全最佳实践》,敬请期待。

【免费下载链接】UI-TARS-desktop A GUI Agent application based on UI-TARS(Vision-Lanuage Model) that allows you to control your computer using natural language. 【免费下载链接】UI-TARS-desktop 项目地址: https://gitcode.com/GitHub_Trending/ui/UI-TARS-desktop

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值