-
Notifications
You must be signed in to change notification settings - Fork 1.5k
chore(vscode): browser_connect via MCP Switcher and out of process backend #823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Can we go lower level and implement it in src/mcp? |
src/mcp/server.ts
Outdated
onChangeProxyTarget: ServerBackend['onChangeProxyTarget']; | ||
} | ||
|
||
export class ServerBackendProxy implements ServerBackend { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServerBackendSwitcher?
src/program.ts
Outdated
const proxy = new ServerBackendProxy( | ||
new BrowserServerBackend(config, factories), | ||
{ | ||
async onChangeProxyTarget(target) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd inline this logic into ServerBackendProxy and have it accept a list of backed factories.
this._target.onChangeProxyTarget = this._handleChangeProxyTarget; | ||
if (this._initializeInfo) { | ||
old.serverClosed?.(); | ||
await this.initialize(this._initializeInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
await this.initialize(this._initializeInfo); | |
await this._target.initialize?.(this._initializeInfo); |
constructor(private readonly _targetFactories: Record<string, (options: any) => ServerBackend>) { | ||
const defaultTargetFactory = this._targetFactories['']; | ||
this._target = defaultTargetFactory({}); | ||
this._target.onChangeProxyTarget = this._handleChangeProxyTarget; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this._handleChangeProxyTarget.bind(this) ?
private _initializeInfo?: InitializeInfo; | ||
|
||
constructor(private readonly _targetFactories: Record<string, (options: any) => ServerBackend>) { | ||
const defaultTargetFactory = this._targetFactories['']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use "default" key for the default factory?
@@ -210,6 +210,10 @@ export class Context { | |||
for (const page of browserContext.pages()) | |||
this._onPageCreated(page); | |||
browserContext.on('page', page => this._onPageCreated(page)); | |||
browserContext.on('close', () => { | |||
this._browserContextPromise = undefined; | |||
this._closeBrowserContextPromise = undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should resolve this promise in case there are waiting close
calls?
].join('\n'), | ||
inputSchema: z.object({ | ||
method: z.enum(factories.map(factory => factory.name) as [string, ...string[]]).default(factories[0].name).describe('The method to use to connect to the browser'), | ||
method: z.enum(contextSwitchers.map(c => c.name) as [string, ...string[]]).describe('The method to use to connect to the browser'), | ||
options: askForOptions ? z.any().optional().describe('options for the connection method') : z.void(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not define this parameter if askForOptions is false
name: factory.name, | ||
description: factory.description, | ||
switch: async () => { | ||
await this._setContextFactory(factory); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that we now mix them and have 2 ways to switch how we connect to the browser. Maybe migrate the context factories to the backend switchers as well or what is the plan?
this._extraEnv = env; | ||
} | ||
|
||
async startRunner(runnerParams: any, options: { onStdOut?: (chunk: Buffer | string) => void, onStdErr?: (chunk: Buffer | string) => void } = {}): Promise<ProcessExitData | undefined> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is Runner
?
const old = this._target; | ||
old.onChangeProxyTarget = undefined; | ||
this._target = target; | ||
this._target.onChangeProxyTarget = this._handleChangeProxyTarget; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have to assign onChangeProxyTarget
to the target while we could just handle that particular tool call in this class ant spare all other backends from the knowledge about onChangeProxyTarget
? Basically similar to how we switch between context factories but just intercept the backend switch call here.
No description provided.