{"version":3,"file":"agent/executor.mjs","sources":["webpack://@agent-infra/browser-use/./src/agent/executor.ts"],"sourcesContent":["/**\n * The following code is modified based on\n * https://github.com/nanobrowser/nanobrowser/blob/master/chrome-extension/src/background/agent/executor.ts\n *\n * Apache-2.0 License\n * Copyright (c) 2024 alexchenzl\n * https://github.com/nanobrowser/nanobrowser/blob/master/LICENSE\n */\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { AgentContext, type AgentOptions } from './types';\nimport { NavigatorAgent, NavigatorActionRegistry } from './agents/navigator';\nimport { PlannerAgent } from './agents/planner';\nimport { ValidatorAgent } from './agents/validator';\nimport { NavigatorPrompt } from './prompts/navigator';\nimport { PlannerPrompt } from './prompts/planner';\nimport { ValidatorPrompt } from './prompts/validator';\nimport { createLogger } from '../utils';\nimport MessageManager from './messages/service';\nimport type BrowserContext from '../browser/context';\nimport { ActionBuilder } from './actions/builder';\nimport { EventManager } from './event/manager';\nimport {\n  Actors,\n  type EventCallback,\n  EventType,\n  ExecutionState,\n} from './event/types';\nimport { ChatModelAuthError } from './agents/errors';\nconst logger = createLogger('Executor');\n\nexport interface ExecutorExtraArgs {\n  plannerLLM?: BaseChatModel;\n  validatorLLM?: BaseChatModel;\n  extractorLLM?: BaseChatModel;\n  agentOptions?: Partial<AgentOptions>;\n}\n\nexport class Executor {\n  private readonly navigator: NavigatorAgent;\n  private readonly planner: PlannerAgent;\n  private readonly validator: ValidatorAgent;\n  private readonly context: AgentContext;\n  private readonly plannerPrompt: PlannerPrompt;\n  private readonly navigatorPrompt: NavigatorPrompt;\n  private readonly validatorPrompt: ValidatorPrompt;\n  private tasks: string[] = [];\n  constructor(\n    task: string,\n    taskId: string,\n    browserContext: BrowserContext,\n    navigatorLLM: BaseChatModel,\n    extraArgs?: Partial<ExecutorExtraArgs>,\n  ) {\n    const messageManager = new MessageManager({});\n\n    const plannerLLM = extraArgs?.plannerLLM ?? navigatorLLM;\n    const validatorLLM = extraArgs?.validatorLLM ?? navigatorLLM;\n    const extractorLLM = extraArgs?.extractorLLM ?? navigatorLLM;\n    const eventManager = new EventManager();\n    const context = new AgentContext(\n      taskId,\n      browserContext,\n      messageManager,\n      eventManager,\n      extraArgs?.agentOptions ?? {},\n    );\n\n    this.tasks.push(task);\n    this.navigatorPrompt = new NavigatorPrompt(\n      context.options.maxActionsPerStep,\n    );\n    this.plannerPrompt = new PlannerPrompt();\n    this.validatorPrompt = new ValidatorPrompt(task);\n\n    const actionBuilder = new ActionBuilder(context, extractorLLM);\n    const navigatorActionRegistry = new NavigatorActionRegistry(\n      actionBuilder.buildDefaultActions(),\n    );\n\n    // Initialize agents with their respective prompts\n    this.navigator = new NavigatorAgent(navigatorActionRegistry, {\n      chatLLM: navigatorLLM,\n      context: context,\n      prompt: this.navigatorPrompt,\n    });\n    this.planner = new PlannerAgent({\n      chatLLM: plannerLLM,\n      context: context,\n      prompt: this.plannerPrompt,\n    });\n\n    this.validator = new ValidatorAgent({\n      chatLLM: validatorLLM,\n      context: context,\n      prompt: this.validatorPrompt,\n    });\n\n    this.context = context;\n    // Initialize message history\n    this.context.messageManager.initTaskMessages(\n      this.navigatorPrompt.getSystemMessage(),\n      task,\n    );\n  }\n\n  subscribeExecutionEvents(callback: EventCallback): void {\n    this.context.eventManager.subscribe(EventType.EXECUTION, callback);\n  }\n\n  clearExecutionEvents(): void {\n    // Clear all execution event listeners\n    this.context.eventManager.clearSubscribers(EventType.EXECUTION);\n  }\n\n  addFollowUpTask(task: string): void {\n    this.tasks.push(task);\n    this.context.messageManager.addNewTask(task);\n    // update validator prompt\n    this.validatorPrompt.addFollowUpTask(task);\n\n    // need to reset previous action results that are not included in memory\n    this.context.actionResults = this.context.actionResults.filter(\n      (result) => result.includeInMemory,\n    );\n  }\n\n  /**\n   * Execute the task\n   *\n   * @returns {Promise<void>}\n   */\n  async execute(): Promise<void> {\n    logger.info(`🚀 Executing task: ${this.tasks[this.tasks.length - 1]}`);\n    // reset the step counter\n    const context = this.context;\n    context.nSteps = 0;\n    const allowedMaxSteps = this.context.options.maxSteps;\n    const browserState = await this.context.browserContext.getState();\n\n    try {\n      this.context.emitEvent(\n        Actors.SYSTEM,\n        ExecutionState.TASK_START,\n        this.context.taskId,\n        browserState,\n      );\n\n      let done = false;\n      let step = 0;\n      let validatorFailed = false;\n\n      for (step = 0; step < allowedMaxSteps; step++) {\n        context.stepInfo = {\n          stepNumber: context.nSteps,\n          maxSteps: context.options.maxSteps,\n        };\n\n        logger.info(`🔄 Step ${step + 1} / ${allowedMaxSteps}`);\n        if (await this.shouldStop()) {\n          break;\n        }\n\n        // Run planner if configured\n        if (\n          this.planner &&\n          (context.nSteps % context.options.planningInterval === 0 ||\n            validatorFailed)\n        ) {\n          validatorFailed = false;\n          // The first planning step is special, we don't want to add the browser state message to memory\n          if (this.tasks.length > 1 || step > 0) {\n            await this.navigator.addStateMessageToMemory();\n          }\n\n          const planOutput = await this.planner.execute();\n          if (planOutput.result) {\n            logger.info(\n              `🔄 Planner output: ${JSON.stringify(planOutput.result, null, 2)}`,\n            );\n            this.context.messageManager.addPlan(\n              JSON.stringify(planOutput.result),\n              this.context.messageManager.length() - 1,\n            );\n            if (planOutput.result.done) {\n              // task is complete, skip navigation\n              done = true;\n              this.validator.setPlan(planOutput.result.next_steps);\n            } else {\n              // task is not complete, let's navigate\n              this.validator.setPlan(null);\n              done = false;\n            }\n\n            if (!planOutput.result.web_task && planOutput.result.done) {\n              break;\n            }\n          }\n        }\n\n        // execute the navigation step\n        if (!done) {\n          done = await this.navigate();\n        }\n\n        // validate the output\n        if (\n          done &&\n          this.context.options.validateOutput &&\n          !this.context.stopped &&\n          !this.context.paused\n        ) {\n          const validatorOutput = await this.validator.execute();\n          if (validatorOutput.result?.is_valid) {\n            logger.info('✅ Task completed successfully');\n            break;\n          }\n          validatorFailed = true;\n        }\n      }\n\n      if (done) {\n        this.context.emitEvent(\n          Actors.SYSTEM,\n          ExecutionState.TASK_OK,\n          this.context.taskId,\n          browserState,\n        );\n      } else if (step >= allowedMaxSteps) {\n        logger.info('❌ Task failed: Max steps reached');\n        this.context.emitEvent(\n          Actors.SYSTEM,\n          ExecutionState.TASK_FAIL,\n          'Task failed: Max steps reached',\n          browserState,\n        );\n      } else if (this.context.stopped) {\n        this.context.emitEvent(\n          Actors.SYSTEM,\n          ExecutionState.TASK_CANCEL,\n          'Task cancelled',\n          browserState,\n        );\n      } else {\n        this.context.emitEvent(\n          Actors.SYSTEM,\n          ExecutionState.TASK_PAUSE,\n          'Task paused',\n          browserState,\n        );\n      }\n    } catch (error) {\n      const errorMessage =\n        error instanceof Error ? error.message : String(error);\n      this.context.emitEvent(\n        Actors.SYSTEM,\n        ExecutionState.TASK_FAIL,\n        `Task failed: ${errorMessage}`,\n        browserState,\n      );\n    }\n  }\n\n  private async navigate(): Promise<boolean> {\n    const context = this.context;\n    try {\n      // Get and execute navigation action\n      // check if the task is paused or stopped\n      if (context.paused || context.stopped) {\n        return false;\n      }\n      const navOutput = await this.navigator.execute();\n      // check if the task is paused or stopped\n      if (context.paused || context.stopped) {\n        return false;\n      }\n      context.nSteps++;\n      if (navOutput.error) {\n        throw new Error(navOutput.error);\n      }\n      context.consecutiveFailures = 0;\n      if (navOutput.result?.done) {\n        return true;\n      }\n    } catch (error) {\n      if (error instanceof ChatModelAuthError) {\n        throw error;\n      }\n      context.consecutiveFailures++;\n      logger.error(`Failed to execute step: ${error}`);\n      if (context.consecutiveFailures >= context.options.maxFailures) {\n        throw new Error('Max failures reached');\n      }\n    }\n    return false;\n  }\n\n  private async shouldStop(): Promise<boolean> {\n    if (this.context.stopped) {\n      logger.info('Agent stopped');\n      return true;\n    }\n\n    while (this.context.paused) {\n      await new Promise((resolve) => setTimeout(resolve, 200));\n      if (this.context.stopped) {\n        return true;\n      }\n    }\n\n    if (this.context.consecutiveFailures >= this.context.options.maxFailures) {\n      logger.error(\n        `Stopping due to ${this.context.options.maxFailures} consecutive failures`,\n      );\n      return true;\n    }\n\n    return false;\n  }\n\n  async cancel(): Promise<void> {\n    this.context.stop();\n  }\n\n  async resume(): Promise<void> {\n    this.context.resume();\n  }\n\n  async pause(): Promise<void> {\n    this.context.pause();\n  }\n\n  async cleanup(): Promise<void> {\n    try {\n      await this.context.browserContext.cleanup();\n    } catch (error) {\n      logger.error(`Failed to cleanup browser context: ${error}`);\n    }\n  }\n\n  async getCurrentTaskId(): Promise<string> {\n    return this.context.taskId;\n  }\n}\n"],"names":["logger","createLogger","Executor","callback","EventType","task","result","context","allowedMaxSteps","browserState","Actors","ExecutionState","done","step","validatorFailed","planOutput","JSON","_validatorOutput_result","validatorOutput","error","errorMessage","Error","String","_navOutput_result","navOutput","ChatModelAuthError","Promise","resolve","setTimeout","taskId","browserContext","navigatorLLM","extraArgs","messageManager","MessageManager","plannerLLM","validatorLLM","extractorLLM","eventManager","EventManager","AgentContext","NavigatorPrompt","PlannerPrompt","ValidatorPrompt","actionBuilder","ActionBuilder","navigatorActionRegistry","NavigatorActionRegistry","NavigatorAgent","PlannerAgent","ValidatorAgent"],"mappings":"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"}