Skip to content

Commit b0e48c5

Browse files
committed
Updates to make browser remote port dynamic from prompt
1 parent 4763c4e commit b0e48c5

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

docs/cypress-cloud.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
Could you navigate to this URL in interactive mode (isInteractive = true), and keep it open while I chat with you, DO NOT DO ANYTHING UNTIL I TELL YOU TO CONTINUE.
2-
https://cloud.cypress.io/projects/hkawvm/runs/22055/overview/b890f243-ce56-4047-9252-c99469dfbbea?roarHideRunsWithDiffGroupsAndTags=1&interactive=true
1+
Could you navigate to this URL in interactive mode (browserPort = 7333)
2+
https://cloud.cypress.io/projects/hkawvm/runs/22055/overview/b890f243-ce56-4047-9252-c99469dfbbea?roarHideRunsWithDiffGroupsAndTags=1&interactive=true
3+
4+
Please analyze the failure and let me know if you can fix it.

src/core/Cline.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export class Cline {
7474
private browserSession: BrowserSession
7575
private didEditFile: boolean = false
7676
private isInteractiveMode: boolean = false
77+
private browserPort: string = '7333'
7778
customInstructions?: string
7879
alwaysAllowReadOnly: boolean
7980
alwaysAllowWrite: boolean
@@ -669,16 +670,22 @@ export class Cline {
669670
newUserContent.push(...formatResponse.imageBlocks(responseImages))
670671
}
671672
const wasInteractiveBrowser = (lastRelevantMessageIndex > 0) ? modifiedClineMessages[lastRelevantMessageIndex - 1].text?.includes("interactive mode") : false
673+
let hadBrowserPort = '';
674+
if ( wasInteractiveBrowser ) {
675+
const match = modifiedClineMessages[lastRelevantMessageIndex - 1].text?.match(/\(browserPort\s*=\s*(\d+)\)/)
676+
if (match) {
677+
hadBrowserPort = match[1] ?? this.browserPort;
678+
this.providerRef.deref()?.outputChannel.appendLine(`resumeTaskFromHistory :: browserPort :: ${hadBrowserPort}`)
679+
}
680+
}
672681
await this.overwriteApiConversationHistory(modifiedApiConversationHistory)
673-
await this.initiateTaskLoop(newUserContent, wasInteractiveBrowser)
682+
await this.initiateTaskLoop(newUserContent, wasInteractiveBrowser, hadBrowserPort)
674683
}
675684

676-
private async initiateTaskLoop(userContent: UserContent, wasInteractiveBrowser: boolean = false): Promise<void> {
685+
private async initiateTaskLoop(userContent: UserContent, wasInteractiveBrowser: boolean = false, hadBrowserPort: string = ''): Promise<void> {
677686
// Check if any text block contains "interactive mode"
678687
const hasInteractiveMode = userContent.some((block) => {
679688
if (block.type === "text" && typeof block.text === "string") {
680-
this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: block.text :: ${block.text.toLowerCase()}`)
681-
682689
return (block.type === "text" &&
683690
typeof block.text === "string" &&
684691
block.text.toLowerCase().includes("interactive mode"))
@@ -693,6 +700,17 @@ export class Cline {
693700
// Set interactive mode flag if found in text
694701
if (hasInteractiveMode) {
695702
this.isInteractiveMode = true;
703+
704+
// Parse browserPort if specified in text blocks
705+
userContent.forEach((block) => {
706+
if (block.type === "text" && typeof block.text === "string") {
707+
const match = block.text.match(/\(browserPort\s*=\s*(\d+)\)/)
708+
if (match) {
709+
this.browserPort = match[1] ?? hadBrowserPort;
710+
this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: browserPort :: ${this.browserPort}`)
711+
}
712+
}
713+
})
696714
}
697715

