{"version":3,"sources":["../src/hooks/use-coagent-state-render.ts"],"sourcesContent":["/**\n * The useCoAgentStateRender hook allows you to render UI or text based components on a Agentic Copilot's state in the chat.\n * This is particularly useful for showing intermediate state or progress during Agentic Copilot operations.\n *\n * ## Usage\n *\n * ### Simple Usage\n *\n * ```tsx\n * import { useCoAgentStateRender } from \"@copilotkit/react-core\";\n *\n * type YourAgentState = {\n *   agent_state_property: string;\n * }\n *\n * useCoAgentStateRender<YourAgentState>({\n *   name: \"basic_agent\",\n *   nodeName: \"optionally_specify_a_specific_node\",\n *   render: ({ status, state, nodeName }) => {\n *     return (\n *       <YourComponent\n *         agentStateProperty={state.agent_state_property}\n *         status={status}\n *         nodeName={nodeName}\n *       />\n *     );\n *   },\n * });\n * ```\n *\n * This allows for you to render UI components or text based on what is happening within the agent.\n *\n * ### Example\n * A great example of this is in our Perplexity Clone where we render the progress of an agent's internet search as it is happening.\n * You can play around with it below or learn how to build it with its [demo](/coagents/videos/perplexity-clone).\n *\n * <Callout type=\"info\">\n *   This example is hosted on Vercel and may take a few seconds to load.\n * </Callout>\n *\n * <iframe src=\"https://examples-coagents-ai-researcher-ui.vercel.app/\" className=\"w-full rounded-lg border h-[700px] my-4\" />\n */\n\nimport { useRef, useContext, useEffect } from \"react\";\nimport { CopilotContext } from \"../context/copilot-context\";\nimport { randomId } from \"@copilotkit/shared\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\nimport { useToast } from \"../components/toast/toast-provider\";\n\n/**\n * This hook is used to render agent state with custom UI components or text. This is particularly\n * useful for showing intermediate state or progress during Agentic Copilot operations.\n * To get started using rendering intermediate state through this hook, checkout the documentation.\n *\n * https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\n */\n\n// We implement useCoAgentStateRender dependency handling so that\n// the developer has the option to not provide any dependencies.\n// see useCopilotAction for more details about this approach.\nexport function useCoAgentStateRender<T = any>(\n  action: CoAgentStateRender<T>,\n  dependencies?: any[],\n): void {\n  const {\n    setCoAgentStateRender,\n    removeCoAgentStateRender,\n    coAgentStateRenders,\n    chatComponentsCache,\n    availableAgents,\n  } = useContext(CopilotContext);\n  const idRef = useRef<string>(randomId());\n  const { addToast } = useToast();\n\n  useEffect(() => {\n    if (availableAgents?.length && !availableAgents.some((a) => a.name === action.name)) {\n      const message = `(useCoAgentStateRender): Agent \"${action.name}\" not found. Make sure the agent exists and is properly configured.`;\n      addToast({ type: \"warning\", message });\n    }\n  }, [availableAgents]);\n\n  const key = `${action.name}-${action.nodeName || \"global\"}`;\n\n  if (dependencies === undefined) {\n    if (coAgentStateRenders[idRef.current]) {\n      coAgentStateRenders[idRef.current].handler = action.handler as any;\n      if (typeof action.render === \"function\") {\n        if (chatComponentsCache.current !== null) {\n          chatComponentsCache.current.coAgentStateRenders[key] = action.render;\n        }\n      }\n    }\n  }\n\n  useEffect(() => {\n    // Check for duplicates by comparing against all other actions\n    const currentId = idRef.current;\n    const hasDuplicate = Object.entries(coAgentStateRenders).some(([id, otherAction]) => {\n      // Skip comparing with self\n      if (id === currentId) return false;\n\n      // Different agent names are never duplicates\n      if (otherAction.name !== action.name) return false;\n\n      // Same agent names:\n      const hasNodeName = !!action.nodeName;\n      const hasOtherNodeName = !!otherAction.nodeName;\n\n      // If neither has nodeName, they're duplicates\n      if (!hasNodeName && !hasOtherNodeName) return true;\n\n      // If one has nodeName and other doesn't, they're not duplicates\n      if (hasNodeName !== hasOtherNodeName) return false;\n\n      // If both have nodeName, they're duplicates only if the names match\n      return action.nodeName === otherAction.nodeName;\n    });\n\n    if (hasDuplicate) {\n      const message = action.nodeName\n        ? `Found multiple state renders for agent ${action.name} and node ${action.nodeName}. State renders might get overridden`\n        : `Found multiple state renders for agent ${action.name}. State renders might get overridden`;\n\n      addToast({\n        type: \"warning\",\n        message,\n        id: `dup-action-${action.name}`,\n      });\n    }\n  }, [coAgentStateRenders]);\n\n  useEffect(() => {\n    setCoAgentStateRender(idRef.current, action as any);\n    if (chatComponentsCache.current !== null && action.render !== undefined) {\n      chatComponentsCache.current.coAgentStateRenders[key] = action.render;\n    }\n    return () => {\n      removeCoAgentStateRender(idRef.current);\n    };\n  }, [\n    setCoAgentStateRender,\n    removeCoAgentStateRender,\n    action.name,\n    // include render only if it's a string\n    typeof action.render === \"string\" ? action.render : undefined,\n    // dependencies set by the developer\n    ...(dependencies || []),\n  ]);\n}\n"],"mappings":";;;;;;;;AA2CA,SAAS,QAAQ,YAAY,iBAAiB;AAE9C,SAAS,gBAAgB;AAelB,SAAS,sBACd,QACA,cACM;AACN,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,WAAW,cAAc;AAC7B,QAAM,QAAQ,OAAe,SAAS,CAAC;AACvC,QAAM,EAAE,SAAS,IAAI,SAAS;AAE9B,YAAU,MAAM;AACd,SAAI,mDAAiB,WAAU,CAAC,gBAAgB,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO,IAAI,GAAG;AACnF,YAAM,UAAU,mCAAmC,OAAO;AAC1D,eAAS,EAAE,MAAM,WAAW,QAAQ,CAAC;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,MAAM,GAAG,OAAO,QAAQ,OAAO,YAAY;AAEjD,MAAI,iBAAiB,QAAW;AAC9B,QAAI,oBAAoB,MAAM,OAAO,GAAG;AACtC,0BAAoB,MAAM,OAAO,EAAE,UAAU,OAAO;AACpD,UAAI,OAAO,OAAO,WAAW,YAAY;AACvC,YAAI,oBAAoB,YAAY,MAAM;AACxC,8BAAoB,QAAQ,oBAAoB,GAAG,IAAI,OAAO;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,YAAU,MAAM;AAEd,UAAM,YAAY,MAAM;AACxB,UAAM,eAAe,OAAO,QAAQ,mBAAmB,EAAE,KAAK,CAAC,CAAC,IAAI,WAAW,MAAM;AAEnF,UAAI,OAAO;AAAW,eAAO;AAG7B,UAAI,YAAY,SAAS,OAAO;AAAM,eAAO;AAG7C,YAAM,cAAc,CAAC,CAAC,OAAO;AAC7B,YAAM,mBAAmB,CAAC,CAAC,YAAY;AAGvC,UAAI,CAAC,eAAe,CAAC;AAAkB,eAAO;AAG9C,UAAI,gBAAgB;AAAkB,eAAO;AAG7C,aAAO,OAAO,aAAa,YAAY;AAAA,IACzC,CAAC;AAED,QAAI,cAAc;AAChB,YAAM,UAAU,OAAO,WACnB,0CAA0C,OAAO,iBAAiB,OAAO,iDACzE,0CAA0C,OAAO;AAErD,eAAS;AAAA,QACP,MAAM;AAAA,QACN;AAAA,QACA,IAAI,cAAc,OAAO;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,mBAAmB,CAAC;AAExB,YAAU,MAAM;AACd,0BAAsB,MAAM,SAAS,MAAa;AAClD,QAAI,oBAAoB,YAAY,QAAQ,OAAO,WAAW,QAAW;AACvE,0BAAoB,QAAQ,oBAAoB,GAAG,IAAI,OAAO;AAAA,IAChE;AACA,WAAO,MAAM;AACX,+BAAyB,MAAM,OAAO;AAAA,IACxC;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA,OAAO;AAAA;AAAA,IAEP,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAAA;AAAA,IAEpD,GAAI,gBAAgB,CAAC;AAAA,EACvB,CAAC;AACH;","names":[]}