mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 21:05:09 +00:00
* clean-up bunch of files for re-write * more clean-up and adding basic agent * Minor fix moved types into respective files. * Deleted bunch of old files backup Update gitignore Deleted a bunch of files Remove message manager Deleted old docs Update rules rename Profiler to profiler * Temporarily adding old code * Adding two small things back * backup * Implemented LangChainProvider and updated cursor rules backup LangChainProvider curosr rules * Implement tests for LangChainProvider -- unit test and integration test integration test passes integration test backup * Tool Design Tools Desing tools design * NavigationTool ready NavigationTool ready NavigationTool ready NaivgationTool ready backup * MessageManager MessageManager backup * Fixed integration test * Agent design new Updated agent design and added bunch of /NTN commands agent new design * Delete old agent design * MessageManagerReadOnly class * PlannerTool ready PlannerTool almost ready * ToolManager and DoneTool * Integration of BrowserAgent * BrowserAgent implementation v0.1 * BrowserAgent small fix v0.2 * Tool calling design too call design tool design claude * Update agent tool design with // NTN * add zod-to-json npm install * BrowserAGent v0.3 * BrowserAgent v0.4 * BrowserAgent v0.5 * fixes * Build error fixes in my NEWLY added code build errors fix * Build error fixes in old code (integration work) backup * Comment StreamEventProcessor for now, it is not used * Small build error fix * Small rename * Added integration test to check structuredLLM and changed to 4o-mini change default to nxtscape integration test * Small docstring * Simplified BrowserAgent code and added integration test Simplified BrowserAgent code BrowserAGent integrationt est * Update CLAUDE.md with project memory and instructions on how to write code Update CLAUDE.md with project memory and instructions on how to write code Project Memory * Just a mova.. Moved ToolManager outside. Build works. * TabOperations tool TabOperations Tool and fixing some test tab operations * Update CLAUDE.md * Added ClassificationTool classifiction tool classification prommpt * Refactored and simplified PlannerTool unit test and integration test * Updated Plnnaer tool * Update CLAUDE.md * BrowserAgent modified to do classification BrowserAgent with classification * minor fix to ToolManager * Instead of ToolCall and ToolResult -- just updating message manager once * minor fix to BrowserAgent integration test * Changed done to "done_tool" * Updated CLAUDE.md to reflect understanding of claude * Uncommented stream event processor * Renamed EventBus to StreamEventBus * Commented StreamEventProcessor * Event Processor * Integrated EventProcessor with BrowserAgent Added EventProcessor to BrowserAgetn * Renamed StreamEventBus to EventBus * Made EventBus required parameter in ExecutionContext * PlanGenerator rewrite PlanGenerator rewrite backup * For simple task, explicitly tell it to call done tool * Max attempts for simple task * backup * Revert "backup" This reverts commit 7d79a3d4d5774bfef79ec9827878b74edad3593f. * Consolidating where EventBus and EventProcessor are created and initialized backup * Update CLAUDE.md Update CLAUDE.md * Improving agent loop code Cleaned up processTooCall classification task * Create test-writer subAgent test-agent-prompt test agent prompt test-agent-prompt Update test-writer.md * BrowserAgent test Browseragent test BrowserAgent test * BrowserAgent refactor backup backup * Minor fixes * Minor fix * minor change -- NEW AGENT LOOP IS WORKING WELL * Update cursor rules * Small change * Improved BrowserAgent integration test Improved BrowserAgent integration test * Small change * Update CLAUDE.md * Different tools * FindElementTool is ready Find element update backup find element backup * Updated to test strings to say "tests..." * ScrollTool is ready * RefreshStateTool is updated as well * MessageManager updated * SearchTool is ready backup * Interaction Element is also ready * Add debugMessage emitter * ValidatorTool ready and tests are passing Validation Tool validator tool backup backup * GroupTabs tool ready * Registered all the tools * Planning changed to 5 steps * BrowserAgent integration test fix * Minor string changes * backup * Removed too many confusing events in EventProcessor -- there is only event.info right now * Abort control implemented backup Abort * Formatter for toolResult Formatter for toolResult backup * Always render using Markdown * Minor fix --------- Co-authored-by: Nikhil Sonti <nikhilsv92@gmail.com>
250 lines
8.1 KiB
TypeScript
250 lines
8.1 KiB
TypeScript
import { z } from 'zod';
|
|
import { NxtscapeTool } from '../base/NxtscapeTool';
|
|
import { ToolConfig } from '../base/ToolConfig';
|
|
import { ExecutionContext } from '@/lib/runtime/ExecutionContext';
|
|
|
|
/**
|
|
* Enum for search providers
|
|
*/
|
|
export const SearchProviderEnum = z.enum([
|
|
'google', // Google search
|
|
'amazon', // Amazon product search
|
|
'google_maps', // Google Maps location search
|
|
'google_finance' // Google Finance stock/financial search
|
|
]);
|
|
|
|
export type SearchProvider = z.infer<typeof SearchProviderEnum>;
|
|
|
|
/**
|
|
* Schema for search tool input
|
|
*/
|
|
export const SearchInputSchema = z.object({
|
|
searchProvider: SearchProviderEnum, // The search provider to use
|
|
query: z.string(), // The search query
|
|
intent: z.string().optional() // Optional description of why this search is being performed
|
|
});
|
|
|
|
export type SearchInput = z.infer<typeof SearchInputSchema>;
|
|
|
|
/**
|
|
* Schema for search tool output
|
|
*/
|
|
export const SearchOutputSchema = z.object({
|
|
success: z.boolean(), // Whether the operation succeeded
|
|
searchProvider: SearchProviderEnum, // Search provider that was used
|
|
message: z.string(), // Human-readable result message
|
|
query: z.string(), // The search query that was used
|
|
url: z.string() // The URL that was navigated to
|
|
});
|
|
|
|
export type SearchOutput = z.infer<typeof SearchOutputSchema>;
|
|
|
|
/**
|
|
* Tool for performing searches across different providers
|
|
*/
|
|
export class SearchTool extends NxtscapeTool<SearchInput, SearchOutput> {
|
|
constructor(executionContext: ExecutionContext) {
|
|
const config: ToolConfig<SearchInput, SearchOutput> = {
|
|
name: 'search',
|
|
description: 'Perform searches on different platforms. Providers: "google" (general web search), "amazon" (product search), "google_maps" (location search), "google_finance" (stock/financial search). Always pass searchProvider and query.',
|
|
category: 'navigation',
|
|
version: '1.0.0',
|
|
inputSchema: SearchInputSchema,
|
|
outputSchema: SearchOutputSchema,
|
|
examples: [
|
|
{
|
|
description: 'Search on Google',
|
|
input: {
|
|
searchProvider: 'google',
|
|
query: 'best programming laptops 2024',
|
|
intent: 'Finding information about programming laptops'
|
|
},
|
|
output: {
|
|
success: true,
|
|
searchProvider: 'google',
|
|
message: 'Searched for "best programming laptops 2024" on Google',
|
|
query: 'best programming laptops 2024',
|
|
url: 'https://www.google.com/search?q=best+programming+laptops+2024'
|
|
}
|
|
},
|
|
{
|
|
description: 'Search on Amazon',
|
|
input: {
|
|
searchProvider: 'amazon',
|
|
query: 'mechanical keyboard',
|
|
intent: 'Looking for mechanical keyboards on Amazon'
|
|
},
|
|
output: {
|
|
success: true,
|
|
searchProvider: 'amazon',
|
|
message: 'Searched for "mechanical keyboard" on Amazon',
|
|
query: 'mechanical keyboard',
|
|
url: 'https://www.amazon.com/s?k=mechanical+keyboard'
|
|
}
|
|
},
|
|
{
|
|
description: 'Search on Google Maps',
|
|
input: {
|
|
searchProvider: 'google_maps',
|
|
query: 'coffee shops near Times Square NYC',
|
|
intent: 'Finding coffee shops in Times Square area'
|
|
},
|
|
output: {
|
|
success: true,
|
|
searchProvider: 'google_maps',
|
|
message: 'Searched for "coffee shops near Times Square NYC" on Google Maps',
|
|
query: 'coffee shops near Times Square NYC',
|
|
url: 'https://www.google.com/maps/search/coffee+shops+near+Times+Square+NYC'
|
|
}
|
|
},
|
|
{
|
|
description: 'Search on Google Finance',
|
|
input: {
|
|
searchProvider: 'google_finance',
|
|
query: 'AAPL',
|
|
intent: 'Looking up Apple stock information'
|
|
},
|
|
output: {
|
|
success: true,
|
|
searchProvider: 'google_finance',
|
|
message: 'Searched for "AAPL" on Google Finance',
|
|
query: 'AAPL',
|
|
url: 'https://www.google.com/finance/quote/AAPL:NASDAQ'
|
|
}
|
|
}
|
|
],
|
|
streamingConfig: {
|
|
displayName: 'Search',
|
|
icon: '🔍',
|
|
progressMessage: 'Performing search...'
|
|
}
|
|
};
|
|
|
|
super(config, executionContext);
|
|
}
|
|
|
|
/**
|
|
* Override: Generate contextual display message based on search provider
|
|
*/
|
|
getProgressMessage(args: SearchInput): string {
|
|
try {
|
|
// Note: args should already be parsed by StreamEventProcessor
|
|
|
|
const searchProvider = args?.searchProvider;
|
|
const query = args?.query;
|
|
const intent = args?.intent;
|
|
|
|
// Use intent if provided, otherwise generate based on provider
|
|
if (intent) {
|
|
return intent;
|
|
}
|
|
|
|
const providerNames = {
|
|
'google': 'Google',
|
|
'amazon': 'Amazon',
|
|
'google_maps': 'Google Maps',
|
|
'google_finance': 'Google Finance'
|
|
};
|
|
|
|
const providerName = providerNames[searchProvider as keyof typeof providerNames] || 'Search';
|
|
return query ? `Searching ${providerName} for "${query}"` : `Searching on ${providerName}`;
|
|
} catch {
|
|
return 'Performing search...';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override: Format result based on search provider
|
|
*/
|
|
FormatResultForUI(output: SearchOutput): string {
|
|
if (!output.success) {
|
|
return `❌ ${output.message}`;
|
|
}
|
|
|
|
const providerIcons = {
|
|
'google': '🔍',
|
|
'amazon': '🛒',
|
|
'google_maps': '📍',
|
|
'google_finance': '📈'
|
|
};
|
|
|
|
const icon = providerIcons[output.searchProvider] || '🔍';
|
|
return `${icon} Searched: "${output.query}"`;
|
|
}
|
|
|
|
protected async execute(input: SearchInput): Promise<SearchOutput> {
|
|
try {
|
|
// Build the search URL based on the provider
|
|
const searchUrl = this.buildSearchUrl(input.searchProvider, input.query);
|
|
|
|
// Get the current page and navigate
|
|
const page = await this.executionContext.browserContext.getCurrentPage();
|
|
await page.navigateTo(searchUrl);
|
|
|
|
// Wait a bit for the page to load
|
|
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
|
|
const providerNames = {
|
|
'google': 'Google',
|
|
'amazon': 'Amazon',
|
|
'google_maps': 'Google Maps',
|
|
'google_finance': 'Google Finance'
|
|
};
|
|
|
|
const providerName = providerNames[input.searchProvider] || input.searchProvider;
|
|
|
|
// Get the final URL after any redirects
|
|
const finalUrl = page.url();
|
|
|
|
return {
|
|
success: true,
|
|
searchProvider: input.searchProvider,
|
|
message: `Searched for "${input.query}" on ${providerName}`,
|
|
query: input.query,
|
|
url: finalUrl
|
|
};
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
return {
|
|
success: false,
|
|
searchProvider: input.searchProvider,
|
|
message: `Search failed: ${errorMessage}`,
|
|
query: input.query,
|
|
url: ''
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build the search URL for the given provider and query
|
|
*/
|
|
private buildSearchUrl(provider: SearchProvider, query: string): string {
|
|
const encodedQuery = encodeURIComponent(query);
|
|
|
|
switch (provider) {
|
|
case 'google':
|
|
return `https://www.google.com/search?q=${encodedQuery}`;
|
|
|
|
case 'amazon':
|
|
return `https://www.amazon.com/s?k=${encodedQuery}`;
|
|
|
|
case 'google_maps':
|
|
return `https://www.google.com/maps/search/${encodedQuery}`;
|
|
|
|
case 'google_finance':
|
|
// Google Finance has a special format for stock symbols
|
|
// Try to detect if it's a stock symbol (all caps, 1-5 letters)
|
|
if (/^[A-Z]{1,5}$/.test(query.trim())) {
|
|
// Assume NASDAQ for US stocks, but this could be improved
|
|
return `https://www.google.com/finance/quote/${query.trim()}:NASDAQ`;
|
|
}
|
|
// For non-symbol queries, use the search
|
|
return `https://www.google.com/search?q=${encodedQuery}+stock+finance`;
|
|
|
|
default:
|
|
// Fallback to Google search
|
|
return `https://www.google.com/search?q=${encodedQuery}`;
|
|
}
|
|
}
|
|
}
|