qwen-code/scripts/sync-computer-use-schemas.ts
顾盼 bb1e71911c
feat(computer-use): configurable screenshot max dimension (setting + env) (#5122)
* feat(computer-use): configurable screenshot max dimension (setting + env)

Add a user-level knob for cua-driver's screenshot longest-edge cap. The
old open-computer-use backend exposed this via OPEN_COMPUTER_USE_IMAGE_*
env vars; the cua-driver migration dropped them, leaving only the
model-driven set_config tool. This restores deterministic user control.

- Setting tools.computerUse.maxImageDimension (number; default -1 = keep
  cua-driver's built-in default of 1568; 0 disables resizing / full
  resolution; a positive value caps the longest edge).
- Env override QWEN_COMPUTER_USE_MAX_IMAGE_DIMENSION (takes precedence
  over the setting; invalid/negative values fall through).
- Resolution lives in resolveMaxImageDimension(); applied via the
  cua-driver set_config tool once per (re)connect in
  ComputerUseClient.doStart — best-effort, never aborts startup, and
  re-applied after a daemon-restart reconnect.
- Docs: document tools.computerUse.{enabled,maxImageDimension} in
  settings.md (the block was previously undocumented). Refresh stale
  ocu/npx comments left in client.ts + install-state.ts by the migration.

Precedence: env var > setting > cua-driver default.

* chore(computer-use): finish ocu→cua-driver cleanup in schema-sync script

The cua-driver migration (#5051) left scripts/sync-computer-use-schemas.ts
pointing at the old open-computer-use backend: it npx'd
@qwen-code/open-computer-use, hard-coded the 9-tool ocu surface, and emitted an
"open-computer-use" header. Re-running it — which constants.ts' version-bump
procedure tells maintainers to do — would have clobbered the migrated 35-tool
cua-driver schemas.ts.

- Drive the locally-pinned `cua-driver mcp` binary (binaryPath /
  CUA_DRIVER_VERSION from constants.ts) instead of npx'ing ocu; expect 35
  tools and warn (don't fail) on drift.
- Emit the cua-driver-flavored schemas.ts header.
- Refresh install-state.test.ts fixtures from ocu package specs to the
  cua-driver-rs approval-key form the field actually stores now.

Verified the fixed script reproduces the committed 35-tool surface exactly
(modulo prettier formatting). No dead env-var handling remained — the module
reads only QWEN_COMPUTER_USE_{AUTO_APPROVE,DOWNLOAD_HOST,MAX_IMAGE_DIMENSION}.
2026-06-15 15:25:27 +08:00

115 lines
3.5 KiB
TypeScript
Executable file

#!/usr/bin/env tsx
/**
* Regenerate packages/core/src/tools/computer-use/schemas.ts from a live
* cua-driver MCP server (`cua-driver mcp`).
*
* Usage:
* npx tsx scripts/sync-computer-use-schemas.ts [binaryPath]
*
* Defaults to the pinned cua-driver binary under `~/.qwen/computer-use/`
* (resolved from CUA_DRIVER_VERSION in constants.ts) — i.e. the binary that
* gets installed the first time Computer Use runs. Pass an explicit path to
* point at a different build.
*
* Bumping the pin is a procedure documented in constants.ts — read that
* JSDoc first.
*/
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { writeFile } from 'node:fs/promises';
import { homedir } from 'node:os';
import { resolve } from 'node:path';
import {
CUA_DRIVER_VERSION,
binaryPath,
} from '../packages/core/src/tools/computer-use/constants.js';
// cua-driver 0.5.2 advertises 35 tools. A drift here just means the upstream
// surface changed — warn (so a bump is reviewed) but don't fail the sync.
const EXPECTED_TOOL_COUNT = 35;
async function main(): Promise<void> {
// Default to the pinned, locally-installed binary; allow an explicit override.
const binary = process.argv[2] ?? binaryPath(homedir());
const transport = new StdioClientTransport({
command: binary,
args: ['mcp'],
});
const client = new Client(
{ name: 'qwen-code-schema-sync', version: '1.0.0' },
{ capabilities: {} },
);
await client.connect(transport);
const result = await client.listTools();
await client.close();
if (result.tools.length !== EXPECTED_TOOL_COUNT) {
process.stderr.write(
`WARNING: cua-driver v${CUA_DRIVER_VERSION} returned ${result.tools.length} tools, expected ${EXPECTED_TOOL_COUNT}. Review the diff before committing.\n`,
);
}
const schemas: Record<
string,
{ description: string; parameterSchema: unknown }
> = {};
for (const tool of result.tools) {
schemas[tool.name] = {
description: tool.description ?? '',
parameterSchema: tool.inputSchema ?? { type: 'object', properties: {} },
};
}
const out = `/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Hardcoded schemas for the cua-driver computer-use tools.
*
* Pinned to: cua-driver-rs v${CUA_DRIVER_VERSION} (see CUA_DRIVER_VERSION in constants.ts).
*
* Generated from the live \`cua-driver mcp\` \`tools/list\` output — the FULL
* tool surface cua-driver advertises (no curation). Exposing the complete set
* (including page/CDP, cursor, session, recording, config, kill_app, …) so the
* model has every capability cua-driver actually provides.
*
* Regenerated by scripts/sync-computer-use-schemas.ts — do not hand-edit.
*/
export interface ComputerUseToolSchema {
description: string;
parameterSchema: Record<string, unknown>;
}
export const COMPUTER_USE_TOOL_NAMES = ${JSON.stringify(
result.tools.map((t) => t.name),
null,
2,
)} as const;
export type ComputerUseToolName = (typeof COMPUTER_USE_TOOL_NAMES)[number];
export const COMPUTER_USE_SCHEMAS: Record<ComputerUseToolName, ComputerUseToolSchema> = ${JSON.stringify(
schemas,
null,
2,
)};
`;
const target = resolve('packages/core/src/tools/computer-use/schemas.ts');
await writeFile(target, out, 'utf8');
process.stdout.write(
`Wrote ${result.tools.length} cua-driver tool schemas to ${target}\n`,
);
}
main().catch((err) => {
process.stderr.write(`Schema sync failed: ${err}\n`);
process.exit(1);
});