@copilotkit/react-core 1.9.2-next.8 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/CHANGELOG.md +193 -0
  2. package/dist/{chunk-ERXWDCY6.mjs → chunk-36MGCCPZ.mjs} +2 -2
  3. package/dist/{chunk-CCESTGAM.mjs → chunk-3OQM3NEK.mjs} +2 -2
  4. package/dist/{chunk-7G6RR4HE.mjs → chunk-3Q4F7RF2.mjs} +2 -2
  5. package/dist/chunk-57K2ZJ5F.mjs +348 -0
  6. package/dist/chunk-57K2ZJ5F.mjs.map +1 -0
  7. package/dist/{chunk-UBNRUXEK.mjs → chunk-5BSUSFHM.mjs} +2 -2
  8. package/dist/{chunk-RN3ZRHI7.mjs → chunk-AD7DWJNW.mjs} +66 -25
  9. package/dist/chunk-AD7DWJNW.mjs.map +1 -0
  10. package/dist/{chunk-JPMIAGI6.mjs → chunk-BVK7PLK6.mjs} +2 -2
  11. package/dist/{chunk-VJCHRQ7Q.mjs → chunk-DGON3GZX.mjs} +39 -6
  12. package/dist/chunk-DGON3GZX.mjs.map +1 -0
  13. package/dist/{chunk-XFOTNHYA.mjs → chunk-DKZTPL66.mjs} +2 -2
  14. package/dist/{chunk-XFOTNHYA.mjs.map → chunk-DKZTPL66.mjs.map} +1 -1
  15. package/dist/{chunk-S4BOATBG.mjs → chunk-FN3UA2ZE.mjs} +3 -3
  16. package/dist/{chunk-ISYBUDL4.mjs → chunk-JWAXDYOW.mjs} +11 -12
  17. package/dist/chunk-JWAXDYOW.mjs.map +1 -0
  18. package/dist/{chunk-T4ZKC4X4.mjs → chunk-KIXKBJUV.mjs} +3 -3
  19. package/dist/{chunk-I4JPQECN.mjs → chunk-LFAZTKBK.mjs} +5 -5
  20. package/dist/{chunk-JHIZ5HAI.mjs → chunk-NJA5ZLAZ.mjs} +29 -10
  21. package/dist/chunk-NJA5ZLAZ.mjs.map +1 -0
  22. package/dist/{chunk-ZHEEHGLS.mjs → chunk-QGT4JO7R.mjs} +35 -6
  23. package/dist/chunk-QGT4JO7R.mjs.map +1 -0
  24. package/dist/{chunk-JXF732XG.mjs → chunk-S5QUEHJC.mjs} +195 -77
  25. package/dist/chunk-S5QUEHJC.mjs.map +1 -0
  26. package/dist/{chunk-QQZLIEXK.mjs → chunk-SJJNFYGQ.mjs} +3 -3
  27. package/dist/{chunk-CMQV4XNY.mjs → chunk-VDADWRS3.mjs} +2 -2
  28. package/dist/chunk-YAF2LATQ.mjs +310 -0
  29. package/dist/chunk-YAF2LATQ.mjs.map +1 -0
  30. package/dist/{chunk-VF6UPRKM.mjs → chunk-ZGMZ5WJI.mjs} +4 -4
  31. package/dist/components/copilot-provider/copilot-messages.js +37 -4
  32. package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
  33. package/dist/components/copilot-provider/copilot-messages.mjs +3 -3
  34. package/dist/components/copilot-provider/copilotkit-props.d.ts +14 -9
  35. package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
  36. package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
  37. package/dist/components/copilot-provider/copilotkit.js +354 -258
  38. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  39. package/dist/components/copilot-provider/copilotkit.mjs +10 -10
  40. package/dist/components/copilot-provider/index.d.ts +1 -1
  41. package/dist/components/copilot-provider/index.js +354 -258
  42. package/dist/components/copilot-provider/index.js.map +1 -1
  43. package/dist/components/copilot-provider/index.mjs +10 -10
  44. package/dist/components/error-boundary/error-boundary.js +135 -146
  45. package/dist/components/error-boundary/error-boundary.js.map +1 -1
  46. package/dist/components/error-boundary/error-boundary.mjs +4 -4
  47. package/dist/components/error-boundary/error-utils.js.map +1 -1
  48. package/dist/components/error-boundary/error-utils.mjs +2 -2
  49. package/dist/components/index.d.ts +1 -1
  50. package/dist/components/index.js +354 -258
  51. package/dist/components/index.js.map +1 -1
  52. package/dist/components/index.mjs +10 -10
  53. package/dist/components/toast/toast-provider.js +118 -85
  54. package/dist/components/toast/toast-provider.js.map +1 -1
  55. package/dist/components/toast/toast-provider.mjs +1 -1
  56. package/dist/components/usage-banner.js +135 -146
  57. package/dist/components/usage-banner.js.map +1 -1
  58. package/dist/components/usage-banner.mjs +1 -1
  59. package/dist/context/copilot-context.d.ts +1 -1
  60. package/dist/context/copilot-context.js +1 -1
  61. package/dist/context/copilot-context.js.map +1 -1
  62. package/dist/context/copilot-context.mjs +1 -1
  63. package/dist/context/index.d.ts +1 -1
  64. package/dist/context/index.js +1 -1
  65. package/dist/context/index.js.map +1 -1
  66. package/dist/context/index.mjs +1 -1
  67. package/dist/{copilot-context-3da805ab.d.ts → copilot-context-3ab4fdf5.d.ts} +3 -3
  68. package/dist/hooks/index.d.ts +1 -1
  69. package/dist/hooks/index.js +249 -88
  70. package/dist/hooks/index.js.map +1 -1
  71. package/dist/hooks/index.mjs +32 -32
  72. package/dist/hooks/use-chat.d.ts +1 -1
  73. package/dist/hooks/use-chat.js +287 -174
  74. package/dist/hooks/use-chat.js.map +1 -1
  75. package/dist/hooks/use-chat.mjs +5 -5
  76. package/dist/hooks/use-coagent-state-render.js +1 -1
  77. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  78. package/dist/hooks/use-coagent-state-render.mjs +3 -3
  79. package/dist/hooks/use-coagent.d.ts +1 -1
  80. package/dist/hooks/use-coagent.js +224 -82
  81. package/dist/hooks/use-coagent.js.map +1 -1
  82. package/dist/hooks/use-coagent.mjs +14 -14
  83. package/dist/hooks/use-copilot-action.js +26 -7
  84. package/dist/hooks/use-copilot-action.js.map +1 -1
  85. package/dist/hooks/use-copilot-action.mjs +4 -4
  86. package/dist/hooks/use-copilot-additional-instructions.js +1 -1
  87. package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
  88. package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
  89. package/dist/hooks/use-copilot-authenticated-action.js +26 -7
  90. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  91. package/dist/hooks/use-copilot-authenticated-action.mjs +5 -5
  92. package/dist/hooks/use-copilot-chat.d.ts +1 -1
  93. package/dist/hooks/use-copilot-chat.js +195 -82
  94. package/dist/hooks/use-copilot-chat.js.map +1 -1
  95. package/dist/hooks/use-copilot-chat.mjs +13 -13
  96. package/dist/hooks/use-copilot-readable.js +1 -1
  97. package/dist/hooks/use-copilot-readable.js.map +1 -1
  98. package/dist/hooks/use-copilot-readable.mjs +2 -2
  99. package/dist/hooks/use-copilot-runtime-client.d.ts +2 -2
  100. package/dist/hooks/use-copilot-runtime-client.js +8 -8
  101. package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
  102. package/dist/hooks/use-copilot-runtime-client.mjs +2 -2
  103. package/dist/hooks/use-langgraph-interrupt-render.js +1 -1
  104. package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
  105. package/dist/hooks/use-langgraph-interrupt-render.mjs +2 -2
  106. package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
  107. package/dist/hooks/use-langgraph-interrupt.js +195 -82
  108. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  109. package/dist/hooks/use-langgraph-interrupt.mjs +14 -14
  110. package/dist/hooks/use-make-copilot-document-readable.js +1 -1
  111. package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
  112. package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
  113. package/dist/index.d.ts +1 -1
  114. package/dist/index.js +593 -336
  115. package/dist/index.js.map +1 -1
  116. package/dist/index.mjs +33 -33
  117. package/dist/lib/copilot-task.d.ts +1 -1
  118. package/dist/lib/copilot-task.js.map +1 -1
  119. package/dist/lib/copilot-task.mjs +11 -11
  120. package/dist/lib/index.d.ts +1 -1
  121. package/dist/lib/index.js.map +1 -1
  122. package/dist/lib/index.mjs +11 -11
  123. package/dist/setupTests.d.ts +2 -0
  124. package/dist/setupTests.js +26 -0
  125. package/dist/setupTests.js.map +1 -0
  126. package/dist/setupTests.mjs +24 -0
  127. package/dist/setupTests.mjs.map +1 -0
  128. package/dist/types/interrupt-action.d.ts +1 -1
  129. package/dist/utils/extract.d.ts +1 -1
  130. package/dist/utils/extract.js.map +1 -1
  131. package/dist/utils/extract.mjs +10 -10
  132. package/dist/utils/index.d.ts +1 -1
  133. package/dist/utils/index.js.map +1 -1
  134. package/dist/utils/index.mjs +10 -10
  135. package/jest.config.js +4 -0
  136. package/package.json +6 -3
  137. package/src/components/copilot-provider/__tests__/{copilotkit-trace.test.tsx → copilotkit-error.test.tsx} +17 -17
  138. package/src/components/copilot-provider/copilot-messages.tsx +43 -4
  139. package/src/components/copilot-provider/copilotkit-props.tsx +13 -8
  140. package/src/components/copilot-provider/copilotkit.tsx +61 -19
  141. package/src/components/toast/toast-provider.tsx +49 -24
  142. package/src/components/usage-banner.tsx +144 -147
  143. package/src/context/copilot-context.tsx +4 -4
  144. package/src/hooks/__tests__/use-coagent-config.test.ts +284 -0
  145. package/src/hooks/use-chat.ts +249 -61
  146. package/src/hooks/use-coagent.ts +41 -0
  147. package/src/hooks/use-copilot-action.ts +51 -9
  148. package/src/hooks/use-copilot-runtime-client.ts +12 -50
  149. package/src/setupTests.ts +26 -0
  150. package/tsconfig.json +5 -2
  151. package/dist/chunk-HD2GE3DK.mjs +0 -359
  152. package/dist/chunk-HD2GE3DK.mjs.map +0 -1
  153. package/dist/chunk-ISYBUDL4.mjs.map +0 -1
  154. package/dist/chunk-JHIZ5HAI.mjs.map +0 -1
  155. package/dist/chunk-JXF732XG.mjs.map +0 -1
  156. package/dist/chunk-RN3ZRHI7.mjs.map +0 -1
  157. package/dist/chunk-VJCHRQ7Q.mjs.map +0 -1
  158. package/dist/chunk-VRXANACV.mjs +0 -277
  159. package/dist/chunk-VRXANACV.mjs.map +0 -1
  160. package/dist/chunk-ZHEEHGLS.mjs.map +0 -1
  161. /package/dist/{chunk-ERXWDCY6.mjs.map → chunk-36MGCCPZ.mjs.map} +0 -0
  162. /package/dist/{chunk-CCESTGAM.mjs.map → chunk-3OQM3NEK.mjs.map} +0 -0
  163. /package/dist/{chunk-7G6RR4HE.mjs.map → chunk-3Q4F7RF2.mjs.map} +0 -0
  164. /package/dist/{chunk-UBNRUXEK.mjs.map → chunk-5BSUSFHM.mjs.map} +0 -0
  165. /package/dist/{chunk-JPMIAGI6.mjs.map → chunk-BVK7PLK6.mjs.map} +0 -0
  166. /package/dist/{chunk-S4BOATBG.mjs.map → chunk-FN3UA2ZE.mjs.map} +0 -0
  167. /package/dist/{chunk-T4ZKC4X4.mjs.map → chunk-KIXKBJUV.mjs.map} +0 -0
  168. /package/dist/{chunk-I4JPQECN.mjs.map → chunk-LFAZTKBK.mjs.map} +0 -0
  169. /package/dist/{chunk-QQZLIEXK.mjs.map → chunk-SJJNFYGQ.mjs.map} +0 -0
  170. /package/dist/{chunk-CMQV4XNY.mjs.map → chunk-VDADWRS3.mjs.map} +0 -0
  171. /package/dist/{chunk-VF6UPRKM.mjs.map → chunk-ZGMZ5WJI.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/use-coagent-state-render.ts","../../src/context/copilot-context.tsx","../../src/components/toast/toast-provider.tsx"],"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, CopilotKitAgentDiscoveryError } 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 { setBannerError, 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\n // Route to banner instead of toast for consistency\n const agentError = new CopilotKitAgentDiscoveryError({\n agentName: action.name,\n availableAgents: availableAgents.map((a) => ({ name: a.name, id: a.id })),\n });\n setBannerError(agentError);\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","import { CopilotCloudConfig, FunctionCallHandler, CopilotTraceHandler } from \"@copilotkit/shared\";\nimport {\n ActionRenderProps,\n CatchAllActionRenderProps,\n FrontendAction,\n} from \"../types/frontend-action\";\nimport React from \"react\";\nimport { TreeNodeId, Tree } from \"../hooks/use-tree\";\nimport { DocumentPointer } from \"../types\";\nimport { CopilotChatSuggestionConfiguration } from \"../types/chat-suggestion-configuration\";\nimport { CoAgentStateRender, CoAgentStateRenderProps } from \"../types/coagent-action\";\nimport { CoagentState } from \"../types/coagent-state\";\nimport {\n CopilotRuntimeClient,\n ExtensionsInput,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { Agent } from \"@copilotkit/runtime-client-gql\";\nimport {\n LangGraphInterruptAction,\n LangGraphInterruptActionSetter,\n} from \"../types/interrupt-action\";\n\n/**\n * Interface for the configuration of the Copilot API.\n */\nexport interface CopilotApiConfig {\n /**\n * The public API key for Copilot Cloud.\n */\n publicApiKey?: string;\n\n /**\n * The configuration for Copilot Cloud.\n */\n cloud?: CopilotCloudConfig;\n\n /**\n * The endpoint for the chat API.\n */\n chatApiEndpoint: string;\n\n /**\n * The endpoint for the Copilot transcribe audio service.\n */\n transcribeAudioUrl?: string;\n\n /**\n * The endpoint for the Copilot text to speech service.\n */\n textToSpeechUrl?: string;\n\n /**\n * additional headers to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'Authorization': 'Bearer your_token_here'\n * }\n * ```\n */\n headers: Record<string, string>;\n\n /**\n * Custom properties to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'user_id': 'user_id'\n * }\n * ```\n */\n properties?: Record<string, any>;\n\n /**\n * Indicates whether the user agent should send or receive cookies from the other domain\n * in the case of cross-origin requests.\n */\n credentials?: RequestCredentials;\n\n /**\n * Optional configuration for connecting to Model Context Protocol (MCP) servers.\n * This is typically derived from the CopilotKitProps and used internally.\n * @experimental\n */\n mcpServers?: Array<{ endpoint: string; apiKey?: string }>;\n}\n\nexport type InChatRenderFunction<TProps = ActionRenderProps<any> | CatchAllActionRenderProps<any>> =\n (props: TProps) => string | JSX.Element;\nexport type CoagentInChatRenderFunction = (\n props: CoAgentStateRenderProps<any>,\n) => string | JSX.Element | undefined | null;\n\nexport interface ChatComponentsCache {\n actions: Record<string, InChatRenderFunction | string>;\n coAgentStateRenders: Record<string, CoagentInChatRenderFunction | string>;\n}\n\nexport interface AgentSession {\n agentName: string;\n threadId?: string;\n nodeName?: string;\n}\n\nexport interface AuthState {\n status: \"authenticated\" | \"unauthenticated\";\n authHeaders: Record<string, string>;\n userId?: string;\n metadata?: Record<string, any>;\n}\n\nexport type ActionName = string;\nexport type ContextTree = Tree;\n\nexport interface CopilotContextParams {\n // function-calling\n actions: Record<string, FrontendAction<any>>;\n setAction: (id: string, action: FrontendAction<any>) => void;\n removeAction: (id: string) => void;\n\n // coagent actions\n coAgentStateRenders: Record<string, CoAgentStateRender<any>>;\n setCoAgentStateRender: (id: string, stateRender: CoAgentStateRender<any>) => void;\n removeCoAgentStateRender: (id: string) => void;\n\n chatComponentsCache: React.RefObject<ChatComponentsCache>;\n\n getFunctionCallHandler: (\n customEntryPoints?: Record<string, FrontendAction<any>>,\n ) => FunctionCallHandler;\n\n // text context\n addContext: (context: string, parentId?: string, categories?: string[]) => TreeNodeId;\n removeContext: (id: TreeNodeId) => void;\n getAllContext: () => Tree;\n getContextString: (documents: DocumentPointer[], categories: string[]) => string;\n\n // document context\n addDocumentContext: (documentPointer: DocumentPointer, categories?: string[]) => TreeNodeId;\n removeDocumentContext: (documentId: string) => void;\n getDocumentsContext: (categories: string[]) => DocumentPointer[];\n\n isLoading: boolean;\n setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;\n\n chatSuggestionConfiguration: { [key: string]: CopilotChatSuggestionConfiguration };\n addChatSuggestionConfiguration: (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => void;\n removeChatSuggestionConfiguration: (id: string) => void;\n\n chatInstructions: string;\n setChatInstructions: React.Dispatch<React.SetStateAction<string>>;\n\n additionalInstructions?: string[];\n setAdditionalInstructions: React.Dispatch<React.SetStateAction<string[]>>;\n\n // api endpoints\n copilotApiConfig: CopilotApiConfig;\n\n showDevConsole: boolean;\n\n // agents\n coagentStates: Record<string, CoagentState>;\n setCoagentStates: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;\n coagentStatesRef: React.RefObject<Record<string, CoagentState>>;\n setCoagentStatesWithRef: (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => void;\n\n agentSession: AgentSession | null;\n setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;\n\n agentLock: string | null;\n\n threadId: string;\n setThreadId: React.Dispatch<React.SetStateAction<string>>;\n\n runId: string | null;\n setRunId: React.Dispatch<React.SetStateAction<string | null>>;\n\n // The chat abort controller can be used to stop generation globally,\n // i.e. when using `stop()` from `useChat`\n chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n\n // runtime\n runtimeClient: CopilotRuntimeClient;\n\n /**\n * The forwarded parameters to use for the task.\n */\n forwardedParameters?: Pick<ForwardedParametersInput, \"temperature\">;\n availableAgents: Agent[];\n\n /**\n * The auth states for the CopilotKit.\n */\n authStates_c?: Record<ActionName, AuthState>;\n setAuthStates_c?: React.Dispatch<React.SetStateAction<Record<ActionName, AuthState>>>;\n\n /**\n * The auth config for the CopilotKit.\n */\n authConfig_c?: {\n SignInComponent: React.ComponentType<{\n onSignInComplete: (authState: AuthState) => void;\n }>;\n };\n\n extensions: ExtensionsInput;\n setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;\n langGraphInterruptAction: LangGraphInterruptAction | null;\n setLangGraphInterruptAction: LangGraphInterruptActionSetter;\n removeLangGraphInterruptAction: () => void;\n\n /**\n * Optional trace handler for comprehensive debugging and observability.\n */\n onTrace?: CopilotTraceHandler;\n}\n\nconst emptyCopilotContext: CopilotContextParams = {\n actions: {},\n setAction: () => {},\n removeAction: () => {},\n\n coAgentStateRenders: {},\n setCoAgentStateRender: () => {},\n removeCoAgentStateRender: () => {},\n\n chatComponentsCache: { current: { actions: {}, coAgentStateRenders: {} } },\n getContextString: (documents: DocumentPointer[], categories: string[]) =>\n returnAndThrowInDebug(\"\"),\n addContext: () => \"\",\n removeContext: () => {},\n getAllContext: () => [],\n\n getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),\n\n isLoading: false,\n setIsLoading: () => returnAndThrowInDebug(false),\n\n chatInstructions: \"\",\n setChatInstructions: () => returnAndThrowInDebug(\"\"),\n\n additionalInstructions: [],\n setAdditionalInstructions: () => returnAndThrowInDebug([]),\n\n getDocumentsContext: (categories: string[]) => returnAndThrowInDebug([]),\n addDocumentContext: () => returnAndThrowInDebug(\"\"),\n removeDocumentContext: () => {},\n runtimeClient: {} as any,\n\n copilotApiConfig: new (class implements CopilotApiConfig {\n get chatApiEndpoint(): string {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n\n get headers(): Record<string, string> {\n return {};\n }\n get body(): Record<string, any> {\n return {};\n }\n })(),\n\n chatSuggestionConfiguration: {},\n addChatSuggestionConfiguration: () => {},\n removeChatSuggestionConfiguration: () => {},\n showDevConsole: false,\n coagentStates: {},\n setCoagentStates: () => {},\n coagentStatesRef: { current: {} },\n setCoagentStatesWithRef: () => {},\n agentSession: null,\n setAgentSession: () => {},\n forwardedParameters: {},\n agentLock: null,\n threadId: \"\",\n setThreadId: () => {},\n runId: null,\n setRunId: () => {},\n chatAbortControllerRef: { current: null },\n availableAgents: [],\n extensions: {},\n setExtensions: () => {},\n langGraphInterruptAction: null,\n setLangGraphInterruptAction: () => null,\n removeLangGraphInterruptAction: () => null,\n onTrace: undefined,\n};\n\nexport const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);\n\nexport function useCopilotContext(): CopilotContextParams {\n const context = React.useContext(CopilotContext);\n if (context === emptyCopilotContext) {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n return context;\n}\n\nfunction returnAndThrowInDebug<T>(_value: T): T {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n}\n","import { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport { ErrorToast } from \"../error-boundary/error-utils\";\nimport { PartialBy, CopilotKitError, CopilotKitErrorCode, Severity } from \"@copilotkit/shared\";\nimport { renderCopilotKitUsage } from \"../usage-banner\";\n\ninterface Toast {\n id: string;\n message: string | React.ReactNode;\n type: \"info\" | \"success\" | \"warning\" | \"error\";\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (toast: PartialBy<Toast, \"id\">) => void;\n addGraphQLErrorsToast: (errors: GraphQLError[]) => void;\n removeToast: (id: string) => void;\n enabled: boolean;\n // Banner management\n bannerError: CopilotKitError | null;\n setBannerError: (error: CopilotKitError | null) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\n// Helper functions for error banner styling\ntype ErrorSeverity = \"critical\" | \"warning\" | \"info\";\n\ninterface ErrorColors {\n background: string;\n border: string;\n text: string;\n icon: string;\n}\n\nfunction getErrorSeverity(error: CopilotKitError): ErrorSeverity {\n // Use structured error severity if available\n if (error.severity) {\n switch (error.severity) {\n case Severity.CRITICAL:\n return \"critical\";\n case Severity.WARNING:\n return \"warning\";\n case Severity.INFO:\n return \"info\";\n default:\n return \"info\";\n }\n }\n\n // Fallback: Check for API key errors which should always be critical\n const message = error.message.toLowerCase();\n if (\n message.includes(\"api key\") ||\n message.includes(\"401\") ||\n message.includes(\"unauthorized\") ||\n message.includes(\"authentication\") ||\n message.includes(\"incorrect api key\")\n ) {\n return \"critical\";\n }\n\n // Default to info level\n return \"info\";\n}\n\nfunction getErrorColors(severity: ErrorSeverity): ErrorColors {\n switch (severity) {\n case \"critical\":\n return {\n background: \"#fee2e2\",\n border: \"#dc2626\",\n text: \"#7f1d1d\",\n icon: \"#dc2626\",\n };\n case \"warning\":\n return {\n background: \"#fef3c7\",\n border: \"#d97706\",\n text: \"#78350f\",\n icon: \"#d97706\",\n };\n case \"info\":\n return {\n background: \"#dbeafe\",\n border: \"#2563eb\",\n text: \"#1e3a8a\",\n icon: \"#2563eb\",\n };\n }\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nexport function ToastProvider({\n enabled,\n children,\n}: {\n enabled: boolean;\n children: React.ReactNode;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [bannerError, setBannerErrorState] = useState<CopilotKitError | null>(null);\n\n const removeToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const addToast = useCallback(\n (toast: PartialBy<Toast, \"id\">) => {\n // Respect the enabled flag for ALL toasts\n if (!enabled) {\n return;\n }\n\n const id = toast.id ?? Math.random().toString(36).substring(2, 9);\n\n setToasts((currentToasts) => {\n if (currentToasts.find((toast) => toast.id === id)) return currentToasts;\n return [...currentToasts, { ...toast, id }];\n });\n\n if (toast.duration) {\n setTimeout(() => {\n removeToast(id);\n }, toast.duration);\n }\n },\n [enabled, removeToast],\n );\n\n const setBannerError = useCallback(\n (error: CopilotKitError | null) => {\n // Respect the enabled flag for ALL errors\n if (!enabled && error !== null) {\n return;\n }\n setBannerErrorState(error);\n },\n [enabled],\n );\n\n const addGraphQLErrorsToast = useCallback((errors: GraphQLError[]) => {\n // DEPRECATED: All errors now route to banners for consistency\n console.warn(\"addGraphQLErrorsToast is deprecated. All errors now show as banners.\");\n // Function kept for backward compatibility - does nothing\n }, []);\n\n const value = {\n toasts,\n addToast,\n addGraphQLErrorsToast,\n removeToast,\n enabled,\n bannerError,\n setBannerError,\n };\n\n return (\n <ToastContext.Provider value={value}>\n {/* Banner Error Display */}\n {bannerError &&\n (() => {\n const severity = getErrorSeverity(bannerError);\n const colors = getErrorColors(severity);\n\n return (\n <div\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 9999,\n backgroundColor: colors.background,\n border: `1px solid ${colors.border}`,\n borderLeft: `4px solid ${colors.border}`,\n borderRadius: \"8px\",\n padding: \"10px 14px\",\n fontSize: \"13px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n backdropFilter: \"blur(8px)\",\n maxWidth: \"500px\",\n minWidth: \"350px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\", flex: 1 }}>\n <div\n style={{\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n backgroundColor: colors.border,\n flexShrink: 0,\n }}\n />\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"10px\", flex: 1 }}>\n <div\n style={{\n color: colors.text,\n lineHeight: \"1.4\",\n fontWeight: \"400\",\n fontSize: \"13px\",\n flex: 1,\n wordWrap: \"break-word\",\n overflowWrap: \"break-word\",\n hyphens: \"auto\",\n }}\n >\n {(() => {\n const message = bannerError.message;\n const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const plainUrlRegex = /(https?:\\/\\/[^\\s)]+)/g;\n\n // Remove URLs and markdown links from the message, keep just the text\n let cleanMessage = message\n .replace(markdownLinkRegex, \"\") // Remove [text](url)\n .replace(plainUrlRegex, \"\") // Remove plain URLs\n .replace(/See more:\\s*/g, \"\") // Remove \"See more:\" text\n .replace(/\\s+/g, \" \") // Clean up extra spaces\n .trim();\n\n // Truncate very long messages for better display\n if (cleanMessage.length > 120) {\n cleanMessage = cleanMessage.substring(0, 117) + \"...\";\n }\n\n return cleanMessage;\n })()}\n </div>\n\n {(() => {\n const message = bannerError.message;\n const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const plainUrlRegex = /(https?:\\/\\/[^\\s)]+)/g;\n\n // Extract the first URL found\n let url = null;\n let buttonText = \"See More\";\n\n // Check for markdown links first\n const markdownMatch = markdownLinkRegex.exec(message);\n if (markdownMatch) {\n url = markdownMatch[2];\n buttonText = \"See More\";\n } else {\n // Check for plain URLs\n const urlMatch = plainUrlRegex.exec(message);\n if (urlMatch) {\n url = urlMatch[0];\n buttonText = \"See More\";\n }\n }\n\n if (!url) return null;\n\n return (\n <button\n onClick={() => window.open(url, \"_blank\", \"noopener,noreferrer\")}\n style={{\n background: colors.border,\n color: \"white\",\n border: \"none\",\n borderRadius: \"5px\",\n padding: \"4px 10px\",\n fontSize: \"11px\",\n fontWeight: \"500\",\n cursor: \"pointer\",\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"0.9\";\n e.currentTarget.style.transform = \"translateY(-1px)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n {buttonText}\n </button>\n );\n })()}\n </div>\n </div>\n <button\n onClick={() => setBannerError(null)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: colors.text,\n cursor: \"pointer\",\n padding: \"2px\",\n borderRadius: \"3px\",\n fontSize: \"14px\",\n lineHeight: \"1\",\n opacity: 0.6,\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n title=\"Dismiss\"\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"0.6\";\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n ×\n </button>\n </div>\n </div>\n );\n })()}\n\n {/* Toast Display - Deprecated: All errors now show as banners */}\n {children}\n </ToastContext.Provider>\n );\n}\n\n// Toast component removed - all errors now show as banners for consistency\n"],"mappings":"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","names":["import_react","React","import_shared","import_react"]}
1
+ {"version":3,"sources":["../../src/hooks/use-coagent-state-render.ts","../../src/context/copilot-context.tsx","../../src/components/toast/toast-provider.tsx"],"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, CopilotKitAgentDiscoveryError } 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 { setBannerError, 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\n // Route to banner instead of toast for consistency\n const agentError = new CopilotKitAgentDiscoveryError({\n agentName: action.name,\n availableAgents: availableAgents.map((a) => ({ name: a.name, id: a.id })),\n });\n setBannerError(agentError);\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","import { CopilotCloudConfig, FunctionCallHandler, CopilotErrorHandler } from \"@copilotkit/shared\";\nimport {\n ActionRenderProps,\n CatchAllActionRenderProps,\n FrontendAction,\n} from \"../types/frontend-action\";\nimport React from \"react\";\nimport { TreeNodeId, Tree } from \"../hooks/use-tree\";\nimport { DocumentPointer } from \"../types\";\nimport { CopilotChatSuggestionConfiguration } from \"../types/chat-suggestion-configuration\";\nimport { CoAgentStateRender, CoAgentStateRenderProps } from \"../types/coagent-action\";\nimport { CoagentState } from \"../types/coagent-state\";\nimport {\n CopilotRuntimeClient,\n ExtensionsInput,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { Agent } from \"@copilotkit/runtime-client-gql\";\nimport {\n LangGraphInterruptAction,\n LangGraphInterruptActionSetter,\n} from \"../types/interrupt-action\";\n\n/**\n * Interface for the configuration of the Copilot API.\n */\nexport interface CopilotApiConfig {\n /**\n * The public API key for Copilot Cloud.\n */\n publicApiKey?: string;\n\n /**\n * The configuration for Copilot Cloud.\n */\n cloud?: CopilotCloudConfig;\n\n /**\n * The endpoint for the chat API.\n */\n chatApiEndpoint: string;\n\n /**\n * The endpoint for the Copilot transcribe audio service.\n */\n transcribeAudioUrl?: string;\n\n /**\n * The endpoint for the Copilot text to speech service.\n */\n textToSpeechUrl?: string;\n\n /**\n * additional headers to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'Authorization': 'Bearer your_token_here'\n * }\n * ```\n */\n headers: Record<string, string>;\n\n /**\n * Custom properties to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'user_id': 'user_id'\n * }\n * ```\n */\n properties?: Record<string, any>;\n\n /**\n * Indicates whether the user agent should send or receive cookies from the other domain\n * in the case of cross-origin requests.\n */\n credentials?: RequestCredentials;\n\n /**\n * Optional configuration for connecting to Model Context Protocol (MCP) servers.\n * This is typically derived from the CopilotKitProps and used internally.\n * @experimental\n */\n mcpServers?: Array<{ endpoint: string; apiKey?: string }>;\n}\n\nexport type InChatRenderFunction<TProps = ActionRenderProps<any> | CatchAllActionRenderProps<any>> =\n (props: TProps) => string | JSX.Element;\nexport type CoagentInChatRenderFunction = (\n props: CoAgentStateRenderProps<any>,\n) => string | JSX.Element | undefined | null;\n\nexport interface ChatComponentsCache {\n actions: Record<string, InChatRenderFunction | string>;\n coAgentStateRenders: Record<string, CoagentInChatRenderFunction | string>;\n}\n\nexport interface AgentSession {\n agentName: string;\n threadId?: string;\n nodeName?: string;\n}\n\nexport interface AuthState {\n status: \"authenticated\" | \"unauthenticated\";\n authHeaders: Record<string, string>;\n userId?: string;\n metadata?: Record<string, any>;\n}\n\nexport type ActionName = string;\nexport type ContextTree = Tree;\n\nexport interface CopilotContextParams {\n // function-calling\n actions: Record<string, FrontendAction<any>>;\n setAction: (id: string, action: FrontendAction<any>) => void;\n removeAction: (id: string) => void;\n\n // coagent actions\n coAgentStateRenders: Record<string, CoAgentStateRender<any>>;\n setCoAgentStateRender: (id: string, stateRender: CoAgentStateRender<any>) => void;\n removeCoAgentStateRender: (id: string) => void;\n\n chatComponentsCache: React.RefObject<ChatComponentsCache>;\n\n getFunctionCallHandler: (\n customEntryPoints?: Record<string, FrontendAction<any>>,\n ) => FunctionCallHandler;\n\n // text context\n addContext: (context: string, parentId?: string, categories?: string[]) => TreeNodeId;\n removeContext: (id: TreeNodeId) => void;\n getAllContext: () => Tree;\n getContextString: (documents: DocumentPointer[], categories: string[]) => string;\n\n // document context\n addDocumentContext: (documentPointer: DocumentPointer, categories?: string[]) => TreeNodeId;\n removeDocumentContext: (documentId: string) => void;\n getDocumentsContext: (categories: string[]) => DocumentPointer[];\n\n isLoading: boolean;\n setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;\n\n chatSuggestionConfiguration: { [key: string]: CopilotChatSuggestionConfiguration };\n addChatSuggestionConfiguration: (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => void;\n removeChatSuggestionConfiguration: (id: string) => void;\n\n chatInstructions: string;\n setChatInstructions: React.Dispatch<React.SetStateAction<string>>;\n\n additionalInstructions?: string[];\n setAdditionalInstructions: React.Dispatch<React.SetStateAction<string[]>>;\n\n // api endpoints\n copilotApiConfig: CopilotApiConfig;\n\n showDevConsole: boolean;\n\n // agents\n coagentStates: Record<string, CoagentState>;\n setCoagentStates: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;\n coagentStatesRef: React.RefObject<Record<string, CoagentState>>;\n setCoagentStatesWithRef: (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => void;\n\n agentSession: AgentSession | null;\n setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;\n\n agentLock: string | null;\n\n threadId: string;\n setThreadId: React.Dispatch<React.SetStateAction<string>>;\n\n runId: string | null;\n setRunId: React.Dispatch<React.SetStateAction<string | null>>;\n\n // The chat abort controller can be used to stop generation globally,\n // i.e. when using `stop()` from `useChat`\n chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n\n // runtime\n runtimeClient: CopilotRuntimeClient;\n\n /**\n * The forwarded parameters to use for the task.\n */\n forwardedParameters?: Partial<Pick<ForwardedParametersInput, \"temperature\">>;\n availableAgents: Agent[];\n\n /**\n * The auth states for the CopilotKit.\n */\n authStates_c?: Record<ActionName, AuthState>;\n setAuthStates_c?: React.Dispatch<React.SetStateAction<Record<ActionName, AuthState>>>;\n\n /**\n * The auth config for the CopilotKit.\n */\n authConfig_c?: {\n SignInComponent: React.ComponentType<{\n onSignInComplete: (authState: AuthState) => void;\n }>;\n };\n\n extensions: ExtensionsInput;\n setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;\n langGraphInterruptAction: LangGraphInterruptAction | null;\n setLangGraphInterruptAction: LangGraphInterruptActionSetter;\n removeLangGraphInterruptAction: () => void;\n\n /**\n * Optional trace handler for comprehensive debugging and observability.\n */\n onError?: CopilotErrorHandler;\n}\n\nconst emptyCopilotContext: CopilotContextParams = {\n actions: {},\n setAction: () => {},\n removeAction: () => {},\n\n coAgentStateRenders: {},\n setCoAgentStateRender: () => {},\n removeCoAgentStateRender: () => {},\n\n chatComponentsCache: { current: { actions: {}, coAgentStateRenders: {} } },\n getContextString: (documents: DocumentPointer[], categories: string[]) =>\n returnAndThrowInDebug(\"\"),\n addContext: () => \"\",\n removeContext: () => {},\n getAllContext: () => [],\n\n getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),\n\n isLoading: false,\n setIsLoading: () => returnAndThrowInDebug(false),\n\n chatInstructions: \"\",\n setChatInstructions: () => returnAndThrowInDebug(\"\"),\n\n additionalInstructions: [],\n setAdditionalInstructions: () => returnAndThrowInDebug([]),\n\n getDocumentsContext: (categories: string[]) => returnAndThrowInDebug([]),\n addDocumentContext: () => returnAndThrowInDebug(\"\"),\n removeDocumentContext: () => {},\n runtimeClient: {} as any,\n\n copilotApiConfig: new (class implements CopilotApiConfig {\n get chatApiEndpoint(): string {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n\n get headers(): Record<string, string> {\n return {};\n }\n get body(): Record<string, any> {\n return {};\n }\n })(),\n\n chatSuggestionConfiguration: {},\n addChatSuggestionConfiguration: () => {},\n removeChatSuggestionConfiguration: () => {},\n showDevConsole: false,\n coagentStates: {},\n setCoagentStates: () => {},\n coagentStatesRef: { current: {} },\n setCoagentStatesWithRef: () => {},\n agentSession: null,\n setAgentSession: () => {},\n forwardedParameters: {},\n agentLock: null,\n threadId: \"\",\n setThreadId: () => {},\n runId: null,\n setRunId: () => {},\n chatAbortControllerRef: { current: null },\n availableAgents: [],\n extensions: {},\n setExtensions: () => {},\n langGraphInterruptAction: null,\n setLangGraphInterruptAction: () => null,\n removeLangGraphInterruptAction: () => null,\n onError: undefined,\n};\n\nexport const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);\n\nexport function useCopilotContext(): CopilotContextParams {\n const context = React.useContext(CopilotContext);\n if (context === emptyCopilotContext) {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n return context;\n}\n\nfunction returnAndThrowInDebug<T>(_value: T): T {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n}\n","import { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport { ErrorToast } from \"../error-boundary/error-utils\";\nimport { PartialBy, CopilotKitError, CopilotKitErrorCode, Severity } from \"@copilotkit/shared\";\nimport { renderCopilotKitUsage } from \"../usage-banner\";\n\ninterface Toast {\n id: string;\n message: string | React.ReactNode;\n type: \"info\" | \"success\" | \"warning\" | \"error\";\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (toast: PartialBy<Toast, \"id\">) => void;\n addGraphQLErrorsToast: (errors: GraphQLError[]) => void;\n removeToast: (id: string) => void;\n enabled: boolean;\n // Banner management\n bannerError: CopilotKitError | null;\n setBannerError: (error: CopilotKitError | null) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\n// Helper functions for error banner styling\ntype ErrorSeverity = \"critical\" | \"warning\" | \"info\";\n\ninterface ErrorColors {\n background: string;\n border: string;\n text: string;\n icon: string;\n}\n\nfunction getErrorSeverity(error: CopilotKitError): ErrorSeverity {\n // Use structured error severity if available\n if (error.severity) {\n switch (error.severity) {\n case Severity.CRITICAL:\n return \"critical\";\n case Severity.WARNING:\n return \"warning\";\n case Severity.INFO:\n return \"info\";\n default:\n return \"info\";\n }\n }\n\n // Fallback: Check for API key errors which should always be critical\n const message = error.message.toLowerCase();\n if (\n message.includes(\"api key\") ||\n message.includes(\"401\") ||\n message.includes(\"unauthorized\") ||\n message.includes(\"authentication\") ||\n message.includes(\"incorrect api key\")\n ) {\n return \"critical\";\n }\n\n // Default to info level\n return \"info\";\n}\n\nfunction getErrorColors(severity: ErrorSeverity): ErrorColors {\n switch (severity) {\n case \"critical\":\n return {\n background: \"#fee2e2\",\n border: \"#dc2626\",\n text: \"#7f1d1d\",\n icon: \"#dc2626\",\n };\n case \"warning\":\n return {\n background: \"#fef3c7\",\n border: \"#d97706\",\n text: \"#78350f\",\n icon: \"#d97706\",\n };\n case \"info\":\n return {\n background: \"#dbeafe\",\n border: \"#2563eb\",\n text: \"#1e3a8a\",\n icon: \"#2563eb\",\n };\n }\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nexport function ToastProvider({\n enabled,\n children,\n}: {\n enabled: boolean;\n children: React.ReactNode;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [bannerError, setBannerErrorState] = useState<CopilotKitError | null>(null);\n\n const removeToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const addToast = useCallback(\n (toast: PartialBy<Toast, \"id\">) => {\n // Respect the enabled flag for ALL toasts\n if (!enabled) {\n return;\n }\n\n const id = toast.id ?? Math.random().toString(36).substring(2, 9);\n\n setToasts((currentToasts) => {\n if (currentToasts.find((toast) => toast.id === id)) return currentToasts;\n return [...currentToasts, { ...toast, id }];\n });\n\n if (toast.duration) {\n setTimeout(() => {\n removeToast(id);\n }, toast.duration);\n }\n },\n [enabled, removeToast],\n );\n\n const setBannerError = useCallback(\n (error: CopilotKitError | null) => {\n // Respect the enabled flag for ALL errors\n if (!enabled && error !== null) {\n return;\n }\n setBannerErrorState(error);\n },\n [enabled],\n );\n\n const addGraphQLErrorsToast = useCallback((errors: GraphQLError[]) => {\n // DEPRECATED: All errors now route to banners for consistency\n console.warn(\"addGraphQLErrorsToast is deprecated. All errors now show as banners.\");\n // Function kept for backward compatibility - does nothing\n }, []);\n\n const value = {\n toasts,\n addToast,\n addGraphQLErrorsToast,\n removeToast,\n enabled,\n bannerError,\n setBannerError,\n };\n\n return (\n <ToastContext.Provider value={value}>\n {/* Banner Error Display */}\n {bannerError &&\n (() => {\n const severity = getErrorSeverity(bannerError);\n const colors = getErrorColors(severity);\n\n return (\n <div\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 9999,\n backgroundColor: colors.background,\n border: `1px solid ${colors.border}`,\n borderLeft: `4px solid ${colors.border}`,\n borderRadius: \"8px\",\n padding: \"12px 16px\",\n fontSize: \"13px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n backdropFilter: \"blur(8px)\",\n maxWidth: \"min(90vw, 700px)\",\n width: \"100%\",\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n backgroundColor: colors.border,\n flexShrink: 0,\n }}\n />\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n color: colors.text,\n lineHeight: \"1.4\",\n fontWeight: \"400\",\n fontSize: \"13px\",\n flex: 1,\n wordBreak: \"break-all\",\n overflowWrap: \"break-word\",\n maxWidth: \"550px\",\n overflow: \"hidden\",\n display: \"-webkit-box\",\n WebkitLineClamp: 10,\n WebkitBoxOrient: \"vertical\",\n }}\n >\n {(() => {\n let message = bannerError.message;\n\n // Try to extract the useful message from JSON first\n const jsonMatch = message.match(/'message':\\s*'([^']+)'/);\n if (jsonMatch) {\n return jsonMatch[1]; // Return the actual error message\n }\n\n // Strip technical garbage but keep the meaningful message\n message = message.split(\" - \")[0]; // Remove everything after \" - {\"\n message = message.split(\": Error code\")[0]; // Remove \": Error code: 401\"\n message = message.replace(/:\\s*\\d{3}$/, \"\"); // Remove trailing \": 401\"\n message = message.replace(/See more:.*$/g, \"\"); // Remove \"See more\" links\n message = message.trim();\n\n // If it's still garbage (contains { or '), use fallback\n // if (message.includes(\"{\") || message.includes(\"'\")) {\n // return \"Configuration error.... Please check your setup.\";\n // }\n\n return message || \"Configuration error occurred.\";\n })()}\n </div>\n\n {(() => {\n const message = bannerError.message;\n const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const plainUrlRegex = /(https?:\\/\\/[^\\s)]+)/g;\n\n // Extract the first URL found\n let url = null;\n let buttonText = \"See More\";\n\n // Check for markdown links first\n const markdownMatch = markdownLinkRegex.exec(message);\n if (markdownMatch) {\n url = markdownMatch[2];\n buttonText = \"See More\";\n } else {\n // Check for plain URLs\n const urlMatch = plainUrlRegex.exec(message);\n if (urlMatch) {\n url = urlMatch[0].replace(/[.,;:'\"]*$/, \"\"); // Remove trailing punctuation\n buttonText = \"See More\";\n }\n }\n\n if (!url) return null;\n\n return (\n <button\n onClick={() => window.open(url, \"_blank\", \"noopener,noreferrer\")}\n style={{\n background: colors.border,\n color: \"white\",\n border: \"none\",\n borderRadius: \"5px\",\n padding: \"4px 10px\",\n fontSize: \"11px\",\n fontWeight: \"500\",\n cursor: \"pointer\",\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"0.9\";\n e.currentTarget.style.transform = \"translateY(-1px)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n {buttonText}\n </button>\n );\n })()}\n </div>\n </div>\n <button\n onClick={() => setBannerError(null)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: colors.text,\n cursor: \"pointer\",\n padding: \"2px\",\n borderRadius: \"3px\",\n fontSize: \"14px\",\n lineHeight: \"1\",\n opacity: 0.6,\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n title=\"Dismiss\"\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"0.6\";\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n ×\n </button>\n </div>\n </div>\n );\n })()}\n\n {/* Toast Display - Deprecated: All errors now show as banners */}\n {children}\n </ToastContext.Provider>\n );\n}\n\n// Toast component removed - all errors now show as banners for consistency\n"],"mappings":"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","names":["import_react","React","import_shared","import_react"]}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  useCoAgentStateRender
3
- } from "../chunk-T4ZKC4X4.mjs";
4
- import "../chunk-VRXANACV.mjs";
5
- import "../chunk-XFOTNHYA.mjs";
3
+ } from "../chunk-KIXKBJUV.mjs";
4
+ import "../chunk-YAF2LATQ.mjs";
5
+ import "../chunk-DKZTPL66.mjs";
6
6
  import "../chunk-SKC7AJIV.mjs";
