mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-19 19:41:06 +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>
242 lines
6.5 KiB
TypeScript
242 lines
6.5 KiB
TypeScript
import { StreamEventBus, StreamEvent } from './EventBus';
|
|
import { MessageType } from '@/lib/types/messaging';
|
|
|
|
/**
|
|
* Simplified UI message types that map to our stream events
|
|
*/
|
|
export enum UIMessageType {
|
|
SystemMessage = 'SystemMessage',
|
|
ThinkingMessage = 'ThinkingMessage',
|
|
NewSegment = 'NewSegment',
|
|
StreamingChunk = 'StreamingChunk',
|
|
FinalizeSegment = 'FinalizeSegment',
|
|
ToolCall = 'ToolCall',
|
|
ToolStream = 'ToolStream',
|
|
ToolResponse = 'ToolResponse',
|
|
DebugMessage = 'DebugMessage',
|
|
ErrorMessage = 'ErrorMessage',
|
|
CompleteMessage = 'CompleteMessage',
|
|
CancelMessage = 'CancelMessage'
|
|
}
|
|
|
|
/**
|
|
* UI message payload structure
|
|
*/
|
|
export interface UIMessage {
|
|
messageType: UIMessageType;
|
|
messageId?: string;
|
|
segmentId?: number;
|
|
content?: string;
|
|
toolName?: string;
|
|
toolArgs?: any;
|
|
toolResult?: string;
|
|
error?: string;
|
|
data?: any;
|
|
}
|
|
|
|
/**
|
|
* Handler that converts StreamEvents to UI messages
|
|
* This bridges the EventBus to the UI port messaging system
|
|
*/
|
|
export class UIEventHandler {
|
|
private eventBus: StreamEventBus;
|
|
private sendToUI: (type: MessageType, payload: any) => void;
|
|
private messageIdMap: Map<number, string> = new Map();
|
|
|
|
constructor(
|
|
eventBus: StreamEventBus,
|
|
sendToUI: (type: MessageType, payload: any) => void
|
|
) {
|
|
this.eventBus = eventBus;
|
|
this.sendToUI = sendToUI;
|
|
this.setupEventListeners();
|
|
}
|
|
|
|
/**
|
|
* Set up listeners for all event types
|
|
*/
|
|
private setupEventListeners(): void {
|
|
// Segment events
|
|
this.eventBus.onStreamEvent('segment.start', this.handleSegmentStart.bind(this));
|
|
this.eventBus.onStreamEvent('segment.chunk', this.handleSegmentChunk.bind(this));
|
|
this.eventBus.onStreamEvent('segment.end', this.handleSegmentEnd.bind(this));
|
|
|
|
// Tool events
|
|
this.eventBus.onStreamEvent('tool.start', this.handleToolStart.bind(this));
|
|
this.eventBus.onStreamEvent('tool.stream', this.handleToolStream.bind(this));
|
|
this.eventBus.onStreamEvent('tool.end', this.handleToolEnd.bind(this));
|
|
|
|
// System events
|
|
this.eventBus.onStreamEvent('system.message', this.handleSystemMessage.bind(this));
|
|
this.eventBus.onStreamEvent('system.thinking', this.handleSystemThinking.bind(this));
|
|
this.eventBus.onStreamEvent('system.error', this.handleSystemError.bind(this));
|
|
this.eventBus.onStreamEvent('system.complete', this.handleSystemComplete.bind(this));
|
|
this.eventBus.onStreamEvent('system.cancel', this.handleSystemCancel.bind(this));
|
|
|
|
// Debug events
|
|
this.eventBus.onStreamEvent('debug.message', this.handleDebugMessage.bind(this));
|
|
}
|
|
|
|
/**
|
|
* Send a UI message via port messaging
|
|
*/
|
|
private sendUIMessage(message: UIMessage): void {
|
|
this.sendToUI(MessageType.AGENT_STREAM_UPDATE, {
|
|
step: Date.now(), // Use timestamp as step for compatibility
|
|
action: message.messageType,
|
|
status: 'executing',
|
|
details: message
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Event handlers
|
|
*/
|
|
|
|
private handleSegmentStart(event: StreamEvent): void {
|
|
const { segmentId, messageId } = event.data as any;
|
|
|
|
// Store message ID mapping
|
|
this.messageIdMap.set(segmentId, messageId);
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.NewSegment,
|
|
messageId,
|
|
segmentId
|
|
});
|
|
}
|
|
|
|
private handleSegmentChunk(event: StreamEvent): void {
|
|
const { segmentId, content, messageId } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.StreamingChunk,
|
|
messageId,
|
|
segmentId,
|
|
content
|
|
});
|
|
}
|
|
|
|
private handleSegmentEnd(event: StreamEvent): void {
|
|
const { segmentId, finalContent, messageId } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.FinalizeSegment,
|
|
messageId,
|
|
segmentId,
|
|
content: finalContent
|
|
});
|
|
}
|
|
|
|
private handleToolStart(event: StreamEvent): void {
|
|
const { toolName, displayName, icon, description, args } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.ToolCall,
|
|
toolName: displayName,
|
|
toolArgs: {
|
|
description,
|
|
icon,
|
|
args
|
|
}
|
|
});
|
|
}
|
|
|
|
private handleToolStream(event: StreamEvent): void {
|
|
const { toolName, content } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.ToolStream,
|
|
toolName,
|
|
content
|
|
});
|
|
}
|
|
|
|
private handleToolEnd(event: StreamEvent): void {
|
|
const { toolName, displayName, result } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.ToolResponse,
|
|
toolName: displayName,
|
|
toolResult: result,
|
|
content: result // For backward compatibility
|
|
});
|
|
}
|
|
|
|
private handleSystemMessage(event: StreamEvent): void {
|
|
const { message } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.SystemMessage,
|
|
content: message
|
|
});
|
|
}
|
|
|
|
private handleSystemError(event: StreamEvent): void {
|
|
const { error } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.ErrorMessage,
|
|
error,
|
|
content: error // For display
|
|
});
|
|
}
|
|
|
|
private handleSystemComplete(event: StreamEvent): void {
|
|
const { success, message } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.CompleteMessage,
|
|
content: message || (success ? '✅ Task completed successfully' : '❌ Task failed')
|
|
});
|
|
}
|
|
|
|
private handleSystemCancel(event: StreamEvent): void {
|
|
const { reason, userInitiated } = event.data as any;
|
|
|
|
if (userInitiated) {
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.CancelMessage,
|
|
content: reason || '✋ Task paused. To continue this task, just type your next request OR use 🔄 to start a new task!'
|
|
});
|
|
}
|
|
}
|
|
|
|
private handleSystemThinking(event: StreamEvent): void {
|
|
const { message, category } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.ThinkingMessage,
|
|
content: message,
|
|
data: { category }
|
|
});
|
|
}
|
|
|
|
private handleDebugMessage(event: StreamEvent): void {
|
|
const { message, data } = event.data as any;
|
|
|
|
this.sendUIMessage({
|
|
messageType: UIMessageType.DebugMessage,
|
|
content: message,
|
|
data
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Clean up event listeners
|
|
*/
|
|
destroy(): void {
|
|
this.eventBus.removeAllListeners();
|
|
this.messageIdMap.clear();
|
|
}
|
|
|
|
/**
|
|
* Replay events for a late subscriber
|
|
*/
|
|
replay(): void {
|
|
this.eventBus.replay((event) => {
|
|
// Re-emit the event to trigger handlers
|
|
this.eventBus.emitStreamEvent(event);
|
|
});
|
|
}
|
|
} |