@copilotkit/react-core 1.5.12-next.5 → 1.5.12-next.7

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 (120) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{chunk-KOSLAM4Z.mjs → chunk-6BQUI465.mjs} +27 -6
  3. package/dist/chunk-6BQUI465.mjs.map +1 -0
  4. package/dist/{chunk-22XKTBPF.mjs → chunk-CBWNO2FP.mjs} +3 -3
  5. package/dist/{chunk-6BQVZFNO.mjs → chunk-CQWEXISS.mjs} +2 -2
  6. package/dist/{chunk-EWKJMQOF.mjs → chunk-EXX267DG.mjs} +3 -3
  7. package/dist/{chunk-LNI2Z45S.mjs → chunk-HZCROITJ.mjs} +5 -3
  8. package/dist/chunk-HZCROITJ.mjs.map +1 -0
  9. package/dist/chunk-IFBUUIU7.mjs +53 -0
  10. package/dist/chunk-IFBUUIU7.mjs.map +1 -0
  11. package/dist/{chunk-HIUT2NLX.mjs → chunk-J6UBNKIR.mjs} +2 -2
  12. package/dist/{chunk-6DQD4B23.mjs → chunk-KGCYVAIN.mjs} +16 -10
  13. package/dist/chunk-KGCYVAIN.mjs.map +1 -0
  14. package/dist/{chunk-LHKIIAUQ.mjs → chunk-MF4F77OY.mjs} +3 -3
  15. package/dist/{chunk-LZWH4OG5.mjs → chunk-MYCYEMIM.mjs} +31 -13
  16. package/dist/chunk-MYCYEMIM.mjs.map +1 -0
  17. package/dist/{chunk-FQ53HQYZ.mjs → chunk-N37EFAUX.mjs} +2 -2
  18. package/dist/{chunk-M2NT7NOO.mjs → chunk-VEGDEDID.mjs} +2 -2
  19. package/dist/{chunk-VNTDIJSG.mjs → chunk-X47CUJJT.mjs} +2 -2
  20. package/dist/{chunk-RD5XFSI4.mjs → chunk-X62FIPVR.mjs} +11 -8
  21. package/dist/chunk-X62FIPVR.mjs.map +1 -0
  22. package/dist/{chunk-WXREY7UP.mjs → chunk-YVQNSJ4Z.mjs} +6 -3
  23. package/dist/chunk-YVQNSJ4Z.mjs.map +1 -0
  24. package/dist/components/copilot-provider/copilot-messages.js +125 -2
  25. package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
  26. package/dist/components/copilot-provider/copilot-messages.mjs +2 -1
  27. package/dist/components/copilot-provider/copilotkit-props.d.ts +4 -0
  28. package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
  29. package/dist/components/copilot-provider/copilotkit.js +58 -9
  30. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  31. package/dist/components/copilot-provider/copilotkit.mjs +7 -7
  32. package/dist/components/copilot-provider/index.js +58 -9
  33. package/dist/components/copilot-provider/index.js.map +1 -1
  34. package/dist/components/copilot-provider/index.mjs +7 -7
  35. package/dist/components/error-boundary/error-boundary.js +4 -2
  36. package/dist/components/error-boundary/error-boundary.js.map +1 -1
  37. package/dist/components/error-boundary/error-boundary.mjs +2 -2
  38. package/dist/components/error-boundary/error-utils.js +14 -2
  39. package/dist/components/error-boundary/error-utils.js.map +1 -1
  40. package/dist/components/error-boundary/error-utils.mjs +1 -1
  41. package/dist/components/index.js +58 -9
  42. package/dist/components/index.js.map +1 -1
  43. package/dist/components/index.mjs +7 -7
  44. package/dist/components/toast/toast-provider.js +14 -2
  45. package/dist/components/toast/toast-provider.js.map +1 -1
  46. package/dist/components/toast/toast-provider.mjs +1 -1
  47. package/dist/context/copilot-context.d.ts +5 -3
  48. package/dist/context/copilot-context.js +5 -2
  49. package/dist/context/copilot-context.js.map +1 -1
  50. package/dist/context/copilot-context.mjs +1 -1
  51. package/dist/context/index.js +5 -2
  52. package/dist/context/index.js.map +1 -1
  53. package/dist/context/index.mjs +1 -1
  54. package/dist/hooks/index.js +46 -15
  55. package/dist/hooks/index.js.map +1 -1
  56. package/dist/hooks/index.mjs +25 -25
  57. package/dist/hooks/use-chat.d.ts +11 -3
  58. package/dist/hooks/use-chat.js +25 -8
  59. package/dist/hooks/use-chat.js.map +1 -1
  60. package/dist/hooks/use-chat.mjs +3 -3
  61. package/dist/hooks/use-coagent-state-render.js +5 -2
  62. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  63. package/dist/hooks/use-coagent-state-render.mjs +3 -3
  64. package/dist/hooks/use-coagent.js +46 -15
  65. package/dist/hooks/use-coagent.js.map +1 -1
  66. package/dist/hooks/use-coagent.mjs +11 -11
  67. package/dist/hooks/use-copilot-action.js +9 -4
  68. package/dist/hooks/use-copilot-action.js.map +1 -1
  69. package/dist/hooks/use-copilot-action.mjs +3 -3
  70. package/dist/hooks/use-copilot-authenticated-action.js +9 -4
  71. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  72. package/dist/hooks/use-copilot-authenticated-action.mjs +4 -4
  73. package/dist/hooks/use-copilot-chat.js +26 -13
  74. package/dist/hooks/use-copilot-chat.js.map +1 -1
  75. package/dist/hooks/use-copilot-chat.mjs +10 -10
  76. package/dist/hooks/use-copilot-readable.js +5 -2
  77. package/dist/hooks/use-copilot-readable.js.map +1 -1
  78. package/dist/hooks/use-copilot-readable.mjs +2 -2
  79. package/dist/hooks/use-copilot-runtime-client.js +14 -2
  80. package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
  81. package/dist/hooks/use-copilot-runtime-client.mjs +2 -2
  82. package/dist/hooks/use-make-copilot-document-readable.js +5 -2
  83. package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
  84. package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
  85. package/dist/index.js +126 -58
  86. package/dist/index.js.map +1 -1
  87. package/dist/index.mjs +26 -26
  88. package/dist/lib/copilot-task.js.map +1 -1
  89. package/dist/lib/copilot-task.mjs +8 -8
  90. package/dist/lib/index.js.map +1 -1
  91. package/dist/lib/index.mjs +8 -8
  92. package/dist/utils/extract.js.map +1 -1
  93. package/dist/utils/extract.mjs +7 -7
  94. package/dist/utils/index.js.map +1 -1
  95. package/dist/utils/index.mjs +7 -7
  96. package/package.json +5 -4
  97. package/src/components/copilot-provider/copilot-messages.tsx +24 -2
  98. package/src/components/copilot-provider/copilotkit-props.tsx +5 -0
  99. package/src/components/copilot-provider/copilotkit.tsx +30 -4
  100. package/src/components/error-boundary/error-utils.tsx +11 -6
  101. package/src/context/copilot-context.tsx +13 -4
  102. package/src/hooks/use-chat.ts +27 -7
  103. package/src/hooks/use-coagent.ts +30 -4
  104. package/src/hooks/use-copilot-chat.ts +5 -2
  105. package/dist/chunk-6DQD4B23.mjs.map +0 -1
  106. package/dist/chunk-KOSLAM4Z.mjs.map +0 -1
  107. package/dist/chunk-LNI2Z45S.mjs.map +0 -1
  108. package/dist/chunk-LZWH4OG5.mjs.map +0 -1
  109. package/dist/chunk-RD5XFSI4.mjs.map +0 -1
  110. package/dist/chunk-WXREY7UP.mjs.map +0 -1
  111. package/dist/chunk-XXR4QFAQ.mjs +0 -29
  112. package/dist/chunk-XXR4QFAQ.mjs.map +0 -1
  113. /package/dist/{chunk-22XKTBPF.mjs.map → chunk-CBWNO2FP.mjs.map} +0 -0
  114. /package/dist/{chunk-6BQVZFNO.mjs.map → chunk-CQWEXISS.mjs.map} +0 -0
  115. /package/dist/{chunk-EWKJMQOF.mjs.map → chunk-EXX267DG.mjs.map} +0 -0
  116. /package/dist/{chunk-HIUT2NLX.mjs.map → chunk-J6UBNKIR.mjs.map} +0 -0
  117. /package/dist/{chunk-LHKIIAUQ.mjs.map → chunk-MF4F77OY.mjs.map} +0 -0
  118. /package/dist/{chunk-FQ53HQYZ.mjs.map → chunk-N37EFAUX.mjs.map} +0 -0
  119. /package/dist/{chunk-M2NT7NOO.mjs.map → chunk-VEGDEDID.mjs.map} +0 -0
  120. /package/dist/{chunk-VNTDIJSG.mjs.map → chunk-X47CUJJT.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/index.ts","../../src/utils/extract.ts","../../src/components/copilot-provider/copilotkit.tsx","../../src/utils/dev-console.ts"],"sourcesContent":["export { extract } from \"./extract\";\nexport * from \"./dev-console\";\n","import {\n Action,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n MappedParameterTypes,\n Parameter,\n actionParametersToJsonSchema,\n} from \"@copilotkit/shared\";\nimport {\n ActionExecutionMessage,\n Message,\n Role,\n TextMessage,\n convertGqlOutputToMessages,\n CopilotRequestType,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { CopilotContextParams, CopilotMessagesContextParams } from \"../context\";\nimport { defaultCopilotContextCategories } from \"../components\";\nimport { CopilotRuntimeClient } from \"@copilotkit/runtime-client-gql\";\nimport {\n convertMessagesToGqlInput,\n filterAgentStateMessages,\n} from \"@copilotkit/runtime-client-gql\";\n\ninterface InitialState<T extends Parameter[] | [] = []> {\n status: \"initial\";\n args: Partial<MappedParameterTypes<T>>;\n}\n\ninterface InProgressState<T extends Parameter[] | [] = []> {\n status: \"inProgress\";\n args: Partial<MappedParameterTypes<T>>;\n}\n\ninterface CompleteState<T extends Parameter[] | [] = []> {\n status: \"complete\";\n args: MappedParameterTypes<T>;\n}\n\ntype StreamHandlerArgs<T extends Parameter[] | [] = []> =\n | InitialState<T>\n | InProgressState<T>\n | CompleteState<T>;\n\ninterface ExtractOptions<T extends Parameter[]> {\n context: CopilotContextParams & CopilotMessagesContextParams;\n instructions: string;\n parameters: T;\n include?: IncludeOptions;\n data?: any;\n abortSignal?: AbortSignal;\n stream?: (args: StreamHandlerArgs<T>) => void;\n requestType?: CopilotRequestType;\n forwardedParameters?: ForwardedParametersInput;\n}\n\ninterface IncludeOptions {\n readable?: boolean;\n messages?: boolean;\n}\n\nexport async function extract<const T extends Parameter[]>({\n context,\n instructions,\n parameters,\n include,\n data,\n abortSignal,\n stream,\n requestType = CopilotRequestType.Task,\n forwardedParameters,\n}: ExtractOptions<T>): Promise<MappedParameterTypes<T>> {\n const { messages } = context;\n\n const action: Action<any> = {\n name: \"extract\",\n description: instructions,\n parameters,\n handler: (args: any) => {},\n };\n\n const includeReadable = include?.readable ?? false;\n const includeMessages = include?.messages ?? false;\n\n let contextString = \"\";\n\n if (data) {\n contextString = (typeof data === \"string\" ? data : JSON.stringify(data)) + \"\\n\\n\";\n }\n\n if (includeReadable) {\n contextString += context.getContextString([], defaultCopilotContextCategories);\n }\n\n const systemMessage: Message = new TextMessage({\n content: makeSystemMessage(contextString, instructions),\n role: Role.System,\n });\n\n const instructionsMessage: Message = new TextMessage({\n content: makeInstructionsMessage(instructions),\n role: Role.User,\n });\n\n const response = context.runtimeClient.asStream(\n context.runtimeClient.generateCopilotResponse({\n data: {\n frontend: {\n actions: [\n {\n name: action.name,\n description: action.description || \"\",\n jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters || [])),\n },\n ],\n url: window.location.href,\n },\n\n messages: convertMessagesToGqlInput(\n includeMessages\n ? [systemMessage, instructionsMessage, ...filterAgentStateMessages(messages)]\n : [systemMessage, instructionsMessage],\n ),\n metadata: {\n requestType: requestType,\n },\n forwardedParameters: {\n ...(forwardedParameters ?? {}),\n toolChoice: \"function\",\n toolChoiceFunctionName: action.name,\n },\n },\n properties: context.copilotApiConfig.properties,\n signal: abortSignal,\n }),\n );\n\n const reader = response.getReader();\n\n let isInitial = true;\n\n let actionExecutionMessage: ActionExecutionMessage | undefined = undefined;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n if (abortSignal?.aborted) {\n throw new Error(\"Aborted\");\n }\n\n actionExecutionMessage = convertGqlOutputToMessages(\n value.generateCopilotResponse.messages,\n ).find((msg) => msg.isActionExecutionMessage()) as ActionExecutionMessage | undefined;\n\n if (!actionExecutionMessage) {\n continue;\n }\n\n stream?.({\n status: isInitial ? \"initial\" : \"inProgress\",\n args: actionExecutionMessage.arguments as Partial<MappedParameterTypes<T>>,\n });\n\n isInitial = false;\n }\n\n if (!actionExecutionMessage) {\n throw new Error(\"extract() failed: No function call occurred\");\n }\n\n stream?.({\n status: \"complete\",\n args: actionExecutionMessage.arguments as MappedParameterTypes<T>,\n });\n\n return actionExecutionMessage.arguments as MappedParameterTypes<T>;\n}\n\n// We need to put this in a user message since some LLMs need\n// at least one user message to function\nfunction makeInstructionsMessage(instructions: string): string {\n return `\nThe user has given you the following task to complete:\n\n\\`\\`\\`\n${instructions}\n\\`\\`\\`\n\nAny additional messages provided are for providing context only and should not be used to ask questions or engage in conversation.\n`;\n}\n\nfunction makeSystemMessage(contextString: string, instructions: string): string {\n return `\nPlease act as an efficient, competent, conscientious, and industrious professional assistant.\n\nHelp the user achieve their goals, and you do so in a way that is as efficient as possible, without unnecessary fluff, but also without sacrificing professionalism.\nAlways be polite and respectful, and prefer brevity over verbosity.\n\nThe user has provided you with the following context:\n\\`\\`\\`\n${contextString}\n\\`\\`\\`\n\nThey have also provided you with a function called extract you MUST call to initiate actions on their behalf.\n\nPlease assist them as best you can.\n\nThis is not a conversation, so please do not ask questions. Just call the function without saying anything else.\n`;\n}\n","/**\n * This component will typically wrap your entire application (or a sub-tree of your application where you want to have a copilot). It provides the copilot context to all other components and hooks.\n *\n * ## Example\n *\n * You can find more information about self-hosting CopilotKit [here](/guides/self-hosting).\n *\n * ```tsx\n * import { CopilotKit } from \"@copilotkit/react-core\";\n *\n * <CopilotKit runtimeUrl=\"<your-runtime-url>\">\n * // ... your app ...\n * </CopilotKit>\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n CopilotContext,\n CopilotApiConfig,\n ChatComponentsCache,\n AgentSession,\n AuthState,\n} from \"../../context/copilot-context\";\nimport useTree from \"../../hooks/use-tree\";\nimport { CopilotChatSuggestionConfiguration, DocumentPointer } from \"../../types\";\nimport { flushSync } from \"react-dom\";\nimport {\n COPILOT_CLOUD_CHAT_URL,\n CopilotCloudConfig,\n FunctionCallHandler,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n} from \"@copilotkit/shared\";\n\nimport { FrontendAction } from \"../../types/frontend-action\";\nimport useFlatCategoryStore from \"../../hooks/use-flat-category-store\";\nimport { CopilotKitProps } from \"./copilotkit-props\";\nimport { CoAgentStateRender } from \"../../types/coagent-action\";\nimport { CoagentState } from \"../../types/coagent-state\";\nimport { CopilotMessages } from \"./copilot-messages\";\nimport { ToastProvider } from \"../toast/toast-provider\";\nimport { useCopilotRuntimeClient } from \"../../hooks/use-copilot-runtime-client\";\nimport { shouldShowDevConsole } from \"../../utils\";\nimport { CopilotErrorBoundary } from \"../error-boundary/error-boundary\";\nimport { Agent } from \"@copilotkit/runtime-client-gql\";\n\nexport function CopilotKit({ children, ...props }: CopilotKitProps) {\n const showDevConsole = props.showDevConsole === undefined ? \"auto\" : props.showDevConsole;\n const enabled = shouldShowDevConsole(showDevConsole);\n return (\n <ToastProvider enabled={enabled}>\n <CopilotErrorBoundary>\n <CopilotKitInternal {...props}>{children}</CopilotKitInternal>\n </CopilotErrorBoundary>\n </ToastProvider>\n );\n}\n\nexport function CopilotKitInternal({ children, ...props }: CopilotKitProps) {\n // Compute all the functions and properties that we need to pass\n // to the CopilotContext.\n\n if (!props.runtimeUrl && !props.publicApiKey) {\n throw new Error(\n \"Please provide either a runtimeUrl or a publicApiKey to the CopilotKit component.\",\n );\n }\n\n const chatApiEndpoint = props.runtimeUrl || COPILOT_CLOUD_CHAT_URL;\n\n const [actions, setActions] = useState<Record<string, FrontendAction<any>>>({});\n const [coAgentStateRenders, setCoAgentStateRenders] = useState<\n Record<string, CoAgentStateRender<any>>\n >({});\n const chatComponentsCache = useRef<ChatComponentsCache>({\n actions: {},\n coAgentStateRenders: {},\n });\n const { addElement, removeElement, printTree } = useTree();\n const [isLoading, setIsLoading] = useState(false);\n const [chatInstructions, setChatInstructions] = useState(\"\");\n const [authStates, setAuthStates] = useState<Record<string, AuthState>>({});\n\n const {\n addElement: addDocument,\n removeElement: removeDocument,\n allElements: allDocuments,\n } = useFlatCategoryStore<DocumentPointer>();\n\n const setAction = useCallback((id: string, action: FrontendAction<any>) => {\n setActions((prevPoints) => {\n return {\n ...prevPoints,\n [id]: action,\n };\n });\n }, []);\n\n const removeAction = useCallback((id: string) => {\n setActions((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const setCoAgentStateRender = useCallback((id: string, stateRender: CoAgentStateRender<any>) => {\n setCoAgentStateRenders((prevPoints) => {\n return {\n ...prevPoints,\n [id]: stateRender,\n };\n });\n }, []);\n\n const removeCoAgentStateRender = useCallback((id: string) => {\n setCoAgentStateRenders((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const getContextString = useCallback(\n (documents: DocumentPointer[], categories: string[]) => {\n const documentsString = documents\n .map((document) => {\n return `${document.name} (${document.sourceApplication}):\\n${document.getContents()}`;\n })\n .join(\"\\n\\n\");\n\n const nonDocumentStrings = printTree(categories);\n\n return `${documentsString}\\n\\n${nonDocumentStrings}`;\n },\n [printTree],\n );\n\n const addContext = useCallback(\n (\n context: string,\n parentId?: string,\n categories: string[] = defaultCopilotContextCategories,\n ) => {\n return addElement(context, categories, parentId);\n },\n [addElement],\n );\n\n const removeContext = useCallback(\n (id: string) => {\n removeElement(id);\n },\n [removeElement],\n );\n\n const getFunctionCallHandler = useCallback(\n (customEntryPoints?: Record<string, FrontendAction<any>>) => {\n return entryPointsToFunctionCallHandler(Object.values(customEntryPoints || actions));\n },\n [actions],\n );\n\n const getDocumentsContext = useCallback(\n (categories: string[]) => {\n return allDocuments(categories);\n },\n [allDocuments],\n );\n\n const addDocumentContext = useCallback(\n (documentPointer: DocumentPointer, categories: string[] = defaultCopilotContextCategories) => {\n return addDocument(documentPointer, categories);\n },\n [addDocument],\n );\n\n const removeDocumentContext = useCallback(\n (documentId: string) => {\n removeDocument(documentId);\n },\n [removeDocument],\n );\n\n if (!props.publicApiKey) {\n if (props.cloudRestrictToTopic) {\n throw new Error(\n \"To use the cloudRestrictToTopic feature, please sign up at https://copilotkit.ai and provide a publicApiKey.\",\n );\n }\n }\n\n // get the appropriate CopilotApiConfig from the props\n const copilotApiConfig: CopilotApiConfig = useMemo(() => {\n let cloud: CopilotCloudConfig | undefined = undefined;\n if (props.publicApiKey) {\n cloud = {\n guardrails: {\n input: {\n restrictToTopic: {\n enabled: props.cloudRestrictToTopic ? true : false,\n validTopics: props.cloudRestrictToTopic?.validTopics || [],\n invalidTopics: props.cloudRestrictToTopic?.invalidTopics || [],\n },\n },\n },\n };\n }\n\n return {\n publicApiKey: props.publicApiKey,\n ...(cloud ? { cloud } : {}),\n chatApiEndpoint: chatApiEndpoint,\n headers: props.headers || {},\n properties: props.properties || {},\n transcribeAudioUrl: props.transcribeAudioUrl,\n textToSpeechUrl: props.textToSpeechUrl,\n credentials: props.credentials,\n };\n }, [\n props.publicApiKey,\n props.headers,\n props.properties,\n props.transcribeAudioUrl,\n props.textToSpeechUrl,\n props.credentials,\n props.cloudRestrictToTopic,\n ]);\n\n const headers = useMemo(() => {\n const authHeaders = Object.values(authStates || {}).reduce((acc, state) => {\n if (state.status === \"authenticated\" && state.authHeaders) {\n return {\n ...acc,\n ...Object.entries(state.authHeaders).reduce(\n (headers, [key, value]) => ({\n ...headers,\n [key.startsWith(\"X-Custom-\") ? key : `X-Custom-${key}`]: value,\n }),\n {},\n ),\n };\n }\n return acc;\n }, {});\n\n return {\n ...(copilotApiConfig.headers || {}),\n ...(copilotApiConfig.publicApiKey\n ? { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: copilotApiConfig.publicApiKey }\n : {}),\n ...authHeaders,\n };\n }, [copilotApiConfig.headers, copilotApiConfig.publicApiKey, authStates]);\n\n const runtimeClient = useCopilotRuntimeClient({\n url: copilotApiConfig.chatApiEndpoint,\n publicApiKey: copilotApiConfig.publicApiKey,\n headers,\n credentials: copilotApiConfig.credentials,\n });\n\n const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = useState<{\n [key: string]: CopilotChatSuggestionConfiguration;\n }>({});\n\n const addChatSuggestionConfiguration = (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => {\n setChatSuggestionConfiguration((prev) => ({ ...prev, [id]: suggestion }));\n };\n\n const removeChatSuggestionConfiguration = (id: string) => {\n setChatSuggestionConfiguration((prev) => {\n const { [id]: _, ...rest } = prev;\n return rest;\n });\n };\n\n const [availableAgents, setAvailableAgents] = useState<Agent[]>([]);\n const [coagentStates, setCoagentStates] = useState<Record<string, CoagentState>>({});\n const coagentStatesRef = useRef<Record<string, CoagentState>>({});\n const setCoagentStatesWithRef = useCallback(\n (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => {\n const newValue = typeof value === \"function\" ? value(coagentStatesRef.current) : value;\n coagentStatesRef.current = newValue;\n setCoagentStates((prev) => {\n return newValue;\n });\n },\n [],\n );\n\n useEffect(() => {\n const fetchData = async () => {\n const result = await runtimeClient.availableAgents();\n if (result.data?.availableAgents) {\n setAvailableAgents(result.data.availableAgents.agents);\n }\n };\n void fetchData();\n }, []);\n\n let initialAgentSession: AgentSession | null = null;\n if (props.agent) {\n initialAgentSession = {\n agentName: props.agent,\n };\n }\n\n const [agentSession, setAgentSession] = useState<AgentSession | null>(initialAgentSession);\n const [threadId, setThreadId] = useState<string | null>(null);\n const [runId, setRunId] = useState<string | null>(null);\n\n const chatAbortControllerRef = useRef<AbortController | null>(null);\n\n const showDevConsole = props.showDevConsole === undefined ? \"auto\" : props.showDevConsole;\n\n return (\n <CopilotContext.Provider\n value={{\n actions,\n chatComponentsCache,\n getFunctionCallHandler,\n setAction,\n removeAction,\n coAgentStateRenders,\n setCoAgentStateRender,\n removeCoAgentStateRender,\n getContextString,\n addContext,\n removeContext,\n getDocumentsContext,\n addDocumentContext,\n removeDocumentContext,\n copilotApiConfig: copilotApiConfig,\n isLoading,\n setIsLoading,\n chatSuggestionConfiguration,\n addChatSuggestionConfiguration,\n removeChatSuggestionConfiguration,\n chatInstructions,\n setChatInstructions,\n showDevConsole,\n coagentStates,\n setCoagentStates,\n coagentStatesRef,\n setCoagentStatesWithRef,\n agentSession,\n setAgentSession,\n runtimeClient,\n forwardedParameters: props.forwardedParameters || {},\n agentLock: props.agent || null,\n threadId,\n setThreadId,\n runId,\n setRunId,\n chatAbortControllerRef,\n availableAgents,\n authConfig: props.authConfig,\n authStates,\n setAuthStates,\n }}\n >\n <CopilotMessages>{children}</CopilotMessages>\n </CopilotContext.Provider>\n );\n}\n\nexport const defaultCopilotContextCategories = [\"global\"];\n\nfunction entryPointsToFunctionCallHandler(actions: FrontendAction<any>[]): FunctionCallHandler {\n return async ({ messages, name, args }) => {\n let actionsByFunctionName: Record<string, FrontendAction<any>> = {};\n for (let action of actions) {\n actionsByFunctionName[action.name] = action;\n }\n\n const action = actionsByFunctionName[name];\n let result: any = undefined;\n if (action) {\n await new Promise<void>((resolve, reject) => {\n flushSync(async () => {\n try {\n result = await action.handler?.(args);\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n });\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n return result;\n };\n}\n","export function shouldShowDevConsole(showDevConsole: boolean | \"auto\"): boolean {\n if (typeof showDevConsole === \"boolean\") {\n return showDevConsole;\n }\n return (\n getHostname() === \"localhost\" ||\n getHostname() === \"127.0.0.1\" ||\n getHostname() === \"0.0.0.0\" ||\n getHostname() === \"::1\"\n );\n}\n\nfunction getHostname(): string {\n if (typeof window !== \"undefined\" && window.location) {\n return window.location.hostname;\n }\n return \"\";\n}\n"],"mappings":"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","names":["import_shared","import_runtime_client_gql"]}
