mirror of
https://github.com/web-infra-dev/midscene.git
synced 2025-12-02 10:00:15 +00:00
feat(mcp): make mcp navigated faster (#671)
This commit is contained in:
parent
061ff92c69
commit
81bcc5ec1a
@ -33,7 +33,9 @@
|
||||
"@midscene/core": "workspace:*",
|
||||
"@midscene/shared": "workspace:*",
|
||||
"@modelcontextprotocol/sdk": "1.10.1",
|
||||
"zod": "3.24.3"
|
||||
"zod": "3.24.3",
|
||||
"kill-port": "2.0.1",
|
||||
"@types/kill-port": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"puppeteer": "24.2.0"
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
} from '@midscene/shared/env';
|
||||
import {
|
||||
AgentOverChromeBridge,
|
||||
DefaultBridgeServerPort,
|
||||
allConfigFromEnv,
|
||||
overrideAIConfig,
|
||||
} from '@midscene/web/bridge-mode';
|
||||
@ -15,6 +16,7 @@ import type {
|
||||
ImageContent,
|
||||
TextContent,
|
||||
} from '@modelcontextprotocol/sdk/types.js';
|
||||
import killPort from 'kill-port';
|
||||
import { z } from 'zod';
|
||||
import { PuppeteerBrowserAgent, ensureBrowser } from './puppeteer';
|
||||
|
||||
@ -33,10 +35,12 @@ export class MidsceneManager {
|
||||
private mcpServer: McpServer; // Add server instance
|
||||
private agent?: AgentOverChromeBridge | PuppeteerBrowserAgent;
|
||||
private puppeteerMode = getAIConfigInBoolean(MIDSCENE_MCP_USE_PUPPETEER_MODE);
|
||||
private initKillPort: Promise<void>;
|
||||
constructor(server: McpServer) {
|
||||
this.mcpServer = server;
|
||||
this.initEnv();
|
||||
this.registerTools();
|
||||
this.initKillPort = this.killPort();
|
||||
}
|
||||
|
||||
private initEnv() {
|
||||
@ -51,6 +55,14 @@ export class MidsceneManager {
|
||||
overrideAIConfig(envOverrides);
|
||||
}
|
||||
|
||||
private async killPort() {
|
||||
// Avoid existing bridge-mode servers that haven't exited occupying ports, which would cause new mcp server connections to take a long time
|
||||
// And the killPort operation may take a long time
|
||||
try {
|
||||
await killPort(DefaultBridgeServerPort, 'tcp');
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// Asynchronously initializes or re-initializes the browser agent.
|
||||
// Accepts an optional 'reInit' flag (default: false). If true, forces re-creation of the agent.
|
||||
private async initAgent(openNewTabWithUrl?: string) {
|
||||
@ -80,6 +92,7 @@ export class MidsceneManager {
|
||||
private async initAgentByBridgeMode(
|
||||
openNewTabWithUrl?: string,
|
||||
): Promise<AgentOverChromeBridge> {
|
||||
await this.initKillPort;
|
||||
let agent: AgentOverChromeBridge;
|
||||
try {
|
||||
// Create a new agent instance designed for bridge mode.
|
||||
|
||||
@ -135,7 +135,6 @@
|
||||
"inquirer": "10.1.5",
|
||||
"js-sha256": "0.11.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"kill-port": "2.0.1",
|
||||
"openai": "4.81.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"socket.io-client": "4.8.1"
|
||||
@ -148,7 +147,6 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/js-yaml": "4.0.9",
|
||||
"@types/kill-port": "2.0.3",
|
||||
"@types/node": "^18.0.0",
|
||||
"playwright": "1.44.1",
|
||||
"puppeteer": "24.2.0",
|
||||
|
||||
@ -20,13 +20,11 @@ const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
// actually, this is a proxy to the page in browser side
|
||||
export const getBridgePageInCliSide = (
|
||||
forceCloseServer?: boolean,
|
||||
timeout?: number | false,
|
||||
): ChromeExtensionPageCliSide => {
|
||||
const server = new BridgeServer(DefaultBridgeServerPort);
|
||||
server.listen({
|
||||
timeout,
|
||||
forceCloseServer,
|
||||
});
|
||||
const bridgeCaller = (method: string) => {
|
||||
return async (...args: any[]) => {
|
||||
@ -109,10 +107,7 @@ export class AgentOverChromeBridge extends PageAgent<ChromeExtensionPageCliSide>
|
||||
serverListeningTimeout?: number | false;
|
||||
},
|
||||
) {
|
||||
const page = getBridgePageInCliSide(
|
||||
opts?.forceCloseServer,
|
||||
opts?.serverListeningTimeout,
|
||||
);
|
||||
const page = getBridgePageInCliSide(opts?.serverListeningTimeout);
|
||||
super(
|
||||
page,
|
||||
Object.assign(opts || {}, {
|
||||
|
||||
@ -3,3 +3,5 @@ import { AgentOverChromeBridge } from './agent-cli-side';
|
||||
export { AgentOverChromeBridge };
|
||||
|
||||
export { overrideAIConfig, allConfigFromEnv } from '@midscene/shared/env';
|
||||
|
||||
export { DefaultBridgeServerPort } from './common';
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { logMsg } from '@midscene/shared/utils';
|
||||
import killPort from 'kill-port';
|
||||
import { Server, type Socket as ServerSocket } from 'socket.io';
|
||||
import {
|
||||
type BridgeCall,
|
||||
@ -34,13 +33,9 @@ export class BridgeServer {
|
||||
async listen(
|
||||
opts: {
|
||||
timeout?: number | false;
|
||||
forceCloseServer?: boolean;
|
||||
} = {},
|
||||
): Promise<void> {
|
||||
const { timeout = 30000, forceCloseServer = false } = opts;
|
||||
if (forceCloseServer) {
|
||||
await this.killPort();
|
||||
}
|
||||
const { timeout = 30000 } = opts;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.listeningTimerFlag) {
|
||||
@ -166,15 +161,6 @@ export class BridgeServer {
|
||||
});
|
||||
}
|
||||
|
||||
async killPort() {
|
||||
if (!this.listeningTimerFlag) {
|
||||
// kill the port if it is already occupied
|
||||
try {
|
||||
await killPort(this.port, 'tcp');
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
private connectionLostErrorMsg = () => {
|
||||
return `Connection lost, reason: ${this.connectionLostReason}`;
|
||||
};
|
||||
|
||||
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@ -555,12 +555,18 @@ importers:
|
||||
'@rslib/core':
|
||||
specifier: ^0.6.2
|
||||
version: 0.6.3(typescript@5.8.3)
|
||||
'@types/kill-port':
|
||||
specifier: 2.0.3
|
||||
version: 2.0.3
|
||||
'@types/node':
|
||||
specifier: ^18.0.0
|
||||
version: 18.19.62
|
||||
dotenv:
|
||||
specifier: 16.4.5
|
||||
version: 16.4.5
|
||||
kill-port:
|
||||
specifier: 2.0.1
|
||||
version: 2.0.1
|
||||
typescript:
|
||||
specifier: ^5.8.2
|
||||
version: 5.8.3
|
||||
@ -740,9 +746,6 @@ importers:
|
||||
js-yaml:
|
||||
specifier: 4.1.0
|
||||
version: 4.1.0
|
||||
kill-port:
|
||||
specifier: 2.0.1
|
||||
version: 2.0.1
|
||||
openai:
|
||||
specifier: 4.81.0
|
||||
version: 4.81.0(ws@8.18.1)(zod@3.24.3)
|
||||
@ -774,9 +777,6 @@ importers:
|
||||
'@types/js-yaml':
|
||||
specifier: 4.0.9
|
||||
version: 4.0.9
|
||||
'@types/kill-port':
|
||||
specifier: 2.0.3
|
||||
version: 2.0.3
|
||||
'@types/node':
|
||||
specifier: ^18.0.0
|
||||
version: 18.19.62
|
||||
@ -5090,9 +5090,6 @@ packages:
|
||||
'@types/node@18.19.62':
|
||||
resolution: {integrity: sha512-UOGhw+yZV/icyM0qohQVh3ktpY40Sp7tdTW7HxG3pTd7AiMrlFlAJNUrGK9t5mdW0+ViQcFV74zCSIx9ZJpncA==}
|
||||
|
||||
'@types/node@18.19.86':
|
||||
resolution: {integrity: sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==}
|
||||
|
||||
'@types/node@18.19.87':
|
||||
resolution: {integrity: sha512-OIAAu6ypnVZHmsHCeJ+7CCSub38QNBS9uceMQeg7K5Ur0Jr+wG9wEOEvvMbhp09pxD5czIUy/jND7s7Tb6Nw7A==}
|
||||
|
||||
@ -18946,7 +18943,7 @@ snapshots:
|
||||
|
||||
'@types/connect@3.4.38':
|
||||
dependencies:
|
||||
'@types/node': 18.19.86
|
||||
'@types/node': 18.19.87
|
||||
|
||||
'@types/conventional-commits-parser@5.0.1':
|
||||
dependencies:
|
||||
@ -19086,7 +19083,7 @@ snapshots:
|
||||
|
||||
'@types/mute-stream@0.0.4':
|
||||
dependencies:
|
||||
'@types/node': 18.19.62
|
||||
'@types/node': 18.19.87
|
||||
|
||||
'@types/node-fetch@2.6.11':
|
||||
dependencies:
|
||||
@ -19101,10 +19098,6 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
'@types/node@18.19.86':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
'@types/node@18.19.87':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
@ -19154,7 +19147,7 @@ snapshots:
|
||||
'@types/send@0.17.4':
|
||||
dependencies:
|
||||
'@types/mime': 1.3.5
|
||||
'@types/node': 18.19.62
|
||||
'@types/node': 18.19.87
|
||||
|
||||
'@types/serve-static@1.15.7':
|
||||
dependencies:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user