mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 12:55: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>
186 lines
6.0 KiB
TypeScript
186 lines
6.0 KiB
TypeScript
import { z } from 'zod';
|
|
import { HumanMessage } from '@langchain/core/messages';
|
|
import { wrapUntrustedContent } from '@/lib/utils/MessageUtils';
|
|
import { ExecutionContext } from '@/lib/runtime/ExecutionContext';
|
|
|
|
/**
|
|
* Base abstract class for all agent prompts.
|
|
* Provides a structured way to build and manage complex prompts.
|
|
*/
|
|
export abstract class BasePrompt {
|
|
/**
|
|
* The name of the agent this prompt is for
|
|
*/
|
|
protected abstract readonly agentName: string;
|
|
|
|
/**
|
|
* Tool documentation string (if any)
|
|
*/
|
|
protected toolDocumentation: string = '';
|
|
|
|
/**
|
|
* Constructor
|
|
* @param toolDocumentation - Optional tool documentation to include
|
|
*/
|
|
constructor(toolDocumentation?: string) {
|
|
if (toolDocumentation) {
|
|
this.toolDocumentation = toolDocumentation;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate the complete prompt by combining all sections
|
|
* @returns The complete system prompt
|
|
*/
|
|
public abstract generate(): string;
|
|
|
|
|
|
|
|
/**
|
|
* Builds the user message containing the browser state
|
|
* @param context - The agent context containing browser state and options
|
|
* @param useVision - Legacy parameter, ignored in V2 (no vision support)
|
|
* @returns HumanMessage with browser state information
|
|
*/
|
|
public async buildBrowserStateUserMessage(context: ExecutionContext, useVision: boolean): Promise<HumanMessage> {
|
|
// Get browser state (V2 doesn't support vision/screenshots)
|
|
const browserState = await context.browserContext.getBrowserState();
|
|
|
|
// Get interactive elements as pre-formatted string
|
|
// V2 provides both clickable and typeable elements
|
|
// Note: The numbers in brackets [11], [23] etc. are nodeIds which are sequential indices
|
|
const clickableElements = browserState.clickableElementsString;
|
|
const typeableElements = browserState.typeableElementsString;
|
|
|
|
// Combine elements into a single display
|
|
let rawElementsText = '';
|
|
if (clickableElements || typeableElements) {
|
|
const parts: string[] = [];
|
|
if (clickableElements) {
|
|
parts.push('Clickable elements (use the nodeId in brackets with tools):\n' + clickableElements);
|
|
}
|
|
if (typeableElements) {
|
|
parts.push('Input fields (use the nodeId in brackets with tools):\n' + typeableElements);
|
|
}
|
|
rawElementsText = parts.join('\n\n');
|
|
}
|
|
|
|
// V2 doesn't provide scroll position info, so we simplify the format
|
|
let formattedElementsText = '';
|
|
if (rawElementsText !== '') {
|
|
// Wrap untrusted content for security
|
|
const elementsText = wrapUntrustedContent(rawElementsText);
|
|
formattedElementsText = `[Page content]\n${elementsText}\n[End of visible content]`;
|
|
} else {
|
|
formattedElementsText = 'empty page';
|
|
}
|
|
|
|
// Add current date/time
|
|
const timeStr = new Date().toISOString().slice(0, 16).replace('T', ' '); // Format: YYYY-MM-DD HH:mm
|
|
const stepInfoDescription = `\nCurrent date and time: ${timeStr}`;
|
|
|
|
// Format current tab info
|
|
const currentTab = `{id: ${browserState.tabId}, url: ${browserState.url}, title: ${browserState.title}}`;
|
|
|
|
// Format other tabs
|
|
const otherTabs = browserState.tabs
|
|
.filter((tab: any) => tab.id !== browserState.tabId)
|
|
.map((tab: any) => `- {id: ${tab.id}, url: ${tab.url}, title: ${tab.title}}`);
|
|
|
|
// Build complete state description
|
|
const stateDescription = `
|
|
[Task history memory ends]
|
|
[Current state starts here]
|
|
The following is one-time information - if you need to remember it write it to memory:
|
|
Current tab: ${currentTab}
|
|
Other available tabs:
|
|
${otherTabs.join('\n ')}
|
|
Interactive elements from the current page (numbers in [brackets] are nodeIds to use with interact/find_element tools):
|
|
${formattedElementsText}
|
|
${stepInfoDescription}
|
|
`;
|
|
|
|
// V2 doesn't support screenshots, always return text-only message
|
|
// TODO: add screenshot if available
|
|
return new HumanMessage(stateDescription);
|
|
}
|
|
|
|
/**
|
|
* Helper method to join sections with proper spacing
|
|
* @param sections - Array of prompt sections
|
|
* @returns Joined prompt string
|
|
*/
|
|
protected joinSections(...sections: string[]): string {
|
|
return sections
|
|
.filter(section => section.trim().length > 0)
|
|
.join('\n\n');
|
|
}
|
|
|
|
/**
|
|
* Format a section with a header
|
|
* @param header - Section header
|
|
* @param content - Section content
|
|
* @returns Formatted section
|
|
*/
|
|
protected formatSection(header: string, content: string): string {
|
|
return `## ${header}\n${content}`;
|
|
}
|
|
|
|
/**
|
|
* Format a subsection with a header
|
|
* @param header - Subsection header
|
|
* @param content - Subsection content
|
|
* @returns Formatted subsection
|
|
*/
|
|
protected formatSubsection(header: string, content: string): string {
|
|
return `### ${header}:\n${content}`;
|
|
}
|
|
|
|
/**
|
|
* Create a bullet list from items
|
|
* @param items - Array of items
|
|
* @param indent - Indentation level (0 = -, 1 = •, 2 = ◦)
|
|
* @returns Formatted bullet list
|
|
*/
|
|
protected bulletList(items: string[], indent: number = 0): string {
|
|
const bullets = ['-', '•', '◦'];
|
|
const bullet = bullets[Math.min(indent, bullets.length - 1)];
|
|
const indentStr = ' '.repeat(indent);
|
|
|
|
return items
|
|
.map(item => `${indentStr}${bullet} ${item}`)
|
|
.join('\n');
|
|
}
|
|
|
|
/**
|
|
* Create a numbered list from items
|
|
* @param items - Array of items
|
|
* @param startNumber - Starting number
|
|
* @returns Formatted numbered list
|
|
*/
|
|
protected numberedList(items: string[], startNumber: number = 1): string {
|
|
return items
|
|
.map((item, index) => `${startNumber + index}. ${item}`)
|
|
.join('\n');
|
|
}
|
|
|
|
/**
|
|
* Format code block
|
|
* @param code - Code content
|
|
* @param language - Language identifier
|
|
* @returns Formatted code block
|
|
*/
|
|
protected codeBlock(code: string, language: string = ''): string {
|
|
return `\`\`\`${language}\n${code}\n\`\`\``;
|
|
}
|
|
|
|
/**
|
|
* Create a divider line
|
|
* @param char - Character to use for divider
|
|
* @param length - Length of divider
|
|
* @returns Divider string
|
|
*/
|
|
protected divider(char: string = '─', length: number = 40): string {
|
|
return char.repeat(length);
|
|
}
|
|
}
|