7
7
  export {
8
8
  useCoAgentStateRender
@@ -1,4 +1,4 @@
1
- import { a as CopilotContextParams } from '../copilot-context-3da805ab.js';
1
+ import { a as CopilotContextParams } from '../copilot-context-3ab4fdf5.js';
2
2
  import { CopilotMessagesContextParams } from '../context/copilot-messages-context.js';
3
3
  import { Message } from '@copilotkit/runtime-client-gql';
4
4
  import '@copilotkit/shared';
@@ -161,7 +161,7 @@ var emptyCopilotContext = {
161
161
  langGraphInterruptAction: null,
162
162
  setLangGraphInterruptAction: () => null,
163
163
  removeLangGraphInterruptAction: () => null,
164
- onTrace: void 0
164
+ onError: void 0
165
165
  };
166
166
  var CopilotContext = import_react.default.createContext(emptyCopilotContext);
167
167
  function useCopilotContext() {
@@ -198,6 +198,7 @@ var import_runtime_client_gql4 = require("@copilotkit/runtime-client-gql");
198
198
 
199
199
  // src/hooks/use-chat.ts
200
200
  var import_react6 = require("react");
201
+ var import_react_dom = require("react-dom");
201
202
  var import_shared4 = require("@copilotkit/shared");
202
203
  var import_runtime_client_gql3 = require("@copilotkit/runtime-client-gql");
203
204
 
@@ -254,13 +255,13 @@ function shouldShowDevConsole(showDevConsole) {
254
255
  // src/hooks/use-copilot-runtime-client.ts
255
256
  var useCopilotRuntimeClient = (options) => {
256
257
  const { setBannerError } = useToast();
257
- const _a = options, { showDevConsole, onTrace } = _a, runtimeOptions = __objRest(_a, ["showDevConsole", "onTrace"]);
258
+ const _a = options, { showDevConsole, onError } = _a, runtimeOptions = __objRest(_a, ["showDevConsole", "onError"]);
258
259
  const lastStructuredErrorRef = (0, import_react4.useRef)(null);
259
260
  const traceUIError = (error, originalError) => __async(void 0, null, function* () {
260
- if (!onTrace || !runtimeOptions.publicApiKey)
261
+ if (!onError || !runtimeOptions.publicApiKey)
261
262
  return;
262
263
  try {
263
- const traceEvent = {
264
+ const errorEvent = {
264
265
  type: "error",
265
266
  timestamp: Date.now(),
266
267
  context: {
@@ -271,16 +272,16 @@ var useCopilotRuntimeClient = (options) => {
271
272
  startTime: Date.now()
272
273
  },
273
274
  technical: {
274
- environment: process.env.NODE_ENV,
275
+ environment: "browser",
275
276
  userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
276
277
  stackTrace: originalError instanceof Error ? originalError.stack : void 0
277
278
  }
278
279
  },
279
280
  error
280
281
  };
281
- yield onTrace(traceEvent);
282
- } catch (traceError) {
283
- console.error("Error in onTrace handler:", traceError);
282
+ yield onError(errorEvent);
283
+ } catch (error2) {
284
+ console.error("Error in onError handler:", error2);
284
285
  }
285
286
  });
286
287
  const runtimeClient = (0, import_react4.useMemo)(() => {
@@ -344,7 +345,7 @@ var useCopilotRuntimeClient = (options) => {
344
345
  setBannerError(warningError);
345
346
  }
346
347
  }));
347
- }, [runtimeOptions, setBannerError, showDevConsole, onTrace]);
348
+ }, [runtimeOptions, setBannerError, showDevConsole, onError]);
348
349
  return runtimeClient;