1
+ {"version":3,"sources":["../../src/utils/index.ts","../../src/utils/extract.ts","../../src/components/copilot-provider/copilotkit.tsx","../../src/utils/dev-console.ts"],"sourcesContent":["export { extract } from \"./extract\";\nexport * from \"./dev-console\";\n","import {\n Action,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n MappedParameterTypes,\n Parameter,\n actionParametersToJsonSchema,\n} from \"@copilotkit/shared\";\nimport {\n ActionExecutionMessage,\n Message,\n Role,\n TextMessage,\n convertGqlOutputToMessages,\n CopilotRequestType,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { CopilotContextParams, CopilotMessagesContextParams } from \"../context\";\nimport { defaultCopilotContextCategories } from \"../components\";\nimport { CopilotRuntimeClient } from \"@copilotkit/runtime-client-gql\";\nimport {\n convertMessagesToGqlInput,\n filterAgentStateMessages,\n} from \"@copilotkit/runtime-client-gql\";\n\ninterface InitialState<T extends Parameter[] | [] = []> {\n status: \"initial\";\n args: Partial<MappedParameterTypes<T>>;\n}\n\ninterface InProgressState<T extends Parameter[] | [] = []> {\n status: \"inProgress\";\n args: Partial<MappedParameterTypes<T>>;\n}\n\ninterface CompleteState<T extends Parameter[] | [] = []> {\n status: \"complete\";\n args: MappedParameterTypes<T>;\n}\n\ntype StreamHandlerArgs<T extends Parameter[] | [] = []> =\n | InitialState<T>\n | InProgressState<T>\n | CompleteState<T>;\n\ninterface ExtractOptions<T extends Parameter[]> {\n context: CopilotContextParams & CopilotMessagesContextParams;\n instructions: string;\n parameters: T;\n include?: IncludeOptions;\n data?: any;\n abortSignal?: AbortSignal;\n stream?: (args: StreamHandlerArgs<T>) => void;\n requestType?: CopilotRequestType;\n forwardedParameters?: ForwardedParametersInput;\n}\n\ninterface IncludeOptions {\n readable?: boolean;\n messages?: boolean;\n}\n\nexport async function extract<const T extends Parameter[]>({\n context,\n instructions,\n parameters,\n include,\n data,\n abortSignal,\n stream,\n requestType = CopilotRequestType.Task,\n forwardedParameters,\n}: ExtractOptions<T>): Promise<MappedParameterTypes<T>> {\n const { messages } = context;\n\n const action: Action<any> = {\n name: \"extract\",\n description: instructions,\n parameters,\n handler: (args: any) => {},\n };\n\n const includeReadable = include?.readable ?? false;\n const includeMessages = include?.messages ?? false;\n\n let contextString = \"\";\n\n if (data) {\n contextString = (typeof data === \"string\" ? data : JSON.stringify(data)) + \"\\n\\n\";\n }\n\n if (includeReadable) {\n contextString += context.getContextString([], defaultCopilotContextCategories);\n }\n\n const systemMessage: Message = new TextMessage({\n content: makeSystemMessage(contextString, instructions),\n role: Role.System,\n });\n\n const instructionsMessage: Message = new TextMessage({\n content: makeInstructionsMessage(instructions),\n role: Role.User,\n });\n\n const response = context.runtimeClient.asStream(\n context.runtimeClient.generateCopilotResponse({\n data: {\n frontend: {\n actions: [\n {\n name: action.name,\n description: action.description || \"\",\n jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters || [])),\n },\n ],\n url: window.location.href,\n },\n\n messages: convertMessagesToGqlInput(\n includeMessages\n ? [systemMessage, instructionsMessage, ...filterAgentStateMessages(messages)]\n : [systemMessage, instructionsMessage],\n ),\n metadata: {\n requestType: requestType,\n },\n forwardedParameters: {\n ...(forwardedParameters ?? {}),\n toolChoice: \"function\",\n toolChoiceFunctionName: action.name,\n },\n },\n properties: context.copilotApiConfig.properties,\n signal: abortSignal,\n }),\n );\n\n const reader = response.getReader();\n\n let isInitial = true;\n\n let actionExecutionMessage: ActionExecutionMessage | undefined = undefined;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n if (abortSignal?.aborted) {\n throw new Error(\"Aborted\");\n }\n\n actionExecutionMessage = convertGqlOutputToMessages(\n value.generateCopilotResponse.messages,\n ).find((msg) => msg.isActionExecutionMessage()) as ActionExecutionMessage | undefined;\n\n if (!actionExecutionMessage) {\n continue;\n }\n\n stream?.({\n status: isInitial ? \"initial\" : \"inProgress\",\n args: actionExecutionMessage.arguments as Partial<MappedParameterTypes<T>>,\n });\n\n isInitial = false;\n }\n\n if (!actionExecutionMessage) {\n throw new Error(\"extract() failed: No function call occurred\");\n }\n\n stream?.({\n status: \"complete\",\n args: actionExecutionMessage.arguments as MappedParameterTypes<T>,\n });\n\n return actionExecutionMessage.arguments as MappedParameterTypes<T>;\n}\n\n// We need to put this in a user message since some LLMs need\n// at least one user message to function\nfunction makeInstructionsMessage(instructions: string): string {\n return `\nThe user has given you the following task to complete:\n\n\\`\\`\\`\n${instructions}\n\\`\\`\\`\n\nAny additional messages provided are for providing context only and should not be used to ask questions or engage in conversation.\n`;\n}\n\nfunction makeSystemMessage(contextString: string, instructions: string): string {\n return `\nPlease act as an efficient, competent, conscientious, and industrious professional assistant.\n\nHelp the user achieve their goals, and you do so in a way that is as efficient as possible, without unnecessary fluff, but also without sacrificing professionalism.\nAlways be polite and respectful, and prefer brevity over verbosity.\n\nThe user has provided you with the following context:\n\\`\\`\\`\n${contextString}\n\\`\\`\\`\n\nThey have also provided you with a function called extract you MUST call to initiate actions on their behalf.\n\nPlease assist them as best you can.\n\nThis is not a conversation, so please do not ask questions. Just call the function without saying anything else.\n`;\n}\n","/**\n * This component will typically wrap your entire application (or a sub-tree of your application where you want to have a copilot). It provides the copilot context to all other components and hooks.\n *\n * ## Example\n *\n * You can find more information about self-hosting CopilotKit [here](/guides/self-hosting).\n *\n * ```tsx\n * import { CopilotKit } from \"@copilotkit/react-core\";\n *\n * <CopilotKit runtimeUrl=\"<your-runtime-url>\">\n * // ... your app ...\n * </CopilotKit>\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState, SetStateAction } from \"react\";\nimport {\n CopilotContext,\n CopilotApiConfig,\n ChatComponentsCache,\n AgentSession,\n AuthState,\n} from \"../../context/copilot-context\";\nimport useTree from \"../../hooks/use-tree\";\nimport { CopilotChatSuggestionConfiguration, DocumentPointer } from \"../../types\";\nimport { flushSync } from \"react-dom\";\nimport {\n COPILOT_CLOUD_CHAT_URL,\n CopilotCloudConfig,\n FunctionCallHandler,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n randomUUID,\n} from \"@copilotkit/shared\";\n\nimport { FrontendAction } from \"../../types/frontend-action\";\nimport useFlatCategoryStore from \"../../hooks/use-flat-category-store\";\nimport { CopilotKitProps } from \"./copilotkit-props\";\nimport { CoAgentStateRender } from \"../../types/coagent-action\";\nimport { CoagentState } from \"../../types/coagent-state\";\nimport { CopilotMessages } from \"./copilot-messages\";\nimport { ToastProvider } from \"../toast/toast-provider\";\nimport { useCopilotRuntimeClient } from \"../../hooks/use-copilot-runtime-client\";\nimport { shouldShowDevConsole } from \"../../utils\";\nimport { CopilotErrorBoundary } from \"../error-boundary/error-boundary\";\nimport {\n Agent,\n ExtensionsInput,\n loadMessagesFromJsonRepresentation,\n} from \"@copilotkit/runtime-client-gql\";\n\nexport function CopilotKit({ children, ...props }: CopilotKitProps) {\n const showDevConsole = props.showDevConsole === undefined ? \"auto\" : props.showDevConsole;\n const enabled = shouldShowDevConsole(showDevConsole);\n return (\n <ToastProvider enabled={enabled}>\n <CopilotErrorBoundary>\n <CopilotKitInternal {...props}>{children}</CopilotKitInternal>\n </CopilotErrorBoundary>\n </ToastProvider>\n );\n}\n\nexport function CopilotKitInternal({ children, ...props }: CopilotKitProps) {\n // Compute all the functions and properties that we need to pass\n // to the CopilotContext.\n\n if (!props.runtimeUrl && !props.publicApiKey) {\n throw new Error(\n \"Please provide either a runtimeUrl or a publicApiKey to the CopilotKit component.\",\n );\n }\n\n const chatApiEndpoint = props.runtimeUrl || COPILOT_CLOUD_CHAT_URL;\n\n const [actions, setActions] = useState<Record<string, FrontendAction<any>>>({});\n const [coAgentStateRenders, setCoAgentStateRenders] = useState<\n Record<string, CoAgentStateRender<any>>\n >({});\n const chatComponentsCache = useRef<ChatComponentsCache>({\n actions: {},\n coAgentStateRenders: {},\n });\n const { addElement, removeElement, printTree } = useTree();\n const [isLoading, setIsLoading] = useState(false);\n const [chatInstructions, setChatInstructions] = useState(\"\");\n const [authStates, setAuthStates] = useState<Record<string, AuthState>>({});\n const [extensions, setExtensions] = useState<ExtensionsInput>({});\n\n const {\n addElement: addDocument,\n removeElement: removeDocument,\n allElements: allDocuments,\n } = useFlatCategoryStore<DocumentPointer>();\n\n const setAction = useCallback((id: string, action: FrontendAction<any>) => {\n setActions((prevPoints) => {\n return {\n ...prevPoints,\n [id]: action,\n };\n });\n }, []);\n\n const removeAction = useCallback((id: string) => {\n setActions((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const setCoAgentStateRender = useCallback((id: string, stateRender: CoAgentStateRender<any>) => {\n setCoAgentStateRenders((prevPoints) => {\n return {\n ...prevPoints,\n [id]: stateRender,\n };\n });\n }, []);\n\n const removeCoAgentStateRender = useCallback((id: string) => {\n setCoAgentStateRenders((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const getContextString = useCallback(\n (documents: DocumentPointer[], categories: string[]) => {\n const documentsString = documents\n .map((document) => {\n return `${document.name} (${document.sourceApplication}):\\n${document.getContents()}`;\n })\n .join(\"\\n\\n\");\n\n const nonDocumentStrings = printTree(categories);\n\n return `${documentsString}\\n\\n${nonDocumentStrings}`;\n },\n [printTree],\n );\n\n const addContext = useCallback(\n (\n context: string,\n parentId?: string,\n categories: string[] = defaultCopilotContextCategories,\n ) => {\n return addElement(context, categories, parentId);\n },\n [addElement],\n );\n\n const removeContext = useCallback(\n (id: string) => {\n removeElement(id);\n },\n [removeElement],\n );\n\n const getFunctionCallHandler = useCallback(\n (customEntryPoints?: Record<string, FrontendAction<any>>) => {\n return entryPointsToFunctionCallHandler(Object.values(customEntryPoints || actions));\n },\n [actions],\n );\n\n const getDocumentsContext = useCallback(\n (categories: string[]) => {\n return allDocuments(categories);\n },\n [allDocuments],\n );\n\n const addDocumentContext = useCallback(\n (documentPointer: DocumentPointer, categories: string[] = defaultCopilotContextCategories) => {\n return addDocument(documentPointer, categories);\n },\n [addDocument],\n );\n\n const removeDocumentContext = useCallback(\n (documentId: string) => {\n removeDocument(documentId);\n },\n [removeDocument],\n );\n\n if (!props.publicApiKey) {\n if (props.cloudRestrictToTopic) {\n throw new Error(\n \"To use the cloudRestrictToTopic feature, please sign up at https://copilotkit.ai and provide a publicApiKey.\",\n );\n }\n }\n\n // get the appropriate CopilotApiConfig from the props\n const copilotApiConfig: CopilotApiConfig = useMemo(() => {\n let cloud: CopilotCloudConfig | undefined = undefined;\n if (props.publicApiKey) {\n cloud = {\n guardrails: {\n input: {\n restrictToTopic: {\n enabled: props.cloudRestrictToTopic ? true : false,\n validTopics: props.cloudRestrictToTopic?.validTopics || [],\n invalidTopics: props.cloudRestrictToTopic?.invalidTopics || [],\n },\n },\n },\n };\n }\n\n return {\n publicApiKey: props.publicApiKey,\n ...(cloud ? { cloud } : {}),\n chatApiEndpoint: chatApiEndpoint,\n headers: props.headers || {},\n properties: props.properties || {},\n transcribeAudioUrl: props.transcribeAudioUrl,\n textToSpeechUrl: props.textToSpeechUrl,\n credentials: props.credentials,\n };\n }, [\n props.publicApiKey,\n props.headers,\n props.properties,\n props.transcribeAudioUrl,\n props.textToSpeechUrl,\n props.credentials,\n props.cloudRestrictToTopic,\n ]);\n\n const headers = useMemo(() => {\n const authHeaders = Object.values(authStates || {}).reduce((acc, state) => {\n if (state.status === \"authenticated\" && state.authHeaders) {\n return {\n ...acc,\n ...Object.entries(state.authHeaders).reduce(\n (headers, [key, value]) => ({\n ...headers,\n [key.startsWith(\"X-Custom-\") ? key : `X-Custom-${key}`]: value,\n }),\n {},\n ),\n };\n }\n return acc;\n }, {});\n\n return {\n ...(copilotApiConfig.headers || {}),\n ...(copilotApiConfig.publicApiKey\n ? { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: copilotApiConfig.publicApiKey }\n : {}),\n ...authHeaders,\n };\n }, [copilotApiConfig.headers, copilotApiConfig.publicApiKey, authStates]);\n\n const runtimeClient = useCopilotRuntimeClient({\n url: copilotApiConfig.chatApiEndpoint,\n publicApiKey: copilotApiConfig.publicApiKey,\n headers,\n credentials: copilotApiConfig.credentials,\n });\n\n const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = useState<{\n [key: string]: CopilotChatSuggestionConfiguration;\n }>({});\n\n const addChatSuggestionConfiguration = (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => {\n setChatSuggestionConfiguration((prev) => ({ ...prev, [id]: suggestion }));\n };\n\n const removeChatSuggestionConfiguration = (id: string) => {\n setChatSuggestionConfiguration((prev) => {\n const { [id]: _, ...rest } = prev;\n return rest;\n });\n };\n\n const [availableAgents, setAvailableAgents] = useState<Agent[]>([]);\n const [coagentStates, setCoagentStates] = useState<Record<string, CoagentState>>({});\n const coagentStatesRef = useRef<Record<string, CoagentState>>({});\n const setCoagentStatesWithRef = useCallback(\n (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => {\n const newValue = typeof value === \"function\" ? value(coagentStatesRef.current) : value;\n coagentStatesRef.current = newValue;\n setCoagentStates((prev) => {\n return newValue;\n });\n },\n [],\n );\n\n useEffect(() => {\n const fetchData = async () => {\n const result = await runtimeClient.availableAgents();\n if (result.data?.availableAgents) {\n setAvailableAgents(result.data.availableAgents.agents);\n }\n };\n void fetchData();\n }, []);\n\n let initialAgentSession: AgentSession | null = null;\n if (props.agent) {\n initialAgentSession = {\n agentName: props.agent,\n };\n }\n\n const [agentSession, setAgentSession] = useState<AgentSession | null>(initialAgentSession);\n\n const [internalThreadId, setInternalThreadId] = useState<string>(props.threadId || randomUUID());\n const setThreadId = useCallback(\n (value: SetStateAction<string>) => {\n if (props.threadId) {\n throw new Error(\"Cannot call setThreadId() when threadId is provided via props.\");\n }\n setInternalThreadId(value);\n },\n [props.threadId],\n );\n\n // update the internal threadId if the props.threadId changes\n useEffect(() => {\n if (props.threadId !== undefined) {\n setInternalThreadId(props.threadId);\n }\n }, [props.threadId]);\n\n const [runId, setRunId] = useState<string | null>(null);\n\n const chatAbortControllerRef = useRef<AbortController | null>(null);\n\n const showDevConsole = props.showDevConsole === undefined ? \"auto\" : props.showDevConsole;\n\n return (\n <CopilotContext.Provider\n value={{\n actions,\n chatComponentsCache,\n getFunctionCallHandler,\n setAction,\n removeAction,\n coAgentStateRenders,\n setCoAgentStateRender,\n removeCoAgentStateRender,\n getContextString,\n addContext,\n removeContext,\n getDocumentsContext,\n addDocumentContext,\n removeDocumentContext,\n copilotApiConfig: copilotApiConfig,\n isLoading,\n setIsLoading,\n chatSuggestionConfiguration,\n addChatSuggestionConfiguration,\n removeChatSuggestionConfiguration,\n chatInstructions,\n setChatInstructions,\n showDevConsole,\n coagentStates,\n setCoagentStates,\n coagentStatesRef,\n setCoagentStatesWithRef,\n agentSession,\n setAgentSession,\n runtimeClient,\n forwardedParameters: props.forwardedParameters || {},\n agentLock: props.agent || null,\n threadId: internalThreadId,\n setThreadId,\n runId,\n setRunId,\n chatAbortControllerRef,\n availableAgents,\n authConfig: props.authConfig,\n authStates,\n setAuthStates,\n extensions,\n setExtensions,\n }}\n >\n <CopilotMessages>{children}</CopilotMessages>\n </CopilotContext.Provider>\n );\n}\n\nexport const defaultCopilotContextCategories = [\"global\"];\n\nfunction entryPointsToFunctionCallHandler(actions: FrontendAction<any>[]): FunctionCallHandler {\n return async ({ messages, name, args }) => {\n let actionsByFunctionName: Record<string, FrontendAction<any>> = {};\n for (let action of actions) {\n actionsByFunctionName[action.name] = action;\n }\n\n const action = actionsByFunctionName[name];\n let result: any = undefined;\n if (action) {\n await new Promise<void>((resolve, reject) => {\n flushSync(async () => {\n try {\n result = await action.handler?.(args);\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n });\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n return result;\n };\n}\n","export function shouldShowDevConsole(showDevConsole: boolean | \"auto\"): boolean {\n if (typeof showDevConsole === \"boolean\") {\n return showDevConsole;\n }\n return (\n getHostname() === \"localhost\" ||\n getHostname() === \"127.0.0.1\" ||\n getHostname() === \"0.0.0.0\" ||\n getHostname() === \"::1\"\n );\n}\n\nfunction getHostname(): string {\n if (typeof window !== \"undefined\" && window.location) {\n return window.location.hostname;\n }\n return \"\";\n}\n"],"mappings":"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","names":["import_shared","import_runtime_client_gql"]}
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  extract
3
- } from "../chunk-LZWH4OG5.mjs";
4
- import "../chunk-VNTDIJSG.mjs";
3
+ } from "../chunk-MYCYEMIM.mjs";
4
+ import "../chunk-X47CUJJT.mjs";
5
5
  import {
6
6
  shouldShowDevConsole
7
7
  } from "../chunk-MLAS4QUR.mjs";
