{"version":3,"file":"agent/agent.mjs","sources":["webpack://@multimodal/agent/./src/agent/agent.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n  AgentStatus,\n  AgentOptions,\n  LLMReasoningOptions,\n  AgentRunOptions,\n  AgentRunStreamingOptions,\n  AgentRunNonStreamingOptions,\n  AgentEventStream,\n  Tool,\n  isAgentRunObjectOptions,\n  isStreamingOptions,\n  AgentContextAwarenessOptions,\n  AgentRunObjectOptions,\n  SummaryRequest,\n  SummaryResponse,\n  ChatCompletionMessageParam,\n  IAgent,\n  ChatCompletionCreateParams,\n  ChatCompletion,\n} from '@multimodal/agent-interface';\n\nimport { BaseAgent } from './base-agent';\nimport { AgentRunner } from './agent-runner';\nimport { AgentEventStreamProcessor } from './event-stream';\nimport { ToolManager } from './tool-manager';\nimport {\n  ModelResolver,\n  ResolvedModel,\n  OpenAI,\n  RequestOptions,\n  ChatCompletionChunk,\n} from '@multimodal/model-provider';\nimport { getLogger, LogLevel, rootLogger } from '../utils/logger';\nimport { AgentExecutionController } from './execution-controller';\nimport { getLLMClient } from './llm-client';\nimport { getToolCallEngineForProvider } from '../tool-call-engine/engine-selector';\n\n/**\n * An event-stream driven agent framework for building effective multimodal Agents.\n *\n * - Multi-turn reasoning agent loop\n * - highly customizable, easy to build higher-level Agents\n * - Tool registration and execution\n * - Multimodal context awareness and management\n * - Communication with multiple LLM providers\n * - Event stream management for tracking agent loop state\n */\nexport class Agent<T extends AgentOptions = AgentOptions>\n  extends BaseAgent<T>\n  implements IAgent<T>\n{\n  private instructions: string;\n  private maxIterations: number;\n  private maxTokens: number | undefined;\n  protected name: string;\n  protected id: string;\n  protected eventStream: AgentEventStreamProcessor;\n  private toolManager: ToolManager;\n  private modelResolver: ModelResolver;\n  private temperature: number;\n  private reasoningOptions: LLMReasoningOptions;\n  private runner: AgentRunner;\n  public logger = getLogger('Core');\n  protected executionController: AgentExecutionController;\n  private customLLMClient?: OpenAI;\n  public initialized = false;\n  public isReplaySnapshot = false;\n  private currentResolvedModel?: ResolvedModel;\n  private isCustomLLMClientSet = false; // Track if custom client was explicitly set\n  private executionStartTime = 0; // Track execution start time\n\n  /**\n   * Creates a new Agent instance.\n   *\n   * @param options - Configuration options for the agent including instructions,\n   * tools, model selection, and runtime parameters.\n   */\n  constructor(options: AgentOptions = {}) {\n    super(options as T);\n\n    this.instructions = options.instructions || this.getDefaultPrompt();\n    this.maxIterations = options.maxIterations ?? 10;\n    this.maxTokens = options.maxTokens;\n    this.name = options.name ?? 'Anonymous';\n    this.id = options.id ?? '@multimodal/agent';\n\n    // console.log(JSON.stringify(options, null, 2));\n\n    // Set the log level if provided in options\n    if (options.logLevel !== undefined) {\n      rootLogger.setLevel(options.logLevel);\n      this.logger.debug(`Log level set to: ${LogLevel[options.logLevel]}`);\n    }\n\n    // Initialize event stream manager\n    this.eventStream = new AgentEventStreamProcessor(options.eventStreamOptions);\n\n    // Initialize Tool Manager\n    this.toolManager = new ToolManager(this.logger);\n\n    // Ensure context options have default values\n    const contextAwarenessOptions: AgentContextAwarenessOptions = options.context ?? {};\n    if (contextAwarenessOptions.maxImagesCount === undefined) {\n      contextAwarenessOptions.maxImagesCount = 5; // Default to 5 images max\n    }\n\n    // Initialize ModelResolver\n    this.modelResolver = new ModelResolver(options.model);\n\n    // Register any provided tools\n    if (options.tools) {\n      options.tools.forEach((tool) => {\n        this.registerTool(tool);\n      });\n    }\n\n    const { providers } = this.options.model ?? {};\n    if (Array.isArray(providers)) {\n      this.logger.info(`Found ${providers.length} custom model providers`);\n    }\n\n    // Log the default selection\n    const defaultSelection = this.modelResolver.getDefaultSelection();\n    if (defaultSelection.provider || defaultSelection.id) {\n      this.logger.info(\n        `[Agent] ${this.name} initialized | Default model provider: ${defaultSelection.provider ?? 'N/A'} | ` +\n          `Default model: ${defaultSelection.id ?? 'N/A'} | ` +\n          `Tools: ${options.tools?.length || 0} | Max iterations: ${this.maxIterations}`,\n      );\n    }\n\n    this.temperature = options.temperature ?? 0.7;\n    this.reasoningOptions = options.thinking ?? { type: 'disabled' };\n\n    // Initialize the resolved model early if possible\n    this.initializeEarlyResolvedModel();\n\n    // Initialize the runner with context options\n    this.runner = new AgentRunner({\n      instructions: this.instructions,\n      maxIterations: this.maxIterations,\n      maxTokens: this.maxTokens,\n      temperature: this.temperature,\n      reasoningOptions: this.reasoningOptions,\n      toolCallEngine: options.toolCallEngine,\n      eventStream: this.eventStream,\n      toolManager: this.toolManager,\n      agent: this,\n      contextAwarenessOptions: contextAwarenessOptions,\n    });\n\n    // Initialize execution controller\n    this.executionController = new AgentExecutionController();\n  }\n\n  /**\n   * Initialize early resolved model if model configuration is available\n   * This allows LLM client to be available immediately after instantiation\n   */\n  private initializeEarlyResolvedModel(): void {\n    try {\n      // Try to resolve with default selection\n      this.currentResolvedModel = this.modelResolver.resolve();\n\n      if (this.currentResolvedModel) {\n        this.logger.info(\n          `[Agent] Early model resolution successful | Provider: ${this.currentResolvedModel.provider} | Model: ${this.currentResolvedModel.id}`,\n        );\n      }\n    } catch (error) {\n      this.logger.debug(`[Agent] Early model resolution failed, will resolve during run: ${error}`);\n      // Not a critical error - model will be resolved during run\n    }\n  }\n\n  /**\n   * Custom LLM client for testing or custom implementations\n   *\n   * @param customLLMClient - OpenAI-compatible llm client\n   */\n  public setCustomLLMClient(client: OpenAI): void {\n    this.customLLMClient = client;\n    this.isCustomLLMClientSet = true;\n    this.runner.llmProcessor.setCustomLLMClient(client);\n\n    this.logger.info('[Agent] Custom LLM client set, will ignore model parameters in run()');\n  }\n\n  /**\n   * Gets the current iteration/loop number of the agent's reasoning process\n   * This is useful for tracking progress and debugging\n   *\n   * @returns The current loop iteration (1-based, 0 if not running)\n   */\n  public getCurrentLoopIteration(): number {\n    return this.runner.getCurrentIteration();\n  }\n\n  /**\n   * Registers a new tool that the agent can use during execution.\n   * Tools are stored in a map keyed by the tool name.\n   *\n   * @param tool - The tool definition to register\n   */\n  public registerTool(tool: Tool): void {\n    this.toolManager.registerTool(tool);\n  }\n\n  /**\n   * Returns all registered tools as an array.\n   *\n   * @returns Array of all registered tool definitions\n   */\n  public getTools(): Tool[] {\n    return this.toolManager.getTools();\n  }\n\n  /**\n   * Provides the default instructions used when none are specified.\n   * These instructions define the agent's basic behavior and capabilities.\n   *\n   * @returns The default instructions string\n   * @private\n   */\n  private getDefaultPrompt(): string {\n    return `You are an intelligent assistant that can use provided tools to answer user questions.\nPlease use tools when needed to get information, don't make up answers.\nProvide concise and accurate responses.`;\n  }\n\n  /**\n   * Returns the event stream manager associated with this agent.\n   * The event stream tracks all conversation events including messages,\n   * tool calls, and system events.\n   *\n   * @returns The EventStream instance\n   */\n  getEventStream(): AgentEventStreamProcessor {\n    return this.eventStream;\n  }\n\n  /**\n   * Returns a string identifier for the agent, including ID if available.\n   * Used for logging and identification purposes.\n   *\n   * @returns A string in format \"name (id)\" or just \"name\" if id is not available\n   * @protected\n   */\n  protected getAgentIdentifier(): string {\n    return this.id ? `${this.name} (${this.id})` : this.name;\n  }\n\n  /**\n   * Executes the main agent reasoning loop.\n   *\n   * This method processes the user input, communicates with the LLM,\n   * executes tools as requested by the LLM, and continues iterating\n   * until a final answer is reached or max iterations are hit.\n   *\n   * @param input - String input for a basic text message\n   * @returns The final response event from the agent (stream is false)\n   */\n  async run(input: string): Promise<AgentEventStream.AssistantMessageEvent>;\n\n  /**\n   * Executes the main agent reasoning loop with additional options.\n   *\n   * @param options - Object with input and optional configuration\n   * @returns The final response event from the agent (when stream is false)\n   */\n  async run(options: AgentRunNonStreamingOptions): Promise<AgentEventStream.AssistantMessageEvent>;\n\n  /**\n   * Executes the main agent reasoning loop with streaming support.\n   *\n   * @param options - Object with input and streaming enabled\n   * @returns An async iterable of streaming events\n   */\n  async run(options: AgentRunStreamingOptions): Promise<AsyncIterable<AgentEventStream.Event>>;\n\n  /**\n   * Implementation of the run method to handle all overload cases\n   * @param runOptions - Input options\n   */\n  async run(\n    runOptions: AgentRunOptions,\n  ): Promise<\n    string | AgentEventStream.AssistantMessageEvent | AsyncIterable<AgentEventStream.Event>\n  > {\n    // Check if agent is already executing\n    if (this.executionController.isExecuting()) {\n      throw new Error(\n        'Agent is already executing a task. Complete or abort the current task before starting a new one.',\n      );\n    }\n\n    // Reset termination flag for new runs\n    this.resetLoopTermination();\n\n    // Begin execution and get abort signal\n    const abortSignal = this.executionController.beginExecution();\n\n    if (!this.initialized) await this.initialize();\n\n    try {\n      // Set execution start time for tracking elapsed time\n      this.executionStartTime = Date.now();\n\n      // Normalize the options\n      const normalizedOptions = isAgentRunObjectOptions(runOptions)\n        ? runOptions\n        : { input: runOptions };\n\n      // Generate sessionId if not provided\n      const sessionId =\n        normalizedOptions.sessionId ??\n        `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\n      // Resolve model before running\n      // If custom LLM client is set, ignore model parameters and use existing resolved model\n      if (this.isCustomLLMClientSet && this.currentResolvedModel) {\n        this.logger.info(\n          `[Agent] Using existing resolved model with custom LLM client | Provider: ${this.currentResolvedModel.provider} | Model: ${this.currentResolvedModel.id}`,\n        );\n      } else {\n        // Normal model resolution\n        this.currentResolvedModel = this.modelResolver.resolve(\n          normalizedOptions.model,\n          normalizedOptions.provider,\n        );\n      }\n\n      // Determine the best tool call engine based on the provider if not explicitly specified\n      if (!this.options.toolCallEngine && !normalizedOptions.toolCallEngine) {\n        const providerEngine = getToolCallEngineForProvider(this.currentResolvedModel.provider);\n        normalizedOptions.toolCallEngine = providerEngine;\n        this.logger.info(\n          `[Agent] Auto-selected tool call engine \"${providerEngine}\" for provider \"${this.currentResolvedModel.provider}\"`,\n        );\n      }\n\n      // Create and send agent run start event\n      const runStartEvent = this.eventStream.createEvent('agent_run_start', {\n        sessionId,\n        runOptions: this.sanitizeRunOptions(normalizedOptions),\n        provider: this.currentResolvedModel.provider,\n        model: this.currentResolvedModel.id,\n      });\n\n      // Add user message to event stream\n      const userEvent = this.eventStream.createEvent('user_message', {\n        content: normalizedOptions.input,\n      });\n\n      this.eventStream.sendEvent(userEvent);\n\n      // Inject abort signal into the execution context\n      normalizedOptions.abortSignal = abortSignal;\n\n      // Check if streaming is requested\n      if (isAgentRunObjectOptions(runOptions) && isStreamingOptions(normalizedOptions)) {\n        // Execute in streaming mode - we return the stream directly but also need to handle cleanup\n        const stream = this.runner.executeStreaming(\n          normalizedOptions,\n          this.currentResolvedModel,\n          sessionId,\n        );\n\n        // In stream mode, we need to wait for the stream created and send the start event.\n        this.eventStream.sendEvent(runStartEvent);\n\n        // Register a cleanup handler for when execution completes\n        this.executionController.registerCleanupHandler(async () => {\n          if (this.executionController.isAborted()) {\n            // Add system event to indicate abort\n            const systemEvent = this.eventStream.createEvent('system', {\n              level: 'warning',\n              message: 'Agent execution was aborted',\n            });\n            this.eventStream.sendEvent(systemEvent);\n          }\n\n          // Send agent run end event regardless of whether it was aborted\n          const endEvent = this.eventStream.createEvent('agent_run_end', {\n            sessionId,\n            iterations: this.runner.getCurrentIteration(),\n            elapsedMs: Date.now() - this.executionStartTime,\n            status: this.executionController.getStatus(),\n          });\n          this.eventStream.sendEvent(endEvent);\n        });\n\n        return stream;\n      } else {\n        // J\n        this.eventStream.sendEvent(runStartEvent);\n\n        // Execute in non-streaming mode\n        try {\n          const result = await this.runner.execute(\n            normalizedOptions,\n            this.currentResolvedModel,\n            sessionId,\n          );\n\n          // Add agent run end event\n          const endEvent = this.eventStream.createEvent('agent_run_end', {\n            sessionId,\n            iterations: this.runner.getCurrentIteration(),\n            elapsedMs: Date.now() - this.executionStartTime,\n            status: AgentStatus.IDLE,\n          });\n          this.eventStream.sendEvent(endEvent);\n\n          await this.executionController.endExecution(AgentStatus.IDLE);\n\n          // For object input without streaming, return the event\n          return result;\n        } catch (error) {\n          // Send agent run end event with error status\n          const endEvent = this.eventStream.createEvent('agent_run_end', {\n            sessionId,\n            iterations: this.runner.getCurrentIteration(),\n            elapsedMs: Date.now() - this.executionStartTime,\n            status: AgentStatus.ERROR,\n          });\n          this.eventStream.sendEvent(endEvent);\n\n          await this.executionController.endExecution(AgentStatus.ERROR);\n          throw error;\n        }\n      }\n    } catch (error) {\n      await this.executionController.endExecution(AgentStatus.ERROR);\n      throw error;\n    }\n  }\n\n  /**\n   * Sanitize run options to remove sensitive or unnecessary data before including in events\n   * @param options The run options to sanitize\n   * @returns A safe version of run options for including in events\n   * @private\n   */\n  private sanitizeRunOptions(options: AgentRunObjectOptions): AgentRunObjectOptions {\n    // Create a copy of the options\n    const sanitized = { ...options };\n\n    // Remove sensitive fields\n    delete sanitized.abortSignal;\n\n    // If input is complex (like with images), simplify it for the event\n    if (Array.isArray(sanitized.input)) {\n      sanitized.input = '[Complex multimodal input]';\n    }\n\n    return sanitized;\n  }\n\n  /**\n   * Get the configured LLM client for making direct requests\n   *\n   * @returns The configured OpenAI-compatible LLM client instance\n   */\n  public getLLMClient(): OpenAI | undefined {\n    // If custom client is set, return it directly\n    if (this.customLLMClient) {\n      return this.customLLMClient;\n    }\n\n    // Try to get from runner if available\n    const runnerClient = this.runner?.llmProcessor.getCurrentLLMClient();\n    if (runnerClient) {\n      return runnerClient;\n    }\n\n    // If no client exists yet but we have a resolved model, create one\n    if (this.currentResolvedModel) {\n      try {\n        const newClient = getLLMClient(this.currentResolvedModel, this.reasoningOptions);\n\n        // Set it to the runner so it's available for future calls\n        if (this.runner?.llmProcessor) {\n          this.runner.llmProcessor.setCustomLLMClient(newClient);\n        }\n\n        return newClient;\n      } catch (error) {\n        this.logger.error(`[Agent] Failed to create LLM client: ${error}`);\n      }\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Generate a summary of the provided conversation messages\n   * FIXME: using current event stream to generate summary.\n   *\n   * @param request The summary request containing messages and optional model settings\n   * @returns Promise resolving to the summary response\n   */\n  public async generateSummary(request: SummaryRequest): Promise<SummaryResponse> {\n    // Get LLM client\n    const llmClient = this.getLLMClient();\n    if (!llmClient) {\n      throw new Error('LLM client not available');\n    }\n\n    // Use current resolved model if available, otherwise resolve based on request\n    const resolvedModel =\n      this.currentResolvedModel || this.modelResolver.resolve(request.model, request.provider);\n\n    // Create a system message to instruct the model\n    const systemMessage: ChatCompletionMessageParam = {\n      role: 'system',\n      content:\n        'Generate a short, concise title (maximum 6 words) that summarizes the main topic of this conversation. Return your response as a JSON object with a single field named \"title\".',\n    };\n\n    // Prepare messages array with system message followed by conversation messages\n    const messages: ChatCompletionMessageParam[] = [systemMessage, ...request.messages];\n\n    try {\n      // Call the LLM with the prepared messages\n      const response = await llmClient.chat.completions.create(\n        {\n          model: resolvedModel.id,\n          messages,\n          temperature: 0.3, // Lower temperature for more focused summaries\n\n          max_tokens: 25, // Short responses for titles\n          response_format: { type: 'json_object' }, // Enable JSON mode\n        },\n        {\n          // Pass abort signal if provided\n          signal: request.abortSignal,\n        },\n      );\n\n      // Extract summary from response\n      const content = response.choices[0]?.message?.content || '{\"title\": \"Untitled Conversation\"}';\n\n      try {\n        const jsonResponse = JSON.parse(content);\n        const summary = jsonResponse.title || 'Untitled Conversation';\n\n        return {\n          summary,\n          model: resolvedModel.id,\n          provider: resolvedModel.provider,\n        };\n      } catch (jsonError) {\n        this.logger.warn(`Failed to parse JSON response: ${content}`);\n        return {\n          summary: 'Untitled Conversation',\n          model: resolvedModel.id,\n          provider: resolvedModel.provider,\n        };\n      }\n    } catch (error) {\n      this.logger.error(`Failed to generate summary: ${error}`);\n      throw new Error(\n        `Failed to generate summary: ${error instanceof Error ? error.message : String(error)}`,\n      );\n    }\n  }\n\n  /**\n   * Get the current resolved model configuration\n   * This is available after the agent loop has started\n   *\n   * @returns The current resolved model configuration or undefined if not set\n   */\n  public getCurrentResolvedModel(): ResolvedModel | undefined {\n    return this.currentResolvedModel;\n  }\n\n  /**\n   * Aborts the currently running agent task if one exists\n   * @returns True if an execution was aborted, false otherwise\n   */\n  public abort(): boolean {\n    return this.executionController.abort();\n  }\n\n  /**\n   * Returns the current execution status of the agent\n   */\n  public status(): AgentStatus {\n    return this.executionController.getStatus();\n  }\n\n  /**\n   * Get the custom LLM client if it was provided\n   * @returns The custom LLM client or undefined if none was provided\n   */\n  getCustomLLMClient(): OpenAI | undefined {\n    return this.customLLMClient;\n  }\n\n  /**\n   * Update the internal `isReplaySnapshot` state, used for the Agent Snapshot frmaework.\n   */\n  public _setIsReplay() {\n    this.isReplaySnapshot = true;\n  }\n\n  /**\n   * Override the onAgentLoopEnd from BaseAgent to add execution controller cleanup\n   */\n  public async onAgentLoopEnd(id: string): Promise<void> {\n    // Call parent implementation first\n    await super.onAgentLoopEnd(id);\n\n    // End execution if not already ended\n    if (this.executionController.isExecuting()) {\n      this.executionController.endExecution(AgentStatus.IDLE).catch((err) => {\n        this.logger.error(`Error ending execution: ${err}`);\n      });\n    }\n  }\n\n  /**\n   * Convenient method to call the current selected LLM\n   * This method encapsulates the common pattern of getting the LLM client and resolved model,\n   * and provides better error handling when these are not available.\n   *\n   * @param params - ChatCompletion parameters (model will be automatically set from current resolved model)\n   * @param options - Optional request options (e.g., signal for abort)\n   * @returns Promise resolving to the LLM response with proper type inference based on stream parameter\n   * @throws Error if LLM client or resolved model is not available\n   */\n  public async callLLM(\n    params: Omit<ChatCompletionCreateParams, 'model'> & { stream?: false },\n    options?: RequestOptions,\n  ): Promise<ChatCompletion>;\n\n  public async callLLM(\n    params: Omit<ChatCompletionCreateParams, 'model'> & { stream: true },\n    options?: RequestOptions,\n  ): Promise<AsyncIterable<ChatCompletionChunk>>;\n\n  public async callLLM(\n    params: Omit<ChatCompletionCreateParams, 'model'>,\n    options?: RequestOptions,\n  ): Promise<ChatCompletion | AsyncIterable<ChatCompletionChunk>> {\n    const llmClient = this.getLLMClient();\n    if (!llmClient) {\n      throw new Error(\n        'LLM client is not available. Make sure the agent is properly initialized and a valid model provider is configured.',\n      );\n    }\n\n    const resolvedModel = this.getCurrentResolvedModel();\n    if (!resolvedModel) {\n      throw new Error(\n        'Resolved model is not available. Make sure the agent has been run at least once or a valid model configuration is provided.',\n      );\n    }\n\n    // Merge the resolved model ID with the provided parameters\n    const completeParams: ChatCompletionCreateParams = {\n      ...params,\n      model: resolvedModel.id,\n    };\n\n    // Call the LLM with the complete parameters\n    const response = await llmClient.chat.completions.create(completeParams, options);\n    return response;\n  }\n\n  /**\n   * Returns all available tools, filtered/modified by onRetrieveTools hook\n   *\n   * This method provides a way to get the current set of tools that would be\n   * available to the agent, after passing through the onRetrieveTools hook.\n   *\n   * Note: If the onRetrieveTools implementation depends on runtime state that\n   * changes during execution, the result of this method may differ from\n   * the actual tools used during run().\n   *\n   * @returns Promise resolving to array of available tool definitions\n   */\n  public async getAvailableTools(): Promise<Tool[]> {\n    const registeredTools = this.getTools();\n    try {\n      return await this.onRetrieveTools(registeredTools);\n    } catch (error) {\n      this.logger.error(`[Agent] Error in onRetrieveTools hook: ${error}`);\n      return registeredTools;\n    }\n  }\n}\n"],"names":["Agent","BaseAgent","error","client","tool","runOptions","Error","abortSignal","Date","normalizedOptions","isAgentRunObjectOptions","sessionId","Math","providerEngine","getToolCallEngineForProvider","runStartEvent","userEvent","isStreamingOptions","stream","systemEvent","endEvent","result","AgentStatus","options","sanitized","Array","_this_runner","runnerClient","_this_runner1","newClient","getLLMClient","request","llmClient","resolvedModel","systemMessage","messages","_response_choices__message","response","content","jsonResponse","JSON","summary","jsonError","String","id","err","params","completeParams","registeredTools","getLogger","undefined","rootLogger","LogLevel","AgentEventStreamProcessor","ToolManager","contextAwarenessOptions","ModelResolver","providers","defaultSelection","_options_tools","AgentRunner","AgentExecutionController"],"mappings":"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"}