{"version":3,"sources":["../src/hooks/use-chat.ts"],"sourcesContent":["import React, { useCallback, useRef } from \"react\";\nimport {\n  FunctionCallHandler,\n  COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n  CoAgentStateRenderHandler,\n  randomId,\n  parseJson,\n} from \"@copilotkit/shared\";\nimport {\n  Message,\n  TextMessage,\n  ResultMessage,\n  convertMessagesToGqlInput,\n  filterAdjacentAgentStateMessages,\n  filterAgentStateMessages,\n  convertGqlOutputToMessages,\n  MessageStatusCode,\n  MessageRole,\n  Role,\n  CopilotRequestType,\n  ForwardedParametersInput,\n  loadMessagesFromJsonRepresentation,\n  ExtensionsInput,\n  CopilotRuntimeClient,\n  langGraphInterruptEvent,\n  MetaEvent,\n  MetaEventName,\n  ActionExecutionMessage,\n  CopilotKitLangGraphInterruptEvent,\n  LangGraphInterruptEvent,\n  MetaEventInput,\n} from \"@copilotkit/runtime-client-gql\";\n\nimport { CopilotApiConfig } from \"../context\";\nimport { FrontendAction, processActionsForRuntimeRequest } from \"../types/frontend-action\";\nimport { CoagentState } from \"../types/coagent-state\";\nimport { AgentSession } from \"../context/copilot-context\";\nimport { useCopilotRuntimeClient } from \"./use-copilot-runtime-client\";\nimport { useAsyncCallback, useErrorToast } from \"../components/error-boundary/error-utils\";\nimport {\n  LangGraphInterruptAction,\n  LangGraphInterruptActionSetter,\n} from \"../types/interrupt-action\";\n\nexport type UseChatOptions = {\n  /**\n   * System messages of the chat. Defaults to an empty array.\n   */\n  initialMessages?: Message[];\n  /**\n   * Callback function to be called when a function call is received.\n   * If the function returns a `ChatRequest` object, the request will be sent\n   * automatically to the API and will be used to update the chat.\n   */\n  onFunctionCall?: FunctionCallHandler;\n\n  /**\n   * Callback function to be called when a coagent action is received.\n   */\n  onCoAgentStateRender?: CoAgentStateRenderHandler;\n\n  /**\n   * Function definitions to be sent to the API.\n   */\n  actions: FrontendAction<any>[];\n\n  /**\n   * The CopilotKit API configuration.\n   */\n  copilotConfig: CopilotApiConfig;\n\n  /**\n   * The current list of messages in the chat.\n   */\n  messages: Message[];\n  /**\n   * The setState-powered method to update the chat messages.\n   */\n  setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n\n  /**\n   * A callback to get the latest system message.\n   */\n  makeSystemMessageCallback: () => TextMessage;\n\n  /**\n   * Whether the API request is in progress\n   */\n  isLoading: boolean;\n\n  /**\n   * setState-powered method to update the isChatLoading value\n   */\n  setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;\n\n  /**\n   * The current list of coagent states.\n   */\n  coagentStatesRef: React.RefObject<Record<string, CoagentState>>;\n\n  /**\n   * setState-powered method to update the agent states\n   */\n  setCoagentStatesWithRef: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;\n\n  /**\n   * The current agent session.\n   */\n  agentSession: AgentSession | null;\n\n  /**\n   * setState-powered method to update the agent session\n   */\n  setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;\n\n  /**\n   * The forwarded parameters.\n   */\n  forwardedParameters?: Pick<ForwardedParametersInput, \"temperature\">;\n\n  /**\n   * The current thread ID.\n   */\n  threadId: string;\n  /**\n   * set the current thread ID\n   */\n  setThreadId: (threadId: string) => void;\n  /**\n   * The current run ID.\n   */\n  runId: string | null;\n  /**\n   * set the current run ID\n   */\n  setRunId: (runId: string | null) => void;\n  /**\n   * The global chat abort controller.\n   */\n  chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n  /**\n   * The agent lock.\n   */\n  agentLock: string | null;\n  /**\n   * The extensions.\n   */\n  extensions: ExtensionsInput;\n  /**\n   * The setState-powered method to update the extensions.\n   */\n  setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;\n\n  langGraphInterruptAction: LangGraphInterruptAction | null;\n\n  setLangGraphInterruptAction: LangGraphInterruptActionSetter;\n};\n\nexport type UseChatHelpers = {\n  /**\n   * Append a user message to the chat list. This triggers the API call to fetch\n   * the assistant's response.\n   * @param message The message to append\n   */\n  append: (message: Message, options?: AppendMessageOptions) => Promise<void>;\n  /**\n   * Reload the last AI chat response for the given chat history. If the last\n   * message isn't from the assistant, it will request the API to generate a\n   * new response.\n   */\n  reload: () => Promise<void>;\n  /**\n   * Abort the current request immediately, keep the generated tokens if any.\n   */\n  stop: () => void;\n\n  /**\n   * Run the chat completion.\n   */\n  runChatCompletion: () => Promise<Message[]>;\n};\n\nexport interface AppendMessageOptions {\n  /**\n   * Whether to run the chat completion after appending the message. Defaults to `true`.\n   */\n  followUp?: boolean;\n}\n\nexport function useChat(options: UseChatOptions): UseChatHelpers {\n  const {\n    messages,\n    setMessages,\n    makeSystemMessageCallback,\n    copilotConfig,\n    setIsLoading,\n    initialMessages,\n    isLoading,\n    actions,\n    onFunctionCall,\n    onCoAgentStateRender,\n    setCoagentStatesWithRef,\n    coagentStatesRef,\n    agentSession,\n    setAgentSession,\n    threadId,\n    setThreadId,\n    runId,\n    setRunId,\n    chatAbortControllerRef,\n    agentLock,\n    extensions,\n    setExtensions,\n    langGraphInterruptAction,\n    setLangGraphInterruptAction,\n  } = options;\n  const runChatCompletionRef = useRef<(previousMessages: Message[]) => Promise<Message[]>>();\n  const addErrorToast = useErrorToast();\n  // We need to keep a ref of coagent states and session because of renderAndWait - making sure\n  // the latest state is sent to the API\n  // This is a workaround and needs to be addressed in the future\n  const agentSessionRef = useRef<AgentSession | null>(agentSession);\n  agentSessionRef.current = agentSession;\n\n  const runIdRef = useRef<string | null>(runId);\n  runIdRef.current = runId;\n  const extensionsRef = useRef<ExtensionsInput>(extensions);\n  extensionsRef.current = extensions;\n\n  const publicApiKey = copilotConfig.publicApiKey;\n\n  const headers = {\n    ...(copilotConfig.headers || {}),\n    ...(publicApiKey ? { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: publicApiKey } : {}),\n  };\n\n  const runtimeClient = useCopilotRuntimeClient({\n    url: copilotConfig.chatApiEndpoint,\n    publicApiKey: copilotConfig.publicApiKey,\n    headers,\n    credentials: copilotConfig.credentials,\n  });\n\n  const runChatCompletion = useAsyncCallback(\n    async (previousMessages: Message[]): Promise<Message[]> => {\n      setIsLoading(true);\n      const interruptEvent = langGraphInterruptAction?.event;\n      // In case an interrupt event exist and valid but has no response yet, we cannot process further messages to an agent\n      if (\n        interruptEvent?.name === MetaEventName.LangGraphInterruptEvent &&\n        interruptEvent?.value &&\n        !interruptEvent?.response &&\n        agentSessionRef.current\n      ) {\n        addErrorToast([\n          new Error(\n            \"A message was sent while interrupt is active. This will cause failure on the agent side\",\n          ),\n        ]);\n      }\n\n      // this message is just a placeholder. It will disappear once the first real message\n      // is received\n      let newMessages: Message[] = [\n        new TextMessage({\n          content: \"\",\n          role: Role.Assistant,\n        }),\n      ];\n\n      chatAbortControllerRef.current = new AbortController();\n\n      setMessages([...previousMessages, ...newMessages]);\n\n      const systemMessage = makeSystemMessageCallback();\n\n      const messagesWithContext = [systemMessage, ...(initialMessages || []), ...previousMessages];\n\n      const isAgentRun = agentSessionRef.current !== null;\n\n      const stream = runtimeClient.asStream(\n        runtimeClient.generateCopilotResponse({\n          data: {\n            frontend: {\n              actions: processActionsForRuntimeRequest(actions),\n              url: window.location.href,\n            },\n            threadId: threadId,\n            runId: runIdRef.current,\n            extensions: extensionsRef.current,\n            metaEvents: composeAndFlushMetaEventsInput([langGraphInterruptAction?.event]),\n            messages: convertMessagesToGqlInput(filterAgentStateMessages(messagesWithContext)),\n            ...(copilotConfig.cloud\n              ? {\n                  cloud: {\n                    ...(copilotConfig.cloud.guardrails?.input?.restrictToTopic?.enabled\n                      ? {\n                          guardrails: {\n                            inputValidationRules: {\n                              allowList:\n                                copilotConfig.cloud.guardrails.input.restrictToTopic.validTopics,\n                              denyList:\n                                copilotConfig.cloud.guardrails.input.restrictToTopic.invalidTopics,\n                            },\n                          },\n                        }\n                      : {}),\n                  },\n                }\n              : {}),\n            metadata: {\n              requestType: CopilotRequestType.Chat,\n            },\n            ...(agentSessionRef.current\n              ? {\n                  agentSession: agentSessionRef.current,\n                }\n              : {}),\n            agentStates: Object.values(coagentStatesRef.current!).map((state) => ({\n              agentName: state.name,\n              state: JSON.stringify(state.state),\n              configurable: JSON.stringify(state.configurable ?? {}),\n            })),\n            forwardedParameters: options.forwardedParameters || {},\n          },\n          properties: copilotConfig.properties,\n          signal: chatAbortControllerRef.current?.signal,\n        }),\n      );\n\n      const guardrailsEnabled =\n        copilotConfig.cloud?.guardrails?.input?.restrictToTopic.enabled || false;\n\n      const reader = stream.getReader();\n\n      let executedCoAgentStateRenders: string[] = [];\n      let followUp: FrontendAction[\"followUp\"] = undefined;\n\n      let messages: Message[] = [];\n      let syncedMessages: Message[] = [];\n      let interruptMessages: Message[] = [];\n\n      try {\n        while (true) {\n          let done, value;\n\n          try {\n            const readResult = await reader.read();\n            done = readResult.done;\n            value = readResult.value;\n          } catch (readError) {\n            break;\n          }\n\n          if (done) {\n            if (chatAbortControllerRef.current.signal.aborted) {\n              return [];\n            }\n            break;\n          }\n\n          if (!value?.generateCopilotResponse) {\n            continue;\n          }\n\n          runIdRef.current = value.generateCopilotResponse.runId || null;\n\n          // in the output, graphql inserts __typename, which leads to an error when sending it along\n          // as input to the next request.\n          extensionsRef.current = CopilotRuntimeClient.removeGraphQLTypename(\n            value.generateCopilotResponse.extensions || {},\n          );\n\n          // setThreadId(threadIdRef.current);\n          setRunId(runIdRef.current);\n          setExtensions(extensionsRef.current);\n          let rawMessagesResponse = value.generateCopilotResponse.messages;\n          (value.generateCopilotResponse?.metaEvents ?? []).forEach((ev) => {\n            if (ev.name === MetaEventName.LangGraphInterruptEvent) {\n              let eventValue = langGraphInterruptEvent(ev as LangGraphInterruptEvent).value;\n              eventValue = parseJson(eventValue, eventValue);\n              setLangGraphInterruptAction({\n                event: {\n                  ...langGraphInterruptEvent(ev as LangGraphInterruptEvent),\n                  value: eventValue,\n                },\n              });\n            }\n            if (ev.name === MetaEventName.CopilotKitLangGraphInterruptEvent) {\n              const data = (ev as CopilotKitLangGraphInterruptEvent).data;\n\n              // @ts-expect-error -- same type of messages\n              rawMessagesResponse = [...rawMessagesResponse, ...data.messages];\n              interruptMessages = convertGqlOutputToMessages(\n                // @ts-ignore\n                filterAdjacentAgentStateMessages(data.messages),\n              );\n            }\n          });\n\n          messages = convertGqlOutputToMessages(\n            filterAdjacentAgentStateMessages(rawMessagesResponse),\n          );\n\n          if (messages.length === 0) {\n            continue;\n          }\n\n          newMessages = [];\n\n          // request failed, display error message and quit\n          if (\n            value.generateCopilotResponse.status?.__typename === \"FailedResponseStatus\" &&\n            value.generateCopilotResponse.status.reason === \"GUARDRAILS_VALIDATION_FAILED\"\n          ) {\n            newMessages = [\n              new TextMessage({\n                role: MessageRole.Assistant,\n                content: value.generateCopilotResponse.status.details?.guardrailsReason || \"\",\n              }),\n            ];\n            setMessages([...previousMessages, ...newMessages]);\n            break;\n          }\n\n          // add messages to the chat\n          else {\n            newMessages = [...messages];\n\n            for (const message of messages) {\n              // execute onCoAgentStateRender handler\n              if (\n                message.isAgentStateMessage() &&\n                !message.active &&\n                !executedCoAgentStateRenders.includes(message.id) &&\n                onCoAgentStateRender\n              ) {\n                // Do not execute a coagent action if guardrails are enabled but the status is not known\n                if (guardrailsEnabled && value.generateCopilotResponse.status === undefined) {\n                  break;\n                }\n                // execute coagent action\n                await onCoAgentStateRender({\n                  name: message.agentName,\n                  nodeName: message.nodeName,\n                  state: message.state,\n                });\n                executedCoAgentStateRenders.push(message.id);\n              }\n            }\n\n            const lastAgentStateMessage = [...messages]\n              .reverse()\n              .find((message) => message.isAgentStateMessage());\n\n            if (lastAgentStateMessage) {\n              if (\n                lastAgentStateMessage.state.messages &&\n                lastAgentStateMessage.state.messages.length > 0\n              ) {\n                syncedMessages = loadMessagesFromJsonRepresentation(\n                  lastAgentStateMessage.state.messages,\n                );\n              }\n              setCoagentStatesWithRef((prevAgentStates) => ({\n                ...prevAgentStates,\n                [lastAgentStateMessage.agentName]: {\n                  name: lastAgentStateMessage.agentName,\n                  state: lastAgentStateMessage.state,\n                  running: lastAgentStateMessage.running,\n                  active: lastAgentStateMessage.active,\n                  threadId: lastAgentStateMessage.threadId,\n                  nodeName: lastAgentStateMessage.nodeName,\n                  runId: lastAgentStateMessage.runId,\n                },\n              }));\n              if (lastAgentStateMessage.running) {\n                setAgentSession({\n                  threadId: lastAgentStateMessage.threadId,\n                  agentName: lastAgentStateMessage.agentName,\n                  nodeName: lastAgentStateMessage.nodeName,\n                });\n              } else {\n                if (agentLock) {\n                  setAgentSession({\n                    threadId: randomId(),\n                    agentName: agentLock,\n                    nodeName: undefined,\n                  });\n                } else {\n                  setAgentSession(null);\n                }\n              }\n            }\n          }\n\n          if (newMessages.length > 0) {\n            // Update message state\n            setMessages([...previousMessages, ...newMessages]);\n          }\n        }\n        let finalMessages = constructFinalMessages(\n          [...syncedMessages, ...interruptMessages],\n          previousMessages,\n          newMessages,\n        );\n\n        let didExecuteAction = false;\n\n        // execute regular action executions that are specific to the frontend (last actions)\n        if (onFunctionCall) {\n          // Find consecutive action execution messages at the end\n          const lastMessages = [];\n          for (let i = finalMessages.length - 1; i >= 0; i--) {\n            const message = finalMessages[i];\n            if (\n              (message.isActionExecutionMessage() || message.isResultMessage()) &&\n              message.status.code !== MessageStatusCode.Pending\n            ) {\n              lastMessages.unshift(message);\n            } else {\n              break;\n            }\n          }\n\n          for (const message of lastMessages) {\n            // We update the message state before calling the handler so that the render\n            // function can be called with `executing` state\n            setMessages(finalMessages);\n\n            const action = actions.find(\n              (action) => action.name === (message as ActionExecutionMessage).name,\n            );\n            const currentResultMessagePairedFeAction = message.isResultMessage()\n              ? getPairedFeAction(actions, message)\n              : null;\n\n            const executeActionFromMessage = async (\n              action: FrontendAction<any>,\n              message: ActionExecutionMessage,\n            ) => {\n              followUp = action?.followUp;\n              const resultMessage = await executeAction({\n                onFunctionCall,\n                previousMessages,\n                message,\n                chatAbortControllerRef,\n                onError: (error: Error) => {\n                  addErrorToast([error]);\n                  console.error(`Failed to execute action ${message.name}: ${error}`);\n                },\n              });\n              didExecuteAction = true;\n              const messageIndex = finalMessages.findIndex((msg) => msg.id === message.id);\n              finalMessages.splice(messageIndex + 1, 0, resultMessage);\n\n              return resultMessage;\n            };\n\n            // execution message which has an action registered with the hook (remote availability):\n            // execute that action first, and then the \"paired FE action\"\n            if (action && message.isActionExecutionMessage()) {\n              const resultMessage = await executeActionFromMessage(action, message);\n              const pairedFeAction = getPairedFeAction(actions, resultMessage);\n\n              if (pairedFeAction) {\n                const newExecutionMessage = new ActionExecutionMessage({\n                  name: pairedFeAction.name,\n                  arguments: parseJson(resultMessage.result, resultMessage.result),\n                  status: message.status,\n                  createdAt: message.createdAt,\n                  parentMessageId: message.parentMessageId,\n                });\n                await executeActionFromMessage(pairedFeAction, newExecutionMessage);\n              }\n            } else if (message.isResultMessage() && currentResultMessagePairedFeAction) {\n              // Actions which are set up in runtime actions array: Grab the result, executed paired FE action with it as args.\n              const newExecutionMessage = new ActionExecutionMessage({\n                name: currentResultMessagePairedFeAction.name,\n                arguments: parseJson(message.result, message.result),\n                status: message.status,\n                createdAt: message.createdAt,\n              });\n              finalMessages.push(newExecutionMessage);\n              await executeActionFromMessage(\n                currentResultMessagePairedFeAction,\n                newExecutionMessage,\n              );\n            }\n          }\n\n          setMessages(finalMessages);\n        }\n\n        if (\n          // if followUp is not explicitly false\n          followUp !== false &&\n          // and we executed an action\n          (didExecuteAction ||\n            // the last message is a server side result\n            (!isAgentRun &&\n              finalMessages.length &&\n              finalMessages[finalMessages.length - 1].isResultMessage())) &&\n          // the user did not stop generation\n          !chatAbortControllerRef.current?.signal.aborted\n        ) {\n          // run the completion again and return the result\n\n          // wait for next tick to make sure all the react state updates\n          // - tried using react-dom's flushSync, but it did not work\n          await new Promise((resolve) => setTimeout(resolve, 10));\n\n          return await runChatCompletionRef.current!(finalMessages);\n        } else if (chatAbortControllerRef.current?.signal.aborted) {\n          // filter out all the action execution messages that do not have a consecutive matching result message\n          const repairedMessages = finalMessages.filter((message, actionExecutionIndex) => {\n            if (message.isActionExecutionMessage()) {\n              return finalMessages.find(\n                (msg, resultIndex) =>\n                  msg.isResultMessage() &&\n                  msg.actionExecutionId === message.id &&\n                  resultIndex === actionExecutionIndex + 1,\n              );\n            }\n            return true;\n          });\n          const repairedMessageIds = repairedMessages.map((message) => message.id);\n          setMessages(repairedMessages);\n\n          // LangGraph needs two pieces of information to continue execution:\n          // 1. The threadId\n          // 2. The nodeName it came from\n          // When stopping the agent, we don't know the nodeName the agent would have ended with\n          // Therefore, we set the nodeName to the most reasonable thing we can guess, which\n          // is \"__end__\"\n          if (agentSessionRef.current?.nodeName) {\n            setAgentSession({\n              threadId: agentSessionRef.current.threadId,\n              agentName: agentSessionRef.current.agentName,\n              nodeName: \"__end__\",\n            });\n          }\n          // only return new messages that were not filtered out\n          return newMessages.filter((message) => repairedMessageIds.includes(message.id));\n        } else {\n          return newMessages.slice();\n        }\n      } finally {\n        setIsLoading(false);\n      }\n    },\n    [\n      messages,\n      setMessages,\n      makeSystemMessageCallback,\n      copilotConfig,\n      setIsLoading,\n      initialMessages,\n      isLoading,\n      actions,\n      onFunctionCall,\n      onCoAgentStateRender,\n      setCoagentStatesWithRef,\n      coagentStatesRef,\n      agentSession,\n      setAgentSession,\n    ],\n  );\n\n  runChatCompletionRef.current = runChatCompletion;\n\n  const runChatCompletionAndHandleFunctionCall = useAsyncCallback(\n    async (messages: Message[]): Promise<void> => {\n      await runChatCompletionRef.current!(messages);\n    },\n    [messages],\n  );\n\n  // Go over all events and see that they include data that should be returned to the agent\n  const composeAndFlushMetaEventsInput = useCallback(\n    (metaEvents: (MetaEvent | undefined | null)[]) => {\n      return metaEvents.reduce((acc: MetaEventInput[], event) => {\n        if (!event) return acc;\n\n        switch (event.name) {\n          case MetaEventName.LangGraphInterruptEvent:\n            if (event.response) {\n              // Flush interrupt event from state\n              setLangGraphInterruptAction(null);\n              const value = (event as LangGraphInterruptEvent).value;\n              return [\n                ...acc,\n                {\n                  name: event.name,\n                  value: typeof value === \"string\" ? value : JSON.stringify(value),\n                  response:\n                    typeof event.response === \"string\"\n                      ? event.response\n                      : JSON.stringify(event.response),\n                },\n              ];\n            }\n            return acc;\n          default:\n            return acc;\n        }\n      }, []);\n    },\n    [setLangGraphInterruptAction],\n  );\n\n  const append = useAsyncCallback(\n    async (message: Message, options?: AppendMessageOptions): Promise<void> => {\n      if (isLoading) {\n        return;\n      }\n\n      const newMessages = [...messages, message];\n      setMessages(newMessages);\n      const followUp = options?.followUp ?? true;\n      if (followUp) {\n        return runChatCompletionAndHandleFunctionCall(newMessages);\n      }\n    },\n    [isLoading, messages, setMessages, runChatCompletionAndHandleFunctionCall],\n  );\n\n  const reload = useAsyncCallback(async (): Promise<void> => {\n    if (isLoading || messages.length === 0) {\n      return;\n    }\n    let newMessages = [...messages];\n    const lastMessage = messages[messages.length - 1];\n\n    if (lastMessage.isTextMessage() && lastMessage.role === \"assistant\") {\n      newMessages = newMessages.slice(0, -1);\n    }\n\n    setMessages(newMessages);\n\n    return runChatCompletionAndHandleFunctionCall(newMessages);\n  }, [isLoading, messages, setMessages, runChatCompletionAndHandleFunctionCall]);\n\n  const stop = (): void => {\n    chatAbortControllerRef.current?.abort(\"Stop was called\");\n  };\n\n  return {\n    append,\n    reload,\n    stop,\n    runChatCompletion: () => runChatCompletionRef.current!(messages),\n  };\n}\n\nfunction constructFinalMessages(\n  syncedMessages: Message[],\n  previousMessages: Message[],\n  newMessages: Message[],\n): Message[] {\n  const finalMessages =\n    syncedMessages.length > 0 ? [...syncedMessages] : [...previousMessages, ...newMessages];\n\n  if (syncedMessages.length > 0) {\n    const messagesWithAgentState = [...previousMessages, ...newMessages];\n\n    let previousMessageId: string | undefined = undefined;\n\n    for (const message of messagesWithAgentState) {\n      if (message.isAgentStateMessage()) {\n        // insert this message into finalMessages after the position of previousMessageId\n        const index = finalMessages.findIndex((msg) => msg.id === previousMessageId);\n        if (index !== -1) {\n          finalMessages.splice(index + 1, 0, message);\n        }\n      }\n\n      previousMessageId = message.id;\n    }\n  }\n\n  return finalMessages;\n}\n\nasync function executeAction({\n  onFunctionCall,\n  previousMessages,\n  message,\n  chatAbortControllerRef,\n  onError,\n}: {\n  onFunctionCall: FunctionCallHandler;\n  previousMessages: Message[];\n  message: ActionExecutionMessage;\n  chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n  onError: (error: Error) => void;\n}) {\n  let result: any;\n  let error: Error | null = null;\n  try {\n    result = await Promise.race([\n      onFunctionCall({\n        messages: previousMessages,\n        name: message.name,\n        args: message.arguments,\n      }),\n      new Promise((resolve) =>\n        chatAbortControllerRef.current?.signal.addEventListener(\"abort\", () =>\n          resolve(\"Operation was aborted by the user\"),\n        ),\n      ),\n      // if the user stopped generation, we also abort consecutive actions\n      new Promise((resolve) => {\n        if (chatAbortControllerRef.current?.signal.aborted) {\n          resolve(\"Operation was aborted by the user\");\n        }\n      }),\n    ]);\n  } catch (e) {\n    onError(e as Error);\n  }\n  return new ResultMessage({\n    id: \"result-\" + message.id,\n    result: ResultMessage.encodeResult(\n      error\n        ? {\n            content: result,\n            error: JSON.parse(JSON.stringify(error, Object.getOwnPropertyNames(error))),\n          }\n        : result,\n    ),\n    actionExecutionId: message.id,\n    actionName: message.name,\n  });\n}\n\nfunction getPairedFeAction(\n  actions: FrontendAction<any>[],\n  message: ActionExecutionMessage | ResultMessage,\n) {\n  let actionName = null;\n  if (message.isActionExecutionMessage()) {\n    actionName = message.name;\n  } else if (message.isResultMessage()) {\n    actionName = message.actionName;\n  }\n  return actions.find(\n    (action) =>\n      (action.name === actionName && action.available === \"frontend\") ||\n      action.pairedAction === actionName,\n  );\n}\n"],"mappings":"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","names":["_a","messages","action","message","options"]}