@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.
- package/CHANGELOG.md +193 -0
- package/dist/{chunk-ERXWDCY6.mjs → chunk-36MGCCPZ.mjs} +2 -2
- package/dist/{chunk-CCESTGAM.mjs → chunk-3OQM3NEK.mjs} +2 -2
- package/dist/{chunk-7G6RR4HE.mjs → chunk-3Q4F7RF2.mjs} +2 -2
- package/dist/chunk-57K2ZJ5F.mjs +348 -0
- package/dist/chunk-57K2ZJ5F.mjs.map +1 -0
- package/dist/{chunk-UBNRUXEK.mjs → chunk-5BSUSFHM.mjs} +2 -2
- package/dist/{chunk-RN3ZRHI7.mjs → chunk-AD7DWJNW.mjs} +66 -25
- package/dist/chunk-AD7DWJNW.mjs.map +1 -0
- package/dist/{chunk-JPMIAGI6.mjs → chunk-BVK7PLK6.mjs} +2 -2
- package/dist/{chunk-VJCHRQ7Q.mjs → chunk-DGON3GZX.mjs} +39 -6
- package/dist/chunk-DGON3GZX.mjs.map +1 -0
- package/dist/{chunk-XFOTNHYA.mjs → chunk-DKZTPL66.mjs} +2 -2
- package/dist/{chunk-XFOTNHYA.mjs.map → chunk-DKZTPL66.mjs.map} +1 -1
- package/dist/{chunk-S4BOATBG.mjs → chunk-FN3UA2ZE.mjs} +3 -3
- package/dist/{chunk-ISYBUDL4.mjs → chunk-JWAXDYOW.mjs} +11 -12
- package/dist/chunk-JWAXDYOW.mjs.map +1 -0
- package/dist/{chunk-T4ZKC4X4.mjs → chunk-KIXKBJUV.mjs} +3 -3
- package/dist/{chunk-I4JPQECN.mjs → chunk-LFAZTKBK.mjs} +5 -5
- package/dist/{chunk-JHIZ5HAI.mjs → chunk-NJA5ZLAZ.mjs} +29 -10
- package/dist/chunk-NJA5ZLAZ.mjs.map +1 -0
- package/dist/{chunk-ZHEEHGLS.mjs → chunk-QGT4JO7R.mjs} +35 -6
- package/dist/chunk-QGT4JO7R.mjs.map +1 -0
- package/dist/{chunk-JXF732XG.mjs → chunk-S5QUEHJC.mjs} +195 -77
- package/dist/chunk-S5QUEHJC.mjs.map +1 -0
- package/dist/{chunk-QQZLIEXK.mjs → chunk-SJJNFYGQ.mjs} +3 -3
- package/dist/{chunk-CMQV4XNY.mjs → chunk-VDADWRS3.mjs} +2 -2
- package/dist/chunk-YAF2LATQ.mjs +310 -0
- package/dist/chunk-YAF2LATQ.mjs.map +1 -0
- package/dist/{chunk-VF6UPRKM.mjs → chunk-ZGMZ5WJI.mjs} +4 -4
- package/dist/components/copilot-provider/copilot-messages.js +37 -4
- package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
- package/dist/components/copilot-provider/copilot-messages.mjs +3 -3
- package/dist/components/copilot-provider/copilotkit-props.d.ts +14 -9
- package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
- package/dist/components/copilot-provider/copilotkit.js +354 -258
- package/dist/components/copilot-provider/copilotkit.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.mjs +10 -10
- package/dist/components/copilot-provider/index.d.ts +1 -1
- package/dist/components/copilot-provider/index.js +354 -258
- package/dist/components/copilot-provider/index.js.map +1 -1
- package/dist/components/copilot-provider/index.mjs +10 -10
- package/dist/components/error-boundary/error-boundary.js +135 -146
- package/dist/components/error-boundary/error-boundary.js.map +1 -1
- package/dist/components/error-boundary/error-boundary.mjs +4 -4
- package/dist/components/error-boundary/error-utils.js.map +1 -1
- package/dist/components/error-boundary/error-utils.mjs +2 -2
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +354 -258
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +10 -10
- package/dist/components/toast/toast-provider.js +118 -85
- package/dist/components/toast/toast-provider.js.map +1 -1
- package/dist/components/toast/toast-provider.mjs +1 -1
- package/dist/components/usage-banner.js +135 -146
- package/dist/components/usage-banner.js.map +1 -1
- package/dist/components/usage-banner.mjs +1 -1
- package/dist/context/copilot-context.d.ts +1 -1
- package/dist/context/copilot-context.js +1 -1
- package/dist/context/copilot-context.js.map +1 -1
- package/dist/context/copilot-context.mjs +1 -1
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/context/index.mjs +1 -1
- package/dist/{copilot-context-3da805ab.d.ts → copilot-context-3ab4fdf5.d.ts} +3 -3
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +249 -88
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +32 -32
- package/dist/hooks/use-chat.d.ts +1 -1
- package/dist/hooks/use-chat.js +287 -174
- package/dist/hooks/use-chat.js.map +1 -1
- package/dist/hooks/use-chat.mjs +5 -5
- package/dist/hooks/use-coagent-state-render.js +1 -1
- package/dist/hooks/use-coagent-state-render.js.map +1 -1
- package/dist/hooks/use-coagent-state-render.mjs +3 -3
- package/dist/hooks/use-coagent.d.ts +1 -1
- package/dist/hooks/use-coagent.js +224 -82
- package/dist/hooks/use-coagent.js.map +1 -1
- package/dist/hooks/use-coagent.mjs +14 -14
- package/dist/hooks/use-copilot-action.js +26 -7
- package/dist/hooks/use-copilot-action.js.map +1 -1
- package/dist/hooks/use-copilot-action.mjs +4 -4
- package/dist/hooks/use-copilot-additional-instructions.js +1 -1
- package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
- package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
- package/dist/hooks/use-copilot-authenticated-action.js +26 -7
- package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
- package/dist/hooks/use-copilot-authenticated-action.mjs +5 -5
- package/dist/hooks/use-copilot-chat.d.ts +1 -1
- package/dist/hooks/use-copilot-chat.js +195 -82
- package/dist/hooks/use-copilot-chat.js.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +13 -13
- package/dist/hooks/use-copilot-readable.js +1 -1
- package/dist/hooks/use-copilot-readable.js.map +1 -1
- package/dist/hooks/use-copilot-readable.mjs +2 -2
- package/dist/hooks/use-copilot-runtime-client.d.ts +2 -2
- package/dist/hooks/use-copilot-runtime-client.js +8 -8
- package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
- package/dist/hooks/use-copilot-runtime-client.mjs +2 -2
- package/dist/hooks/use-langgraph-interrupt-render.js +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.mjs +2 -2
- package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
- package/dist/hooks/use-langgraph-interrupt.js +195 -82
- package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
- package/dist/hooks/use-langgraph-interrupt.mjs +14 -14
- package/dist/hooks/use-make-copilot-document-readable.js +1 -1
- package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
- package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +593 -336
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +33 -33
- package/dist/lib/copilot-task.d.ts +1 -1
- package/dist/lib/copilot-task.js.map +1 -1
- package/dist/lib/copilot-task.mjs +11 -11
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +11 -11
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.js +26 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/setupTests.mjs +24 -0
- package/dist/setupTests.mjs.map +1 -0
- package/dist/types/interrupt-action.d.ts +1 -1
- package/dist/utils/extract.d.ts +1 -1
- package/dist/utils/extract.js.map +1 -1
- package/dist/utils/extract.mjs +10 -10
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +10 -10
- package/jest.config.js +4 -0
- package/package.json +6 -3
- package/src/components/copilot-provider/__tests__/{copilotkit-trace.test.tsx → copilotkit-error.test.tsx} +17 -17
- package/src/components/copilot-provider/copilot-messages.tsx +43 -4
- package/src/components/copilot-provider/copilotkit-props.tsx +13 -8
- package/src/components/copilot-provider/copilotkit.tsx +61 -19
- package/src/components/toast/toast-provider.tsx +49 -24
- package/src/components/usage-banner.tsx +144 -147
- package/src/context/copilot-context.tsx +4 -4
- package/src/hooks/__tests__/use-coagent-config.test.ts +284 -0
- package/src/hooks/use-chat.ts +249 -61
- package/src/hooks/use-coagent.ts +41 -0
- package/src/hooks/use-copilot-action.ts +51 -9
- package/src/hooks/use-copilot-runtime-client.ts +12 -50
- package/src/setupTests.ts +26 -0
- package/tsconfig.json +5 -2
- package/dist/chunk-HD2GE3DK.mjs +0 -359
- package/dist/chunk-HD2GE3DK.mjs.map +0 -1
- package/dist/chunk-ISYBUDL4.mjs.map +0 -1
- package/dist/chunk-JHIZ5HAI.mjs.map +0 -1
- package/dist/chunk-JXF732XG.mjs.map +0 -1
- package/dist/chunk-RN3ZRHI7.mjs.map +0 -1
- package/dist/chunk-VJCHRQ7Q.mjs.map +0 -1
- package/dist/chunk-VRXANACV.mjs +0 -277
- package/dist/chunk-VRXANACV.mjs.map +0 -1
- package/dist/chunk-ZHEEHGLS.mjs.map +0 -1
- /package/dist/{chunk-ERXWDCY6.mjs.map → chunk-36MGCCPZ.mjs.map} +0 -0
- /package/dist/{chunk-CCESTGAM.mjs.map → chunk-3OQM3NEK.mjs.map} +0 -0
- /package/dist/{chunk-7G6RR4HE.mjs.map → chunk-3Q4F7RF2.mjs.map} +0 -0
- /package/dist/{chunk-UBNRUXEK.mjs.map → chunk-5BSUSFHM.mjs.map} +0 -0
- /package/dist/{chunk-JPMIAGI6.mjs.map → chunk-BVK7PLK6.mjs.map} +0 -0
- /package/dist/{chunk-S4BOATBG.mjs.map → chunk-FN3UA2ZE.mjs.map} +0 -0
- /package/dist/{chunk-T4ZKC4X4.mjs.map → chunk-KIXKBJUV.mjs.map} +0 -0
- /package/dist/{chunk-I4JPQECN.mjs.map → chunk-LFAZTKBK.mjs.map} +0 -0
- /package/dist/{chunk-QQZLIEXK.mjs.map → chunk-SJJNFYGQ.mjs.map} +0 -0
- /package/dist/{chunk-CMQV4XNY.mjs.map → chunk-VDADWRS3.mjs.map} +0 -0
- /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-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
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-
|
|
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
|
-
|
|
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,
|
|
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 (!
|
|
261
|
+
if (!onError || !runtimeOptions.publicApiKey)
|
|
261
262
|
return;
|
|
262
263
|
try {
|
|
263
|
-
const
|
|
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:
|
|
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
|
|
282
|
-
} catch (
|
|
283
|
-
console.error("Error in
|
|
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,
|
|
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:
|
|
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
|
-
}
|
|
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) =>
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
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
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
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
|
-
|
|
811
|
-
|
|
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 ((
|
|
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 ((
|
|
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
|
-
(
|
|
1011
|
+
(reloadMessageId) => __async(this, null, function* () {
|
|
924
1012
|
if (isLoading || messages.length === 0) {
|
|
925
1013
|
return;
|
|
926
1014
|
}
|
|
927
|
-
const
|
|
928
|
-
if (
|
|
929
|
-
console.warn(`Message with id ${
|
|
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
|
-
|
|
933
|
-
if (
|
|
934
|
-
|
|
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
|
-
|
|
937
|
-
|
|
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
|
-
|
|
982
|
-
|
|
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
|
|
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);
|