UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

171 lines (145 loc) 5.45 kB
/** * @claude-flow/browser - Hooks Integration * pre-browse and post-browse hooks for claude-flow */ import { getReasoningBank } from './reasoningbank-adapter.js'; import type { BrowserTrajectory, ActionResult } from '../domain/types.js'; // ============================================================================ // Hook Handlers // ============================================================================ export interface PreBrowseInput { goal: string; url?: string; context?: string; } export interface PreBrowseResult { recommendedSteps: Array<{ action: string; selector?: string; value?: string; }>; similarPatterns: number; suggestedModel: 'haiku' | 'sonnet' | 'opus'; estimatedDuration: number; warnings: string[]; } export interface PostBrowseInput { trajectoryId: string; success: boolean; verdict?: string; duration: number; stepsCompleted: number; errors?: string[]; } export interface PostBrowseResult { patternStored: boolean; patternId?: string; learnedFrom: boolean; statsUpdated: boolean; } // ============================================================================ // Pre-Browse Hook // ============================================================================ /** * Pre-browse hook - called before starting browser automation * Returns recommendations based on learned patterns */ export async function preBrowseHook(input: PreBrowseInput): Promise<PreBrowseResult> { const reasoningBank = getReasoningBank(); const warnings: string[] = []; // Find similar patterns const similarPatterns = await reasoningBank.findSimilarPatterns(input.goal); // Get recommended steps const recommendedSteps = await reasoningBank.getRecommendedSteps(input.goal); // Suggest model based on complexity let suggestedModel: 'haiku' | 'sonnet' | 'opus' = 'sonnet'; if (recommendedSteps.length <= 3) { suggestedModel = 'haiku'; } else if (recommendedSteps.length > 10 || input.goal.toLowerCase().includes('complex')) { suggestedModel = 'opus'; } // Estimate duration based on patterns let estimatedDuration = 5000; // Default 5s if (similarPatterns.length > 0) { estimatedDuration = Math.round( similarPatterns.reduce((sum, p) => sum + p.avgDuration * p.steps.length, 0) / similarPatterns.length ); } // Generate warnings if (input.url && !input.url.startsWith('https://')) { warnings.push('URL is not HTTPS - authentication data may be at risk'); } if (input.goal.toLowerCase().includes('login') && !input.goal.toLowerCase().includes('test')) { warnings.push('Login detected - consider using state-save/state-load for session persistence'); } if (similarPatterns.length === 0) { warnings.push('No similar patterns found - this is a new workflow'); } return { recommendedSteps, similarPatterns: similarPatterns.length, suggestedModel, estimatedDuration, warnings, }; } // ============================================================================ // Post-Browse Hook // ============================================================================ /** * Post-browse hook - called after browser automation completes * Stores patterns and records learning feedback */ export async function postBrowseHook(input: PostBrowseInput): Promise<PostBrowseResult> { const reasoningBank = getReasoningBank(); // Record verdict for learning await reasoningBank.recordVerdict(input.trajectoryId, input.success, input.verdict); // If there were errors, analyze them if (input.errors && input.errors.length > 0) { console.log(`[post-browse] Errors to learn from: ${input.errors.join(', ')}`); } const stats = reasoningBank.getStats(); return { patternStored: input.success, patternId: input.success ? `pattern-${input.trajectoryId}` : undefined, learnedFrom: true, statsUpdated: true, }; } // ============================================================================ // Hook Registration for CLI // ============================================================================ export const browserHooks = { 'pre-browse': { name: 'pre-browse', description: 'Get recommendations before browser automation', handler: preBrowseHook, inputSchema: { type: 'object', properties: { goal: { type: 'string', description: 'What you want to accomplish' }, url: { type: 'string', description: 'Target URL (optional)' }, context: { type: 'string', description: 'Additional context' }, }, required: ['goal'], }, }, 'post-browse': { name: 'post-browse', description: 'Record browser automation outcome for learning', handler: postBrowseHook, inputSchema: { type: 'object', properties: { trajectoryId: { type: 'string', description: 'Trajectory ID from browser service' }, success: { type: 'boolean', description: 'Whether the automation succeeded' }, verdict: { type: 'string', description: 'Human feedback on quality' }, duration: { type: 'number', description: 'Total duration in ms' }, stepsCompleted: { type: 'number', description: 'Number of steps completed' }, errors: { type: 'array', items: { type: 'string' }, description: 'Error messages if any' }, }, required: ['trajectoryId', 'success', 'duration', 'stepsCompleted'], }, }, }; export default browserHooks;