8
- import "../chunk-XXR4QFAQ.mjs";
9
- import "../chunk-5FHSUKQL.mjs";
8
+ import "../chunk-IFBUUIU7.mjs";
10
9
  import "../chunk-6U3UH3KO.mjs";
10
+ import "../chunk-5FHSUKQL.mjs";
11
11
  import "../chunk-DCTJZ742.mjs";
12
- import "../chunk-6BQVZFNO.mjs";
13
- import "../chunk-WXREY7UP.mjs";
14
- import "../chunk-LNI2Z45S.mjs";
12
+ import "../chunk-CQWEXISS.mjs";
13
+ import "../chunk-YVQNSJ4Z.mjs";
14
+ import "../chunk-HZCROITJ.mjs";
15
15
  import "../chunk-O7ARI5CV.mjs";
16
16
  import "../chunk-SKC7AJIV.mjs";
17
17
  export {
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "1.5.12-next.5",
12
+ "version": "1.5.12-next.7",
13
13
  "sideEffects": false,
14
14
  "main": "./dist/index.js",
15
15
  "module": "./dist/index.mjs",
@@ -29,21 +29,22 @@
29
29
  "devDependencies": {
30
30
  "@types/jest": "^29.5.4",
31
31
  "@types/react": "^18.2.5",
32
+ "@types/react-dom": "^18.2.4",
32
33
  "eslint": "^8.56.0",
33
34
  "jest": "^29.6.4",
34
35
  "react": "^18.2.0",
35
36
  "ts-jest": "^29.1.1",
36
37
  "tsup": "^6.7.0",
37
38
  "typescript": "^5.2.3",
38
- "@types/react-dom": "^18.2.4",
39
39
  "eslint-config-custom": "1.4.6",
40
40
  "tsconfig": "1.4.6"
41
41
  },
42
42
  "dependencies": {
43
43
  "@scarf/scarf": "^1.3.0",
44
+ "react-markdown": "^8.0.7",
44
45
  "untruncate-json": "^0.0.1",
45
- "@copilotkit/runtime-client-gql": "1.5.12-next.5",
46
- "@copilotkit/shared": "1.5.12-next.5"
46
+ "@copilotkit/runtime-client-gql": "1.5.12-next.7",
47
+ "@copilotkit/shared": "1.5.12-next.7"
47
48
  },
48
49
  "keywords": [
49
50
  "copilotkit",
@@ -2,14 +2,36 @@
2
2
  * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
3
3
  */
4
4
 
5
- import { useState } from "react";
5
+ import { useEffect, useState } from "react";
6
6
  import { CopilotMessagesContext } from "../../context/copilot-messages-context";
7
- import { Message } from "@copilotkit/runtime-client-gql";
7
+ import { loadMessagesFromJsonRepresentation, Message } from "@copilotkit/runtime-client-gql";
8
8
  import { CopilotKitProps } from "./copilotkit-props";
9
+ import { useCopilotContext } from "../../context/copilot-context";
9
10
 
10
11
  export function CopilotMessages({ children, ...props }: CopilotKitProps) {
11
12
  const [messages, setMessages] = useState<Message[]>([]);
12
13
 
14
+ const { threadId, agentSession, runtimeClient } = useCopilotContext();
15
+
16
+ useEffect(() => {
17
+ if (agentSession?.agentName) {
18
+ // reload messages
19
+ const fetchAgentState = async () => {
20
+ const result = await runtimeClient.loadAgentState({
21
+ threadId,
22
+ agentName: agentSession.agentName,
23
+ });
24
+ if (result.data?.loadAgentState?.threadExists) {
25
+ const messages = loadMessagesFromJsonRepresentation(
26
+ JSON.parse(result.data?.loadAgentState?.messages || "[]"),
27
+ );
28
+ setMessages(messages);
29
+ }
30
+ };
31
+ void fetchAgentState();
32
+ }
33
+ }, [threadId, agentSession?.agentName !== undefined]);
34
+
13
35
  return (
14
36
  <CopilotMessagesContext.Provider
15
37
  value={{
@@ -94,4 +94,9 @@ export interface CopilotKitProps {
94
94
  onSignInComplete: (authState: AuthState) => void;
95
95
  }>;
96
96
  };
97
+
98
+ /**
99
+ * The thread id to use for the CopilotKit.
100
+ */
101
+ threadId?: string;
97
102
  }
@@ -14,7 +14,7 @@
14
14
  * ```
15
15
  */
16
16
 
17
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
17
+ import { useCallback, useEffect, useMemo, useRef, useState, SetStateAction } from "react";
18
18
  import {
19
19
  CopilotContext,
20
20
  CopilotApiConfig,
@@ -30,6 +30,7 @@ import {
30
30
  CopilotCloudConfig,
31
31
  FunctionCallHandler,
32
32
  COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,
33
+ randomUUID,
33
34
  } from "@copilotkit/shared";
34
35
 
35
36
  import { FrontendAction } from "../../types/frontend-action";
@@ -42,7 +43,11 @@ import { ToastProvider } from "../toast/toast-provider";
42
43
  import { useCopilotRuntimeClient } from "../../hooks/use-copilot-runtime-client";
43
44
  import { shouldShowDevConsole } from "../../utils";
44
45
  import { CopilotErrorBoundary } from "../error-boundary/error-boundary";
45
- import { Agent } from "@copilotkit/runtime-client-gql";
46
+ import {
47
+ Agent,
48
+ ExtensionsInput,
49
+ loadMessagesFromJsonRepresentation,
50
+ } from "@copilotkit/runtime-client-gql";
46
51
 
47
52
  export function CopilotKit({ children, ...props }: CopilotKitProps) {
48
53
  const showDevConsole = props.showDevConsole === undefined ? "auto" : props.showDevConsole;
@@ -80,6 +85,7 @@ export function CopilotKitInternal({ children, ...props }: CopilotKitProps) {
80
85
  const [isLoading, setIsLoading] = useState(false);
81
86
  const [chatInstructions, setChatInstructions] = useState("");
82
87
  const [authStates, setAuthStates] = useState<Record<string, AuthState>>({});
88
+ const [extensions, setExtensions] = useState<ExtensionsInput>({});
83
89
 
84
90
  const {
85
91
  addElement: addDocument,
@@ -314,7 +320,25 @@ export function CopilotKitInternal({ children, ...props }: CopilotKitProps) {
314
320
  }
315
321
 
316
322
  const [agentSession, setAgentSession] = useState<AgentSession | null>(initialAgentSession);
317
- const [threadId, setThreadId] = useState<string | null>(null);
323
+
324
+ const [internalThreadId, setInternalThreadId] = useState<string>(props.threadId || randomUUID());
325
+ const setThreadId = useCallback(
326
+ (value: SetStateAction<string>) => {
327
+ if (props.threadId) {
328
+ throw new Error("Cannot call setThreadId() when threadId is provided via props.");
329
+ }
330
+ setInternalThreadId(value);
331
+ },
332
+ [props.threadId],
333
+ );
334
+
335
+ // update the internal threadId if the props.threadId changes
336
+ useEffect(() => {
337
+ if (props.threadId !== undefined) {
338
+ setInternalThreadId(props.threadId);
339
+ }
340
+ }, [props.threadId]);
341
+
318
342
  const [runId, setRunId] = useState<string | null>(null);
319
343
 
320
344
  const chatAbortControllerRef = useRef<AbortController | null>(null);
@@ -356,7 +380,7 @@ export function CopilotKitInternal({ children, ...props }: CopilotKitProps) {
356
380
  runtimeClient,
357
381
  forwardedParameters: props.forwardedParameters || {},
358
382
  agentLock: props.agent || null,
359
- threadId,
383
+ threadId: internalThreadId,
360
384
  setThreadId,
361
385
  runId,
362
386
  setRunId,
@@ -365,6 +389,8 @@ export function CopilotKitInternal({ children, ...props }: CopilotKitProps) {
365
389
  authConfig: props.authConfig,
366
390
  authStates,
367
391
  setAuthStates,
392
+ extensions,
393
+ setExtensions,
368
394
  }}
369
395
  >
370
396
  <CopilotMessages>{children}</CopilotMessages>
@@ -1,14 +1,19 @@
1
- import React, { useCallback, useEffect } from "react";
1
+ import React, { useCallback } from "react";
2
2
  import { GraphQLError } from "@copilotkit/runtime-client-gql";
3
3
  import { useToast } from "../toast/toast-provider";
4
4
  import { ExclamationMarkIcon } from "../toast/exclamation-mark-icon";
5
+ import ReactMarkdown from "react-markdown";
6
+
7
+ interface OriginalError {
8
+ message?: string;
9
+ stack?: string;
10
+ }
5
11
 
6
12
  export function ErrorToast({ errors }: { errors: (Error | GraphQLError)[] }) {
7
13
  const errorsToRender = errors.map((error, idx) => {
8
- const message =
9
- "extensions" in error
10
- ? (error.extensions?.originalError as undefined | { message?: string })?.message
11
- : error.message;
14
+ const originalError =
15
+ "extensions" in error ? (error.extensions?.originalError as undefined | OriginalError) : {};
16
+ const message = originalError?.message ?? error.message;
12
17
  const code = "extensions" in error ? (error.extensions?.code as string) : null;
13
18
 
14
19
  return (
@@ -32,7 +37,7 @@ export function ErrorToast({ errors }: { errors: (Error | GraphQLError)[] }) {
32
37
  <span style={{ fontFamily: "monospace", fontWeight: "normal" }}>{code}</span>
33
38
  </div>
34
39
  )}
35
- <div>{message}</div>
40
+ <ReactMarkdown>{message}</ReactMarkdown>
36
41
  </div>
37
42
  );
38
43
  });
@@ -10,7 +10,11 @@ import { DocumentPointer } from "../types";
10
10
  import { CopilotChatSuggestionConfiguration } from "../types/chat-suggestion-configuration";
11
11
  import { CoAgentStateRender, CoAgentStateRenderProps } from "../types/coagent-action";
12
12
  import { CoagentState } from "../types/coagent-state";
13
- import { CopilotRuntimeClient, ForwardedParametersInput } from "@copilotkit/runtime-client-gql";
13
+ import {
14
+ CopilotRuntimeClient,
15
+ ExtensionsInput,
16
+ ForwardedParametersInput,
17
+ } from "@copilotkit/runtime-client-gql";
14
18
  import { Agent } from "@copilotkit/runtime-client-gql";
15
19
 
16
20
  /**
@@ -160,8 +164,8 @@ export interface CopilotContextParams {
160
164
 
161
165
  agentLock: string | null;
162
166
 
163
- threadId: string | null;
164
- setThreadId: React.Dispatch<React.SetStateAction<string | null>>;
167
+ threadId: string;
168
+ setThreadId: React.Dispatch<React.SetStateAction<string>>;
165
169
 
166
170
  runId: string | null;
167
171
  setRunId: React.Dispatch<React.SetStateAction<string | null>>;
@@ -193,6 +197,9 @@ export interface CopilotContextParams {
193
197
  onSignInComplete: (authState: AuthState) => void;
194
198
  }>;
195
199
  };
200
+
201
+ extensions: ExtensionsInput;
202
+ setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;
196
203
  }
197
204
 
198
205
  const emptyCopilotContext: CopilotContextParams = {
@@ -248,12 +255,14 @@ const emptyCopilotContext: CopilotContextParams = {
248
255
  setAgentSession: () => {},
249
256
  forwardedParameters: {},
250
257
  agentLock: null,
251
- threadId: null,
258
+ threadId: "",
252
259
  setThreadId: () => {},
253
260
  runId: null,
254
261
  setRunId: () => {},
255
262
  chatAbortControllerRef: { current: null },
256
263
  availableAgents: [],
264
+ extensions: {},
265
+ setExtensions: () => {},
257
266
  };
258
267
 
259
268
  export const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);
@@ -19,6 +19,8 @@ import {
19
19
  CopilotRequestType,
20
20
  ForwardedParametersInput,
21
21
  loadMessagesFromJsonRepresentation,
22
+ ExtensionsInput,
23
+ CopilotRuntimeClient,
22
24
  } from "@copilotkit/runtime-client-gql";
23
25
 
24
26
  import { CopilotApiConfig } from "../context";
@@ -107,11 +109,11 @@ export type UseChatOptions = {
107
109
  /**
108
110
  * The current thread ID.
109
111
  */
110
- threadId: string | null;
112
+ threadId: string;
111
113
  /**
112
114
  * set the current thread ID
113
115
  */
114
- setThreadId: (threadId: string | null) => void;
116
+ setThreadId: (threadId: string) => void;
115
117
  /**
116
118
  * The current run ID.
117
119
  */
@@ -128,6 +130,14 @@ export type UseChatOptions = {
128
130
  * The agent lock.
129
131
  */
130
132
  agentLock: string | null;
133
+ /**
134
+ * The extensions.
135
+ */
136
+ extensions: ExtensionsInput;
137
+ /**
138
+ * The setState-powered method to update the extensions.
139
+ */
140
+ setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;
131
141
  };
132
142
 
133
143
  export type UseChatHelpers = {
@@ -183,6 +193,8 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
183
193
  setRunId,
184
194
  chatAbortControllerRef,
185
195
  agentLock,
196
+ extensions,
197
+ setExtensions,
186
198
  } = options;
187
199
  const runChatCompletionRef = useRef<(previousMessages: Message[]) => Promise<Message[]>>();
188
200
  const addErrorToast = useErrorToast();
@@ -191,10 +203,11 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
191
203
  // This is a workaround and needs to be addressed in the future
192
204
  const agentSessionRef = useRef<AgentSession | null>(agentSession);
193
205
  agentSessionRef.current = agentSession;
194
- const threadIdRef = useRef<string | null>(threadId);
195
- threadIdRef.current = threadId;
206
+
196
207
  const runIdRef = useRef<string | null>(runId);
197
208
  runIdRef.current = runId;
209
+ const extensionsRef = useRef<ExtensionsInput>(extensions);
210
+ extensionsRef.current = extensions;
198
211
 
199
212
  const publicApiKey = copilotConfig.publicApiKey;
200
213
 
@@ -240,8 +253,9 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
240
253
  actions: processActionsForRuntimeRequest(actions),
241
254
  url: window.location.href,
242
255
  },
243
- threadId: threadIdRef.current,
256
+ threadId: threadId,
244
257
  runId: runIdRef.current,
258
+ extensions: extensionsRef.current,
245
259
  messages: convertMessagesToGqlInput(filterAgentStateMessages(messagesWithContext)),
246
260
  ...(copilotConfig.cloud
247
261
  ? {
@@ -314,11 +328,17 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
314
328
  continue;
315
329
  }
316
330
 
317
- threadIdRef.current = value.generateCopilotResponse.threadId || null;
318
331
  runIdRef.current = value.generateCopilotResponse.runId || null;
319
332
 
320
- setThreadId(threadIdRef.current);
333
+ // in the output, graphql inserts __typename, which leads to an error when sending it along
334
+ // as input to the next request.
335
+ extensionsRef.current = CopilotRuntimeClient.removeGraphQLTypename(
336
+ value.generateCopilotResponse.extensions || {},
337
+ );
338
+
339
+ // setThreadId(threadIdRef.current);
321
340
  setRunId(runIdRef.current);
341
+ setExtensions(extensionsRef.current);
322
342
 
323
343
  messages = convertGqlOutputToMessages(
324
344
  filterAdjacentAgentStateMessages(value.generateCopilotResponse.messages),
@@ -97,10 +97,11 @@ import {
97
97
  } from "../context";
98
98
  import { CoagentState } from "../types/coagent-state";
99
99
  import { useCopilotChat } from "./use-copilot-chat";
100
- import { Message } from "@copilotkit/runtime-client-gql";
100
+ import { loadMessagesFromJsonRepresentation, Message } from "@copilotkit/runtime-client-gql";
101
101
  import { flushSync } from "react-dom";
102
102
  import { useAsyncCallback } from "../components/error-boundary/error-utils";
103
103
  import { useToast } from "../components/toast/toast-provider";
104
+ import { useCopilotRuntimeClient } from "./use-copilot-runtime-client";
104
105
 
105
106
  interface WithInternalStateManagementAndInitial<T> {
106
107
  /**
@@ -230,7 +231,8 @@ export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentRe
230
231
 
231
232
  const messagesContext = useCopilotMessagesContext();
232
233
  const context = { ...generalContext, ...messagesContext };
233
- const { coagentStates, coagentStatesRef, setCoagentStatesWithRef } = context;
234
+ const { coagentStates, coagentStatesRef, setCoagentStatesWithRef, threadId, copilotApiConfig } =
235
+ context;
234
236
  const { appendMessage, runChatCompletion } = useCopilotChat();
235
237
 
236
238
  const getCoagentState = (coagentStates: Record<string, CoagentState>, name: string) => {
@@ -249,6 +251,12 @@ export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentRe
249
251
  }
250
252
  };
251
253
 
254
+ const runtimeClient = useCopilotRuntimeClient({
255
+ url: copilotApiConfig.chatApiEndpoint,
256
+ publicApiKey: copilotApiConfig.publicApiKey,
257
+ credentials: copilotApiConfig.credentials,
258
+ });
259
+
252
260
  // if we manage state internally, we need to provide a function to set the state
253
261
  const setState = (newState: T | ((prevState: T | undefined) => T)) => {
254
262
  let coagentState: CoagentState = getCoagentState(coagentStatesRef.current || {}, name);
@@ -264,9 +272,27 @@ export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentRe
264
272
  });
265
273
  };
266
274
 
267
- const coagentState = getCoagentState(coagentStates, name);
275
+ useEffect(() => {
276
+ const fetchAgentState = async () => {
277
+ const result = await runtimeClient.loadAgentState({
278
+ threadId: threadId,
279
+ agentName: name,
280
+ });
281
+ if (
282
+ result.data?.loadAgentState?.threadExists &&
283
+ result.data?.loadAgentState?.state &&
284
+ result.data?.loadAgentState?.state != "{}"
285
+ ) {
286
+ const fetchedState = JSON.parse(result.data?.loadAgentState?.state);
287
+ isExternalStateManagement(options)
288
+ ? options.setState(fetchedState)
289
+ : setState(fetchedState);
290
+ }
291
+ };
292
+ void fetchAgentState();
293
+ }, [threadId]);
268
294
 
269
- const state = isExternalStateManagement(options) ? options.state : coagentState.state;
295
+ const coagentState = getCoagentState(coagentStates, name);
270
296
 
271
297
  // Sync internal state with external state if state management is external
272
298
  useEffect(() => {
@@ -47,7 +47,7 @@ import { Message, Role, TextMessage } from "@copilotkit/runtime-client-gql";
47
47
  import { SystemMessageFunction } from "../types";
48
48
  import { useChat, AppendMessageOptions } from "./use-chat";
49
49
  import { defaultCopilotContextCategories } from "../components";
50
- import { CoAgentStateRenderHandlerArguments } from "@copilotkit/shared";
50
+ import { CoAgentStateRenderHandlerArguments, randomId } from "@copilotkit/shared";
51
51
  import { useCopilotMessagesContext } from "../context";
52
52
  import { useAsyncCallback } from "../components/error-boundary/error-utils";
53
53
 
@@ -110,6 +110,8 @@ export function useCopilotChat({
110
110
  runId,
111
111
  setRunId,
112
112
  chatAbortControllerRef,
113
+ extensions,
114
+ setExtensions,
113
115
  } = useCopilotContext();
114
116
  const { messages, setMessages } = useCopilotMessagesContext();
115
117
 
@@ -175,6 +177,8 @@ export function useCopilotChat({
175
177
  setRunId,
176
178
  chatAbortControllerRef,
177
179
  agentLock,
180
+ extensions,
181
+ setExtensions,
178
182
  });
179
183
 
180
184
  // this is a workaround born out of a bug that Athena incessantly ran into.
@@ -227,7 +231,6 @@ export function useCopilotChat({
227
231
  const reset = useCallback(() => {
228
232
  latestStopFunc();
229
233
  setMessages([]);
230
- setThreadId(null);
231
234
  setRunId(null);
232
235
  setCoagentStatesWithRef({});
233
236
  let initialAgentSession: AgentSession | null = null;