698716
let nextUserContent = userContent;
@@ -701,7 +719,8 @@ export class Cline {
701719
const didEndLoop = await this.recursivelyMakeClineRequests(
702720
nextUserContent,
703721
includeFileDetails,
704-
this.isInteractiveMode // Pass the flag to recursivelyMakeClineRequests
722+
this.isInteractiveMode, // Pass the flag to recursivelyMakeClineRequests
723+
this.browserPort // Pass the browserPort to recursivelyMakeClineRequests
705724
)
706725
includeFileDetails = false
707726

@@ -1493,7 +1512,7 @@ export class Cline {
14931512
// NOTE: it's okay that we call this message since the partial inspect_site is finished streaming. The only scenario we have to avoid is sending messages WHILE a partial message exists at the end of the messages array. For example the api_req_finished message would interfere with the partial message, so we needed to remove that.
14941513
// await this.say("inspect_site_result", "") // no result, starts the loading spinner waiting for result
14951514
await this.say("browser_action_result", "") // starts loading spinner
1496-
await this.browserSession.launchBrowser(this.isInteractiveMode)
1515+
await this.browserSession.launchBrowser(this.isInteractiveMode, this.browserPort)
14971516
browserActionResult = await this.browserSession.navigateToUrl(url)
14981517
} else {
14991518
if (action === "click") {
@@ -1817,7 +1836,8 @@ export class Cline {
18171836
async recursivelyMakeClineRequests(
18181837
userContent: UserContent,
18191838
includeFileDetails: boolean = false,
1820-
isInteractiveMode: boolean = false
1839+
isInteractiveMode: boolean = false,
1840+
browserPort: string = '7333'
18211841
): Promise<boolean> {
18221842
if (this.abort) {
18231843
throw new Error("Cline instance aborted")
@@ -2074,7 +2094,7 @@ export class Cline {
20742094
this.consecutiveMistakeCount++
20752095
}
20762096

2077-
const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent, false, this.isInteractiveMode)
2097+
const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent, false, this.isInteractiveMode, browserPort)
20782098
didEndLoop = recDidEndLoop
20792099
} else {
20802100
// if there's no assistant_responses, that means we got no text or tool_use content blocks from API which we should assume is an error

src/services/browser/BrowserSession.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,42 @@ export class BrowserSession {
1313
private page?: Page
1414
private currentMousePosition?: string
1515
private isInteractive: boolean = false
16+
private browserPort: string = '7333'
1617

1718
constructor(context: vscode.ExtensionContext) {
1819
this.context = context
1920
}
2021

21-
async launchBrowser(interactive: boolean = false) {
22+
async launchBrowser(interactive: boolean = false, port?: string) {
2223
console.log("launch browser called")
2324
this.isInteractive = interactive
2425

26+
// Set browserPort if provided, otherwise use default
27+
if (port) {
28+
this.browserPort = port
29+
}
30+
2531
if (this.browser) {
2632
await this.closeBrowser() // this may happen when the model launches a browser again after having used it already before
2733
}
2834

2935
if (this.isInteractive) {
3036
try {
3137
// Fetch the WebSocket endpoint from Chrome's debugging API
32-
const response = await fetch('http://127.0.0.1:7333/json/version')
38+
const response = await fetch(`http://127.0.0.1:${this.browserPort}/json/version`)
3339
const data = await response.json()
3440
const browserWSEndpoint = data.webSocketDebuggerUrl
3541

3642
if (!browserWSEndpoint) {
37-
throw new Error('Could not get WebSocket endpoint from Chrome debugging API')
43+
throw new Error(`BrowserSession.ts :: launchBrowser :: Could not get webSocketDebuggerUrl from Chrome debugging API, port: ${this.browserPort}`)
3844
}
3945

4046
this.browser = await connect({
4147
browserWSEndpoint,
4248
})
4349
} catch (error) {
44-
console.error("Failed to connect to browser:", error)
45-
throw new Error(`Failed to connect to browser: ${error.message}`)
50+
console.error("BrowserSession.ts :: launchBrowser :: Failed to connect to browser, make sure you have a running browser with --remote-debugging-port=7333", error)
51+
throw new Error(`BrowserSession.ts :: launchBrowser :: Failed to connect to browser: ${error.message}, make sure you have a running browser with --remote-debugging-port=7333`)
4652
}
4753
} else {
4854
this.browser = await launch({
@@ -63,7 +69,7 @@ export class BrowserSession {
6369
return {
6470
screenshot: "",
6571
logs: this.isInteractive ?
66-
"Browser launched in interactive mode. Please confirm when you're done using the browser." :
72+
"Connected to browser in remote debugging mode." :
6773
"Browser launched successfully.",
6874
currentUrl: this.page?.url(),
6975
currentMousePosition: this.currentMousePosition,

0 commit comments

Comments
 (0)