fix(tools): updated browser use and stagehand to use the latest models (#2319)

* fix(stagehand): incl stagehand in the standalone build

* fix(stagehand): updated browser use and stagehand to use the latest models
This commit is contained in:
Waleed
2025-12-11 14:39:25 -08:00
committed by GitHub
parent c592e54118
commit 3b9cbeaa49
5 changed files with 52 additions and 33 deletions

View File

@@ -496,7 +496,7 @@ export async function POST(request: NextRequest) {
verbose: 1,
logger: (msg) => logger.info(typeof msg === 'string' ? msg : JSON.stringify(msg)),
model: {
modelName: 'claude-sonnet-4-20250514',
modelName: 'anthropic/claude-3-7-sonnet-latest',
apiKey: apiKey,
},
})
@@ -704,7 +704,14 @@ The system will substitute actual values when these placeholders are used, keepi
`.trim()
const agent = stagehand.agent({
model: 'anthropic/claude-sonnet-4-20250514',
model: {
modelName: 'anthropic/claude-3-7-sonnet-latest',
apiKey: apiKey,
},
executionModel: {
modelName: 'anthropic/claude-3-7-sonnet-latest',
apiKey: apiKey,
},
systemPrompt: `${agentInstructions}\n\n${additionalContext}`,
})
@@ -795,6 +802,9 @@ The system will substitute actual values when these placeholders are used, keepi
})
let structuredOutput = null
const hasOutputSchema =
outputSchema && typeof outputSchema === 'object' && outputSchema !== null
if (agentResult.message) {
try {
let jsonContent = agentResult.message
@@ -807,33 +817,31 @@ The system will substitute actual values when these placeholders are used, keepi
structuredOutput = JSON.parse(jsonContent)
logger.info('Successfully parsed structured output from agent response')
} catch (parseError) {
logger.error('Failed to parse JSON from agent message', {
error: parseError,
message: agentResult.message,
})
if (hasOutputSchema) {
logger.warn('Failed to parse JSON from agent message, attempting fallback extraction', {
error: parseError,
})
if (
outputSchema &&
typeof outputSchema === 'object' &&
outputSchema !== null &&
stagehand
) {
try {
logger.info('Attempting to extract structured data using Stagehand extract')
const schemaObj = getSchemaObject(outputSchema)
const zodSchema = ensureZodObject(logger, schemaObj)
if (stagehand) {
try {
logger.info('Attempting to extract structured data using Stagehand extract')
const schemaObj = getSchemaObject(outputSchema)
const zodSchema = ensureZodObject(logger, schemaObj)
structuredOutput = await stagehand.extract(
'Extract the requested information from this page according to the schema',
zodSchema
)
structuredOutput = await stagehand.extract(
'Extract the requested information from this page according to the schema',
zodSchema
)
logger.info('Successfully extracted structured data as fallback', {
keys: structuredOutput ? Object.keys(structuredOutput) : [],
})
} catch (extractError) {
logger.error('Fallback extraction also failed', { error: extractError })
logger.info('Successfully extracted structured data as fallback', {
keys: structuredOutput ? Object.keys(structuredOutput) : [],
})
} catch (extractError) {
logger.error('Fallback extraction also failed', { error: extractError })
}
}
} else {
logger.info('Agent returned plain text response (no schema provided)')
}
}
}

View File

@@ -86,7 +86,7 @@ export async function POST(request: NextRequest) {
verbose: 1,
logger: (msg) => logger.info(typeof msg === 'string' ? msg : JSON.stringify(msg)),
model: {
modelName: 'gpt-4o',
modelName: 'openai/gpt-4o',
apiKey: apiKey,
},
})

View File

@@ -32,11 +32,23 @@ export const BrowserUseBlock: BlockConfig<BrowserUseResponse> = {
title: 'Model',
type: 'dropdown',
options: [
{ label: 'gpt-4o', id: 'gpt-4o' },
{ label: 'gemini-2.0-flash', id: 'gemini-2.0-flash' },
{ label: 'gemini-2.0-flash-lite', id: 'gemini-2.0-flash-lite' },
{ label: 'claude-3-7-sonnet-20250219', id: 'claude-3-7-sonnet-20250219' },
{ label: 'llama-4-maverick-17b-128e-instruct', id: 'llama-4-maverick-17b-128e-instruct' },
{ label: 'Browser Use LLM', id: 'browser-use-llm' },
{ label: 'GPT-4o', id: 'gpt-4o' },
{ label: 'GPT-4o Mini', id: 'gpt-4o-mini' },
{ label: 'GPT-4.1', id: 'gpt-4.1' },
{ label: 'GPT-4.1 Mini', id: 'gpt-4.1-mini' },
{ label: 'O3', id: 'o3' },
{ label: 'O4 Mini', id: 'o4-mini' },
{ label: 'Gemini 2.5 Flash', id: 'gemini-2.5-flash' },
{ label: 'Gemini 2.5 Pro', id: 'gemini-2.5-pro' },
{ label: 'Gemini 3 Pro Preview', id: 'gemini-3-pro-preview' },
{ label: 'Gemini Flash Latest', id: 'gemini-flash-latest' },
{ label: 'Gemini Flash Lite Latest', id: 'gemini-flash-lite-latest' },
{ label: 'Claude 3.7 Sonnet', id: 'claude-3-7-sonnet-20250219' },
{ label: 'Claude Sonnet 4', id: 'claude-sonnet-4-20250514' },
{ label: 'Claude Sonnet 4.5', id: 'claude-sonnet-4-5-20250929' },
{ label: 'Claude Opus 4.5', id: 'claude-opus-4-5-20251101' },
{ label: 'Llama 4 Maverick', id: 'llama-4-maverick-17b-128e-instruct' },
],
},
{

View File

@@ -79,6 +79,7 @@ const nextConfig: NextConfig = {
'pino',
'pino-pretty',
'thread-stream',
'@browserbasehq/stagehand',
],
experimental: {
optimizeCss: true,

View File

@@ -195,8 +195,6 @@ async function flushSubblockUpdate(
sock.emit('operation-confirmed', { operationId: opId, serverTimestamp: Date.now() })
}
})
logger.debug(`Flushed subblock update ${workflowId}: ${blockId}.${subblockId}`)
} else {
pending.opToSocket.forEach((socketId, opId) => {
const sock = (roomManager as any).io?.sockets?.sockets?.get(socketId)