@@ -14,38 +14,23 @@ import { Operator, ScreenContext } from '@gui-agent/shared/base';
1414import { ConsoleLogger , LogLevel } from '@agent-infra/logger' ;
1515import { Base64ImageParser } from '@agent-infra/media-utils' ;
1616
17- import { AIOComputer } from './AIOComputer' ;
17+ import { AIOComputer , keyNameMap } from './AIOComputer' ;
1818import { AIOBrowser } from './AIOBrowser' ;
1919import type { AIOHybridOptions } from './types' ;
2020
2121const defaultLogger = new ConsoleLogger ( undefined , LogLevel . DEBUG ) ;
2222
23- const arrowKeyMap = {
24- arrowup : 'up' ,
25- arrowdown : 'down' ,
26- arrowleft : 'left' ,
27- arrowright : 'right' ,
28- } ;
29-
3023export class AIOHybridOperator extends Operator {
31- private static currentInstance : AIOHybridOperator | null = null ;
32- public static async create ( options : AIOHybridOptions ) : Promise < AIOHybridOperator > {
33- defaultLogger . info ( '[AioHybridOperator.create]:' , options . baseURL ) ;
34- const instance = new AIOHybridOperator ( options ) ;
35- // await instance.initialize(options);
36- this . currentInstance = instance ;
37- return instance ;
38- }
39-
4024 private options : AIOHybridOptions ;
41- private logger : ConsoleLogger ;
42- private aioBrowser : AIOBrowser | null = null ;
43- private aioComputer : AIOComputer ;
25+
26+ protected logger : ConsoleLogger ;
27+ protected aioBrowser : AIOBrowser | null = null ;
28+ protected aioComputer : AIOComputer ;
4429
4530 private screenshotWidth = 1280 ;
4631 private screenshotHeight = 1024 ;
4732
48- private constructor ( options : AIOHybridOptions , logger : ConsoleLogger = defaultLogger ) {
33+ constructor ( options : AIOHybridOptions , logger : ConsoleLogger = defaultLogger ) {
4934 super ( ) ;
5035 this . options = options ;
5136 this . logger = logger . spawn ( '[AIOHybridOperator]' ) ;
@@ -184,30 +169,30 @@ export class AIOHybridOperator extends Operator {
184169 case 'click' :
185170 case 'left_click' :
186171 case 'left_single' : {
187- this . handleClick ( actionInputs , 'left' ) ;
172+ await this . handleClick ( actionInputs , 'left' ) ;
188173 const { point } = actionInputs ;
189174 startXPercent = ( point as Coordinates ) ?. normalized ?. x ;
190175 startYPercent = ( point as Coordinates ) ?. normalized ?. y ;
191176 break ;
192177 }
193178 case 'left_double' :
194179 case 'double_click' : {
195- this . handleClick ( actionInputs , 'left' , 2 ) ;
180+ await this . handleClick ( actionInputs , 'left' , 2 ) ;
196181 const { point } = actionInputs ;
197182 startXPercent = ( point as Coordinates ) ?. normalized ?. x ;
198183 startYPercent = ( point as Coordinates ) ?. normalized ?. y ;
199184 break ;
200185 }
201186 case 'right_click' :
202187 case 'right_single' : {
203- this . handleClick ( actionInputs , 'right' ) ;
188+ await this . handleClick ( actionInputs , 'right' ) ;
204189 const { point } = actionInputs ;
205190 startXPercent = ( point as Coordinates ) ?. normalized ?. x ;
206191 startYPercent = ( point as Coordinates ) ?. normalized ?. y ;
207192 break ;
208193 }
209194 case 'middle_click' : {
210- this . handleClick ( actionInputs , 'middle' ) ;
195+ await this . handleClick ( actionInputs , 'middle' ) ;
211196 const { point } = actionInputs ;
212197 startXPercent = ( point as Coordinates ) ?. normalized ?. x ;
213198 startYPercent = ( point as Coordinates ) ?. normalized ?. y ;
@@ -216,7 +201,7 @@ export class AIOHybridOperator extends Operator {
216201 case 'left_click_drag' :
217202 case 'drag' :
218203 case 'select' : {
219- this . handleDrag ( actionInputs ) ;
204+ await this . handleDrag ( actionInputs ) ;
220205 break ;
221206 }
222207 case 'type' : {
@@ -230,18 +215,26 @@ export class AIOHybridOperator extends Operator {
230215 }
231216 case 'hotkey' :
232217 case 'press' : {
233- let keyStr = actionInputs ?. key || actionInputs ?. hotkey ;
218+ const keyStr = actionInputs ?. key || actionInputs ?. hotkey ;
234219 if ( typeof keyStr !== 'string' ) {
235220 throw new Error ( 'key string is required when press or hotkey' ) ;
236221 }
237- keyStr = keyStr . toLowerCase ( ) ;
238- const keys = ( keyStr as string ) . split ( / [ \s + ] / ) . filter ( ( k ) => k . length > 0 ) ;
239- if ( keys . length > 1 ) {
240- await this . aioComputer . hotkey ( keys ) ;
222+ const lowerKeyStr : string = keyStr . toLowerCase ( ) ;
223+ const keys = lowerKeyStr . split ( / \s + / ) . filter ( ( k ) => k . length > 0 ) ;
224+
225+ // Validate and map each key in the hotkey combination
226+ const mappedKeys = keys . map ( ( key ) => {
227+ return keyNameMap [ key as keyof typeof keyNameMap ] || key ;
228+ } ) ;
229+ if ( mappedKeys . length === 0 ) {
230+ throw new Error ( 'key string is required when press or hotkey' ) ;
231+ }
232+
233+ this . logger . info ( 'Press/hotkey action mappedKeys:' , mappedKeys . join ( '+' ) ) ;
234+ if ( mappedKeys . length > 1 ) {
235+ await this . aioComputer . hotkey ( mappedKeys ) ;
241236 } else {
242- // Check if the key can be mapped using arrowKeyMap
243- const mappedKey = arrowKeyMap [ keyStr as keyof typeof arrowKeyMap ] || keyStr ;
244- await this . aioComputer . press ( mappedKey ) ;
237+ await this . aioComputer . press ( mappedKeys [ 0 ] ) ;
245238 }
246239 break ;
247240 }
@@ -343,9 +336,9 @@ export class AIOHybridOperator extends Operator {
343336 }
344337 const { realX : startX , realY : startY } = await this . calculateRealCoords ( startPoint ) ;
345338 const { realX : endX , realY : endY } = await this . calculateRealCoords ( endPoint ) ;
346- if ( startX > endX || startY > endY ) {
347- throw new Error ( 'start point must be top left of end point' ) ;
348- }
339+ // if (startX > endX || startY > endY) {
340+ // throw new Error('start point must be top left of end point');
341+ // }
349342 // Move to start position, press mouse, drag to end position, release mouse
350343 await this . aioComputer . moveTo ( startX , startY ) ;
351344 await this . aioComputer . mouseDown ( ) ;
0 commit comments