Skip to content

Commit 2d3368f

Browse files
waleedlatif1claude
andcommitted
fix(browser-use,stagehand): address PR review feedback
- Browser Use: fetch liveUrl during polling once sessionId is known, instead of immediately after task creation. Handles tasks started without profile_id (where sessionId isn't returned in create response) and ensures session is active before fetching. - Stagehand: coerce empty/whitespace maxSteps strings to undefined so they're dropped from the request body instead of failing zod validation as ''. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cf9460b commit 2d3368f

2 files changed

Lines changed: 35 additions & 14 deletions

File tree

apps/sim/blocks/blocks/stagehand.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,14 @@ Example 3 (Data Collection):
362362
},
363363
params: (params) => {
364364
const next: Record<string, any> = { ...params }
365-
if (typeof next.maxSteps === 'string' && next.maxSteps.trim() !== '') {
366-
const n = Number(next.maxSteps)
367-
next.maxSteps = Number.isFinite(n) ? n : undefined
365+
if (typeof next.maxSteps === 'string') {
366+
const trimmed = next.maxSteps.trim()
367+
if (trimmed === '') {
368+
next.maxSteps = undefined
369+
} else {
370+
const n = Number(trimmed)
371+
next.maxSteps = Number.isFinite(n) ? n : undefined
372+
}
368373
}
369374
return next
370375
},

apps/sim/tools/browser_use/run_task.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,16 @@ interface PollResult {
171171
output: any
172172
steps: any[]
173173
sessionId: string | null
174+
liveUrl: string | null
175+
publicShareUrl: string | null
174176
error?: string
175177
}
176178

177179
async function pollForCompletion(taskId: string, apiKey: string): Promise<PollResult> {
178180
let consecutiveErrors = 0
179181
let sessionId: string | null = null
182+
let liveUrl: string | null = null
183+
let publicShareUrl: string | null = null
180184
const startTime = Date.now()
181185

182186
while (Date.now() - startTime < MAX_POLL_TIME_MS) {
@@ -194,6 +198,8 @@ async function pollForCompletion(taskId: string, apiKey: string): Promise<PollRe
194198
output: null,
195199
steps: [],
196200
sessionId,
201+
liveUrl,
202+
publicShareUrl,
197203
error: `Failed to poll task status after ${MAX_CONSECUTIVE_ERRORS} attempts: ${result.error}`,
198204
}
199205
}
@@ -209,12 +215,23 @@ async function pollForCompletion(taskId: string, apiKey: string): Promise<PollRe
209215

210216
logger.info(`BrowserUse task ${taskId} status: ${status}`)
211217

218+
if (sessionId && !liveUrl) {
219+
const session = await fetchSessionLiveUrl(sessionId, apiKey)
220+
if (session.liveUrl) {
221+
liveUrl = session.liveUrl
222+
logger.info(`BrowserUse live URL: ${liveUrl}`)
223+
}
224+
if (session.publicShareUrl) publicShareUrl = session.publicShareUrl
225+
}
226+
212227
if (['finished', 'failed', 'stopped'].includes(status)) {
213228
return {
214229
success: status === 'finished',
215230
output: taskData.output ?? null,
216231
steps: taskData.steps || [],
217232
sessionId,
233+
liveUrl,
234+
publicShareUrl,
218235
}
219236
}
220237

@@ -228,6 +245,8 @@ async function pollForCompletion(taskId: string, apiKey: string): Promise<PollRe
228245
output: finalResult.data.output ?? null,
229246
steps: finalResult.data.steps || [],
230247
sessionId: finalResult.data.sessionId ?? sessionId,
248+
liveUrl,
249+
publicShareUrl,
231250
}
232251
}
233252

@@ -236,6 +255,8 @@ async function pollForCompletion(taskId: string, apiKey: string): Promise<PollRe
236255
output: null,
237256
steps: [],
238257
sessionId,
258+
liveUrl,
259+
publicShareUrl,
239260
error: `Task did not complete within the maximum polling time (${MAX_POLL_TIME_MS / 1000}s)`,
240261
}
241262
}
@@ -418,21 +439,16 @@ export const runTaskTool: ToolConfig<BrowserUseRunTaskParams, BrowserUseRunTaskR
418439
}
419440
}
420441

421-
const data = (await response.json()) as { id: string; sessionId: string }
442+
const data = (await response.json()) as { id: string; sessionId?: string }
422443
const taskId = data.id
423-
const taskSessionId = sessionId ?? data.sessionId
424-
logger.info(`Created BrowserUse task ${taskId} on session ${taskSessionId}`)
425-
426-
const liveSession = await fetchSessionLiveUrl(taskSessionId, params.apiKey)
427-
if (liveSession.liveUrl) {
428-
logger.info(`BrowserUse live URL: ${liveSession.liveUrl}`)
429-
}
444+
const initialSessionId = sessionId ?? data.sessionId ?? null
445+
logger.info(`Created BrowserUse task ${taskId}`, { sessionId: initialSessionId })
430446

431447
const result = await pollForCompletion(taskId, params.apiKey)
432448

433-
const finalSessionId = result.sessionId ?? taskSessionId ?? null
449+
const finalSessionId = result.sessionId ?? initialSessionId
434450
const shareUrl =
435-
liveSession.publicShareUrl ??
451+
result.publicShareUrl ??
436452
(finalSessionId ? await createShareUrl(finalSessionId, params.apiKey) : null)
437453

438454
if (sessionId) {
@@ -446,7 +462,7 @@ export const runTaskTool: ToolConfig<BrowserUseRunTaskParams, BrowserUseRunTaskR
446462
success: result.success,
447463
output: result.output,
448464
steps: result.steps,
449-
liveUrl: liveSession.liveUrl,
465+
liveUrl: result.liveUrl,
450466
shareUrl,
451467
sessionId: finalSessionId,
452468
},

0 commit comments

Comments
 (0)