@midscene/web 0.27.3-beta-20250825082408.0 → 0.27.3
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/bin/midscene-playground +1 -1
- package/dist/es/bridge-mode/io-client.mjs +1 -1
- package/dist/es/bridge-mode/io-server.mjs +2 -2
- package/dist/es/bridge-mode/io-server.mjs.map +1 -1
- package/dist/es/bridge-mode/page-browser-side.mjs +1 -1
- package/dist/es/bridge-mode/page-browser-side.mjs.map +1 -1
- package/dist/es/chrome-extension/page.mjs +1 -1
- package/dist/es/playground/server.mjs +2 -12
- package/dist/es/playground/server.mjs.map +1 -1
- package/dist/es/playground/static-page.mjs +2 -1
- package/dist/es/playground/static-page.mjs.map +1 -1
- package/dist/lib/bridge-mode/io-client.js +1 -1
- package/dist/lib/bridge-mode/io-server.js +2 -2
- package/dist/lib/bridge-mode/io-server.js.map +1 -1
- package/dist/lib/bridge-mode/page-browser-side.js +1 -1
- package/dist/lib/bridge-mode/page-browser-side.js.map +1 -1
- package/dist/lib/chrome-extension/page.js +1 -1
- package/dist/lib/playground/server.js +2 -12
- package/dist/lib/playground/server.js.map +1 -1
- package/dist/lib/playground/static-page.js +2 -1
- package/dist/lib/playground/static-page.js.map +1 -1
- package/package.json +3 -3
package/bin/midscene-playground
CHANGED
|
@@ -71,7 +71,7 @@ class BridgeServer {
|
|
|
71
71
|
logMsg('one client connected');
|
|
72
72
|
this.socket = socket;
|
|
73
73
|
const clientVersion = socket.handshake.query.version;
|
|
74
|
-
logMsg(`Bridge connected, cli-side version v0.27.3
|
|
74
|
+
logMsg(`Bridge connected, cli-side version v0.27.3, browser-side version v${clientVersion}`);
|
|
75
75
|
socket.on(BridgeEvent.CallResponse, (params)=>{
|
|
76
76
|
const id = params.id;
|
|
77
77
|
const response = params.response;
|
|
@@ -99,7 +99,7 @@ class BridgeServer {
|
|
|
99
99
|
var _this_onConnect, _this;
|
|
100
100
|
null == (_this_onConnect = (_this = this).onConnect) || _this_onConnect.call(_this);
|
|
101
101
|
const payload = {
|
|
102
|
-
version: "0.27.3
|
|
102
|
+
version: "0.27.3"
|
|
103
103
|
};
|
|
104
104
|
socket.emit(BridgeEvent.Connected, payload);
|
|
105
105
|
Promise.resolve().then(()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-mode/io-server.mjs","sources":["webpack://@midscene/web/./src/bridge-mode/io-server.ts"],"sourcesContent":["import { sleep } from '@midscene/core/utils';\nimport { logMsg } from '@midscene/shared/utils';\nimport { Server, type Socket as ServerSocket } from 'socket.io';\nimport { io as ClientIO } from 'socket.io-client';\n\nimport {\n type BridgeCall,\n type BridgeCallResponse,\n BridgeCallTimeout,\n type BridgeConnectedEventPayload,\n BridgeErrorCodeNoClientConnected,\n BridgeEvent,\n BridgeSignalKill,\n DefaultBridgeServerPort,\n} from './common';\n\ndeclare const __VERSION__: string;\n\nexport const killRunningServer = async (port?: number) => {\n try {\n const client = ClientIO(\n `ws://localhost:${port || DefaultBridgeServerPort}`,\n {\n query: {\n [BridgeSignalKill]: 1,\n },\n },\n );\n await sleep(100);\n await client.close();\n } catch (e) {\n // console.error('failed to kill port', e);\n }\n};\n\n// ws server, this is where the request is sent\nexport class BridgeServer {\n private callId = 0;\n private io: Server | null = null;\n private socket: ServerSocket | null = null;\n private listeningTimeoutId: NodeJS.Timeout | null = null;\n private listeningTimerFlag = false;\n private connectionTipTimer: NodeJS.Timeout | null = null;\n public calls: Record<string, BridgeCall> = {};\n\n private connectionLost = false;\n private connectionLostReason = '';\n\n constructor(\n public port: number,\n public onConnect?: () => void,\n public onDisconnect?: (reason: string) => void,\n public closeConflictServer?: boolean,\n ) {}\n\n async listen(\n opts: {\n timeout?: number | false;\n } = {},\n ): Promise<void> {\n const { timeout = 30000 } = opts;\n\n if (this.closeConflictServer) {\n await killRunningServer(this.port);\n }\n\n return new Promise((resolve, reject) => {\n if (this.listeningTimerFlag) {\n return reject(new Error('already listening'));\n }\n this.listeningTimerFlag = true;\n\n this.listeningTimeoutId = timeout\n ? setTimeout(() => {\n reject(\n new Error(\n `no extension connected after ${timeout}ms (${BridgeErrorCodeNoClientConnected})`,\n ),\n );\n }, timeout)\n : null;\n\n this.connectionTipTimer =\n !timeout || timeout > 3000\n ? setTimeout(() => {\n logMsg('waiting for bridge to connect...');\n }, 2000)\n : null;\n this.io = new Server(this.port, {\n maxHttpBufferSize: 100 * 1024 * 1024, // 100MB\n });\n\n // Listen for the native HTTP server 'listening' event\n this.io.httpServer.once('listening', () => {\n resolve();\n });\n\n this.io.httpServer.once('error', (err: Error) => {\n reject(new Error(`Bridge Listening Error: ${err.message}`));\n });\n\n this.io.use((socket, next) => {\n if (this.socket) {\n next(new Error('server already connected by another client'));\n }\n next();\n });\n\n this.io.on('connection', (socket) => {\n // check the connection url\n const url = socket.handshake.url;\n if (url.includes(BridgeSignalKill)) {\n console.warn('kill signal received, closing bridge server');\n return this.close();\n }\n\n this.connectionLost = false;\n this.connectionLostReason = '';\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.listeningTimeoutId = null;\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n this.connectionTipTimer = null;\n if (this.socket) {\n socket.emit(BridgeEvent.Refused);\n // close the socket\n socket.disconnect();\n\n return reject(\n new Error('server already connected by another client'),\n );\n }\n\n try {\n logMsg('one client connected');\n this.socket = socket;\n\n const clientVersion = socket.handshake.query.version;\n logMsg(\n `Bridge connected, cli-side version v${__VERSION__}, browser-side version v${clientVersion}`,\n );\n\n socket.on(BridgeEvent.CallResponse, (params: BridgeCallResponse) => {\n const id = params.id;\n const response = params.response;\n const error = params.error;\n\n this.triggerCallResponseCallback(id, error, response);\n });\n\n socket.on('disconnect', (reason: string) => {\n this.connectionLost = true;\n this.connectionLostReason = reason;\n\n try {\n this.io?.close();\n } catch (e) {\n // ignore\n }\n\n // flush all pending calls as error\n for (const id in this.calls) {\n const call = this.calls[id];\n\n if (!call.responseTime) {\n const errorMessage = this.connectionLostErrorMsg();\n this.triggerCallResponseCallback(\n id,\n new Error(errorMessage),\n null,\n );\n }\n }\n\n this.onDisconnect?.(reason);\n });\n\n setTimeout(() => {\n this.onConnect?.();\n\n const payload = {\n version: __VERSION__,\n } as BridgeConnectedEventPayload;\n socket.emit(BridgeEvent.Connected, payload);\n Promise.resolve().then(() => {\n for (const id in this.calls) {\n if (this.calls[id].callTime === 0) {\n this.emitCall(id);\n }\n }\n });\n }, 0);\n } catch (e) {\n console.error('failed to handle connection event', e);\n reject(e);\n }\n });\n\n this.io.on('close', () => {\n this.close();\n });\n });\n }\n\n private connectionLostErrorMsg = () => {\n return `Connection lost, reason: ${this.connectionLostReason}`;\n };\n\n private async triggerCallResponseCallback(\n id: string | number,\n error: Error | null,\n response: any,\n ) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n call.error = error || undefined;\n call.response = response;\n call.responseTime = Date.now();\n\n call.callback(call.error, response);\n }\n\n private async emitCall(id: string) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n\n if (this.connectionLost) {\n const message = `Connection lost, reason: ${this.connectionLostReason}`;\n call.callback(new Error(message), null);\n return;\n }\n\n if (this.socket) {\n this.socket.emit(BridgeEvent.Call, {\n id,\n method: call.method,\n args: call.args,\n });\n call.callTime = Date.now();\n }\n }\n\n async call<T = any>(\n method: string,\n args: any[],\n timeout = BridgeCallTimeout,\n ): Promise<T> {\n const id = `${this.callId++}`;\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n logMsg(`bridge call timeout, id=${id}, method=${method}, args=`, args);\n this.calls[id].error = new Error(\n `Bridge call timeout after ${timeout}ms: ${method}`,\n );\n reject(this.calls[id].error);\n }, timeout);\n\n this.calls[id] = {\n method,\n args,\n response: null,\n callTime: 0,\n responseTime: 0,\n callback: (error: Error | undefined, response: any) => {\n clearTimeout(timeoutId);\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n },\n };\n\n this.emitCall(id);\n });\n }\n\n // do NOT restart after close\n async close() {\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n const closeProcess = this.io?.close();\n this.io = null;\n\n return closeProcess;\n }\n}\n"],"names":["killRunningServer","port","client","ClientIO","DefaultBridgeServerPort","BridgeSignalKill","sleep","e","BridgeServer","opts","timeout","Promise","resolve","reject","Error","setTimeout","BridgeErrorCodeNoClientConnected","logMsg","Server","err","socket","next","url","console","clearTimeout","BridgeEvent","clientVersion","params","id","response","error","reason","_this","_this_io","call","errorMessage","payload","__VERSION__","undefined","Date","message","method","args","BridgeCallTimeout","timeoutId","closeProcess","onConnect","onDisconnect","closeConflictServer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bridge-mode/io-server.mjs","sources":["webpack://@midscene/web/./src/bridge-mode/io-server.ts"],"sourcesContent":["import { sleep } from '@midscene/core/utils';\nimport { logMsg } from '@midscene/shared/utils';\nimport { Server, type Socket as ServerSocket } from 'socket.io';\nimport { io as ClientIO } from 'socket.io-client';\n\nimport {\n type BridgeCall,\n type BridgeCallResponse,\n BridgeCallTimeout,\n type BridgeConnectedEventPayload,\n BridgeErrorCodeNoClientConnected,\n BridgeEvent,\n BridgeSignalKill,\n DefaultBridgeServerPort,\n} from './common';\n\ndeclare const __VERSION__: string;\n\nexport const killRunningServer = async (port?: number) => {\n try {\n const client = ClientIO(\n `ws://localhost:${port || DefaultBridgeServerPort}`,\n {\n query: {\n [BridgeSignalKill]: 1,\n },\n },\n );\n await sleep(100);\n await client.close();\n } catch (e) {\n // console.error('failed to kill port', e);\n }\n};\n\n// ws server, this is where the request is sent\nexport class BridgeServer {\n private callId = 0;\n private io: Server | null = null;\n private socket: ServerSocket | null = null;\n private listeningTimeoutId: NodeJS.Timeout | null = null;\n private listeningTimerFlag = false;\n private connectionTipTimer: NodeJS.Timeout | null = null;\n public calls: Record<string, BridgeCall> = {};\n\n private connectionLost = false;\n private connectionLostReason = '';\n\n constructor(\n public port: number,\n public onConnect?: () => void,\n public onDisconnect?: (reason: string) => void,\n public closeConflictServer?: boolean,\n ) {}\n\n async listen(\n opts: {\n timeout?: number | false;\n } = {},\n ): Promise<void> {\n const { timeout = 30000 } = opts;\n\n if (this.closeConflictServer) {\n await killRunningServer(this.port);\n }\n\n return new Promise((resolve, reject) => {\n if (this.listeningTimerFlag) {\n return reject(new Error('already listening'));\n }\n this.listeningTimerFlag = true;\n\n this.listeningTimeoutId = timeout\n ? setTimeout(() => {\n reject(\n new Error(\n `no extension connected after ${timeout}ms (${BridgeErrorCodeNoClientConnected})`,\n ),\n );\n }, timeout)\n : null;\n\n this.connectionTipTimer =\n !timeout || timeout > 3000\n ? setTimeout(() => {\n logMsg('waiting for bridge to connect...');\n }, 2000)\n : null;\n this.io = new Server(this.port, {\n maxHttpBufferSize: 100 * 1024 * 1024, // 100MB\n });\n\n // Listen for the native HTTP server 'listening' event\n this.io.httpServer.once('listening', () => {\n resolve();\n });\n\n this.io.httpServer.once('error', (err: Error) => {\n reject(new Error(`Bridge Listening Error: ${err.message}`));\n });\n\n this.io.use((socket, next) => {\n if (this.socket) {\n next(new Error('server already connected by another client'));\n }\n next();\n });\n\n this.io.on('connection', (socket) => {\n // check the connection url\n const url = socket.handshake.url;\n if (url.includes(BridgeSignalKill)) {\n console.warn('kill signal received, closing bridge server');\n return this.close();\n }\n\n this.connectionLost = false;\n this.connectionLostReason = '';\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.listeningTimeoutId = null;\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n this.connectionTipTimer = null;\n if (this.socket) {\n socket.emit(BridgeEvent.Refused);\n // close the socket\n socket.disconnect();\n\n return reject(\n new Error('server already connected by another client'),\n );\n }\n\n try {\n logMsg('one client connected');\n this.socket = socket;\n\n const clientVersion = socket.handshake.query.version;\n logMsg(\n `Bridge connected, cli-side version v${__VERSION__}, browser-side version v${clientVersion}`,\n );\n\n socket.on(BridgeEvent.CallResponse, (params: BridgeCallResponse) => {\n const id = params.id;\n const response = params.response;\n const error = params.error;\n\n this.triggerCallResponseCallback(id, error, response);\n });\n\n socket.on('disconnect', (reason: string) => {\n this.connectionLost = true;\n this.connectionLostReason = reason;\n\n try {\n this.io?.close();\n } catch (e) {\n // ignore\n }\n\n // flush all pending calls as error\n for (const id in this.calls) {\n const call = this.calls[id];\n\n if (!call.responseTime) {\n const errorMessage = this.connectionLostErrorMsg();\n this.triggerCallResponseCallback(\n id,\n new Error(errorMessage),\n null,\n );\n }\n }\n\n this.onDisconnect?.(reason);\n });\n\n setTimeout(() => {\n this.onConnect?.();\n\n const payload = {\n version: __VERSION__,\n } as BridgeConnectedEventPayload;\n socket.emit(BridgeEvent.Connected, payload);\n Promise.resolve().then(() => {\n for (const id in this.calls) {\n if (this.calls[id].callTime === 0) {\n this.emitCall(id);\n }\n }\n });\n }, 0);\n } catch (e) {\n console.error('failed to handle connection event', e);\n reject(e);\n }\n });\n\n this.io.on('close', () => {\n this.close();\n });\n });\n }\n\n private connectionLostErrorMsg = () => {\n return `Connection lost, reason: ${this.connectionLostReason}`;\n };\n\n private async triggerCallResponseCallback(\n id: string | number,\n error: Error | null,\n response: any,\n ) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n call.error = error || undefined;\n call.response = response;\n call.responseTime = Date.now();\n\n call.callback(call.error, response);\n }\n\n private async emitCall(id: string) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n\n if (this.connectionLost) {\n const message = `Connection lost, reason: ${this.connectionLostReason}`;\n call.callback(new Error(message), null);\n return;\n }\n\n if (this.socket) {\n this.socket.emit(BridgeEvent.Call, {\n id,\n method: call.method,\n args: call.args,\n });\n call.callTime = Date.now();\n }\n }\n\n async call<T = any>(\n method: string,\n args: any[],\n timeout = BridgeCallTimeout,\n ): Promise<T> {\n const id = `${this.callId++}`;\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n logMsg(`bridge call timeout, id=${id}, method=${method}, args=`, args);\n this.calls[id].error = new Error(\n `Bridge call timeout after ${timeout}ms: ${method}`,\n );\n reject(this.calls[id].error);\n }, timeout);\n\n this.calls[id] = {\n method,\n args,\n response: null,\n callTime: 0,\n responseTime: 0,\n callback: (error: Error | undefined, response: any) => {\n clearTimeout(timeoutId);\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n },\n };\n\n this.emitCall(id);\n });\n }\n\n // do NOT restart after close\n async close() {\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n const closeProcess = this.io?.close();\n this.io = null;\n\n return closeProcess;\n }\n}\n"],"names":["killRunningServer","port","client","ClientIO","DefaultBridgeServerPort","BridgeSignalKill","sleep","e","BridgeServer","opts","timeout","Promise","resolve","reject","Error","setTimeout","BridgeErrorCodeNoClientConnected","logMsg","Server","err","socket","next","url","console","clearTimeout","BridgeEvent","clientVersion","params","id","response","error","reason","_this","_this_io","call","errorMessage","payload","__VERSION__","undefined","Date","message","method","args","BridgeCallTimeout","timeoutId","closeProcess","onConnect","onDisconnect","closeConflictServer"],"mappings":";;;;;;;;;;;;;;;AAkBO,MAAMA,oBAAoB,OAAOC;IACtC,IAAI;QACF,MAAMC,SAASC,GACb,CAAC,eAAe,EAAEF,QAAQG,yBAAyB,EACnD;YACE,OAAO;gBACL,CAACC,iBAAiB,EAAE;YACtB;QACF;QAEF,MAAMC,MAAM;QACZ,MAAMJ,OAAO,KAAK;IACpB,EAAE,OAAOK,GAAG,CAEZ;AACF;AAGO,MAAMC;IAmBX,MAAM,OACJC,OAEI,CAAC,CAAC,EACS;QACf,MAAM,EAAEC,UAAU,KAAK,EAAE,GAAGD;QAE5B,IAAI,IAAI,CAAC,mBAAmB,EAC1B,MAAMT,kBAAkB,IAAI,CAAC,IAAI;QAGnC,OAAO,IAAIW,QAAQ,CAACC,SAASC;YAC3B,IAAI,IAAI,CAAC,kBAAkB,EACzB,OAAOA,OAAO,IAAIC,MAAM;YAE1B,IAAI,CAAC,kBAAkB,GAAG;YAE1B,IAAI,CAAC,kBAAkB,GAAGJ,UACtBK,WAAW;gBACTF,OACE,IAAIC,MACF,CAAC,6BAA6B,EAAEJ,QAAQ,IAAI,EAAEM,iCAAiC,CAAC,CAAC;YAGvF,GAAGN,WACH;YAEJ,IAAI,CAAC,kBAAkB,GACrB,CAACA,WAAWA,UAAU,OAClBK,WAAW;gBACTE,OAAO;YACT,GAAG,QACH;YACN,IAAI,CAAC,EAAE,GAAG,IAAIC,OAAO,IAAI,CAAC,IAAI,EAAE;gBAC9B,mBAAmB;YACrB;YAGA,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa;gBACnCN;YACF;YAEA,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAACO;gBAChCN,OAAO,IAAIC,MAAM,CAAC,wBAAwB,EAAEK,IAAI,OAAO,EAAE;YAC3D;YAEA,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAACC,QAAQC;gBACnB,IAAI,IAAI,CAAC,MAAM,EACbA,KAAK,IAAIP,MAAM;gBAEjBO;YACF;YAEA,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAACD;gBAExB,MAAME,MAAMF,OAAO,SAAS,CAAC,GAAG;gBAChC,IAAIE,IAAI,QAAQ,CAACjB,mBAAmB;oBAClCkB,QAAQ,IAAI,CAAC;oBACb,OAAO,IAAI,CAAC,KAAK;gBACnB;gBAEA,IAAI,CAAC,cAAc,GAAG;gBACtB,IAAI,CAAC,oBAAoB,GAAG;gBAC5B,IAAI,CAAC,kBAAkB,IAAIC,aAAa,IAAI,CAAC,kBAAkB;gBAC/D,IAAI,CAAC,kBAAkB,GAAG;gBAC1B,IAAI,CAAC,kBAAkB,IAAIA,aAAa,IAAI,CAAC,kBAAkB;gBAC/D,IAAI,CAAC,kBAAkB,GAAG;gBAC1B,IAAI,IAAI,CAAC,MAAM,EAAE;oBACfJ,OAAO,IAAI,CAACK,YAAY,OAAO;oBAE/BL,OAAO,UAAU;oBAEjB,OAAOP,OACL,IAAIC,MAAM;gBAEd;gBAEA,IAAI;oBACFG,OAAO;oBACP,IAAI,CAAC,MAAM,GAAGG;oBAEd,MAAMM,gBAAgBN,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO;oBACpDH,OACE,qEAA6ES,eAAe;oBAG9FN,OAAO,EAAE,CAACK,YAAY,YAAY,EAAE,CAACE;wBACnC,MAAMC,KAAKD,OAAO,EAAE;wBACpB,MAAME,WAAWF,OAAO,QAAQ;wBAChC,MAAMG,QAAQH,OAAO,KAAK;wBAE1B,IAAI,CAAC,2BAA2B,CAACC,IAAIE,OAAOD;oBAC9C;oBAEAT,OAAO,EAAE,CAAC,cAAc,CAACW;4BAwBvBC,oBAAAA;wBAvBA,IAAI,CAAC,cAAc,GAAG;wBACtB,IAAI,CAAC,oBAAoB,GAAGD;wBAE5B,IAAI;gCACFE;oCAAAA,CAAAA,WAAAA,IAAI,CAAC,EAAE,AAAD,KAANA,SAAS,KAAK;wBAChB,EAAE,OAAO1B,GAAG,CAEZ;wBAGA,IAAK,MAAMqB,MAAM,IAAI,CAAC,KAAK,CAAE;4BAC3B,MAAMM,OAAO,IAAI,CAAC,KAAK,CAACN,GAAG;4BAE3B,IAAI,CAACM,KAAK,YAAY,EAAE;gCACtB,MAAMC,eAAe,IAAI,CAAC,sBAAsB;gCAChD,IAAI,CAAC,2BAA2B,CAC9BP,IACA,IAAId,MAAMqB,eACV;4BAEJ;wBACF;gCAEAH,CAAAA,qBAAAA,AAAAA,CAAAA,QAAAA,IAAI,AAAD,EAAE,YAAY,AAAD,KAAhBA,mBAAAA,IAAAA,CAAAA,OAAoBD;oBACtB;oBAEAhB,WAAW;4BACTiB,iBAAAA;gCAAAA,CAAAA,kBAAAA,AAAAA,CAAAA,QAAAA,IAAI,AAAD,EAAE,SAAS,AAAD,KAAbA,gBAAAA,IAAAA,CAAAA;wBAEA,MAAMI,UAAU;4BACd,SAASC;wBACX;wBACAjB,OAAO,IAAI,CAACK,YAAY,SAAS,EAAEW;wBACnCzB,QAAQ,OAAO,GAAG,IAAI,CAAC;4BACrB,IAAK,MAAMiB,MAAM,IAAI,CAAC,KAAK,CACzB,IAAI,AAA4B,MAA5B,IAAI,CAAC,KAAK,CAACA,GAAG,CAAC,QAAQ,EACzB,IAAI,CAAC,QAAQ,CAACA;wBAGpB;oBACF,GAAG;gBACL,EAAE,OAAOrB,GAAG;oBACVgB,QAAQ,KAAK,CAAC,qCAAqChB;oBACnDM,OAAON;gBACT;YACF;YAEA,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS;gBAClB,IAAI,CAAC,KAAK;YACZ;QACF;IACF;IAMA,MAAc,4BACZqB,EAAmB,EACnBE,KAAmB,EACnBD,QAAa,EACb;QACA,MAAMK,OAAO,IAAI,CAAC,KAAK,CAACN,GAAG;QAC3B,IAAI,CAACM,MACH,MAAM,IAAIpB,MAAM,CAAC,KAAK,EAAEc,GAAG,UAAU,CAAC;QAExCM,KAAK,KAAK,GAAGJ,SAASQ;QACtBJ,KAAK,QAAQ,GAAGL;QAChBK,KAAK,YAAY,GAAGK,KAAK,GAAG;QAE5BL,KAAK,QAAQ,CAACA,KAAK,KAAK,EAAEL;IAC5B;IAEA,MAAc,SAASD,EAAU,EAAE;QACjC,MAAMM,OAAO,IAAI,CAAC,KAAK,CAACN,GAAG;QAC3B,IAAI,CAACM,MACH,MAAM,IAAIpB,MAAM,CAAC,KAAK,EAAEc,GAAG,UAAU,CAAC;QAGxC,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,MAAMY,UAAU,CAAC,yBAAyB,EAAE,IAAI,CAAC,oBAAoB,EAAE;YACvEN,KAAK,QAAQ,CAAC,IAAIpB,MAAM0B,UAAU;YAClC;QACF;QAEA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAACf,YAAY,IAAI,EAAE;gBACjCG;gBACA,QAAQM,KAAK,MAAM;gBACnB,MAAMA,KAAK,IAAI;YACjB;YACAA,KAAK,QAAQ,GAAGK,KAAK,GAAG;QAC1B;IACF;IAEA,MAAM,KACJE,MAAc,EACdC,IAAW,EACXhC,UAAUiC,iBAAiB,EACf;QACZ,MAAMf,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI;QAE7B,OAAO,IAAIjB,QAAQ,CAACC,SAASC;YAC3B,MAAM+B,YAAY7B,WAAW;gBAC3BE,OAAO,CAAC,wBAAwB,EAAEW,GAAG,SAAS,EAAEa,OAAO,OAAO,CAAC,EAAEC;gBACjE,IAAI,CAAC,KAAK,CAACd,GAAG,CAAC,KAAK,GAAG,IAAId,MACzB,CAAC,0BAA0B,EAAEJ,QAAQ,IAAI,EAAE+B,QAAQ;gBAErD5B,OAAO,IAAI,CAAC,KAAK,CAACe,GAAG,CAAC,KAAK;YAC7B,GAAGlB;YAEH,IAAI,CAAC,KAAK,CAACkB,GAAG,GAAG;gBACfa;gBACAC;gBACA,UAAU;gBACV,UAAU;gBACV,cAAc;gBACd,UAAU,CAACZ,OAA0BD;oBACnCL,aAAaoB;oBACb,IAAId,OACFjB,OAAOiB;yBAEPlB,QAAQiB;gBAEZ;YACF;YAEA,IAAI,CAAC,QAAQ,CAACD;QAChB;IACF;IAGA,MAAM,QAAQ;YAGSK;QAFrB,IAAI,CAAC,kBAAkB,IAAIT,aAAa,IAAI,CAAC,kBAAkB;QAC/D,IAAI,CAAC,kBAAkB,IAAIA,aAAa,IAAI,CAAC,kBAAkB;QAC/D,MAAMqB,eAAe,QAAAZ,CAAAA,WAAAA,IAAI,CAAC,EAAE,AAAD,IAANA,KAAAA,IAAAA,SAAS,KAAK;QACnC,IAAI,CAAC,EAAE,GAAG;QAEV,OAAOY;IACT;IAjPA,YACS5C,IAAY,EACZ6C,SAAsB,EACtBC,YAAuC,EACvCC,mBAA6B,CACpC;;;;;QAhBF,uBAAQ,UAAR;QACA,uBAAQ,MAAR;QACA,uBAAQ,UAAR;QACA,uBAAQ,sBAAR;QACA,uBAAQ,sBAAR;QACA,uBAAQ,sBAAR;QACA,uBAAO,SAAP;QAEA,uBAAQ,kBAAR;QACA,uBAAQ,wBAAR;QA6JA,uBAAQ,0BAAR;aA1JS/C,IAAI,GAAJA;aACA6C,SAAS,GAATA;aACAC,YAAY,GAAZA;aACAC,mBAAmB,GAAnBA;aAfD,MAAM,GAAG;aACT,EAAE,GAAkB;aACpB,MAAM,GAAwB;aAC9B,kBAAkB,GAA0B;aAC5C,kBAAkB,GAAG;aACrB,kBAAkB,GAA0B;aAC7C,KAAK,GAA+B,CAAC;aAEpC,cAAc,GAAG;aACjB,oBAAoB,GAAG;aA6JvB,sBAAsB,GAAG,IACxB,CAAC,yBAAyB,EAAE,IAAI,CAAC,oBAAoB,EAAE;IAvJ7D;AA6OL"}
|
|
@@ -44,7 +44,7 @@ class ExtensionBridgePageBrowserSide extends page {
|
|
|
44
44
|
}
|
|
45
45
|
}, ()=>this.destroy());
|
|
46
46
|
await this.bridgeClient.connect();
|
|
47
|
-
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v0.27.3
|
|
47
|
+
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v0.27.3`, 'log');
|
|
48
48
|
}
|
|
49
49
|
async connect() {
|
|
50
50
|
return await this.setupBridgeClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-mode/page-browser-side.mjs","sources":["webpack://@midscene/web/./src/bridge-mode/page-browser-side.ts"],"sourcesContent":["import type {\n ChromePageDestroyOptions,\n KeyboardAction,\n MouseAction,\n} from '@midscene/core/device';\nimport { assert } from '@midscene/shared/utils';\nimport ChromeExtensionProxyPage from '../chrome-extension/page';\nimport {\n type BridgeConnectTabOptions,\n BridgeEvent,\n DefaultBridgeServerPort,\n KeyboardEvent,\n MouseEvent,\n} from './common';\nimport { BridgeClient } from './io-client';\n\ndeclare const __VERSION__: string;\n\nexport class ExtensionBridgePageBrowserSide extends ChromeExtensionProxyPage {\n public bridgeClient: BridgeClient | null = null;\n\n private destroyOptions?: ChromePageDestroyOptions;\n\n private newlyCreatedTabIds: number[] = [];\n\n constructor(\n public onDisconnect: () => void = () => {},\n public onLogMessage: (\n message: string,\n type: 'log' | 'status',\n ) => void = () => {},\n forceSameTabNavigation = true,\n ) {\n super(forceSameTabNavigation);\n }\n\n private async setupBridgeClient() {\n this.bridgeClient = new BridgeClient(\n `ws://localhost:${DefaultBridgeServerPort}`,\n async (method, args: any[]) => {\n console.log('bridge call from cli side', method, args);\n if (method === BridgeEvent.ConnectNewTabWithUrl) {\n return this.connectNewTabWithUrl.apply(\n this,\n args as unknown as [string],\n );\n }\n\n if (method === BridgeEvent.GetBrowserTabList) {\n return this.getBrowserTabList.apply(this, args as any);\n }\n\n if (method === BridgeEvent.SetActiveTabId) {\n return this.setActiveTabId.apply(this, args as any);\n }\n\n if (method === BridgeEvent.ConnectCurrentTab) {\n return this.connectCurrentTab.apply(this, args as any);\n }\n\n if (method === BridgeEvent.UpdateAgentStatus) {\n return this.onLogMessage(args[0] as string, 'status');\n }\n\n const tabId = await this.getActiveTabId();\n if (!tabId || tabId === 0) {\n throw new Error('no tab is connected');\n }\n\n // this.onLogMessage(`calling method: ${method}`);\n\n if (method.startsWith(MouseEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof MouseAction;\n if (actionName === 'drag') {\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n\n if (method.startsWith(KeyboardEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof KeyboardAction;\n if (actionName === 'press') {\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n\n try {\n // @ts-expect-error\n const result = await this[method as keyof ChromeExtensionProxyPage](\n ...args,\n );\n return result;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : 'Unknown error';\n console.error('error calling method', method, args, e);\n this.onLogMessage(\n `Error calling method: ${method}, ${errorMessage}`,\n 'log',\n );\n throw new Error(errorMessage, { cause: e });\n }\n },\n // on disconnect\n () => {\n return this.destroy();\n },\n );\n await this.bridgeClient.connect();\n this.onLogMessage(\n `Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v${__VERSION__}`,\n 'log',\n );\n }\n\n public async connect() {\n return await this.setupBridgeClient();\n }\n\n public async connectNewTabWithUrl(\n url: string,\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tab = await chrome.tabs.create({ url });\n const tabId = tab.id;\n assert(tabId, 'failed to get tabId after creating a new tab');\n\n // new tab\n this.onLogMessage(`Creating new tab: ${url}`, 'log');\n this.newlyCreatedTabIds.push(tabId);\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async connectCurrentTab(\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tabs = await chrome.tabs.query({ active: true, currentWindow: true });\n const tabId = tabs[0]?.id;\n assert(tabId, 'failed to get tabId');\n\n this.onLogMessage(`Connected to current tab: ${tabs[0]?.url}`, 'log');\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async setDestroyOptions(options: ChromePageDestroyOptions) {\n this.destroyOptions = options;\n }\n\n async destroy() {\n if (this.destroyOptions?.closeTab && this.newlyCreatedTabIds.length > 0) {\n this.onLogMessage('Closing all newly created tabs by bridge...', 'log');\n for (const tabId of this.newlyCreatedTabIds) {\n await chrome.tabs.remove(tabId);\n }\n this.newlyCreatedTabIds = [];\n }\n\n await super.destroy();\n\n if (this.bridgeClient) {\n this.bridgeClient.disconnect();\n this.bridgeClient = null;\n this.onDisconnect();\n }\n }\n}\n"],"names":["ExtensionBridgePageBrowserSide","ChromeExtensionProxyPage","BridgeClient","DefaultBridgeServerPort","method","args","console","BridgeEvent","tabId","Error","MouseEvent","actionName","KeyboardEvent","result","e","errorMessage","url","options","tab","chrome","assert","_tabs_","_tabs_1","tabs","_this_destroyOptions","onDisconnect","onLogMessage","forceSameTabNavigation"],"mappings":";;;;;;;;;;;;;;AAkBO,MAAMA,uCAAuCC;IAkBlD,MAAc,oBAAoB;QAChC,IAAI,CAAC,YAAY,GAAG,IAAIC,aACtB,CAAC,eAAe,EAAEC,yBAAyB,EAC3C,OAAOC,QAAQC;YACbC,QAAQ,GAAG,CAAC,6BAA6BF,QAAQC;YACjD,IAAID,WAAWG,YAAY,oBAAoB,EAC7C,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CACpC,IAAI,EACJF;YAIJ,IAAID,WAAWG,YAAY,iBAAiB,EAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAEF;YAG5C,IAAID,WAAWG,YAAY,cAAc,EACvC,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAEF;YAGzC,IAAID,WAAWG,YAAY,iBAAiB,EAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAEF;YAG5C,IAAID,WAAWG,YAAY,iBAAiB,EAC1C,OAAO,IAAI,CAAC,YAAY,CAACF,IAAI,CAAC,EAAE,EAAY;YAG9C,MAAMG,QAAQ,MAAM,IAAI,CAAC,cAAc;YACvC,IAAI,CAACA,SAASA,AAAU,MAAVA,OACZ,MAAM,IAAIC,MAAM;YAKlB,IAAIL,OAAO,UAAU,CAACM,WAAW,MAAM,GAAG;gBACxC,MAAMC,aAAaP,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE;gBAIvC,OAAO,IAAI,CAAC,KAAK,CAACO,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAEN;YAClD;YAEA,IAAID,OAAO,UAAU,CAACQ,cAAc,MAAM,GAAG;gBAC3C,MAAMD,aAAaP,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE;gBAIvC,OAAO,IAAI,CAAC,QAAQ,CAACO,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAEN;YACxD;YAEA,IAAI;gBAEF,MAAMQ,SAAS,MAAM,IAAI,CAACT,OAAyC,IAC9DC;gBAEL,OAAOQ;YACT,EAAE,OAAOC,GAAG;gBACV,MAAMC,eAAeD,aAAaL,QAAQK,EAAE,OAAO,GAAG;gBACtDR,QAAQ,KAAK,CAAC,wBAAwBF,QAAQC,MAAMS;gBACpD,IAAI,CAAC,YAAY,CACf,CAAC,sBAAsB,EAAEV,OAAO,EAAE,EAAEW,cAAc,EAClD;gBAEF,MAAM,IAAIN,MAAMM,cAAc;oBAAE,OAAOD;gBAAE;YAC3C;QACF,GAEA,IACS,IAAI,CAAC,OAAO;QAGvB,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO;QAC/B,IAAI,CAAC,YAAY,CACf,uCAAuC,IAAI,CAAC,YAAY,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"bridge-mode/page-browser-side.mjs","sources":["webpack://@midscene/web/./src/bridge-mode/page-browser-side.ts"],"sourcesContent":["import type {\n ChromePageDestroyOptions,\n KeyboardAction,\n MouseAction,\n} from '@midscene/core/device';\nimport { assert } from '@midscene/shared/utils';\nimport ChromeExtensionProxyPage from '../chrome-extension/page';\nimport {\n type BridgeConnectTabOptions,\n BridgeEvent,\n DefaultBridgeServerPort,\n KeyboardEvent,\n MouseEvent,\n} from './common';\nimport { BridgeClient } from './io-client';\n\ndeclare const __VERSION__: string;\n\nexport class ExtensionBridgePageBrowserSide extends ChromeExtensionProxyPage {\n public bridgeClient: BridgeClient | null = null;\n\n private destroyOptions?: ChromePageDestroyOptions;\n\n private newlyCreatedTabIds: number[] = [];\n\n constructor(\n public onDisconnect: () => void = () => {},\n public onLogMessage: (\n message: string,\n type: 'log' | 'status',\n ) => void = () => {},\n forceSameTabNavigation = true,\n ) {\n super(forceSameTabNavigation);\n }\n\n private async setupBridgeClient() {\n this.bridgeClient = new BridgeClient(\n `ws://localhost:${DefaultBridgeServerPort}`,\n async (method, args: any[]) => {\n console.log('bridge call from cli side', method, args);\n if (method === BridgeEvent.ConnectNewTabWithUrl) {\n return this.connectNewTabWithUrl.apply(\n this,\n args as unknown as [string],\n );\n }\n\n if (method === BridgeEvent.GetBrowserTabList) {\n return this.getBrowserTabList.apply(this, args as any);\n }\n\n if (method === BridgeEvent.SetActiveTabId) {\n return this.setActiveTabId.apply(this, args as any);\n }\n\n if (method === BridgeEvent.ConnectCurrentTab) {\n return this.connectCurrentTab.apply(this, args as any);\n }\n\n if (method === BridgeEvent.UpdateAgentStatus) {\n return this.onLogMessage(args[0] as string, 'status');\n }\n\n const tabId = await this.getActiveTabId();\n if (!tabId || tabId === 0) {\n throw new Error('no tab is connected');\n }\n\n // this.onLogMessage(`calling method: ${method}`);\n\n if (method.startsWith(MouseEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof MouseAction;\n if (actionName === 'drag') {\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n\n if (method.startsWith(KeyboardEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof KeyboardAction;\n if (actionName === 'press') {\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n\n try {\n // @ts-expect-error\n const result = await this[method as keyof ChromeExtensionProxyPage](\n ...args,\n );\n return result;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : 'Unknown error';\n console.error('error calling method', method, args, e);\n this.onLogMessage(\n `Error calling method: ${method}, ${errorMessage}`,\n 'log',\n );\n throw new Error(errorMessage, { cause: e });\n }\n },\n // on disconnect\n () => {\n return this.destroy();\n },\n );\n await this.bridgeClient.connect();\n this.onLogMessage(\n `Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v${__VERSION__}`,\n 'log',\n );\n }\n\n public async connect() {\n return await this.setupBridgeClient();\n }\n\n public async connectNewTabWithUrl(\n url: string,\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tab = await chrome.tabs.create({ url });\n const tabId = tab.id;\n assert(tabId, 'failed to get tabId after creating a new tab');\n\n // new tab\n this.onLogMessage(`Creating new tab: ${url}`, 'log');\n this.newlyCreatedTabIds.push(tabId);\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async connectCurrentTab(\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tabs = await chrome.tabs.query({ active: true, currentWindow: true });\n const tabId = tabs[0]?.id;\n assert(tabId, 'failed to get tabId');\n\n this.onLogMessage(`Connected to current tab: ${tabs[0]?.url}`, 'log');\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async setDestroyOptions(options: ChromePageDestroyOptions) {\n this.destroyOptions = options;\n }\n\n async destroy() {\n if (this.destroyOptions?.closeTab && this.newlyCreatedTabIds.length > 0) {\n this.onLogMessage('Closing all newly created tabs by bridge...', 'log');\n for (const tabId of this.newlyCreatedTabIds) {\n await chrome.tabs.remove(tabId);\n }\n this.newlyCreatedTabIds = [];\n }\n\n await super.destroy();\n\n if (this.bridgeClient) {\n this.bridgeClient.disconnect();\n this.bridgeClient = null;\n this.onDisconnect();\n }\n }\n}\n"],"names":["ExtensionBridgePageBrowserSide","ChromeExtensionProxyPage","BridgeClient","DefaultBridgeServerPort","method","args","console","BridgeEvent","tabId","Error","MouseEvent","actionName","KeyboardEvent","result","e","errorMessage","url","options","tab","chrome","assert","_tabs_","_tabs_1","tabs","_this_destroyOptions","onDisconnect","onLogMessage","forceSameTabNavigation"],"mappings":"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"}
|
|
@@ -346,7 +346,7 @@ class ChromeExtensionProxyPage {
|
|
|
346
346
|
constructor(forceSameTabNavigation){
|
|
347
347
|
_define_property(this, "pageType", 'chrome-extension-proxy');
|
|
348
348
|
_define_property(this, "forceSameTabNavigation", void 0);
|
|
349
|
-
_define_property(this, "version", "0.27.3
|
|
349
|
+
_define_property(this, "version", "0.27.3");
|
|
350
350
|
_define_property(this, "viewportSize", void 0);
|
|
351
351
|
_define_property(this, "activeTabId", null);
|
|
352
352
|
_define_property(this, "tabIdOfDebuggerAttached", null);
|
|
@@ -216,20 +216,10 @@ class PlaygroundServer {
|
|
|
216
216
|
} else {
|
|
217
217
|
const actualPrompt = prompt || (null == params ? void 0 : params.prompt);
|
|
218
218
|
if (!actualPrompt) throw new Error(`Missing prompt for ${type}`);
|
|
219
|
-
if ('
|
|
220
|
-
else if ('aiAction' === type) response.result = await agent.aiAction(actualPrompt);
|
|
221
|
-
else if ('aiAssert' === type) response.result = await agent.aiAssert(actualPrompt, void 0, {
|
|
219
|
+
if ('aiAssert' === type) response.result = await agent.aiAssert(actualPrompt, void 0, {
|
|
222
220
|
keepRawResponse: true
|
|
223
221
|
});
|
|
224
|
-
else if ('
|
|
225
|
-
else if ('aiNumber' === type) response.result = await agent.aiNumber(actualPrompt);
|
|
226
|
-
else if ('aiString' === type) response.result = await agent.aiString(actualPrompt);
|
|
227
|
-
else if ('aiAsk' === type) response.result = await agent.aiAsk(actualPrompt);
|
|
228
|
-
else if ('aiWaitFor' === type) response.result = await agent.aiWaitFor(actualPrompt, {
|
|
229
|
-
timeoutMs: 15000,
|
|
230
|
-
checkIntervalMs: 3000
|
|
231
|
-
});
|
|
232
|
-
else if ('aiLocate' === type) response.result = await agent.aiLocate(actualPrompt, {
|
|
222
|
+
else if (agent && 'function' == typeof agent[type]) response.result = await agent[type](actualPrompt, {
|
|
233
223
|
deepThink
|
|
234
224
|
});
|
|
235
225
|
else response.error = `Unknown type: ${type}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground/server.mjs","sources":["webpack://@midscene/web/./src/playground/server.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport type { Server } from 'node:http';\nimport { join } from 'node:path';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { getTmpDir } from '@midscene/core/utils';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport express from 'express';\n\nconst defaultPort = PLAYGROUND_SERVER_PORT;\n// const staticPath = join(__dirname, '../../static');\n\nconst errorHandler = (err: any, req: any, res: any, next: any) => {\n console.error(err);\n res.status(500).json({\n error: err.message,\n });\n};\n\nconst setup = async () => {\n if (!ifInBrowser && !ifInWorker) {\n dotenv.config();\n }\n};\n\nexport default class PlaygroundServer {\n app: express.Application;\n tmpDir: string;\n server?: Server;\n port?: number | null;\n pageClass: new (\n ...args: any[]\n ) => AbstractPage;\n agentClass: new (\n ...args: any[]\n ) => PageAgent;\n staticPath?: string;\n taskProgressTips: Record<string, string>;\n activeAgents: Record<string, PageAgent>;\n\n constructor(\n pageClass: new (...args: any[]) => AbstractPage,\n agentClass: new (...args: any[]) => PageAgent,\n staticPath?: string,\n ) {\n this.app = express();\n this.tmpDir = getTmpDir()!;\n this.pageClass = pageClass;\n this.agentClass = agentClass;\n this.staticPath = staticPath;\n this.taskProgressTips = {};\n this.activeAgents = {};\n setup();\n }\n\n filePathForUuid(uuid: string) {\n return join(this.tmpDir, `${uuid}.json`);\n }\n\n saveContextFile(uuid: string, context: string) {\n const tmpFile = this.filePathForUuid(uuid);\n console.log(`save context file: ${tmpFile}`);\n writeFileSync(tmpFile, context);\n return tmpFile;\n }\n\n async launch(port?: number) {\n this.port = port || defaultPort;\n this.app.use(errorHandler);\n\n this.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n );\n\n this.app.get('/status', cors(), async (req, res) => {\n // const modelName = g\n res.send({\n status: 'ok',\n });\n });\n\n // this.app.get('/playground/:uuid', async (req, res) => {\n // res.sendFile(join(staticPath, 'index.html'));\n // });\n\n this.app.get('/context/:uuid', async (req, res) => {\n const { uuid } = req.params;\n const contextFile = this.filePathForUuid(uuid);\n\n if (!existsSync(contextFile)) {\n return res.status(404).json({\n error: 'Context not found',\n });\n }\n\n const context = readFileSync(contextFile, 'utf8');\n res.json({\n context,\n });\n });\n\n this.app.get('/task-progress/:requestId', cors(), async (req, res) => {\n const { requestId } = req.params;\n res.json({\n tip: this.taskProgressTips[requestId] || '',\n });\n });\n\n // -------------------------\n // actions from report file\n this.app.post(\n '/playground-with-context',\n express.json({ limit: '50mb' }),\n async (req, res) => {\n const context = req.body.context;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n const uuid = randomUUID();\n this.saveContextFile(uuid, context);\n return res.json({\n location: `/playground/${uuid}`,\n uuid,\n });\n },\n );\n\n this.app.post(\n '/execute',\n express.json({ limit: '30mb' }),\n async (req, res) => {\n const { context, type, prompt, params, requestId, deepThink } =\n req.body;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n if (!type) {\n return res.status(400).json({\n error: 'type is required',\n });\n }\n\n if (!prompt && !params) {\n return res.status(400).json({\n error: 'prompt or params is required',\n });\n }\n\n // build an agent with context\n const page = new this.pageClass(context);\n const agent = new this.agentClass(page);\n\n if (requestId) {\n this.taskProgressTips[requestId] = '';\n this.activeAgents[requestId] = agent;\n\n agent.onTaskStartTip = (tip: string) => {\n this.taskProgressTips[requestId] = tip;\n };\n }\n\n const response: {\n result: any;\n dump: string | null;\n error: string | null;\n reportHTML: string | null;\n requestId?: string;\n } = {\n result: null,\n dump: null,\n error: null,\n reportHTML: null,\n requestId,\n };\n\n // Helper function to parse action parameters based on type\n const parseActionParams = (\n actionType: string,\n inputPrompt: string | undefined,\n inputParams: any | undefined,\n options: { deepThink?: boolean } = {},\n ): any[] => {\n // If structured params are provided, use them directly\n if (inputParams) {\n switch (actionType) {\n case 'aiInput': {\n if (!inputParams.value || !inputParams.locate) {\n throw new Error(\n 'aiInput requires both value and locate parameters',\n );\n }\n return [\n inputParams.locate,\n { value: inputParams.value, ...options },\n ];\n }\n\n case 'aiKeyboardPress': {\n if (!inputParams.keyName) {\n throw new Error('aiKeyboardPress requires keyName parameter');\n }\n return [\n inputParams.locate,\n { keyName: inputParams.keyName, ...options },\n ];\n }\n\n case 'aiScroll': {\n if (!inputParams.direction || !inputParams.distance) {\n throw new Error(\n 'aiScroll requires direction and distance parameters',\n );\n }\n const scrollParam = {\n direction: inputParams.direction as\n | 'up'\n | 'down'\n | 'left'\n | 'right',\n scrollType: inputParams.scrollType || 'once',\n distance: inputParams.distance,\n ...options,\n };\n return [inputParams.locate, scrollParam];\n }\n\n default:\n // For other actions that only need locate prompt\n return [\n inputParams.locate || inputParams.prompt || inputPrompt,\n options,\n ];\n }\n }\n\n // Fallback to legacy prompt parsing for backward compatibility\n if (!inputPrompt) {\n throw new Error(`Missing prompt for ${actionType}`);\n }\n\n switch (actionType) {\n case 'aiInput': {\n const inputParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n if (inputParts.length !== 2) {\n throw new Error('aiInput requires format: \"value | element\"');\n }\n return [inputParts[1], { value: inputParts[0], ...options }];\n }\n\n case 'aiKeyboardPress': {\n const keyParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const keyName = keyParts[0];\n const keyElement = keyParts[1] || undefined;\n return [keyElement, { keyName, ...options }];\n }\n\n case 'aiScroll': {\n const scrollParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const scrollArgs = scrollParts[0]\n .split(' ')\n .map((s: string) => s.trim());\n\n if (scrollArgs.length < 2) {\n throw new Error(\n 'aiScroll requires format: \"direction amount | element (optional)\"',\n );\n }\n\n const direction = scrollArgs[0] as\n | 'up'\n | 'down'\n | 'left'\n | 'right';\n const amount = Number.parseInt(scrollArgs[1]);\n const scrollElement = scrollParts[1] || undefined;\n\n const scrollParam = {\n direction,\n scrollType: 'once' as const,\n distance: amount,\n ...options,\n };\n\n return [scrollElement, scrollParam];\n }\n\n default:\n return [inputPrompt, options];\n }\n };\n\n const startTime = Date.now();\n try {\n // Get action space to check for dynamic actions\n const actionSpace = await agent.getActionSpace();\n\n // Check if this is an action in the actionSpace\n const action = actionSpace.find(\n (action) => action.interfaceAlias === type || action.name === type,\n );\n\n if (\n action?.interfaceAlias &&\n typeof (agent as any)[action.interfaceAlias] === 'function'\n ) {\n // Use actionSpace method dynamically\n const parsedParams = parseActionParams(type, prompt, params, {\n deepThink,\n });\n response.result = await (agent as any)[action.interfaceAlias](\n ...parsedParams,\n );\n } else {\n // Get the prompt from either prompt field or params.prompt\n const actualPrompt = prompt || params?.prompt;\n\n if (!actualPrompt) {\n throw new Error(`Missing prompt for ${type}`);\n }\n\n if (type === 'aiQuery') {\n response.result = await agent.aiQuery(actualPrompt);\n } else if (type === 'aiAction') {\n response.result = await agent.aiAction(actualPrompt);\n } else if (type === 'aiAssert') {\n response.result = await agent.aiAssert(actualPrompt, undefined, {\n keepRawResponse: true,\n });\n } else if (type === 'aiBoolean') {\n response.result = await agent.aiBoolean(actualPrompt);\n } else if (type === 'aiNumber') {\n response.result = await agent.aiNumber(actualPrompt);\n } else if (type === 'aiString') {\n response.result = await agent.aiString(actualPrompt);\n } else if (type === 'aiAsk') {\n response.result = await agent.aiAsk(actualPrompt);\n } else if (type === 'aiWaitFor') {\n response.result = await agent.aiWaitFor(actualPrompt, {\n timeoutMs: 15000,\n checkIntervalMs: 3000,\n });\n } else if (type === 'aiLocate') {\n response.result = await agent.aiLocate(actualPrompt, {\n deepThink,\n });\n } else {\n response.error = `Unknown type: ${type}`;\n }\n }\n } catch (error: any) {\n if (!error.message.includes(ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED)) {\n response.error = error.message;\n }\n }\n\n try {\n response.dump = JSON.parse(agent.dumpDataString());\n response.reportHTML = agent.reportHTMLString() || null;\n\n agent.writeOutActionDumps();\n agent.destroy();\n } catch (error: any) {\n console.error(\n `write out dump failed: requestId: ${requestId}, ${error.message}`,\n );\n }\n\n res.send(response);\n const timeCost = Date.now() - startTime;\n\n if (response.error) {\n console.error(\n `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`,\n );\n } else {\n console.log(\n `handle request done after ${timeCost}ms: requestId: ${requestId}`,\n );\n }\n\n // Clean up the agent from activeAgents after execution completes\n if (requestId && this.activeAgents[requestId]) {\n delete this.activeAgents[requestId];\n }\n },\n );\n\n this.app.get('/cancel/:requestId', async (req, res) => {\n const { requestId } = req.params;\n\n if (!requestId) {\n return res.status(400).json({\n error: 'requestId is required',\n });\n }\n\n const agent = this.activeAgents[requestId];\n if (!agent) {\n return res.status(404).json({\n error: 'No active agent found for this requestId',\n });\n }\n\n try {\n await agent.destroy();\n delete this.activeAgents[requestId];\n res.json({ status: 'cancelled' });\n } catch (error: any) {\n console.error(`Failed to cancel agent: ${error.message}`);\n res.status(500).json({\n error: `Failed to cancel: ${error.message}`,\n });\n }\n });\n\n this.app.post(\n '/config',\n express.json({ limit: '1mb' }),\n async (req, res) => {\n const { aiConfig } = req.body;\n\n if (!aiConfig || typeof aiConfig !== 'object') {\n return res.status(400).json({\n error: 'aiConfig is required and must be an object',\n });\n }\n\n try {\n overrideAIConfig(aiConfig);\n\n return res.json({\n status: 'ok',\n message: 'AI config updated successfully',\n });\n } catch (error: any) {\n console.error(`Failed to update AI config: ${error.message}`);\n return res.status(500).json({\n error: `Failed to update AI config: ${error.message}`,\n });\n }\n },\n );\n\n // Set up static file serving after all API routes are defined\n if (this.staticPath) {\n this.app.get('/', (req, res) => {\n // compatible with windows\n res.redirect('/index.html');\n });\n\n this.app.get('*', (req, res) => {\n const requestedPath = join(this.staticPath!, req.path);\n if (existsSync(requestedPath)) {\n res.sendFile(requestedPath);\n } else {\n res.sendFile(join(this.staticPath!, 'index.html'));\n }\n });\n }\n\n return new Promise((resolve, reject) => {\n const port = this.port;\n this.server = this.app.listen(port, () => {\n resolve(this);\n });\n });\n }\n\n close() {\n // close the server\n if (this.server) {\n return this.server.close();\n }\n }\n}\n"],"names":["defaultPort","PLAYGROUND_SERVER_PORT","errorHandler","err","req","res","next","console","setup","ifInBrowser","ifInWorker","dotenv","PlaygroundServer","uuid","join","context","tmpFile","writeFileSync","port","cors","contextFile","existsSync","readFileSync","requestId","express","randomUUID","type","prompt","params","deepThink","page","agent","tip","response","parseActionParams","actionType","inputPrompt","inputParams","options","Error","scrollParam","inputParts","s","keyParts","keyName","keyElement","undefined","scrollParts","scrollArgs","direction","amount","Number","scrollElement","startTime","Date","actionSpace","action","parsedParams","actualPrompt","error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","JSON","timeCost","aiConfig","overrideAIConfig","requestedPath","Promise","resolve","reject","pageClass","agentClass","staticPath","getTmpDir"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"playground/server.mjs","sources":["webpack://@midscene/web/./src/playground/server.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport type { Server } from 'node:http';\nimport { join } from 'node:path';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { getTmpDir } from '@midscene/core/utils';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport express from 'express';\n\nconst defaultPort = PLAYGROUND_SERVER_PORT;\n// const staticPath = join(__dirname, '../../static');\n\nconst errorHandler = (err: any, req: any, res: any, next: any) => {\n console.error(err);\n res.status(500).json({\n error: err.message,\n });\n};\n\nconst setup = async () => {\n if (!ifInBrowser && !ifInWorker) {\n dotenv.config();\n }\n};\n\nexport default class PlaygroundServer {\n app: express.Application;\n tmpDir: string;\n server?: Server;\n port?: number | null;\n pageClass: new (\n ...args: any[]\n ) => AbstractPage;\n agentClass: new (\n ...args: any[]\n ) => PageAgent;\n staticPath?: string;\n taskProgressTips: Record<string, string>;\n activeAgents: Record<string, PageAgent>;\n\n constructor(\n pageClass: new (...args: any[]) => AbstractPage,\n agentClass: new (...args: any[]) => PageAgent,\n staticPath?: string,\n ) {\n this.app = express();\n this.tmpDir = getTmpDir()!;\n this.pageClass = pageClass;\n this.agentClass = agentClass;\n this.staticPath = staticPath;\n this.taskProgressTips = {};\n this.activeAgents = {};\n setup();\n }\n\n filePathForUuid(uuid: string) {\n return join(this.tmpDir, `${uuid}.json`);\n }\n\n saveContextFile(uuid: string, context: string) {\n const tmpFile = this.filePathForUuid(uuid);\n console.log(`save context file: ${tmpFile}`);\n writeFileSync(tmpFile, context);\n return tmpFile;\n }\n\n async launch(port?: number) {\n this.port = port || defaultPort;\n this.app.use(errorHandler);\n\n this.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n );\n\n this.app.get('/status', cors(), async (req, res) => {\n // const modelName = g\n res.send({\n status: 'ok',\n });\n });\n\n // this.app.get('/playground/:uuid', async (req, res) => {\n // res.sendFile(join(staticPath, 'index.html'));\n // });\n\n this.app.get('/context/:uuid', async (req, res) => {\n const { uuid } = req.params;\n const contextFile = this.filePathForUuid(uuid);\n\n if (!existsSync(contextFile)) {\n return res.status(404).json({\n error: 'Context not found',\n });\n }\n\n const context = readFileSync(contextFile, 'utf8');\n res.json({\n context,\n });\n });\n\n this.app.get('/task-progress/:requestId', cors(), async (req, res) => {\n const { requestId } = req.params;\n res.json({\n tip: this.taskProgressTips[requestId] || '',\n });\n });\n\n // -------------------------\n // actions from report file\n this.app.post(\n '/playground-with-context',\n express.json({ limit: '50mb' }),\n async (req, res) => {\n const context = req.body.context;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n const uuid = randomUUID();\n this.saveContextFile(uuid, context);\n return res.json({\n location: `/playground/${uuid}`,\n uuid,\n });\n },\n );\n\n this.app.post(\n '/execute',\n express.json({ limit: '30mb' }),\n async (req, res) => {\n const { context, type, prompt, params, requestId, deepThink } =\n req.body;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n if (!type) {\n return res.status(400).json({\n error: 'type is required',\n });\n }\n\n if (!prompt && !params) {\n return res.status(400).json({\n error: 'prompt or params is required',\n });\n }\n\n // build an agent with context\n const page = new this.pageClass(context);\n const agent = new this.agentClass(page);\n\n if (requestId) {\n this.taskProgressTips[requestId] = '';\n this.activeAgents[requestId] = agent;\n\n agent.onTaskStartTip = (tip: string) => {\n this.taskProgressTips[requestId] = tip;\n };\n }\n\n const response: {\n result: any;\n dump: string | null;\n error: string | null;\n reportHTML: string | null;\n requestId?: string;\n } = {\n result: null,\n dump: null,\n error: null,\n reportHTML: null,\n requestId,\n };\n\n // Helper function to parse action parameters based on type\n const parseActionParams = (\n actionType: string,\n inputPrompt: string | undefined,\n inputParams: any | undefined,\n options: { deepThink?: boolean } = {},\n ): any[] => {\n // If structured params are provided, use them directly\n if (inputParams) {\n switch (actionType) {\n case 'aiInput': {\n if (!inputParams.value || !inputParams.locate) {\n throw new Error(\n 'aiInput requires both value and locate parameters',\n );\n }\n return [\n inputParams.locate,\n { value: inputParams.value, ...options },\n ];\n }\n\n case 'aiKeyboardPress': {\n if (!inputParams.keyName) {\n throw new Error('aiKeyboardPress requires keyName parameter');\n }\n return [\n inputParams.locate,\n { keyName: inputParams.keyName, ...options },\n ];\n }\n\n case 'aiScroll': {\n if (!inputParams.direction || !inputParams.distance) {\n throw new Error(\n 'aiScroll requires direction and distance parameters',\n );\n }\n const scrollParam = {\n direction: inputParams.direction as\n | 'up'\n | 'down'\n | 'left'\n | 'right',\n scrollType: inputParams.scrollType || 'once',\n distance: inputParams.distance,\n ...options,\n };\n return [inputParams.locate, scrollParam];\n }\n\n default:\n // For other actions that only need locate prompt\n return [\n inputParams.locate || inputParams.prompt || inputPrompt,\n options,\n ];\n }\n }\n\n // Fallback to legacy prompt parsing for backward compatibility\n if (!inputPrompt) {\n throw new Error(`Missing prompt for ${actionType}`);\n }\n\n switch (actionType) {\n case 'aiInput': {\n const inputParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n if (inputParts.length !== 2) {\n throw new Error('aiInput requires format: \"value | element\"');\n }\n return [inputParts[1], { value: inputParts[0], ...options }];\n }\n\n case 'aiKeyboardPress': {\n const keyParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const keyName = keyParts[0];\n const keyElement = keyParts[1] || undefined;\n return [keyElement, { keyName, ...options }];\n }\n\n case 'aiScroll': {\n const scrollParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const scrollArgs = scrollParts[0]\n .split(' ')\n .map((s: string) => s.trim());\n\n if (scrollArgs.length < 2) {\n throw new Error(\n 'aiScroll requires format: \"direction amount | element (optional)\"',\n );\n }\n\n const direction = scrollArgs[0] as\n | 'up'\n | 'down'\n | 'left'\n | 'right';\n const amount = Number.parseInt(scrollArgs[1]);\n const scrollElement = scrollParts[1] || undefined;\n\n const scrollParam = {\n direction,\n scrollType: 'once' as const,\n distance: amount,\n ...options,\n };\n\n return [scrollElement, scrollParam];\n }\n\n default:\n return [inputPrompt, options];\n }\n };\n\n const startTime = Date.now();\n try {\n // Get action space to check for dynamic actions\n const actionSpace = await agent.getActionSpace();\n\n // Check if this is an action in the actionSpace\n const action = actionSpace.find(\n (action) => action.interfaceAlias === type || action.name === type,\n );\n\n if (\n action?.interfaceAlias &&\n typeof (agent as any)[action.interfaceAlias] === 'function'\n ) {\n // Use actionSpace method dynamically\n const parsedParams = parseActionParams(type, prompt, params, {\n deepThink,\n });\n response.result = await (agent as any)[action.interfaceAlias](\n ...parsedParams,\n );\n } else {\n // Get the prompt from either prompt field or params.prompt\n const actualPrompt = prompt || params?.prompt;\n\n if (!actualPrompt) {\n throw new Error(`Missing prompt for ${type}`);\n }\n\n // special handle for methods that need custom parameters or return format\n if (type === 'aiAssert') {\n response.result = await agent.aiAssert(actualPrompt, undefined, {\n keepRawResponse: true,\n });\n } else if (agent && typeof (agent as any)[type] === 'function') {\n // for other methods, check if the agent has the method\n response.result = await (agent as any)[type](actualPrompt, {\n deepThink,\n });\n } else {\n response.error = `Unknown type: ${type}`;\n }\n }\n } catch (error: any) {\n if (!error.message.includes(ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED)) {\n response.error = error.message;\n }\n }\n\n try {\n response.dump = JSON.parse(agent.dumpDataString());\n response.reportHTML = agent.reportHTMLString() || null;\n\n agent.writeOutActionDumps();\n agent.destroy();\n } catch (error: any) {\n console.error(\n `write out dump failed: requestId: ${requestId}, ${error.message}`,\n );\n }\n\n res.send(response);\n const timeCost = Date.now() - startTime;\n\n if (response.error) {\n console.error(\n `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`,\n );\n } else {\n console.log(\n `handle request done after ${timeCost}ms: requestId: ${requestId}`,\n );\n }\n\n // Clean up the agent from activeAgents after execution completes\n if (requestId && this.activeAgents[requestId]) {\n delete this.activeAgents[requestId];\n }\n },\n );\n\n this.app.get('/cancel/:requestId', async (req, res) => {\n const { requestId } = req.params;\n\n if (!requestId) {\n return res.status(400).json({\n error: 'requestId is required',\n });\n }\n\n const agent = this.activeAgents[requestId];\n if (!agent) {\n return res.status(404).json({\n error: 'No active agent found for this requestId',\n });\n }\n\n try {\n await agent.destroy();\n delete this.activeAgents[requestId];\n res.json({ status: 'cancelled' });\n } catch (error: any) {\n console.error(`Failed to cancel agent: ${error.message}`);\n res.status(500).json({\n error: `Failed to cancel: ${error.message}`,\n });\n }\n });\n\n this.app.post(\n '/config',\n express.json({ limit: '1mb' }),\n async (req, res) => {\n const { aiConfig } = req.body;\n\n if (!aiConfig || typeof aiConfig !== 'object') {\n return res.status(400).json({\n error: 'aiConfig is required and must be an object',\n });\n }\n\n try {\n overrideAIConfig(aiConfig);\n\n return res.json({\n status: 'ok',\n message: 'AI config updated successfully',\n });\n } catch (error: any) {\n console.error(`Failed to update AI config: ${error.message}`);\n return res.status(500).json({\n error: `Failed to update AI config: ${error.message}`,\n });\n }\n },\n );\n\n // Set up static file serving after all API routes are defined\n if (this.staticPath) {\n this.app.get('/', (req, res) => {\n // compatible with windows\n res.redirect('/index.html');\n });\n\n this.app.get('*', (req, res) => {\n const requestedPath = join(this.staticPath!, req.path);\n if (existsSync(requestedPath)) {\n res.sendFile(requestedPath);\n } else {\n res.sendFile(join(this.staticPath!, 'index.html'));\n }\n });\n }\n\n return new Promise((resolve, reject) => {\n const port = this.port;\n this.server = this.app.listen(port, () => {\n resolve(this);\n });\n });\n }\n\n close() {\n // close the server\n if (this.server) {\n return this.server.close();\n }\n }\n}\n"],"names":["defaultPort","PLAYGROUND_SERVER_PORT","errorHandler","err","req","res","next","console","setup","ifInBrowser","ifInWorker","dotenv","PlaygroundServer","uuid","join","context","tmpFile","writeFileSync","port","cors","contextFile","existsSync","readFileSync","requestId","express","randomUUID","type","prompt","params","deepThink","page","agent","tip","response","parseActionParams","actionType","inputPrompt","inputParams","options","Error","scrollParam","inputParts","s","keyParts","keyName","keyElement","undefined","scrollParts","scrollArgs","direction","amount","Number","scrollElement","startTime","Date","actionSpace","action","parsedParams","actualPrompt","error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","JSON","timeCost","aiConfig","overrideAIConfig","requestedPath","Promise","resolve","reject","pageClass","agentClass","staticPath","getTmpDir"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { commonWebActionsForWebPage } from "@midscene/core/agent";
|
|
1
2
|
import { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from "@midscene/shared/common";
|
|
2
3
|
function _define_property(obj, key, value) {
|
|
3
4
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -14,7 +15,7 @@ const ThrowNotImplemented = (methodName)=>{
|
|
|
14
15
|
};
|
|
15
16
|
class StaticPage {
|
|
16
17
|
actionSpace() {
|
|
17
|
-
return
|
|
18
|
+
return commonWebActionsForWebPage(this);
|
|
18
19
|
}
|
|
19
20
|
async evaluateJavaScript(script) {
|
|
20
21
|
return ThrowNotImplemented('evaluateJavaScript');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground/static-page.mjs","sources":["webpack://@midscene/web/./src/playground/static-page.ts"],"sourcesContent":["import type { DeviceAction, Point, UIContext } from '@midscene/core';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport type { WebUIContext } from '../web-element';\n\nconst ThrowNotImplemented: any = (methodName: string) => {\n throw new Error(\n `The method \"${methodName}\" is not implemented as designed since this is a static UI context. (${ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED})`,\n );\n};\n\nexport default class StaticPage implements AbstractPage {\n pageType = 'static';\n\n private uiContext: WebUIContext;\n\n constructor(uiContext: WebUIContext) {\n if (uiContext.tree) {\n this.uiContext = uiContext;\n } else {\n this.uiContext = Object.assign(uiContext, {\n tree: {\n node: null,\n children: [],\n },\n });\n }\n }\n\n actionSpace(): DeviceAction[] {\n //
|
|
1
|
+
{"version":3,"file":"playground/static-page.mjs","sources":["webpack://@midscene/web/./src/playground/static-page.ts"],"sourcesContent":["import type { DeviceAction, Point, UIContext } from '@midscene/core';\nimport { commonWebActionsForWebPage } from '@midscene/core/agent';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport type { WebUIContext } from '../web-element';\n\nconst ThrowNotImplemented: any = (methodName: string) => {\n throw new Error(\n `The method \"${methodName}\" is not implemented as designed since this is a static UI context. (${ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED})`,\n );\n};\n\nexport default class StaticPage implements AbstractPage {\n pageType = 'static';\n\n private uiContext: WebUIContext;\n\n constructor(uiContext: WebUIContext) {\n if (uiContext.tree) {\n this.uiContext = uiContext;\n } else {\n this.uiContext = Object.assign(uiContext, {\n tree: {\n node: null,\n children: [],\n },\n });\n }\n }\n\n actionSpace(): DeviceAction[] {\n // Return common web actions for planning, but they won't actually execute\n return commonWebActionsForWebPage(this);\n }\n\n async evaluateJavaScript<T = any>(script: string): Promise<T> {\n return ThrowNotImplemented('evaluateJavaScript');\n }\n\n // @deprecated\n async getElementsInfo() {\n return ThrowNotImplemented('getElementsInfo');\n }\n\n async getElementsNodeTree() {\n return ThrowNotImplemented('getElementsNodeTree');\n }\n\n async getXpathsById(id: string) {\n return ThrowNotImplemented('getXpathsById');\n }\n\n async getXpathsByPoint(point: Point) {\n return ThrowNotImplemented('getXpathsByPoint');\n }\n\n async getElementInfoByXpath(xpath: string) {\n return ThrowNotImplemented('getElementInfoByXpath');\n }\n\n async size() {\n return this.uiContext.size;\n }\n\n async screenshotBase64() {\n const base64 = this.uiContext.screenshotBase64;\n if (!base64) {\n throw new Error('screenshot base64 is empty');\n }\n return base64;\n }\n\n async url() {\n return Promise.resolve(this.uiContext.url || '');\n }\n\n async scrollUntilTop(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilTop');\n }\n\n async scrollUntilBottom(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilBottom');\n }\n\n async scrollUntilLeft(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilLeft');\n }\n\n async scrollUntilRight(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilRight');\n }\n\n async scrollUp(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollUp');\n }\n\n async scrollDown(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollDown');\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollLeft');\n }\n\n async scrollRight(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollRight');\n }\n\n async clearInput() {\n return ThrowNotImplemented('clearInput');\n }\n\n mouse = {\n click: ThrowNotImplemented.bind(null, 'mouse.click'),\n wheel: ThrowNotImplemented.bind(null, 'mouse.wheel'),\n move: ThrowNotImplemented.bind(null, 'mouse.move'),\n drag: ThrowNotImplemented.bind(null, 'mouse.drag'),\n };\n\n keyboard = {\n type: ThrowNotImplemented.bind(null, 'keyboard.type'),\n press: ThrowNotImplemented.bind(null, 'keyboard.press'),\n };\n\n async destroy(): Promise<void> {\n //\n }\n\n async getContext(): Promise<UIContext> {\n return this.uiContext;\n }\n}\n"],"names":["ThrowNotImplemented","methodName","Error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","StaticPage","commonWebActionsForWebPage","script","id","point","xpath","base64","Promise","startingPoint","distance","uiContext","Object"],"mappings":";;;;;;;;;;;;AAMA,MAAMA,sBAA2B,CAACC;IAChC,MAAM,IAAIC,MACR,CAAC,YAAY,EAAED,WAAW,qEAAqE,EAAEE,uCAAuC,CAAC,CAAC;AAE9I;AAEe,MAAMC;IAkBnB,cAA8B;QAE5B,OAAOC,2BAA2B,IAAI;IACxC;IAEA,MAAM,mBAA4BC,MAAc,EAAc;QAC5D,OAAON,oBAAoB;IAC7B;IAGA,MAAM,kBAAkB;QACtB,OAAOA,oBAAoB;IAC7B;IAEA,MAAM,sBAAsB;QAC1B,OAAOA,oBAAoB;IAC7B;IAEA,MAAM,cAAcO,EAAU,EAAE;QAC9B,OAAOP,oBAAoB;IAC7B;IAEA,MAAM,iBAAiBQ,KAAY,EAAE;QACnC,OAAOR,oBAAoB;IAC7B;IAEA,MAAM,sBAAsBS,KAAa,EAAE;QACzC,OAAOT,oBAAoB;IAC7B;IAEA,MAAM,OAAO;QACX,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI;IAC5B;IAEA,MAAM,mBAAmB;QACvB,MAAMU,SAAS,IAAI,CAAC,SAAS,CAAC,gBAAgB;QAC9C,IAAI,CAACA,QACH,MAAM,IAAIR,MAAM;QAElB,OAAOQ;IACT;IAEA,MAAM,MAAM;QACV,OAAOC,QAAQ,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI;IAC/C;IAEA,MAAM,eAAeC,aAAqB,EAAE;QAC1C,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,kBAAkBY,aAAqB,EAAE;QAC7C,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,gBAAgBY,aAAqB,EAAE;QAC3C,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,iBAAiBY,aAAqB,EAAE;QAC5C,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,SAASa,QAAiB,EAAED,aAAqB,EAAE;QACvD,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,WAAWa,QAAiB,EAAED,aAAqB,EAAE;QACzD,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,WAAWa,QAAiB,EAAED,aAAqB,EAAE;QACzD,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,YAAYa,QAAiB,EAAED,aAAqB,EAAE;QAC1D,OAAOZ,oBAAoB;IAC7B;IAEA,MAAM,aAAa;QACjB,OAAOA,oBAAoB;IAC7B;IAcA,MAAM,UAAyB,CAE/B;IAEA,MAAM,aAAiC;QACrC,OAAO,IAAI,CAAC,SAAS;IACvB;IAjHA,YAAYc,SAAuB,CAAE;QAJrC,mCAAW;QAEX,uBAAQ,aAAR;QAiGA,gCAAQ;YACN,OAAOd,oBAAoB,IAAI,CAAC,MAAM;YACtC,OAAOA,oBAAoB,IAAI,CAAC,MAAM;YACtC,MAAMA,oBAAoB,IAAI,CAAC,MAAM;YACrC,MAAMA,oBAAoB,IAAI,CAAC,MAAM;QACvC;QAEA,mCAAW;YACT,MAAMA,oBAAoB,IAAI,CAAC,MAAM;YACrC,OAAOA,oBAAoB,IAAI,CAAC,MAAM;QACxC;QAxGE,IAAIc,UAAU,IAAI,EAChB,IAAI,CAAC,SAAS,GAAGA;aAEjB,IAAI,CAAC,SAAS,GAAGC,OAAO,MAAM,CAACD,WAAW;YACxC,MAAM;gBACJ,MAAM;gBACN,UAAU,EAAE;YACd;QACF;IAEJ;AAuGF"}
|
|
@@ -100,7 +100,7 @@ class BridgeServer {
|
|
|
100
100
|
(0, shared_utils_namespaceObject.logMsg)('one client connected');
|
|
101
101
|
this.socket = socket;
|
|
102
102
|
const clientVersion = socket.handshake.query.version;
|
|
103
|
-
(0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v0.27.3
|
|
103
|
+
(0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v0.27.3, browser-side version v${clientVersion}`);
|
|
104
104
|
socket.on(external_common_js_namespaceObject.BridgeEvent.CallResponse, (params)=>{
|
|
105
105
|
const id = params.id;
|
|
106
106
|
const response = params.response;
|
|
@@ -128,7 +128,7 @@ class BridgeServer {
|
|
|
128
128
|
var _this_onConnect, _this;
|
|
129
129
|
null == (_this_onConnect = (_this = this).onConnect) || _this_onConnect.call(_this);
|
|
130
130
|
const payload = {
|
|
131
|
-
version: "0.27.3
|
|
131
|
+
version: "0.27.3"
|
|
132
132
|
};
|
|
133
133
|
socket.emit(external_common_js_namespaceObject.BridgeEvent.Connected, payload);
|
|
134
134
|
Promise.resolve().then(()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-mode/io-server.js","sources":["webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/bridge-mode/io-server.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { sleep } from '@midscene/core/utils';\nimport { logMsg } from '@midscene/shared/utils';\nimport { Server, type Socket as ServerSocket } from 'socket.io';\nimport { io as ClientIO } from 'socket.io-client';\n\nimport {\n type BridgeCall,\n type BridgeCallResponse,\n BridgeCallTimeout,\n type BridgeConnectedEventPayload,\n BridgeErrorCodeNoClientConnected,\n BridgeEvent,\n BridgeSignalKill,\n DefaultBridgeServerPort,\n} from './common';\n\ndeclare const __VERSION__: string;\n\nexport const killRunningServer = async (port?: number) => {\n try {\n const client = ClientIO(\n `ws://localhost:${port || DefaultBridgeServerPort}`,\n {\n query: {\n [BridgeSignalKill]: 1,\n },\n },\n );\n await sleep(100);\n await client.close();\n } catch (e) {\n // console.error('failed to kill port', e);\n }\n};\n\n// ws server, this is where the request is sent\nexport class BridgeServer {\n private callId = 0;\n private io: Server | null = null;\n private socket: ServerSocket | null = null;\n private listeningTimeoutId: NodeJS.Timeout | null = null;\n private listeningTimerFlag = false;\n private connectionTipTimer: NodeJS.Timeout | null = null;\n public calls: Record<string, BridgeCall> = {};\n\n private connectionLost = false;\n private connectionLostReason = '';\n\n constructor(\n public port: number,\n public onConnect?: () => void,\n public onDisconnect?: (reason: string) => void,\n public closeConflictServer?: boolean,\n ) {}\n\n async listen(\n opts: {\n timeout?: number | false;\n } = {},\n ): Promise<void> {\n const { timeout = 30000 } = opts;\n\n if (this.closeConflictServer) {\n await killRunningServer(this.port);\n }\n\n return new Promise((resolve, reject) => {\n if (this.listeningTimerFlag) {\n return reject(new Error('already listening'));\n }\n this.listeningTimerFlag = true;\n\n this.listeningTimeoutId = timeout\n ? setTimeout(() => {\n reject(\n new Error(\n `no extension connected after ${timeout}ms (${BridgeErrorCodeNoClientConnected})`,\n ),\n );\n }, timeout)\n : null;\n\n this.connectionTipTimer =\n !timeout || timeout > 3000\n ? setTimeout(() => {\n logMsg('waiting for bridge to connect...');\n }, 2000)\n : null;\n this.io = new Server(this.port, {\n maxHttpBufferSize: 100 * 1024 * 1024, // 100MB\n });\n\n // Listen for the native HTTP server 'listening' event\n this.io.httpServer.once('listening', () => {\n resolve();\n });\n\n this.io.httpServer.once('error', (err: Error) => {\n reject(new Error(`Bridge Listening Error: ${err.message}`));\n });\n\n this.io.use((socket, next) => {\n if (this.socket) {\n next(new Error('server already connected by another client'));\n }\n next();\n });\n\n this.io.on('connection', (socket) => {\n // check the connection url\n const url = socket.handshake.url;\n if (url.includes(BridgeSignalKill)) {\n console.warn('kill signal received, closing bridge server');\n return this.close();\n }\n\n this.connectionLost = false;\n this.connectionLostReason = '';\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.listeningTimeoutId = null;\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n this.connectionTipTimer = null;\n if (this.socket) {\n socket.emit(BridgeEvent.Refused);\n // close the socket\n socket.disconnect();\n\n return reject(\n new Error('server already connected by another client'),\n );\n }\n\n try {\n logMsg('one client connected');\n this.socket = socket;\n\n const clientVersion = socket.handshake.query.version;\n logMsg(\n `Bridge connected, cli-side version v${__VERSION__}, browser-side version v${clientVersion}`,\n );\n\n socket.on(BridgeEvent.CallResponse, (params: BridgeCallResponse) => {\n const id = params.id;\n const response = params.response;\n const error = params.error;\n\n this.triggerCallResponseCallback(id, error, response);\n });\n\n socket.on('disconnect', (reason: string) => {\n this.connectionLost = true;\n this.connectionLostReason = reason;\n\n try {\n this.io?.close();\n } catch (e) {\n // ignore\n }\n\n // flush all pending calls as error\n for (const id in this.calls) {\n const call = this.calls[id];\n\n if (!call.responseTime) {\n const errorMessage = this.connectionLostErrorMsg();\n this.triggerCallResponseCallback(\n id,\n new Error(errorMessage),\n null,\n );\n }\n }\n\n this.onDisconnect?.(reason);\n });\n\n setTimeout(() => {\n this.onConnect?.();\n\n const payload = {\n version: __VERSION__,\n } as BridgeConnectedEventPayload;\n socket.emit(BridgeEvent.Connected, payload);\n Promise.resolve().then(() => {\n for (const id in this.calls) {\n if (this.calls[id].callTime === 0) {\n this.emitCall(id);\n }\n }\n });\n }, 0);\n } catch (e) {\n console.error('failed to handle connection event', e);\n reject(e);\n }\n });\n\n this.io.on('close', () => {\n this.close();\n });\n });\n }\n\n private connectionLostErrorMsg = () => {\n return `Connection lost, reason: ${this.connectionLostReason}`;\n };\n\n private async triggerCallResponseCallback(\n id: string | number,\n error: Error | null,\n response: any,\n ) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n call.error = error || undefined;\n call.response = response;\n call.responseTime = Date.now();\n\n call.callback(call.error, response);\n }\n\n private async emitCall(id: string) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n\n if (this.connectionLost) {\n const message = `Connection lost, reason: ${this.connectionLostReason}`;\n call.callback(new Error(message), null);\n return;\n }\n\n if (this.socket) {\n this.socket.emit(BridgeEvent.Call, {\n id,\n method: call.method,\n args: call.args,\n });\n call.callTime = Date.now();\n }\n }\n\n async call<T = any>(\n method: string,\n args: any[],\n timeout = BridgeCallTimeout,\n ): Promise<T> {\n const id = `${this.callId++}`;\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n logMsg(`bridge call timeout, id=${id}, method=${method}, args=`, args);\n this.calls[id].error = new Error(\n `Bridge call timeout after ${timeout}ms: ${method}`,\n );\n reject(this.calls[id].error);\n }, timeout);\n\n this.calls[id] = {\n method,\n args,\n response: null,\n callTime: 0,\n responseTime: 0,\n callback: (error: Error | undefined, response: any) => {\n clearTimeout(timeoutId);\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n },\n };\n\n this.emitCall(id);\n });\n }\n\n // do NOT restart after close\n async close() {\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n const closeProcess = this.io?.close();\n this.io = null;\n\n return closeProcess;\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","killRunningServer","port","client","ClientIO","DefaultBridgeServerPort","BridgeSignalKill","sleep","e","BridgeServer","opts","timeout","Promise","resolve","reject","Error","setTimeout","BridgeErrorCodeNoClientConnected","logMsg","Server","err","socket","next","url","console","clearTimeout","BridgeEvent","clientVersion","params","id","response","error","reason","_this","_this_io","call","errorMessage","payload","__VERSION__","undefined","Date","message","method","args","BridgeCallTimeout","timeoutId","closeProcess","onConnect","onDisconnect","closeConflictServer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bridge-mode/io-server.js","sources":["webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/bridge-mode/io-server.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { sleep } from '@midscene/core/utils';\nimport { logMsg } from '@midscene/shared/utils';\nimport { Server, type Socket as ServerSocket } from 'socket.io';\nimport { io as ClientIO } from 'socket.io-client';\n\nimport {\n type BridgeCall,\n type BridgeCallResponse,\n BridgeCallTimeout,\n type BridgeConnectedEventPayload,\n BridgeErrorCodeNoClientConnected,\n BridgeEvent,\n BridgeSignalKill,\n DefaultBridgeServerPort,\n} from './common';\n\ndeclare const __VERSION__: string;\n\nexport const killRunningServer = async (port?: number) => {\n try {\n const client = ClientIO(\n `ws://localhost:${port || DefaultBridgeServerPort}`,\n {\n query: {\n [BridgeSignalKill]: 1,\n },\n },\n );\n await sleep(100);\n await client.close();\n } catch (e) {\n // console.error('failed to kill port', e);\n }\n};\n\n// ws server, this is where the request is sent\nexport class BridgeServer {\n private callId = 0;\n private io: Server | null = null;\n private socket: ServerSocket | null = null;\n private listeningTimeoutId: NodeJS.Timeout | null = null;\n private listeningTimerFlag = false;\n private connectionTipTimer: NodeJS.Timeout | null = null;\n public calls: Record<string, BridgeCall> = {};\n\n private connectionLost = false;\n private connectionLostReason = '';\n\n constructor(\n public port: number,\n public onConnect?: () => void,\n public onDisconnect?: (reason: string) => void,\n public closeConflictServer?: boolean,\n ) {}\n\n async listen(\n opts: {\n timeout?: number | false;\n } = {},\n ): Promise<void> {\n const { timeout = 30000 } = opts;\n\n if (this.closeConflictServer) {\n await killRunningServer(this.port);\n }\n\n return new Promise((resolve, reject) => {\n if (this.listeningTimerFlag) {\n return reject(new Error('already listening'));\n }\n this.listeningTimerFlag = true;\n\n this.listeningTimeoutId = timeout\n ? setTimeout(() => {\n reject(\n new Error(\n `no extension connected after ${timeout}ms (${BridgeErrorCodeNoClientConnected})`,\n ),\n );\n }, timeout)\n : null;\n\n this.connectionTipTimer =\n !timeout || timeout > 3000\n ? setTimeout(() => {\n logMsg('waiting for bridge to connect...');\n }, 2000)\n : null;\n this.io = new Server(this.port, {\n maxHttpBufferSize: 100 * 1024 * 1024, // 100MB\n });\n\n // Listen for the native HTTP server 'listening' event\n this.io.httpServer.once('listening', () => {\n resolve();\n });\n\n this.io.httpServer.once('error', (err: Error) => {\n reject(new Error(`Bridge Listening Error: ${err.message}`));\n });\n\n this.io.use((socket, next) => {\n if (this.socket) {\n next(new Error('server already connected by another client'));\n }\n next();\n });\n\n this.io.on('connection', (socket) => {\n // check the connection url\n const url = socket.handshake.url;\n if (url.includes(BridgeSignalKill)) {\n console.warn('kill signal received, closing bridge server');\n return this.close();\n }\n\n this.connectionLost = false;\n this.connectionLostReason = '';\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.listeningTimeoutId = null;\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n this.connectionTipTimer = null;\n if (this.socket) {\n socket.emit(BridgeEvent.Refused);\n // close the socket\n socket.disconnect();\n\n return reject(\n new Error('server already connected by another client'),\n );\n }\n\n try {\n logMsg('one client connected');\n this.socket = socket;\n\n const clientVersion = socket.handshake.query.version;\n logMsg(\n `Bridge connected, cli-side version v${__VERSION__}, browser-side version v${clientVersion}`,\n );\n\n socket.on(BridgeEvent.CallResponse, (params: BridgeCallResponse) => {\n const id = params.id;\n const response = params.response;\n const error = params.error;\n\n this.triggerCallResponseCallback(id, error, response);\n });\n\n socket.on('disconnect', (reason: string) => {\n this.connectionLost = true;\n this.connectionLostReason = reason;\n\n try {\n this.io?.close();\n } catch (e) {\n // ignore\n }\n\n // flush all pending calls as error\n for (const id in this.calls) {\n const call = this.calls[id];\n\n if (!call.responseTime) {\n const errorMessage = this.connectionLostErrorMsg();\n this.triggerCallResponseCallback(\n id,\n new Error(errorMessage),\n null,\n );\n }\n }\n\n this.onDisconnect?.(reason);\n });\n\n setTimeout(() => {\n this.onConnect?.();\n\n const payload = {\n version: __VERSION__,\n } as BridgeConnectedEventPayload;\n socket.emit(BridgeEvent.Connected, payload);\n Promise.resolve().then(() => {\n for (const id in this.calls) {\n if (this.calls[id].callTime === 0) {\n this.emitCall(id);\n }\n }\n });\n }, 0);\n } catch (e) {\n console.error('failed to handle connection event', e);\n reject(e);\n }\n });\n\n this.io.on('close', () => {\n this.close();\n });\n });\n }\n\n private connectionLostErrorMsg = () => {\n return `Connection lost, reason: ${this.connectionLostReason}`;\n };\n\n private async triggerCallResponseCallback(\n id: string | number,\n error: Error | null,\n response: any,\n ) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n call.error = error || undefined;\n call.response = response;\n call.responseTime = Date.now();\n\n call.callback(call.error, response);\n }\n\n private async emitCall(id: string) {\n const call = this.calls[id];\n if (!call) {\n throw new Error(`call ${id} not found`);\n }\n\n if (this.connectionLost) {\n const message = `Connection lost, reason: ${this.connectionLostReason}`;\n call.callback(new Error(message), null);\n return;\n }\n\n if (this.socket) {\n this.socket.emit(BridgeEvent.Call, {\n id,\n method: call.method,\n args: call.args,\n });\n call.callTime = Date.now();\n }\n }\n\n async call<T = any>(\n method: string,\n args: any[],\n timeout = BridgeCallTimeout,\n ): Promise<T> {\n const id = `${this.callId++}`;\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n logMsg(`bridge call timeout, id=${id}, method=${method}, args=`, args);\n this.calls[id].error = new Error(\n `Bridge call timeout after ${timeout}ms: ${method}`,\n );\n reject(this.calls[id].error);\n }, timeout);\n\n this.calls[id] = {\n method,\n args,\n response: null,\n callTime: 0,\n responseTime: 0,\n callback: (error: Error | undefined, response: any) => {\n clearTimeout(timeoutId);\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n },\n };\n\n this.emitCall(id);\n });\n }\n\n // do NOT restart after close\n async close() {\n this.listeningTimeoutId && clearTimeout(this.listeningTimeoutId);\n this.connectionTipTimer && clearTimeout(this.connectionTipTimer);\n const closeProcess = this.io?.close();\n this.io = null;\n\n return closeProcess;\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","killRunningServer","port","client","ClientIO","DefaultBridgeServerPort","BridgeSignalKill","sleep","e","BridgeServer","opts","timeout","Promise","resolve","reject","Error","setTimeout","BridgeErrorCodeNoClientConnected","logMsg","Server","err","socket","next","url","console","clearTimeout","BridgeEvent","clientVersion","params","id","response","error","reason","_this","_this_io","call","errorMessage","payload","__VERSION__","undefined","Date","message","method","args","BridgeCallTimeout","timeoutId","closeProcess","onConnect","onDisconnect","closeConflictServer"],"mappings":"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"}
|
|
@@ -82,7 +82,7 @@ class ExtensionBridgePageBrowserSide extends page_js_default() {
|
|
|
82
82
|
}
|
|
83
83
|
}, ()=>this.destroy());
|
|
84
84
|
await this.bridgeClient.connect();
|
|
85
|
-
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v0.27.3
|
|
85
|
+
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v0.27.3`, 'log');
|
|
86
86
|
}
|
|
87
87
|
async connect() {
|
|
88
88
|
return await this.setupBridgeClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-mode/page-browser-side.js","sources":["webpack://@midscene/web/webpack/runtime/compat_get_default_export","webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/bridge-mode/page-browser-side.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n ChromePageDestroyOptions,\n KeyboardAction,\n MouseAction,\n} from '@midscene/core/device';\nimport { assert } from '@midscene/shared/utils';\nimport ChromeExtensionProxyPage from '../chrome-extension/page';\nimport {\n type BridgeConnectTabOptions,\n BridgeEvent,\n DefaultBridgeServerPort,\n KeyboardEvent,\n MouseEvent,\n} from './common';\nimport { BridgeClient } from './io-client';\n\ndeclare const __VERSION__: string;\n\nexport class ExtensionBridgePageBrowserSide extends ChromeExtensionProxyPage {\n public bridgeClient: BridgeClient | null = null;\n\n private destroyOptions?: ChromePageDestroyOptions;\n\n private newlyCreatedTabIds: number[] = [];\n\n constructor(\n public onDisconnect: () => void = () => {},\n public onLogMessage: (\n message: string,\n type: 'log' | 'status',\n ) => void = () => {},\n forceSameTabNavigation = true,\n ) {\n super(forceSameTabNavigation);\n }\n\n private async setupBridgeClient() {\n this.bridgeClient = new BridgeClient(\n `ws://localhost:${DefaultBridgeServerPort}`,\n async (method, args: any[]) => {\n console.log('bridge call from cli side', method, args);\n if (method === BridgeEvent.ConnectNewTabWithUrl) {\n return this.connectNewTabWithUrl.apply(\n this,\n args as unknown as [string],\n );\n }\n\n if (method === BridgeEvent.GetBrowserTabList) {\n return this.getBrowserTabList.apply(this, args as any);\n }\n\n if (method === BridgeEvent.SetActiveTabId) {\n return this.setActiveTabId.apply(this, args as any);\n }\n\n if (method === BridgeEvent.ConnectCurrentTab) {\n return this.connectCurrentTab.apply(this, args as any);\n }\n\n if (method === BridgeEvent.UpdateAgentStatus) {\n return this.onLogMessage(args[0] as string, 'status');\n }\n\n const tabId = await this.getActiveTabId();\n if (!tabId || tabId === 0) {\n throw new Error('no tab is connected');\n }\n\n // this.onLogMessage(`calling method: ${method}`);\n\n if (method.startsWith(MouseEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof MouseAction;\n if (actionName === 'drag') {\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n\n if (method.startsWith(KeyboardEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof KeyboardAction;\n if (actionName === 'press') {\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n\n try {\n // @ts-expect-error\n const result = await this[method as keyof ChromeExtensionProxyPage](\n ...args,\n );\n return result;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : 'Unknown error';\n console.error('error calling method', method, args, e);\n this.onLogMessage(\n `Error calling method: ${method}, ${errorMessage}`,\n 'log',\n );\n throw new Error(errorMessage, { cause: e });\n }\n },\n // on disconnect\n () => {\n return this.destroy();\n },\n );\n await this.bridgeClient.connect();\n this.onLogMessage(\n `Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v${__VERSION__}`,\n 'log',\n );\n }\n\n public async connect() {\n return await this.setupBridgeClient();\n }\n\n public async connectNewTabWithUrl(\n url: string,\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tab = await chrome.tabs.create({ url });\n const tabId = tab.id;\n assert(tabId, 'failed to get tabId after creating a new tab');\n\n // new tab\n this.onLogMessage(`Creating new tab: ${url}`, 'log');\n this.newlyCreatedTabIds.push(tabId);\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async connectCurrentTab(\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tabs = await chrome.tabs.query({ active: true, currentWindow: true });\n const tabId = tabs[0]?.id;\n assert(tabId, 'failed to get tabId');\n\n this.onLogMessage(`Connected to current tab: ${tabs[0]?.url}`, 'log');\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async setDestroyOptions(options: ChromePageDestroyOptions) {\n this.destroyOptions = options;\n }\n\n async destroy() {\n if (this.destroyOptions?.closeTab && this.newlyCreatedTabIds.length > 0) {\n this.onLogMessage('Closing all newly created tabs by bridge...', 'log');\n for (const tabId of this.newlyCreatedTabIds) {\n await chrome.tabs.remove(tabId);\n }\n this.newlyCreatedTabIds = [];\n }\n\n await super.destroy();\n\n if (this.bridgeClient) {\n this.bridgeClient.disconnect();\n this.bridgeClient = null;\n this.onDisconnect();\n }\n }\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","ExtensionBridgePageBrowserSide","ChromeExtensionProxyPage","BridgeClient","DefaultBridgeServerPort","method","args","console","BridgeEvent","tabId","Error","MouseEvent","actionName","KeyboardEvent","result","e","errorMessage","url","options","tab","chrome","assert","_tabs_","_tabs_1","tabs","_this_destroyOptions","onDisconnect","onLogMessage","forceSameTabNavigation"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bridge-mode/page-browser-side.js","sources":["webpack://@midscene/web/webpack/runtime/compat_get_default_export","webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/bridge-mode/page-browser-side.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n ChromePageDestroyOptions,\n KeyboardAction,\n MouseAction,\n} from '@midscene/core/device';\nimport { assert } from '@midscene/shared/utils';\nimport ChromeExtensionProxyPage from '../chrome-extension/page';\nimport {\n type BridgeConnectTabOptions,\n BridgeEvent,\n DefaultBridgeServerPort,\n KeyboardEvent,\n MouseEvent,\n} from './common';\nimport { BridgeClient } from './io-client';\n\ndeclare const __VERSION__: string;\n\nexport class ExtensionBridgePageBrowserSide extends ChromeExtensionProxyPage {\n public bridgeClient: BridgeClient | null = null;\n\n private destroyOptions?: ChromePageDestroyOptions;\n\n private newlyCreatedTabIds: number[] = [];\n\n constructor(\n public onDisconnect: () => void = () => {},\n public onLogMessage: (\n message: string,\n type: 'log' | 'status',\n ) => void = () => {},\n forceSameTabNavigation = true,\n ) {\n super(forceSameTabNavigation);\n }\n\n private async setupBridgeClient() {\n this.bridgeClient = new BridgeClient(\n `ws://localhost:${DefaultBridgeServerPort}`,\n async (method, args: any[]) => {\n console.log('bridge call from cli side', method, args);\n if (method === BridgeEvent.ConnectNewTabWithUrl) {\n return this.connectNewTabWithUrl.apply(\n this,\n args as unknown as [string],\n );\n }\n\n if (method === BridgeEvent.GetBrowserTabList) {\n return this.getBrowserTabList.apply(this, args as any);\n }\n\n if (method === BridgeEvent.SetActiveTabId) {\n return this.setActiveTabId.apply(this, args as any);\n }\n\n if (method === BridgeEvent.ConnectCurrentTab) {\n return this.connectCurrentTab.apply(this, args as any);\n }\n\n if (method === BridgeEvent.UpdateAgentStatus) {\n return this.onLogMessage(args[0] as string, 'status');\n }\n\n const tabId = await this.getActiveTabId();\n if (!tabId || tabId === 0) {\n throw new Error('no tab is connected');\n }\n\n // this.onLogMessage(`calling method: ${method}`);\n\n if (method.startsWith(MouseEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof MouseAction;\n if (actionName === 'drag') {\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n return this.mouse[actionName].apply(this.mouse, args as any);\n }\n\n if (method.startsWith(KeyboardEvent.PREFIX)) {\n const actionName = method.split('.')[1] as keyof KeyboardAction;\n if (actionName === 'press') {\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n return this.keyboard[actionName].apply(this.keyboard, args as any);\n }\n\n try {\n // @ts-expect-error\n const result = await this[method as keyof ChromeExtensionProxyPage](\n ...args,\n );\n return result;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : 'Unknown error';\n console.error('error calling method', method, args, e);\n this.onLogMessage(\n `Error calling method: ${method}, ${errorMessage}`,\n 'log',\n );\n throw new Error(errorMessage, { cause: e });\n }\n },\n // on disconnect\n () => {\n return this.destroy();\n },\n );\n await this.bridgeClient.connect();\n this.onLogMessage(\n `Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v${__VERSION__}`,\n 'log',\n );\n }\n\n public async connect() {\n return await this.setupBridgeClient();\n }\n\n public async connectNewTabWithUrl(\n url: string,\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tab = await chrome.tabs.create({ url });\n const tabId = tab.id;\n assert(tabId, 'failed to get tabId after creating a new tab');\n\n // new tab\n this.onLogMessage(`Creating new tab: ${url}`, 'log');\n this.newlyCreatedTabIds.push(tabId);\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async connectCurrentTab(\n options: BridgeConnectTabOptions = {\n forceSameTabNavigation: true,\n },\n ) {\n const tabs = await chrome.tabs.query({ active: true, currentWindow: true });\n const tabId = tabs[0]?.id;\n assert(tabId, 'failed to get tabId');\n\n this.onLogMessage(`Connected to current tab: ${tabs[0]?.url}`, 'log');\n\n if (options?.forceSameTabNavigation) {\n this.forceSameTabNavigation = true;\n }\n\n await this.setActiveTabId(tabId);\n }\n\n public async setDestroyOptions(options: ChromePageDestroyOptions) {\n this.destroyOptions = options;\n }\n\n async destroy() {\n if (this.destroyOptions?.closeTab && this.newlyCreatedTabIds.length > 0) {\n this.onLogMessage('Closing all newly created tabs by bridge...', 'log');\n for (const tabId of this.newlyCreatedTabIds) {\n await chrome.tabs.remove(tabId);\n }\n this.newlyCreatedTabIds = [];\n }\n\n await super.destroy();\n\n if (this.bridgeClient) {\n this.bridgeClient.disconnect();\n this.bridgeClient = null;\n this.onDisconnect();\n }\n }\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","ExtensionBridgePageBrowserSide","ChromeExtensionProxyPage","BridgeClient","DefaultBridgeServerPort","method","args","console","BridgeEvent","tabId","Error","MouseEvent","actionName","KeyboardEvent","result","e","errorMessage","url","options","tab","chrome","assert","_tabs_","_tabs_1","tabs","_this_destroyOptions","onDisconnect","onLogMessage","forceSameTabNavigation"],"mappings":"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"}
|
|
@@ -374,7 +374,7 @@ class ChromeExtensionProxyPage {
|
|
|
374
374
|
constructor(forceSameTabNavigation){
|
|
375
375
|
_define_property(this, "pageType", 'chrome-extension-proxy');
|
|
376
376
|
_define_property(this, "forceSameTabNavigation", void 0);
|
|
377
|
-
_define_property(this, "version", "0.27.3
|
|
377
|
+
_define_property(this, "version", "0.27.3");
|
|
378
378
|
_define_property(this, "viewportSize", void 0);
|
|
379
379
|
_define_property(this, "activeTabId", null);
|
|
380
380
|
_define_property(this, "tabIdOfDebuggerAttached", null);
|
|
@@ -256,20 +256,10 @@ class PlaygroundServer {
|
|
|
256
256
|
} else {
|
|
257
257
|
const actualPrompt = prompt || (null == params ? void 0 : params.prompt);
|
|
258
258
|
if (!actualPrompt) throw new Error(`Missing prompt for ${type}`);
|
|
259
|
-
if ('
|
|
260
|
-
else if ('aiAction' === type) response.result = await agent.aiAction(actualPrompt);
|
|
261
|
-
else if ('aiAssert' === type) response.result = await agent.aiAssert(actualPrompt, void 0, {
|
|
259
|
+
if ('aiAssert' === type) response.result = await agent.aiAssert(actualPrompt, void 0, {
|
|
262
260
|
keepRawResponse: true
|
|
263
261
|
});
|
|
264
|
-
else if ('
|
|
265
|
-
else if ('aiNumber' === type) response.result = await agent.aiNumber(actualPrompt);
|
|
266
|
-
else if ('aiString' === type) response.result = await agent.aiString(actualPrompt);
|
|
267
|
-
else if ('aiAsk' === type) response.result = await agent.aiAsk(actualPrompt);
|
|
268
|
-
else if ('aiWaitFor' === type) response.result = await agent.aiWaitFor(actualPrompt, {
|
|
269
|
-
timeoutMs: 15000,
|
|
270
|
-
checkIntervalMs: 3000
|
|
271
|
-
});
|
|
272
|
-
else if ('aiLocate' === type) response.result = await agent.aiLocate(actualPrompt, {
|
|
262
|
+
else if (agent && 'function' == typeof agent[type]) response.result = await agent[type](actualPrompt, {
|
|
273
263
|
deepThink
|
|
274
264
|
});
|
|
275
265
|
else response.error = `Unknown type: ${type}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground/server.js","sources":["webpack://@midscene/web/webpack/runtime/compat_get_default_export","webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/playground/server.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport type { Server } from 'node:http';\nimport { join } from 'node:path';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { getTmpDir } from '@midscene/core/utils';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport express from 'express';\n\nconst defaultPort = PLAYGROUND_SERVER_PORT;\n// const staticPath = join(__dirname, '../../static');\n\nconst errorHandler = (err: any, req: any, res: any, next: any) => {\n console.error(err);\n res.status(500).json({\n error: err.message,\n });\n};\n\nconst setup = async () => {\n if (!ifInBrowser && !ifInWorker) {\n dotenv.config();\n }\n};\n\nexport default class PlaygroundServer {\n app: express.Application;\n tmpDir: string;\n server?: Server;\n port?: number | null;\n pageClass: new (\n ...args: any[]\n ) => AbstractPage;\n agentClass: new (\n ...args: any[]\n ) => PageAgent;\n staticPath?: string;\n taskProgressTips: Record<string, string>;\n activeAgents: Record<string, PageAgent>;\n\n constructor(\n pageClass: new (...args: any[]) => AbstractPage,\n agentClass: new (...args: any[]) => PageAgent,\n staticPath?: string,\n ) {\n this.app = express();\n this.tmpDir = getTmpDir()!;\n this.pageClass = pageClass;\n this.agentClass = agentClass;\n this.staticPath = staticPath;\n this.taskProgressTips = {};\n this.activeAgents = {};\n setup();\n }\n\n filePathForUuid(uuid: string) {\n return join(this.tmpDir, `${uuid}.json`);\n }\n\n saveContextFile(uuid: string, context: string) {\n const tmpFile = this.filePathForUuid(uuid);\n console.log(`save context file: ${tmpFile}`);\n writeFileSync(tmpFile, context);\n return tmpFile;\n }\n\n async launch(port?: number) {\n this.port = port || defaultPort;\n this.app.use(errorHandler);\n\n this.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n );\n\n this.app.get('/status', cors(), async (req, res) => {\n // const modelName = g\n res.send({\n status: 'ok',\n });\n });\n\n // this.app.get('/playground/:uuid', async (req, res) => {\n // res.sendFile(join(staticPath, 'index.html'));\n // });\n\n this.app.get('/context/:uuid', async (req, res) => {\n const { uuid } = req.params;\n const contextFile = this.filePathForUuid(uuid);\n\n if (!existsSync(contextFile)) {\n return res.status(404).json({\n error: 'Context not found',\n });\n }\n\n const context = readFileSync(contextFile, 'utf8');\n res.json({\n context,\n });\n });\n\n this.app.get('/task-progress/:requestId', cors(), async (req, res) => {\n const { requestId } = req.params;\n res.json({\n tip: this.taskProgressTips[requestId] || '',\n });\n });\n\n // -------------------------\n // actions from report file\n this.app.post(\n '/playground-with-context',\n express.json({ limit: '50mb' }),\n async (req, res) => {\n const context = req.body.context;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n const uuid = randomUUID();\n this.saveContextFile(uuid, context);\n return res.json({\n location: `/playground/${uuid}`,\n uuid,\n });\n },\n );\n\n this.app.post(\n '/execute',\n express.json({ limit: '30mb' }),\n async (req, res) => {\n const { context, type, prompt, params, requestId, deepThink } =\n req.body;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n if (!type) {\n return res.status(400).json({\n error: 'type is required',\n });\n }\n\n if (!prompt && !params) {\n return res.status(400).json({\n error: 'prompt or params is required',\n });\n }\n\n // build an agent with context\n const page = new this.pageClass(context);\n const agent = new this.agentClass(page);\n\n if (requestId) {\n this.taskProgressTips[requestId] = '';\n this.activeAgents[requestId] = agent;\n\n agent.onTaskStartTip = (tip: string) => {\n this.taskProgressTips[requestId] = tip;\n };\n }\n\n const response: {\n result: any;\n dump: string | null;\n error: string | null;\n reportHTML: string | null;\n requestId?: string;\n } = {\n result: null,\n dump: null,\n error: null,\n reportHTML: null,\n requestId,\n };\n\n // Helper function to parse action parameters based on type\n const parseActionParams = (\n actionType: string,\n inputPrompt: string | undefined,\n inputParams: any | undefined,\n options: { deepThink?: boolean } = {},\n ): any[] => {\n // If structured params are provided, use them directly\n if (inputParams) {\n switch (actionType) {\n case 'aiInput': {\n if (!inputParams.value || !inputParams.locate) {\n throw new Error(\n 'aiInput requires both value and locate parameters',\n );\n }\n return [\n inputParams.locate,\n { value: inputParams.value, ...options },\n ];\n }\n\n case 'aiKeyboardPress': {\n if (!inputParams.keyName) {\n throw new Error('aiKeyboardPress requires keyName parameter');\n }\n return [\n inputParams.locate,\n { keyName: inputParams.keyName, ...options },\n ];\n }\n\n case 'aiScroll': {\n if (!inputParams.direction || !inputParams.distance) {\n throw new Error(\n 'aiScroll requires direction and distance parameters',\n );\n }\n const scrollParam = {\n direction: inputParams.direction as\n | 'up'\n | 'down'\n | 'left'\n | 'right',\n scrollType: inputParams.scrollType || 'once',\n distance: inputParams.distance,\n ...options,\n };\n return [inputParams.locate, scrollParam];\n }\n\n default:\n // For other actions that only need locate prompt\n return [\n inputParams.locate || inputParams.prompt || inputPrompt,\n options,\n ];\n }\n }\n\n // Fallback to legacy prompt parsing for backward compatibility\n if (!inputPrompt) {\n throw new Error(`Missing prompt for ${actionType}`);\n }\n\n switch (actionType) {\n case 'aiInput': {\n const inputParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n if (inputParts.length !== 2) {\n throw new Error('aiInput requires format: \"value | element\"');\n }\n return [inputParts[1], { value: inputParts[0], ...options }];\n }\n\n case 'aiKeyboardPress': {\n const keyParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const keyName = keyParts[0];\n const keyElement = keyParts[1] || undefined;\n return [keyElement, { keyName, ...options }];\n }\n\n case 'aiScroll': {\n const scrollParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const scrollArgs = scrollParts[0]\n .split(' ')\n .map((s: string) => s.trim());\n\n if (scrollArgs.length < 2) {\n throw new Error(\n 'aiScroll requires format: \"direction amount | element (optional)\"',\n );\n }\n\n const direction = scrollArgs[0] as\n | 'up'\n | 'down'\n | 'left'\n | 'right';\n const amount = Number.parseInt(scrollArgs[1]);\n const scrollElement = scrollParts[1] || undefined;\n\n const scrollParam = {\n direction,\n scrollType: 'once' as const,\n distance: amount,\n ...options,\n };\n\n return [scrollElement, scrollParam];\n }\n\n default:\n return [inputPrompt, options];\n }\n };\n\n const startTime = Date.now();\n try {\n // Get action space to check for dynamic actions\n const actionSpace = await agent.getActionSpace();\n\n // Check if this is an action in the actionSpace\n const action = actionSpace.find(\n (action) => action.interfaceAlias === type || action.name === type,\n );\n\n if (\n action?.interfaceAlias &&\n typeof (agent as any)[action.interfaceAlias] === 'function'\n ) {\n // Use actionSpace method dynamically\n const parsedParams = parseActionParams(type, prompt, params, {\n deepThink,\n });\n response.result = await (agent as any)[action.interfaceAlias](\n ...parsedParams,\n );\n } else {\n // Get the prompt from either prompt field or params.prompt\n const actualPrompt = prompt || params?.prompt;\n\n if (!actualPrompt) {\n throw new Error(`Missing prompt for ${type}`);\n }\n\n if (type === 'aiQuery') {\n response.result = await agent.aiQuery(actualPrompt);\n } else if (type === 'aiAction') {\n response.result = await agent.aiAction(actualPrompt);\n } else if (type === 'aiAssert') {\n response.result = await agent.aiAssert(actualPrompt, undefined, {\n keepRawResponse: true,\n });\n } else if (type === 'aiBoolean') {\n response.result = await agent.aiBoolean(actualPrompt);\n } else if (type === 'aiNumber') {\n response.result = await agent.aiNumber(actualPrompt);\n } else if (type === 'aiString') {\n response.result = await agent.aiString(actualPrompt);\n } else if (type === 'aiAsk') {\n response.result = await agent.aiAsk(actualPrompt);\n } else if (type === 'aiWaitFor') {\n response.result = await agent.aiWaitFor(actualPrompt, {\n timeoutMs: 15000,\n checkIntervalMs: 3000,\n });\n } else if (type === 'aiLocate') {\n response.result = await agent.aiLocate(actualPrompt, {\n deepThink,\n });\n } else {\n response.error = `Unknown type: ${type}`;\n }\n }\n } catch (error: any) {\n if (!error.message.includes(ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED)) {\n response.error = error.message;\n }\n }\n\n try {\n response.dump = JSON.parse(agent.dumpDataString());\n response.reportHTML = agent.reportHTMLString() || null;\n\n agent.writeOutActionDumps();\n agent.destroy();\n } catch (error: any) {\n console.error(\n `write out dump failed: requestId: ${requestId}, ${error.message}`,\n );\n }\n\n res.send(response);\n const timeCost = Date.now() - startTime;\n\n if (response.error) {\n console.error(\n `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`,\n );\n } else {\n console.log(\n `handle request done after ${timeCost}ms: requestId: ${requestId}`,\n );\n }\n\n // Clean up the agent from activeAgents after execution completes\n if (requestId && this.activeAgents[requestId]) {\n delete this.activeAgents[requestId];\n }\n },\n );\n\n this.app.get('/cancel/:requestId', async (req, res) => {\n const { requestId } = req.params;\n\n if (!requestId) {\n return res.status(400).json({\n error: 'requestId is required',\n });\n }\n\n const agent = this.activeAgents[requestId];\n if (!agent) {\n return res.status(404).json({\n error: 'No active agent found for this requestId',\n });\n }\n\n try {\n await agent.destroy();\n delete this.activeAgents[requestId];\n res.json({ status: 'cancelled' });\n } catch (error: any) {\n console.error(`Failed to cancel agent: ${error.message}`);\n res.status(500).json({\n error: `Failed to cancel: ${error.message}`,\n });\n }\n });\n\n this.app.post(\n '/config',\n express.json({ limit: '1mb' }),\n async (req, res) => {\n const { aiConfig } = req.body;\n\n if (!aiConfig || typeof aiConfig !== 'object') {\n return res.status(400).json({\n error: 'aiConfig is required and must be an object',\n });\n }\n\n try {\n overrideAIConfig(aiConfig);\n\n return res.json({\n status: 'ok',\n message: 'AI config updated successfully',\n });\n } catch (error: any) {\n console.error(`Failed to update AI config: ${error.message}`);\n return res.status(500).json({\n error: `Failed to update AI config: ${error.message}`,\n });\n }\n },\n );\n\n // Set up static file serving after all API routes are defined\n if (this.staticPath) {\n this.app.get('/', (req, res) => {\n // compatible with windows\n res.redirect('/index.html');\n });\n\n this.app.get('*', (req, res) => {\n const requestedPath = join(this.staticPath!, req.path);\n if (existsSync(requestedPath)) {\n res.sendFile(requestedPath);\n } else {\n res.sendFile(join(this.staticPath!, 'index.html'));\n }\n });\n }\n\n return new Promise((resolve, reject) => {\n const port = this.port;\n this.server = this.app.listen(port, () => {\n resolve(this);\n });\n });\n }\n\n close() {\n // close the server\n if (this.server) {\n return this.server.close();\n }\n }\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","defaultPort","PLAYGROUND_SERVER_PORT","errorHandler","err","req","res","next","console","setup","ifInBrowser","ifInWorker","dotenv","PlaygroundServer","uuid","join","context","tmpFile","writeFileSync","port","cors","contextFile","existsSync","readFileSync","requestId","express","randomUUID","type","prompt","params","deepThink","page","agent","tip","response","parseActionParams","actionType","inputPrompt","inputParams","options","Error","scrollParam","inputParts","s","keyParts","keyName","keyElement","undefined","scrollParts","scrollArgs","direction","amount","Number","scrollElement","startTime","Date","actionSpace","action","parsedParams","actualPrompt","error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","JSON","timeCost","aiConfig","overrideAIConfig","requestedPath","Promise","resolve","reject","pageClass","agentClass","staticPath","getTmpDir"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"playground/server.js","sources":["webpack://@midscene/web/webpack/runtime/compat_get_default_export","webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/playground/server.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport type { Server } from 'node:http';\nimport { join } from 'node:path';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { getTmpDir } from '@midscene/core/utils';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport express from 'express';\n\nconst defaultPort = PLAYGROUND_SERVER_PORT;\n// const staticPath = join(__dirname, '../../static');\n\nconst errorHandler = (err: any, req: any, res: any, next: any) => {\n console.error(err);\n res.status(500).json({\n error: err.message,\n });\n};\n\nconst setup = async () => {\n if (!ifInBrowser && !ifInWorker) {\n dotenv.config();\n }\n};\n\nexport default class PlaygroundServer {\n app: express.Application;\n tmpDir: string;\n server?: Server;\n port?: number | null;\n pageClass: new (\n ...args: any[]\n ) => AbstractPage;\n agentClass: new (\n ...args: any[]\n ) => PageAgent;\n staticPath?: string;\n taskProgressTips: Record<string, string>;\n activeAgents: Record<string, PageAgent>;\n\n constructor(\n pageClass: new (...args: any[]) => AbstractPage,\n agentClass: new (...args: any[]) => PageAgent,\n staticPath?: string,\n ) {\n this.app = express();\n this.tmpDir = getTmpDir()!;\n this.pageClass = pageClass;\n this.agentClass = agentClass;\n this.staticPath = staticPath;\n this.taskProgressTips = {};\n this.activeAgents = {};\n setup();\n }\n\n filePathForUuid(uuid: string) {\n return join(this.tmpDir, `${uuid}.json`);\n }\n\n saveContextFile(uuid: string, context: string) {\n const tmpFile = this.filePathForUuid(uuid);\n console.log(`save context file: ${tmpFile}`);\n writeFileSync(tmpFile, context);\n return tmpFile;\n }\n\n async launch(port?: number) {\n this.port = port || defaultPort;\n this.app.use(errorHandler);\n\n this.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n );\n\n this.app.get('/status', cors(), async (req, res) => {\n // const modelName = g\n res.send({\n status: 'ok',\n });\n });\n\n // this.app.get('/playground/:uuid', async (req, res) => {\n // res.sendFile(join(staticPath, 'index.html'));\n // });\n\n this.app.get('/context/:uuid', async (req, res) => {\n const { uuid } = req.params;\n const contextFile = this.filePathForUuid(uuid);\n\n if (!existsSync(contextFile)) {\n return res.status(404).json({\n error: 'Context not found',\n });\n }\n\n const context = readFileSync(contextFile, 'utf8');\n res.json({\n context,\n });\n });\n\n this.app.get('/task-progress/:requestId', cors(), async (req, res) => {\n const { requestId } = req.params;\n res.json({\n tip: this.taskProgressTips[requestId] || '',\n });\n });\n\n // -------------------------\n // actions from report file\n this.app.post(\n '/playground-with-context',\n express.json({ limit: '50mb' }),\n async (req, res) => {\n const context = req.body.context;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n const uuid = randomUUID();\n this.saveContextFile(uuid, context);\n return res.json({\n location: `/playground/${uuid}`,\n uuid,\n });\n },\n );\n\n this.app.post(\n '/execute',\n express.json({ limit: '30mb' }),\n async (req, res) => {\n const { context, type, prompt, params, requestId, deepThink } =\n req.body;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n if (!type) {\n return res.status(400).json({\n error: 'type is required',\n });\n }\n\n if (!prompt && !params) {\n return res.status(400).json({\n error: 'prompt or params is required',\n });\n }\n\n // build an agent with context\n const page = new this.pageClass(context);\n const agent = new this.agentClass(page);\n\n if (requestId) {\n this.taskProgressTips[requestId] = '';\n this.activeAgents[requestId] = agent;\n\n agent.onTaskStartTip = (tip: string) => {\n this.taskProgressTips[requestId] = tip;\n };\n }\n\n const response: {\n result: any;\n dump: string | null;\n error: string | null;\n reportHTML: string | null;\n requestId?: string;\n } = {\n result: null,\n dump: null,\n error: null,\n reportHTML: null,\n requestId,\n };\n\n // Helper function to parse action parameters based on type\n const parseActionParams = (\n actionType: string,\n inputPrompt: string | undefined,\n inputParams: any | undefined,\n options: { deepThink?: boolean } = {},\n ): any[] => {\n // If structured params are provided, use them directly\n if (inputParams) {\n switch (actionType) {\n case 'aiInput': {\n if (!inputParams.value || !inputParams.locate) {\n throw new Error(\n 'aiInput requires both value and locate parameters',\n );\n }\n return [\n inputParams.locate,\n { value: inputParams.value, ...options },\n ];\n }\n\n case 'aiKeyboardPress': {\n if (!inputParams.keyName) {\n throw new Error('aiKeyboardPress requires keyName parameter');\n }\n return [\n inputParams.locate,\n { keyName: inputParams.keyName, ...options },\n ];\n }\n\n case 'aiScroll': {\n if (!inputParams.direction || !inputParams.distance) {\n throw new Error(\n 'aiScroll requires direction and distance parameters',\n );\n }\n const scrollParam = {\n direction: inputParams.direction as\n | 'up'\n | 'down'\n | 'left'\n | 'right',\n scrollType: inputParams.scrollType || 'once',\n distance: inputParams.distance,\n ...options,\n };\n return [inputParams.locate, scrollParam];\n }\n\n default:\n // For other actions that only need locate prompt\n return [\n inputParams.locate || inputParams.prompt || inputPrompt,\n options,\n ];\n }\n }\n\n // Fallback to legacy prompt parsing for backward compatibility\n if (!inputPrompt) {\n throw new Error(`Missing prompt for ${actionType}`);\n }\n\n switch (actionType) {\n case 'aiInput': {\n const inputParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n if (inputParts.length !== 2) {\n throw new Error('aiInput requires format: \"value | element\"');\n }\n return [inputParts[1], { value: inputParts[0], ...options }];\n }\n\n case 'aiKeyboardPress': {\n const keyParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const keyName = keyParts[0];\n const keyElement = keyParts[1] || undefined;\n return [keyElement, { keyName, ...options }];\n }\n\n case 'aiScroll': {\n const scrollParts = inputPrompt\n .split('|')\n .map((s: string) => s.trim());\n const scrollArgs = scrollParts[0]\n .split(' ')\n .map((s: string) => s.trim());\n\n if (scrollArgs.length < 2) {\n throw new Error(\n 'aiScroll requires format: \"direction amount | element (optional)\"',\n );\n }\n\n const direction = scrollArgs[0] as\n | 'up'\n | 'down'\n | 'left'\n | 'right';\n const amount = Number.parseInt(scrollArgs[1]);\n const scrollElement = scrollParts[1] || undefined;\n\n const scrollParam = {\n direction,\n scrollType: 'once' as const,\n distance: amount,\n ...options,\n };\n\n return [scrollElement, scrollParam];\n }\n\n default:\n return [inputPrompt, options];\n }\n };\n\n const startTime = Date.now();\n try {\n // Get action space to check for dynamic actions\n const actionSpace = await agent.getActionSpace();\n\n // Check if this is an action in the actionSpace\n const action = actionSpace.find(\n (action) => action.interfaceAlias === type || action.name === type,\n );\n\n if (\n action?.interfaceAlias &&\n typeof (agent as any)[action.interfaceAlias] === 'function'\n ) {\n // Use actionSpace method dynamically\n const parsedParams = parseActionParams(type, prompt, params, {\n deepThink,\n });\n response.result = await (agent as any)[action.interfaceAlias](\n ...parsedParams,\n );\n } else {\n // Get the prompt from either prompt field or params.prompt\n const actualPrompt = prompt || params?.prompt;\n\n if (!actualPrompt) {\n throw new Error(`Missing prompt for ${type}`);\n }\n\n // special handle for methods that need custom parameters or return format\n if (type === 'aiAssert') {\n response.result = await agent.aiAssert(actualPrompt, undefined, {\n keepRawResponse: true,\n });\n } else if (agent && typeof (agent as any)[type] === 'function') {\n // for other methods, check if the agent has the method\n response.result = await (agent as any)[type](actualPrompt, {\n deepThink,\n });\n } else {\n response.error = `Unknown type: ${type}`;\n }\n }\n } catch (error: any) {\n if (!error.message.includes(ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED)) {\n response.error = error.message;\n }\n }\n\n try {\n response.dump = JSON.parse(agent.dumpDataString());\n response.reportHTML = agent.reportHTMLString() || null;\n\n agent.writeOutActionDumps();\n agent.destroy();\n } catch (error: any) {\n console.error(\n `write out dump failed: requestId: ${requestId}, ${error.message}`,\n );\n }\n\n res.send(response);\n const timeCost = Date.now() - startTime;\n\n if (response.error) {\n console.error(\n `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`,\n );\n } else {\n console.log(\n `handle request done after ${timeCost}ms: requestId: ${requestId}`,\n );\n }\n\n // Clean up the agent from activeAgents after execution completes\n if (requestId && this.activeAgents[requestId]) {\n delete this.activeAgents[requestId];\n }\n },\n );\n\n this.app.get('/cancel/:requestId', async (req, res) => {\n const { requestId } = req.params;\n\n if (!requestId) {\n return res.status(400).json({\n error: 'requestId is required',\n });\n }\n\n const agent = this.activeAgents[requestId];\n if (!agent) {\n return res.status(404).json({\n error: 'No active agent found for this requestId',\n });\n }\n\n try {\n await agent.destroy();\n delete this.activeAgents[requestId];\n res.json({ status: 'cancelled' });\n } catch (error: any) {\n console.error(`Failed to cancel agent: ${error.message}`);\n res.status(500).json({\n error: `Failed to cancel: ${error.message}`,\n });\n }\n });\n\n this.app.post(\n '/config',\n express.json({ limit: '1mb' }),\n async (req, res) => {\n const { aiConfig } = req.body;\n\n if (!aiConfig || typeof aiConfig !== 'object') {\n return res.status(400).json({\n error: 'aiConfig is required and must be an object',\n });\n }\n\n try {\n overrideAIConfig(aiConfig);\n\n return res.json({\n status: 'ok',\n message: 'AI config updated successfully',\n });\n } catch (error: any) {\n console.error(`Failed to update AI config: ${error.message}`);\n return res.status(500).json({\n error: `Failed to update AI config: ${error.message}`,\n });\n }\n },\n );\n\n // Set up static file serving after all API routes are defined\n if (this.staticPath) {\n this.app.get('/', (req, res) => {\n // compatible with windows\n res.redirect('/index.html');\n });\n\n this.app.get('*', (req, res) => {\n const requestedPath = join(this.staticPath!, req.path);\n if (existsSync(requestedPath)) {\n res.sendFile(requestedPath);\n } else {\n res.sendFile(join(this.staticPath!, 'index.html'));\n }\n });\n }\n\n return new Promise((resolve, reject) => {\n const port = this.port;\n this.server = this.app.listen(port, () => {\n resolve(this);\n });\n });\n }\n\n close() {\n // close the server\n if (this.server) {\n return this.server.close();\n }\n }\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","defaultPort","PLAYGROUND_SERVER_PORT","errorHandler","err","req","res","next","console","setup","ifInBrowser","ifInWorker","dotenv","PlaygroundServer","uuid","join","context","tmpFile","writeFileSync","port","cors","contextFile","existsSync","readFileSync","requestId","express","randomUUID","type","prompt","params","deepThink","page","agent","tip","response","parseActionParams","actionType","inputPrompt","inputParams","options","Error","scrollParam","inputParts","s","keyParts","keyName","keyElement","undefined","scrollParts","scrollArgs","direction","amount","Number","scrollElement","startTime","Date","actionSpace","action","parsedParams","actualPrompt","error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","JSON","timeCost","aiConfig","overrideAIConfig","requestedPath","Promise","resolve","reject","pageClass","agentClass","staticPath","getTmpDir"],"mappings":"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"}
|
|
@@ -26,6 +26,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
27
|
default: ()=>StaticPage
|
|
28
28
|
});
|
|
29
|
+
const agent_namespaceObject = require("@midscene/core/agent");
|
|
29
30
|
const common_namespaceObject = require("@midscene/shared/common");
|
|
30
31
|
function _define_property(obj, key, value) {
|
|
31
32
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -42,7 +43,7 @@ const ThrowNotImplemented = (methodName)=>{
|
|
|
42
43
|
};
|
|
43
44
|
class StaticPage {
|
|
44
45
|
actionSpace() {
|
|
45
|
-
return
|
|
46
|
+
return (0, agent_namespaceObject.commonWebActionsForWebPage)(this);
|
|
46
47
|
}
|
|
47
48
|
async evaluateJavaScript(script) {
|
|
48
49
|
return ThrowNotImplemented('evaluateJavaScript');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground/static-page.js","sources":["webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/playground/static-page.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction, Point, UIContext } from '@midscene/core';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport type { WebUIContext } from '../web-element';\n\nconst ThrowNotImplemented: any = (methodName: string) => {\n throw new Error(\n `The method \"${methodName}\" is not implemented as designed since this is a static UI context. (${ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED})`,\n );\n};\n\nexport default class StaticPage implements AbstractPage {\n pageType = 'static';\n\n private uiContext: WebUIContext;\n\n constructor(uiContext: WebUIContext) {\n if (uiContext.tree) {\n this.uiContext = uiContext;\n } else {\n this.uiContext = Object.assign(uiContext, {\n tree: {\n node: null,\n children: [],\n },\n });\n }\n }\n\n actionSpace(): DeviceAction[] {\n //
|
|
1
|
+
{"version":3,"file":"playground/static-page.js","sources":["webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/playground/static-page.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction, Point, UIContext } from '@midscene/core';\nimport { commonWebActionsForWebPage } from '@midscene/core/agent';\nimport type { AbstractPage } from '@midscene/core/device';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\nimport type { WebUIContext } from '../web-element';\n\nconst ThrowNotImplemented: any = (methodName: string) => {\n throw new Error(\n `The method \"${methodName}\" is not implemented as designed since this is a static UI context. (${ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED})`,\n );\n};\n\nexport default class StaticPage implements AbstractPage {\n pageType = 'static';\n\n private uiContext: WebUIContext;\n\n constructor(uiContext: WebUIContext) {\n if (uiContext.tree) {\n this.uiContext = uiContext;\n } else {\n this.uiContext = Object.assign(uiContext, {\n tree: {\n node: null,\n children: [],\n },\n });\n }\n }\n\n actionSpace(): DeviceAction[] {\n // Return common web actions for planning, but they won't actually execute\n return commonWebActionsForWebPage(this);\n }\n\n async evaluateJavaScript<T = any>(script: string): Promise<T> {\n return ThrowNotImplemented('evaluateJavaScript');\n }\n\n // @deprecated\n async getElementsInfo() {\n return ThrowNotImplemented('getElementsInfo');\n }\n\n async getElementsNodeTree() {\n return ThrowNotImplemented('getElementsNodeTree');\n }\n\n async getXpathsById(id: string) {\n return ThrowNotImplemented('getXpathsById');\n }\n\n async getXpathsByPoint(point: Point) {\n return ThrowNotImplemented('getXpathsByPoint');\n }\n\n async getElementInfoByXpath(xpath: string) {\n return ThrowNotImplemented('getElementInfoByXpath');\n }\n\n async size() {\n return this.uiContext.size;\n }\n\n async screenshotBase64() {\n const base64 = this.uiContext.screenshotBase64;\n if (!base64) {\n throw new Error('screenshot base64 is empty');\n }\n return base64;\n }\n\n async url() {\n return Promise.resolve(this.uiContext.url || '');\n }\n\n async scrollUntilTop(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilTop');\n }\n\n async scrollUntilBottom(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilBottom');\n }\n\n async scrollUntilLeft(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilLeft');\n }\n\n async scrollUntilRight(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilRight');\n }\n\n async scrollUp(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollUp');\n }\n\n async scrollDown(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollDown');\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollLeft');\n }\n\n async scrollRight(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollRight');\n }\n\n async clearInput() {\n return ThrowNotImplemented('clearInput');\n }\n\n mouse = {\n click: ThrowNotImplemented.bind(null, 'mouse.click'),\n wheel: ThrowNotImplemented.bind(null, 'mouse.wheel'),\n move: ThrowNotImplemented.bind(null, 'mouse.move'),\n drag: ThrowNotImplemented.bind(null, 'mouse.drag'),\n };\n\n keyboard = {\n type: ThrowNotImplemented.bind(null, 'keyboard.type'),\n press: ThrowNotImplemented.bind(null, 'keyboard.press'),\n };\n\n async destroy(): Promise<void> {\n //\n }\n\n async getContext(): Promise<UIContext> {\n return this.uiContext;\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","ThrowNotImplemented","methodName","Error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","StaticPage","commonWebActionsForWebPage","script","id","point","xpath","base64","Promise","startingPoint","distance","uiContext"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"Browser use",
|
|
9
9
|
"Android use"
|
|
10
10
|
],
|
|
11
|
-
"version": "0.27.3
|
|
11
|
+
"version": "0.27.3",
|
|
12
12
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
13
13
|
"homepage": "https://midscenejs.com/",
|
|
14
14
|
"main": "./dist/lib/index.js",
|
|
@@ -123,8 +123,8 @@
|
|
|
123
123
|
"http-server": "14.1.1",
|
|
124
124
|
"socket.io": "^4.8.1",
|
|
125
125
|
"socket.io-client": "4.8.1",
|
|
126
|
-
"@midscene/core": "0.27.3
|
|
127
|
-
"@midscene/shared": "0.27.3
|
|
126
|
+
"@midscene/core": "0.27.3",
|
|
127
|
+
"@midscene/shared": "0.27.3"
|
|
128
128
|
},
|
|
129
129
|
"devDependencies": {
|
|
130
130
|
"devtools-protocol": "0.0.1380148",
|