@midscene/computer 1.2.1-beta-20260112081017.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +243 -0
- package/dist/es/index.mjs +438 -0
- package/dist/es/mcp-server.mjs +508 -0
- package/dist/lib/index.js +498 -0
- package/dist/lib/mcp-server.js +559 -0
- package/dist/types/index.d.ts +70 -0
- package/dist/types/mcp-server.d.ts +88 -0
- package/package.json +48 -0
- package/rslib.config.ts +26 -0
- package/src/agent.ts +17 -0
- package/src/device.ts +554 -0
- package/src/index.ts +8 -0
- package/src/mcp-server.ts +65 -0
- package/src/mcp-tools.ts +96 -0
- package/src/types/libnut.d.ts +36 -0
- package/src/utils.ts +51 -0
- package/tests/ai/ai-auto-todo.test.ts +85 -0
- package/tests/ai/ai-shop.test.ts +56 -0
- package/tests/ai/basic.test.ts +46 -0
- package/tests/ai/keyboard.test.ts +66 -0
- package/tests/ai/multi-display.test.ts +76 -0
- package/tests/ai/test-utils.ts +31 -0
- package/tests/ai/web-browser.test.ts +63 -0
- package/tests/unit-test/agent.test.ts +34 -0
- package/tests/unit-test/device.test.ts +53 -0
- package/tsconfig.json +18 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +47 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
14
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: definition[key]
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
})();
|
|
20
|
+
(()=>{
|
|
21
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
22
|
+
})();
|
|
23
|
+
(()=>{
|
|
24
|
+
__webpack_require__.r = (exports1)=>{
|
|
25
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
26
|
+
value: 'Module'
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
29
|
+
value: true
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
})();
|
|
33
|
+
var __webpack_exports__ = {};
|
|
34
|
+
__webpack_require__.r(__webpack_exports__);
|
|
35
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
36
|
+
overrideAIConfig: ()=>env_namespaceObject.overrideAIConfig,
|
|
37
|
+
getConnectedDisplays: ()=>getConnectedDisplays,
|
|
38
|
+
checkComputerEnvironment: ()=>checkComputerEnvironment,
|
|
39
|
+
ComputerDevice: ()=>ComputerDevice,
|
|
40
|
+
agentFromComputer: ()=>agentFromComputer,
|
|
41
|
+
ComputerAgent: ()=>ComputerAgent
|
|
42
|
+
});
|
|
43
|
+
const external_node_assert_namespaceObject = require("node:assert");
|
|
44
|
+
var external_node_assert_default = /*#__PURE__*/ __webpack_require__.n(external_node_assert_namespaceObject);
|
|
45
|
+
const core_namespaceObject = require("@midscene/core");
|
|
46
|
+
const device_namespaceObject = require("@midscene/core/device");
|
|
47
|
+
const utils_namespaceObject = require("@midscene/core/utils");
|
|
48
|
+
const img_namespaceObject = require("@midscene/shared/img");
|
|
49
|
+
const logger_namespaceObject = require("@midscene/shared/logger");
|
|
50
|
+
const external_screenshot_desktop_namespaceObject = require("screenshot-desktop");
|
|
51
|
+
var external_screenshot_desktop_default = /*#__PURE__*/ __webpack_require__.n(external_screenshot_desktop_namespaceObject);
|
|
52
|
+
function _define_property(obj, key, value) {
|
|
53
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
54
|
+
value: value,
|
|
55
|
+
enumerable: true,
|
|
56
|
+
configurable: true,
|
|
57
|
+
writable: true
|
|
58
|
+
});
|
|
59
|
+
else obj[key] = value;
|
|
60
|
+
return obj;
|
|
61
|
+
}
|
|
62
|
+
const SMOOTH_MOVE_STEPS_TAP = 8;
|
|
63
|
+
const SMOOTH_MOVE_STEPS_HOVER = 10;
|
|
64
|
+
const SMOOTH_MOVE_DELAY_TAP = 8;
|
|
65
|
+
const SMOOTH_MOVE_DELAY_HOVER = 10;
|
|
66
|
+
const HOVER_EFFECT_WAIT = 300;
|
|
67
|
+
const CLICK_HOLD_DURATION = 50;
|
|
68
|
+
const INPUT_FOCUS_DELAY = 300;
|
|
69
|
+
const INPUT_CLEAR_DELAY = 150;
|
|
70
|
+
const SCROLL_REPEAT_COUNT = 10;
|
|
71
|
+
const SCROLL_STEP_DELAY = 100;
|
|
72
|
+
const SCROLL_COMPLETE_DELAY = 500;
|
|
73
|
+
let device_libnut = null;
|
|
74
|
+
let libnutLoadError = null;
|
|
75
|
+
async function getLibnut() {
|
|
76
|
+
if (device_libnut) return device_libnut;
|
|
77
|
+
if (libnutLoadError) throw libnutLoadError;
|
|
78
|
+
try {
|
|
79
|
+
const libnutModule = await import("@computer-use/libnut/dist/import_libnut");
|
|
80
|
+
device_libnut = libnutModule.libnut;
|
|
81
|
+
if (!device_libnut) throw new Error('libnut module loaded but libnut object is undefined');
|
|
82
|
+
return device_libnut;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
libnutLoadError = error;
|
|
85
|
+
throw new Error(`Failed to load @computer-use/libnut. Make sure it is properly installed and compiled for your platform. Error: ${error}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const debugDevice = (0, logger_namespaceObject.getDebug)('computer:device');
|
|
89
|
+
async function smoothMoveMouse(targetX, targetY, steps, stepDelay) {
|
|
90
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
91
|
+
const currentPos = device_libnut.getMousePos();
|
|
92
|
+
for(let i = 1; i <= steps; i++){
|
|
93
|
+
const stepX = Math.round(currentPos.x + (targetX - currentPos.x) * i / steps);
|
|
94
|
+
const stepY = Math.round(currentPos.y + (targetY - currentPos.y) * i / steps);
|
|
95
|
+
device_libnut.moveMouse(stepX, stepY);
|
|
96
|
+
await (0, utils_namespaceObject.sleep)(stepDelay);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const KEY_NAME_MAP = {
|
|
100
|
+
windows: 'win',
|
|
101
|
+
win: 'win',
|
|
102
|
+
ctrl: 'control',
|
|
103
|
+
esc: 'escape',
|
|
104
|
+
del: 'delete',
|
|
105
|
+
ins: 'insert',
|
|
106
|
+
pgup: 'pageup',
|
|
107
|
+
pgdn: 'pagedown',
|
|
108
|
+
arrowup: 'up',
|
|
109
|
+
arrowdown: 'down',
|
|
110
|
+
arrowleft: 'left',
|
|
111
|
+
arrowright: 'right',
|
|
112
|
+
volumedown: 'audio_vol_down',
|
|
113
|
+
volumeup: 'audio_vol_up',
|
|
114
|
+
mediavolumedown: 'audio_vol_down',
|
|
115
|
+
mediavolumeup: 'audio_vol_up',
|
|
116
|
+
mute: 'audio_mute',
|
|
117
|
+
mediamute: 'audio_mute',
|
|
118
|
+
mediaplay: 'audio_play',
|
|
119
|
+
mediapause: 'audio_pause',
|
|
120
|
+
mediaplaypause: 'audio_play',
|
|
121
|
+
mediastop: 'audio_stop',
|
|
122
|
+
medianexttrack: 'audio_next',
|
|
123
|
+
mediaprevioustrack: 'audio_prev',
|
|
124
|
+
medianext: 'audio_next',
|
|
125
|
+
mediaprev: 'audio_prev'
|
|
126
|
+
};
|
|
127
|
+
const PRIMARY_KEY_MAP = {
|
|
128
|
+
command: 'cmd',
|
|
129
|
+
cmd: 'cmd',
|
|
130
|
+
meta: 'meta',
|
|
131
|
+
control: 'control',
|
|
132
|
+
ctrl: 'control',
|
|
133
|
+
shift: 'shift',
|
|
134
|
+
alt: 'alt',
|
|
135
|
+
option: 'alt'
|
|
136
|
+
};
|
|
137
|
+
function normalizeKeyName(key) {
|
|
138
|
+
const lowerKey = key.toLowerCase();
|
|
139
|
+
return KEY_NAME_MAP[lowerKey] || lowerKey;
|
|
140
|
+
}
|
|
141
|
+
function normalizePrimaryKey(key) {
|
|
142
|
+
const lowerKey = key.toLowerCase();
|
|
143
|
+
if (PRIMARY_KEY_MAP[lowerKey]) return PRIMARY_KEY_MAP[lowerKey];
|
|
144
|
+
return KEY_NAME_MAP[lowerKey] || lowerKey;
|
|
145
|
+
}
|
|
146
|
+
class ComputerDevice {
|
|
147
|
+
describe() {
|
|
148
|
+
return this.description || 'Computer Device';
|
|
149
|
+
}
|
|
150
|
+
static async listDisplays() {
|
|
151
|
+
try {
|
|
152
|
+
const displays = await external_screenshot_desktop_default().listDisplays();
|
|
153
|
+
return displays.map((d)=>({
|
|
154
|
+
id: String(d.id),
|
|
155
|
+
name: d.name || `Display ${d.id}`,
|
|
156
|
+
primary: d.primary || false
|
|
157
|
+
}));
|
|
158
|
+
} catch (error) {
|
|
159
|
+
debugDevice(`Failed to list displays: ${error}`);
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async connect() {
|
|
164
|
+
debugDevice('Connecting to computer device');
|
|
165
|
+
try {
|
|
166
|
+
device_libnut = await getLibnut();
|
|
167
|
+
const size = await this.size();
|
|
168
|
+
const displays = await ComputerDevice.listDisplays();
|
|
169
|
+
this.description = `
|
|
170
|
+
Type: Computer
|
|
171
|
+
Platform: ${process.platform}
|
|
172
|
+
Display: ${this.displayId || 'Primary'}
|
|
173
|
+
Screen Size: ${size.width}x${size.height}
|
|
174
|
+
Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ') : 'Unknown'}
|
|
175
|
+
`;
|
|
176
|
+
debugDevice('Computer device connected', this.description);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
debugDevice(`Failed to connect: ${error}`);
|
|
179
|
+
throw new Error(`Unable to connect to computer device: ${error}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async screenshotBase64() {
|
|
183
|
+
debugDevice('Taking screenshot', {
|
|
184
|
+
displayId: this.displayId
|
|
185
|
+
});
|
|
186
|
+
try {
|
|
187
|
+
const options = {
|
|
188
|
+
format: 'png'
|
|
189
|
+
};
|
|
190
|
+
if (void 0 !== this.displayId) if ('darwin' === process.platform) {
|
|
191
|
+
const screenIndex = Number(this.displayId);
|
|
192
|
+
if (!Number.isNaN(screenIndex)) options.screen = screenIndex;
|
|
193
|
+
} else options.screen = this.displayId;
|
|
194
|
+
debugDevice('Screenshot options', options);
|
|
195
|
+
const buffer = await external_screenshot_desktop_default()(options);
|
|
196
|
+
return (0, img_namespaceObject.createImgBase64ByFormat)('png', buffer.toString('base64'));
|
|
197
|
+
} catch (error) {
|
|
198
|
+
debugDevice(`Screenshot failed: ${error}`);
|
|
199
|
+
throw new Error(`Failed to take screenshot: ${error}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async size() {
|
|
203
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
204
|
+
try {
|
|
205
|
+
const screenSize = device_libnut.getScreenSize();
|
|
206
|
+
return {
|
|
207
|
+
width: screenSize.width,
|
|
208
|
+
height: screenSize.height,
|
|
209
|
+
dpr: 1
|
|
210
|
+
};
|
|
211
|
+
} catch (error) {
|
|
212
|
+
debugDevice(`Failed to get screen size: ${error}`);
|
|
213
|
+
throw new Error(`Failed to get screen size: ${error}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
actionSpace() {
|
|
217
|
+
const defaultActions = [
|
|
218
|
+
(0, device_namespaceObject.defineActionTap)(async (param)=>{
|
|
219
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
220
|
+
const element = param.locate;
|
|
221
|
+
external_node_assert_default()(element, 'Element not found, cannot tap');
|
|
222
|
+
const [x, y] = element.center;
|
|
223
|
+
const targetX = Math.round(x);
|
|
224
|
+
const targetY = Math.round(y);
|
|
225
|
+
await smoothMoveMouse(targetX, targetY, SMOOTH_MOVE_STEPS_TAP, SMOOTH_MOVE_DELAY_TAP);
|
|
226
|
+
device_libnut.mouseToggle('down', 'left');
|
|
227
|
+
await (0, utils_namespaceObject.sleep)(CLICK_HOLD_DURATION);
|
|
228
|
+
device_libnut.mouseToggle('up', 'left');
|
|
229
|
+
}),
|
|
230
|
+
(0, device_namespaceObject.defineActionDoubleClick)(async (param)=>{
|
|
231
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
232
|
+
const element = param.locate;
|
|
233
|
+
external_node_assert_default()(element, 'Element not found, cannot double click');
|
|
234
|
+
const [x, y] = element.center;
|
|
235
|
+
device_libnut.moveMouse(Math.round(x), Math.round(y));
|
|
236
|
+
device_libnut.mouseClick('left', true);
|
|
237
|
+
}),
|
|
238
|
+
(0, device_namespaceObject.defineActionRightClick)(async (param)=>{
|
|
239
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
240
|
+
const element = param.locate;
|
|
241
|
+
external_node_assert_default()(element, 'Element not found, cannot right click');
|
|
242
|
+
const [x, y] = element.center;
|
|
243
|
+
device_libnut.moveMouse(Math.round(x), Math.round(y));
|
|
244
|
+
device_libnut.mouseClick('right');
|
|
245
|
+
}),
|
|
246
|
+
(0, device_namespaceObject.defineActionHover)(async (param)=>{
|
|
247
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
248
|
+
const element = param.locate;
|
|
249
|
+
external_node_assert_default()(element, 'Element not found, cannot hover');
|
|
250
|
+
const [x, y] = element.center;
|
|
251
|
+
const targetX = Math.round(x);
|
|
252
|
+
const targetY = Math.round(y);
|
|
253
|
+
await smoothMoveMouse(targetX, targetY, SMOOTH_MOVE_STEPS_HOVER, SMOOTH_MOVE_DELAY_HOVER);
|
|
254
|
+
await (0, utils_namespaceObject.sleep)(HOVER_EFFECT_WAIT);
|
|
255
|
+
}),
|
|
256
|
+
(0, device_namespaceObject.defineAction)({
|
|
257
|
+
name: 'Input',
|
|
258
|
+
description: 'Input text into the input field',
|
|
259
|
+
interfaceAlias: 'aiInput',
|
|
260
|
+
paramSchema: core_namespaceObject.z.object({
|
|
261
|
+
value: core_namespaceObject.z.string().describe('The text to input'),
|
|
262
|
+
mode: core_namespaceObject.z["enum"]([
|
|
263
|
+
'replace',
|
|
264
|
+
'clear',
|
|
265
|
+
'append'
|
|
266
|
+
]).default('replace').optional().describe('Input mode: replace, clear, or append'),
|
|
267
|
+
locate: (0, core_namespaceObject.getMidsceneLocationSchema)().describe('The input field to be filled').optional()
|
|
268
|
+
}),
|
|
269
|
+
call: async (param)=>{
|
|
270
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
271
|
+
const element = param.locate;
|
|
272
|
+
if (element && 'append' !== param.mode) {
|
|
273
|
+
const [x, y] = element.center;
|
|
274
|
+
device_libnut.moveMouse(Math.round(x), Math.round(y));
|
|
275
|
+
device_libnut.mouseClick('left');
|
|
276
|
+
await (0, utils_namespaceObject.sleep)(INPUT_FOCUS_DELAY);
|
|
277
|
+
const modifier = 'darwin' === process.platform ? 'command' : 'control';
|
|
278
|
+
device_libnut.keyTap('a', [
|
|
279
|
+
modifier
|
|
280
|
+
]);
|
|
281
|
+
await (0, utils_namespaceObject.sleep)(50);
|
|
282
|
+
device_libnut.keyTap('backspace');
|
|
283
|
+
await (0, utils_namespaceObject.sleep)(INPUT_CLEAR_DELAY);
|
|
284
|
+
}
|
|
285
|
+
if ('clear' === param.mode) return;
|
|
286
|
+
if (!param.value) return;
|
|
287
|
+
device_libnut.typeString(param.value);
|
|
288
|
+
}
|
|
289
|
+
}),
|
|
290
|
+
(0, device_namespaceObject.defineActionScroll)(async (param)=>{
|
|
291
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
292
|
+
if (param.locate) {
|
|
293
|
+
const element = param.locate;
|
|
294
|
+
const [x, y] = element.center;
|
|
295
|
+
device_libnut.moveMouse(Math.round(x), Math.round(y));
|
|
296
|
+
}
|
|
297
|
+
const scrollType = param?.scrollType;
|
|
298
|
+
const scrollToEdgeActions = {
|
|
299
|
+
scrollToTop: [
|
|
300
|
+
0,
|
|
301
|
+
10
|
|
302
|
+
],
|
|
303
|
+
scrollToBottom: [
|
|
304
|
+
0,
|
|
305
|
+
-10
|
|
306
|
+
],
|
|
307
|
+
scrollToLeft: [
|
|
308
|
+
-10,
|
|
309
|
+
0
|
|
310
|
+
],
|
|
311
|
+
scrollToRight: [
|
|
312
|
+
10,
|
|
313
|
+
0
|
|
314
|
+
]
|
|
315
|
+
};
|
|
316
|
+
const edgeAction = scrollToEdgeActions[scrollType || ''];
|
|
317
|
+
if (edgeAction) {
|
|
318
|
+
const [dx, dy] = edgeAction;
|
|
319
|
+
for(let i = 0; i < SCROLL_REPEAT_COUNT; i++){
|
|
320
|
+
device_libnut.scrollMouse(dx, dy);
|
|
321
|
+
await (0, utils_namespaceObject.sleep)(SCROLL_STEP_DELAY);
|
|
322
|
+
}
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if ('singleAction' === scrollType || !scrollType) {
|
|
326
|
+
const distance = param?.distance || 500;
|
|
327
|
+
const ticks = Math.ceil(distance / 100);
|
|
328
|
+
const direction = param?.direction || 'down';
|
|
329
|
+
const directionMap = {
|
|
330
|
+
up: [
|
|
331
|
+
0,
|
|
332
|
+
ticks
|
|
333
|
+
],
|
|
334
|
+
down: [
|
|
335
|
+
0,
|
|
336
|
+
-ticks
|
|
337
|
+
],
|
|
338
|
+
left: [
|
|
339
|
+
-ticks,
|
|
340
|
+
0
|
|
341
|
+
],
|
|
342
|
+
right: [
|
|
343
|
+
ticks,
|
|
344
|
+
0
|
|
345
|
+
]
|
|
346
|
+
};
|
|
347
|
+
const [dx, dy] = directionMap[direction] || [
|
|
348
|
+
0,
|
|
349
|
+
-ticks
|
|
350
|
+
];
|
|
351
|
+
device_libnut.scrollMouse(dx, dy);
|
|
352
|
+
await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
throw new Error(`Unknown scroll type: ${scrollType}, param: ${JSON.stringify(param)}`);
|
|
356
|
+
}),
|
|
357
|
+
(0, device_namespaceObject.defineActionKeyboardPress)(async (param)=>{
|
|
358
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
359
|
+
if (param.locate) {
|
|
360
|
+
const [x, y] = param.locate.center;
|
|
361
|
+
device_libnut.moveMouse(Math.round(x), Math.round(y));
|
|
362
|
+
device_libnut.mouseClick('left');
|
|
363
|
+
await (0, utils_namespaceObject.sleep)(50);
|
|
364
|
+
}
|
|
365
|
+
const keys = param.keyName.split('+');
|
|
366
|
+
const modifiers = keys.slice(0, -1).map(normalizeKeyName);
|
|
367
|
+
const key = normalizePrimaryKey(keys[keys.length - 1]);
|
|
368
|
+
debugDevice('KeyboardPress', {
|
|
369
|
+
original: param.keyName,
|
|
370
|
+
key,
|
|
371
|
+
modifiers
|
|
372
|
+
});
|
|
373
|
+
if (modifiers.length > 0) device_libnut.keyTap(key, modifiers);
|
|
374
|
+
else device_libnut.keyTap(key);
|
|
375
|
+
}),
|
|
376
|
+
(0, device_namespaceObject.defineActionDragAndDrop)(async (param)=>{
|
|
377
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
378
|
+
const from = param.from;
|
|
379
|
+
const to = param.to;
|
|
380
|
+
external_node_assert_default()(from, 'missing "from" param for drag and drop');
|
|
381
|
+
external_node_assert_default()(to, 'missing "to" param for drag and drop');
|
|
382
|
+
const [fromX, fromY] = from.center;
|
|
383
|
+
const [toX, toY] = to.center;
|
|
384
|
+
device_libnut.moveMouse(Math.round(fromX), Math.round(fromY));
|
|
385
|
+
device_libnut.mouseToggle('down', 'left');
|
|
386
|
+
await (0, utils_namespaceObject.sleep)(100);
|
|
387
|
+
device_libnut.moveMouse(Math.round(toX), Math.round(toY));
|
|
388
|
+
await (0, utils_namespaceObject.sleep)(100);
|
|
389
|
+
device_libnut.mouseToggle('up', 'left');
|
|
390
|
+
}),
|
|
391
|
+
(0, device_namespaceObject.defineActionClearInput)(async (param)=>{
|
|
392
|
+
external_node_assert_default()(device_libnut, 'libnut not initialized');
|
|
393
|
+
const element = param.locate;
|
|
394
|
+
external_node_assert_default()(element, 'Element not found, cannot clear input');
|
|
395
|
+
const [x, y] = element.center;
|
|
396
|
+
device_libnut.moveMouse(Math.round(x), Math.round(y));
|
|
397
|
+
device_libnut.mouseClick('left');
|
|
398
|
+
await (0, utils_namespaceObject.sleep)(100);
|
|
399
|
+
const modifier = 'darwin' === process.platform ? 'command' : 'control';
|
|
400
|
+
device_libnut.keyTap('a', [
|
|
401
|
+
modifier
|
|
402
|
+
]);
|
|
403
|
+
device_libnut.keyTap('backspace');
|
|
404
|
+
await (0, utils_namespaceObject.sleep)(50);
|
|
405
|
+
})
|
|
406
|
+
];
|
|
407
|
+
const platformActions = Object.values(createPlatformActions());
|
|
408
|
+
const customActions = this.options?.customActions || [];
|
|
409
|
+
return [
|
|
410
|
+
...defaultActions,
|
|
411
|
+
...platformActions,
|
|
412
|
+
...customActions
|
|
413
|
+
];
|
|
414
|
+
}
|
|
415
|
+
async destroy() {
|
|
416
|
+
if (this.destroyed) return;
|
|
417
|
+
this.destroyed = true;
|
|
418
|
+
debugDevice('Computer device destroyed');
|
|
419
|
+
}
|
|
420
|
+
async url() {
|
|
421
|
+
return '';
|
|
422
|
+
}
|
|
423
|
+
constructor(options){
|
|
424
|
+
_define_property(this, "interfaceType", 'computer');
|
|
425
|
+
_define_property(this, "options", void 0);
|
|
426
|
+
_define_property(this, "displayId", void 0);
|
|
427
|
+
_define_property(this, "description", void 0);
|
|
428
|
+
_define_property(this, "destroyed", false);
|
|
429
|
+
_define_property(this, "uri", void 0);
|
|
430
|
+
this.options = options;
|
|
431
|
+
this.displayId = options?.displayId;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function createPlatformActions() {
|
|
435
|
+
return {
|
|
436
|
+
ListDisplays: (0, device_namespaceObject.defineAction)({
|
|
437
|
+
name: 'ListDisplays',
|
|
438
|
+
description: 'List all available displays/monitors',
|
|
439
|
+
call: async ()=>await ComputerDevice.listDisplays()
|
|
440
|
+
})
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
const agent_namespaceObject = require("@midscene/core/agent");
|
|
444
|
+
class ComputerAgent extends agent_namespaceObject.Agent {
|
|
445
|
+
}
|
|
446
|
+
async function agentFromComputer(opts) {
|
|
447
|
+
const device = new ComputerDevice(opts || {});
|
|
448
|
+
await device.connect();
|
|
449
|
+
return new ComputerAgent(device, opts);
|
|
450
|
+
}
|
|
451
|
+
const env_namespaceObject = require("@midscene/shared/env");
|
|
452
|
+
async function checkComputerEnvironment() {
|
|
453
|
+
try {
|
|
454
|
+
const libnutModule = await import("@computer-use/libnut/dist/import_libnut");
|
|
455
|
+
const libnut = libnutModule.libnut;
|
|
456
|
+
const screenSize = libnut.getScreenSize();
|
|
457
|
+
if (!screenSize || screenSize.width <= 0) return {
|
|
458
|
+
available: false,
|
|
459
|
+
error: 'libnut cannot get screen size',
|
|
460
|
+
platform: process.platform,
|
|
461
|
+
displays: 0
|
|
462
|
+
};
|
|
463
|
+
const displays = await ComputerDevice.listDisplays();
|
|
464
|
+
return {
|
|
465
|
+
available: true,
|
|
466
|
+
platform: process.platform,
|
|
467
|
+
displays: displays.length
|
|
468
|
+
};
|
|
469
|
+
} catch (error) {
|
|
470
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
471
|
+
return {
|
|
472
|
+
available: false,
|
|
473
|
+
error: errorMessage,
|
|
474
|
+
platform: process.platform,
|
|
475
|
+
displays: 0
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
async function getConnectedDisplays() {
|
|
480
|
+
return ComputerDevice.listDisplays();
|
|
481
|
+
}
|
|
482
|
+
exports.ComputerAgent = __webpack_exports__.ComputerAgent;
|
|
483
|
+
exports.ComputerDevice = __webpack_exports__.ComputerDevice;
|
|
484
|
+
exports.agentFromComputer = __webpack_exports__.agentFromComputer;
|
|
485
|
+
exports.checkComputerEnvironment = __webpack_exports__.checkComputerEnvironment;
|
|
486
|
+
exports.getConnectedDisplays = __webpack_exports__.getConnectedDisplays;
|
|
487
|
+
exports.overrideAIConfig = __webpack_exports__.overrideAIConfig;
|
|
488
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
489
|
+
"ComputerAgent",
|
|
490
|
+
"ComputerDevice",
|
|
491
|
+
"agentFromComputer",
|
|
492
|
+
"checkComputerEnvironment",
|
|
493
|
+
"getConnectedDisplays",
|
|
494
|
+
"overrideAIConfig"
|
|
495
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
496
|
+
Object.defineProperty(exports, '__esModule', {
|
|
497
|
+
value: true
|
|
498
|
+
});
|