349
350
  };
350
351
  function createStructuredError(gqlError) {
@@ -516,6 +517,35 @@ function useChat(options) {
516
517
  } = options;
517
518
  const runChatCompletionRef = (0, import_react6.useRef)();
518
519
  const addErrorToast = useErrorToast();
520
+ const { setBannerError } = useToast();
521
+ const { onError } = useCopilotContext();
522
+ const traceUIError = (error, originalError) => __async(this, null, function* () {
523
+ if (!onError || !(copilotConfig == null ? void 0 : copilotConfig.publicApiKey))
524
+ return;
525
+ try {
526
+ const traceEvent = {
527
+ type: "error",
528
+ timestamp: Date.now(),
529
+ context: {
530
+ source: "ui",
531
+ request: {
532
+ operation: "useChatCompletion",
533
+ url: copilotConfig.chatApiEndpoint,
534
+ startTime: Date.now()
535
+ },
536
+ technical: {
537
+ environment: "browser",
538
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
539
+ stackTrace: originalError instanceof Error ? originalError.stack : void 0
540
+ }
541
+ },
542
+ error
543
+ };
544
+ yield onError(traceEvent);
545
+ } catch (traceError) {
546
+ console.error("Error in use-chat onError handler:", traceError);
547
+ }
548
+ });
519
549
  const agentSessionRef = (0, import_react6.useRef)(agentSession);
520
550
  agentSessionRef.current = agentSession;
521
551
  const runIdRef = (0, import_react6.useRef)(runId);
@@ -535,7 +565,7 @@ function useChat(options) {
535
565
  const pendingAppendsRef = (0, import_react6.useRef)([]);
536
566
  const runChatCompletion = useAsyncCallback(
537
567
  (previousMessages) => __async(this, null, function* () {
538
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
568
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
539
569
  setIsLoading(true);
540
570
  const interruptEvent = langGraphInterruptAction == null ? void 0 : langGraphInterruptAction.event;
541
571
  if ((interruptEvent == null ? void 0 : interruptEvent.name) === import_runtime_client_gql3.MetaEventName.LangGraphInterruptEvent && (interruptEvent == null ? void 0 : interruptEvent.value) && !(interruptEvent == null ? void 0 : interruptEvent.response) && agentSessionRef.current) {
@@ -667,20 +697,53 @@ function useChat(options) {
667
697
  messages2 = (0, import_runtime_client_gql3.convertGqlOutputToMessages)(
668
698
  (0, import_runtime_client_gql3.filterAdjacentAgentStateMessages)(rawMessagesResponse)
669
699
  );
670
- if (messages2.length === 0) {
671
- continue;
672
- }
673
700
  newMessages = [];
674
701
  if (((_k = value.generateCopilotResponse.status) == null ? void 0 : _k.__typename) === "FailedResponseStatus" && value.generateCopilotResponse.status.reason === "GUARDRAILS_VALIDATION_FAILED") {
702
+ const guardrailsReason = ((_l = value.generateCopilotResponse.status.details) == null ? void 0 : _l.guardrailsReason) || "";
675
703
  newMessages = [
676
704
  new import_runtime_client_gql3.TextMessage({
677
705
  role: import_runtime_client_gql3.MessageRole.Assistant,
678
- content: ((_l = value.generateCopilotResponse.status.details) == null ? void 0 : _l.guardrailsReason) || ""
706
+ content: guardrailsReason
679
707
  })
680
708
  ];
709
+ const guardrailsError = new import_shared4.CopilotKitError({
710
+ message: `Guardrails validation failed: ${guardrailsReason}`,
711
+ code: import_shared4.CopilotKitErrorCode.MISUSE
712
+ });
713
+ yield traceUIError(guardrailsError, {
714
+ statusReason: value.generateCopilotResponse.status.reason,
715
+ statusDetails: value.generateCopilotResponse.status.details
716
+ });
681
717
  setMessages([...previousMessages, ...newMessages]);
682
718
  break;
683
- } else {
719
+ }
720
+ if (((_m = value.generateCopilotResponse.status) == null ? void 0 : _m.__typename) === "FailedResponseStatus" && value.generateCopilotResponse.status.reason === "UNKNOWN_ERROR") {
721
+ const errorMessage = ((_n = value.generateCopilotResponse.status.details) == null ? void 0 : _n.description) || "An unknown error occurred";
722
+ const statusDetails = value.generateCopilotResponse.status.details;
723
+ const originalError = (statusDetails == null ? void 0 : statusDetails.originalError) || (statusDetails == null ? void 0 : statusDetails.error);
724
+ const originalCode = (originalError == null ? void 0 : originalError.code) || ((_o = originalError == null ? void 0 : originalError.extensions) == null ? void 0 : _o.code);
725
+ const originalSeverity = (originalError == null ? void 0 : originalError.severity) || ((_p = originalError == null ? void 0 : originalError.extensions) == null ? void 0 : _p.severity);
726
+ const originalVisibility = (originalError == null ? void 0 : originalError.visibility) || ((_q = originalError == null ? void 0 : originalError.extensions) == null ? void 0 : _q.visibility);
727
+ let errorCode = import_shared4.CopilotKitErrorCode.NETWORK_ERROR;
728
+ if (originalCode && Object.values(import_shared4.CopilotKitErrorCode).includes(originalCode)) {
729
+ errorCode = originalCode;
730
+ }
731
+ const structuredError = new import_shared4.CopilotKitError({
732
+ message: errorMessage,
733
+ code: errorCode,
734
+ severity: originalSeverity,
735
+ visibility: originalVisibility
736
+ });
737
+ setBannerError(structuredError);
738
+ yield traceUIError(structuredError, {
739
+ statusReason: value.generateCopilotResponse.status.reason,
740
+ statusDetails: value.generateCopilotResponse.status.details,
741
+ originalErrorCode: originalCode,
742
+ preservedStructure: !!originalCode
743
+ });
744
+ setIsLoading(false);
745
+ break;
746
+ } else if (messages2.length > 0) {
684
747
  newMessages = [...messages2];
685
748
  for (const message of messages2) {
686
749
  if (message.isAgentStateMessage() && !message.active && !executedCoAgentStateRenders.includes(message.id) && onCoAgentStateRender) {
@@ -702,17 +765,22 @@ function useChat(options) {
702
765
  lastAgentStateMessage.state.messages
703
766
  );
704
767
  }
705
- setCoagentStatesWithRef((prevAgentStates) => __spreadProps(__spreadValues({}, prevAgentStates), {
706
- [lastAgentStateMessage.agentName]: {
707
- name: lastAgentStateMessage.agentName,
708
- state: lastAgentStateMessage.state,
709
- running: lastAgentStateMessage.running,
710
- active: lastAgentStateMessage.active,
711
- threadId: lastAgentStateMessage.threadId,
712
- nodeName: lastAgentStateMessage.nodeName,
713
- runId: lastAgentStateMessage.runId
714
- }
715
- }));
768
+ setCoagentStatesWithRef((prevAgentStates) => {
769
+ var _a2;
770
+ return __spreadProps(__spreadValues({}, prevAgentStates), {
771
+ [lastAgentStateMessage.agentName]: {
772
+ name: lastAgentStateMessage.agentName,
773
+ state: lastAgentStateMessage.state,
774
+ running: lastAgentStateMessage.running,
775
+ active: lastAgentStateMessage.active,
776
+ threadId: lastAgentStateMessage.threadId,
777
+ nodeName: lastAgentStateMessage.nodeName,
778
+ runId: lastAgentStateMessage.runId,
779
+ // Preserve existing config from previous state
780
+ config: (_a2 = prevAgentStates[lastAgentStateMessage.agentName]) == null ? void 0 : _a2.config
781
+ }
782
+ });
783
+ });
716
784
  if (lastAgentStateMessage.running) {
717
785
  setAgentSession({
718
786
  threadId: lastAgentStateMessage.threadId,
@@ -742,6 +810,39 @@ function useChat(options) {
742
810
  newMessages
743
811
  );
744
812
  let didExecuteAction = false;
813
+ const executeActionFromMessage = (currentAction, actionMessage) => __async(this, null, function* () {
814
+ var _a2;
815
+ const isInterruptAction = interruptMessages.find((m) => m.id === actionMessage.id);
816
+ followUp = (_a2 = currentAction == null ? void 0 : currentAction.followUp) != null ? _a2 : !isInterruptAction;
817
+ if (currentAction == null ? void 0 : currentAction._setActivatingMessageId) {
818
+ currentAction._setActivatingMessageId(actionMessage.id);
819
+ }
820
+ const resultMessage = yield executeAction({
821
+ onFunctionCall,
822
+ message: actionMessage,
823
+ chatAbortControllerRef,
824
+ onError: (error) => {
825
+ addErrorToast([error]);
826
+ console.error(`Failed to execute action ${actionMessage.name}: ${error}`);
827
+ },
828
+ setMessages,
829
+ getFinalMessages: () => finalMessages,
830
+ isRenderAndWait: (currentAction == null ? void 0 : currentAction._isRenderAndWait) || false
831
+ });
832
+ didExecuteAction = true;
833
+ const messageIndex = finalMessages.findIndex((msg) => msg.id === actionMessage.id);
834
+ finalMessages.splice(messageIndex + 1, 0, resultMessage);
835
+ if (currentAction == null ? void 0 : currentAction._isRenderAndWait) {
836
+ const messagesForImmediateUpdate = [...finalMessages];
837
+ (0, import_react_dom.flushSync)(() => {
838
+ setMessages(messagesForImmediateUpdate);
839
+ });
840
+ }
841
+ if (currentAction == null ? void 0 : currentAction._setActivatingMessageId) {
842
+ currentAction._setActivatingMessageId(null);
843
+ }
844
+ return resultMessage;
845
+ });
745
846
  if (onFunctionCall) {
746
847
  const lastMessages = [];
747
848
  for (let i = finalMessages.length - 1; i >= 0; i--) {
@@ -758,37 +859,28 @@ function useChat(options) {
758
859
  (action2) => action2.name === message.name
759
860
  );
760
861
  const currentResultMessagePairedFeAction = message.isResultMessage() ? getPairedFeAction(actions, message) : null;
761
- const executeActionFromMessage = (action2, message2) => __async(this, null, function* () {
762
- var _a2;
763
- const isInterruptAction = interruptMessages.find((m) => m.id === message2.id);
764
- followUp = (_a2 = action2 == null ? void 0 : action2.followUp) != null ? _a2 : !isInterruptAction;
765
- const resultMessage = yield executeAction({
766
- onFunctionCall,
767
- previousMessages,
768
- message: message2,
769
- chatAbortControllerRef,
770
- onError: (error) => {
771
- addErrorToast([error]);
772
- console.error(`Failed to execute action ${message2.name}: ${error}`);
773
- }
774
- });
775
- didExecuteAction = true;
776
- const messageIndex = finalMessages.findIndex((msg) => msg.id === message2.id);
777
- finalMessages.splice(messageIndex + 1, 0, resultMessage);
778
- return resultMessage;
779
- });
780
862
  if (action && message.isActionExecutionMessage()) {
781
- const resultMessage = yield executeActionFromMessage(action, message);
782
- const pairedFeAction = getPairedFeAction(actions, resultMessage);
783
- if (pairedFeAction) {
784
- const newExecutionMessage = new import_runtime_client_gql3.ActionExecutionMessage({
785
- name: pairedFeAction.name,
786
- arguments: (0, import_shared4.parseJson)(resultMessage.result, resultMessage.result),
787
- status: message.status,
788
- createdAt: message.createdAt,
789
- parentMessageId: message.parentMessageId
790
- });
791
- yield executeActionFromMessage(pairedFeAction, newExecutionMessage);
863
+ const isRenderAndWaitAction = (action == null ? void 0 : action._isRenderAndWait) || false;
864
+ const alreadyProcessed = isRenderAndWaitAction && finalMessages.some(
865
+ (fm) => fm.isResultMessage() && fm.actionExecutionId === message.id
866
+ );
867
+ if (alreadyProcessed) {
868
+ } else {
869
+ const resultMessage = yield executeActionFromMessage(
870
+ action,
871
+ message
872
+ );
873
+ const pairedFeAction = getPairedFeAction(actions, resultMessage);
874
+ if (pairedFeAction) {
875
+ const newExecutionMessage = new import_runtime_client_gql3.ActionExecutionMessage({
876
+ name: pairedFeAction.name,
877
+ arguments: (0, import_shared4.parseJson)(resultMessage.result, resultMessage.result),
878
+ status: message.status,
879
+ createdAt: message.createdAt,
880
+ parentMessageId: message.parentMessageId
881
+ });
882
+ yield executeActionFromMessage(pairedFeAction, newExecutionMessage);
883
+ }
792
884
  }
793
885
  } else if (message.isResultMessage() && currentResultMessagePairedFeAction) {
794
886
  const newExecutionMessage = new import_runtime_client_gql3.ActionExecutionMessage({
@@ -806,16 +898,12 @@ function useChat(options) {
806
898
  }
807
899
  setMessages(finalMessages);
808
900
  }
809
- if (
810
- // if followUp is not explicitly false
811
- followUp !== false && // and we executed an action
812
- (didExecuteAction || // the last message is a server side result
813
- !isAgentRun && finalMessages.length && finalMessages[finalMessages.length - 1].isResultMessage()) && // the user did not stop generation
814
- !((_m = chatAbortControllerRef.current) == null ? void 0 : _m.signal.aborted)
815
- ) {
901
+ if (followUp !== false && (didExecuteAction || // the last message is a server side result
902
+ !isAgentRun && finalMessages.length && finalMessages[finalMessages.length - 1].isResultMessage()) && // the user did not stop generation
903
+ !((_r = chatAbortControllerRef.current) == null ? void 0 : _r.signal.aborted)) {
816
904
  yield new Promise((resolve) => setTimeout(resolve, 10));
817
905
  return yield runChatCompletionRef.current(finalMessages);
818
- } else if ((_n = chatAbortControllerRef.current) == null ? void 0 : _n.signal.aborted) {
906
+ } else if ((_s = chatAbortControllerRef.current) == null ? void 0 : _s.signal.aborted) {
819
907
  const repairedMessages = finalMessages.filter((message, actionExecutionIndex) => {
820
908
  if (message.isActionExecutionMessage()) {
821
909
  return finalMessages.find(
@@ -826,7 +914,7 @@ function useChat(options) {
826
914
  });
827
915
  const repairedMessageIds = repairedMessages.map((message) => message.id);
828
916
  setMessages(repairedMessages);
829
- if ((_o = agentSessionRef.current) == null ? void 0 : _o.nodeName) {
917
+ if ((_t = agentSessionRef.current) == null ? void 0 : _t.nodeName) {
830
918
  setAgentSession({
831
919
  threadId: agentSessionRef.current.threadId,
832
920
  agentName: agentSessionRef.current.agentName,
@@ -920,21 +1008,35 @@ function useChat(options) {
920
1008
  [isLoading, messages, setMessages, runChatCompletionAndHandleFunctionCall]
921
1009
  );
922
1010
  const reload = useAsyncCallback(
923
- (messageId) => __async(this, null, function* () {
1011
+ (reloadMessageId) => __async(this, null, function* () {
924
1012
  if (isLoading || messages.length === 0) {
925
1013
  return;
926
1014
  }
927
- const index = messages.findIndex((msg) => msg.id === messageId);
928
- if (index === -1) {
929
- console.warn(`Message with id ${messageId} not found`);
1015
+ const reloadMessageIndex = messages.findIndex((msg) => msg.id === reloadMessageId);
1016
+ if (reloadMessageIndex === -1) {
1017
+ console.warn(`Message with id ${reloadMessageId} not found`);
930
1018
  return;
931
1019
  }
932
- let newMessages = messages.slice(0, index);
933
- if (newMessages.length > 0 && newMessages[newMessages.length - 1].isAgentStateMessage()) {
934
- newMessages = newMessages.slice(0, newMessages.length - 1);
1020
+ const reloadMessageRole = messages[reloadMessageIndex].role;
1021
+ if (reloadMessageRole !== import_runtime_client_gql3.MessageRole.Assistant) {
1022
+ console.warn(`Regenerate cannot be performed on ${reloadMessageRole} role`);
1023
+ return;
935
1024
  }
936
- setMessages(newMessages);
937
- return runChatCompletionAndHandleFunctionCall(newMessages);
1025
+ let historyCutoff = [];
1026
+ if (messages.length > 2) {
1027
+ const lastUserMessageBeforeRegenerate = messages.slice(0, reloadMessageIndex).reverse().find(
1028
+ (msg) => (
1029
+ // @ts-expect-error -- message has role
1030
+ msg.role === import_runtime_client_gql3.MessageRole.User
1031
+ )
1032
+ );
1033
+ const indexOfLastUserMessageBeforeRegenerate = messages.findIndex(
1034
+ (msg) => msg.id === lastUserMessageBeforeRegenerate.id
1035
+ );
1036
+ historyCutoff = messages.slice(0, indexOfLastUserMessageBeforeRegenerate + 1);
1037
+ }
1038
+ setMessages(historyCutoff);
1039
+ return runChatCompletionAndHandleFunctionCall(historyCutoff);
938
1040
  }),
939
1041
  [isLoading, messages, setMessages, runChatCompletionAndHandleFunctionCall]
940
1042
  );
@@ -969,20 +1071,31 @@ function constructFinalMessages(syncedMessages, previousMessages, newMessages) {
969
1071
  function executeAction(_0) {
970
1072
  return __async(this, arguments, function* ({
971
1073
  onFunctionCall,
972
- previousMessages,
973
1074
  message,
974
1075
  chatAbortControllerRef,
975
- onError
1076
+ onError,
1077
+ setMessages,
1078
+ getFinalMessages,
1079
+ isRenderAndWait
976
1080
  }) {
977
1081
  let result;
978
1082
  let error = null;
1083
+ const currentMessagesForHandler = getFinalMessages();
1084
+ const handlerReturnedPromise = onFunctionCall({
1085
+ messages: currentMessagesForHandler,
1086
+ name: message.name,
1087
+ args: message.arguments
1088
+ });
1089
+ if (isRenderAndWait) {
1090
+ const currentMessagesForRender = getFinalMessages();
1091
+ (0, import_react_dom.flushSync)(() => {
1092
+ setMessages([...currentMessagesForRender]);
1093
+ });
1094
+ }
979
1095
  try {
980
1096
  result = yield Promise.race([
981
- onFunctionCall({
982
- messages: previousMessages,
983
- name: message.name,
984
- args: message.arguments
985
- }),
1097
+ handlerReturnedPromise,
1098
+ // Await the promise returned by the handler
986
1099
  new Promise(
987
1100
  (resolve) => {
988
1101
  var _a;
@@ -1030,7 +1143,7 @@ function getPairedFeAction(actions, message) {
1030
1143
 
1031
1144
  // src/components/copilot-provider/copilotkit.tsx
1032
1145
  var import_react7 = require("react");
1033
- var import_react_dom = require("react-dom");
1146
+ var import_react_dom2 = require("react-dom");
1034
1147
  var import_shared5 = require("@copilotkit/shared");
1035
1148
  var import_jsx_runtime4 = require("react/jsx-runtime");
1036
1149
  var defaultCopilotContextCategories = ["global"];
@@ -1302,6 +1415,9 @@ function useCoAgent(options) {
1302
1415
  threadId,
1303
1416
  agentName: name
1304
1417
  });
1418
+ if (result.error) {
1419
+ return;
1420
+ }
1305
1421
  const newState = (_b = (_a = result.data) == null ? void 0 : _a.loadAgentState) == null ? void 0 : _b.state;
1306
1422
  if (newState === lastLoadedState.current)
1307
1423
  return;
@@ -1325,6 +1441,32 @@ function useCoAgent(options) {
1325
1441
  // reset initialstate on reset
1326
1442
  coagentStates[name] === void 0
1327
1443
  ]);
1444
+ (0, import_react9.useEffect)(() => {
1445
+ const newConfig = options.config ? options.config : options.configurable ? { configurable: options.configurable } : void 0;
1446
+ if (newConfig === void 0)
1447
+ return;
1448
+ setCoagentStatesWithRef((prev) => {
1449
+ var _a;
1450
+ const existing = (_a = prev[name]) != null ? _a : {
1451
+ name,
1452
+ state: isInternalStateManagementWithInitial(options) ? options.initialState : {},
1453
+ config: {},
1454
+ running: false,
1455
+ active: false,
1456
+ threadId: void 0,
1457
+ nodeName: void 0,
1458
+ runId: void 0
1459
+ };
1460
+ if (JSON.stringify(existing.config) === JSON.stringify(newConfig)) {
1461
+ return prev;
1462
+ }
1463
+ return __spreadProps(__spreadValues({}, prev), {
1464
+ [name]: __spreadProps(__spreadValues({}, existing), {
1465
+ config: newConfig
1466
+ })
1467
+ });
1468
+ });
1469
+ }, [JSON.stringify(options.config), JSON.stringify(options.configurable)]);
1328
1470
  const runAgentCallback = useAsyncCallback(
1329
1471
  (hint) => __async(this, null, function* () {
1330
1472
  yield runAgent(name, context, appendMessage, runChatCompletion, hint);