@copilotkit/react-core 2.0.0-next.1 → 2.0.0-rc.0
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/LICENSE +21 -0
- package/README.md +18 -12
- package/dist/MarkdownRendererContext-B4Us6mwL.d.cts +954 -0
- package/dist/MarkdownRendererContext-B4Us6mwL.d.cts.map +1 -0
- package/dist/MarkdownRendererContext-CRKFzsEB.d.mts +954 -0
- package/dist/MarkdownRendererContext-CRKFzsEB.d.mts.map +1 -0
- package/dist/MarkdownSurfaces-C2XZISKn.cjs +3964 -0
- package/dist/MarkdownSurfaces-C2XZISKn.cjs.map +1 -0
- package/dist/MarkdownSurfaces-ChSlVYOk.mjs +3655 -0
- package/dist/MarkdownSurfaces-ChSlVYOk.mjs.map +1 -0
- package/dist/context.cjs +144 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +166 -0
- package/dist/context.d.cts.map +1 -0
- package/dist/context.d.mts +166 -0
- package/dist/context.d.mts.map +1 -0
- package/dist/context.mjs +136 -0
- package/dist/context.mjs.map +1 -0
- package/dist/generative-ui.cjs +8151 -0
- package/dist/generative-ui.cjs.map +1 -0
- package/dist/generative-ui.d.cts +4952 -0
- package/dist/generative-ui.d.cts.map +1 -0
- package/dist/generative-ui.d.mts +4952 -0
- package/dist/generative-ui.d.mts.map +1 -0
- package/dist/generative-ui.mjs +8137 -0
- package/dist/generative-ui.mjs.map +1 -0
- package/dist/headless.cjs +1927 -0
- package/dist/headless.cjs.map +1 -0
- package/dist/headless.d.cts +1117 -0
- package/dist/headless.d.cts.map +1 -0
- package/dist/headless.d.mts +1008 -0
- package/dist/headless.d.mts.map +1 -0
- package/dist/headless.mjs +1869 -0
- package/dist/headless.mjs.map +1 -0
- package/dist/index.cjs +15576 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +2 -0
- package/dist/index.d.cts +3450 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +3433 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +13927 -146
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +18856 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +124 -52
- package/CHANGELOG.md +0 -4210
- package/dist/chunk-2IDV5OHF.mjs +0 -11
- package/dist/chunk-2IDV5OHF.mjs.map +0 -1
- package/dist/chunk-36KQV2NA.mjs +0 -1
- package/dist/chunk-36KQV2NA.mjs.map +0 -1
- package/dist/chunk-3V5TOYKW.mjs +0 -120
- package/dist/chunk-3V5TOYKW.mjs.map +0 -1
- package/dist/chunk-4CEQJ2X6.mjs +0 -31
- package/dist/chunk-4CEQJ2X6.mjs.map +0 -1
- package/dist/chunk-4RRMC7L2.mjs +0 -32
- package/dist/chunk-4RRMC7L2.mjs.map +0 -1
- package/dist/chunk-4YZA2BZC.mjs +0 -551
- package/dist/chunk-4YZA2BZC.mjs.map +0 -1
- package/dist/chunk-53K6WNJG.mjs +0 -36
- package/dist/chunk-53K6WNJG.mjs.map +0 -1
- package/dist/chunk-6ESSSQ7Q.mjs +0 -134
- package/dist/chunk-6ESSSQ7Q.mjs.map +0 -1
- package/dist/chunk-6PUNP7CD.mjs +0 -102
- package/dist/chunk-6PUNP7CD.mjs.map +0 -1
- package/dist/chunk-6YOKPWQ7.mjs +0 -1
- package/dist/chunk-6YOKPWQ7.mjs.map +0 -1
- package/dist/chunk-6ZLPNY7X.mjs +0 -225
- package/dist/chunk-6ZLPNY7X.mjs.map +0 -1
- package/dist/chunk-7DTB7S5V.mjs +0 -83
- package/dist/chunk-7DTB7S5V.mjs.map +0 -1
- package/dist/chunk-7IBF6RBW.mjs +0 -23
- package/dist/chunk-7IBF6RBW.mjs.map +0 -1
- package/dist/chunk-A6NKSGH3.mjs +0 -1
- package/dist/chunk-A6NKSGH3.mjs.map +0 -1
- package/dist/chunk-ABWT4DRT.mjs +0 -24
- package/dist/chunk-ABWT4DRT.mjs.map +0 -1
- package/dist/chunk-AFNWX62Q.mjs +0 -110
- package/dist/chunk-AFNWX62Q.mjs.map +0 -1
- package/dist/chunk-BUSWSDYO.mjs +0 -17
- package/dist/chunk-BUSWSDYO.mjs.map +0 -1
- package/dist/chunk-CDUIA2WM.mjs +0 -60
- package/dist/chunk-CDUIA2WM.mjs.map +0 -1
- package/dist/chunk-CYDWEPFL.mjs +0 -1
- package/dist/chunk-CYDWEPFL.mjs.map +0 -1
- package/dist/chunk-DMLQZG75.mjs +0 -25
- package/dist/chunk-DMLQZG75.mjs.map +0 -1
- package/dist/chunk-E7SE25ZU.mjs +0 -59
- package/dist/chunk-E7SE25ZU.mjs.map +0 -1
- package/dist/chunk-EFL5OBKN.mjs +0 -310
- package/dist/chunk-EFL5OBKN.mjs.map +0 -1
- package/dist/chunk-F555TVE4.mjs +0 -33
- package/dist/chunk-F555TVE4.mjs.map +0 -1
- package/dist/chunk-FD6FGKYY.mjs +0 -1
- package/dist/chunk-FD6FGKYY.mjs.map +0 -1
- package/dist/chunk-FDOMAPJY.mjs +0 -59
- package/dist/chunk-FDOMAPJY.mjs.map +0 -1
- package/dist/chunk-FQFXYAV7.mjs +0 -86
- package/dist/chunk-FQFXYAV7.mjs.map +0 -1
- package/dist/chunk-GPEJNVE5.mjs +0 -80
- package/dist/chunk-GPEJNVE5.mjs.map +0 -1
- package/dist/chunk-HE22TZMF.mjs +0 -186
- package/dist/chunk-HE22TZMF.mjs.map +0 -1
- package/dist/chunk-I76HKHPJ.mjs +0 -32
- package/dist/chunk-I76HKHPJ.mjs.map +0 -1
- package/dist/chunk-ICIK2BSB.mjs +0 -17
- package/dist/chunk-ICIK2BSB.mjs.map +0 -1
- package/dist/chunk-JD7BAH7U.mjs +0 -1
- package/dist/chunk-JD7BAH7U.mjs.map +0 -1
- package/dist/chunk-LHERIF3L.mjs +0 -83
- package/dist/chunk-LHERIF3L.mjs.map +0 -1
- package/dist/chunk-LSHFN2Y5.mjs +0 -349
- package/dist/chunk-LSHFN2Y5.mjs.map +0 -1
- package/dist/chunk-LUGEI4YQ.mjs +0 -1
- package/dist/chunk-LUGEI4YQ.mjs.map +0 -1
- package/dist/chunk-NB2FKV2V.mjs +0 -1
- package/dist/chunk-NB2FKV2V.mjs.map +0 -1
- package/dist/chunk-NBK4KBLX.mjs +0 -54
- package/dist/chunk-NBK4KBLX.mjs.map +0 -1
- package/dist/chunk-O7ARI5CV.mjs +0 -31
- package/dist/chunk-O7ARI5CV.mjs.map +0 -1
- package/dist/chunk-PIF5KJYI.mjs +0 -103
- package/dist/chunk-PIF5KJYI.mjs.map +0 -1
- package/dist/chunk-PMAFHQ7P.mjs +0 -65
- package/dist/chunk-PMAFHQ7P.mjs.map +0 -1
- package/dist/chunk-QNUAXSDP.mjs +0 -166
- package/dist/chunk-QNUAXSDP.mjs.map +0 -1
- package/dist/chunk-RKTVJRK7.mjs +0 -143
- package/dist/chunk-RKTVJRK7.mjs.map +0 -1
- package/dist/chunk-SKC7AJIV.mjs +0 -61
- package/dist/chunk-SKC7AJIV.mjs.map +0 -1
- package/dist/chunk-SPCZTZCY.mjs +0 -1
- package/dist/chunk-SPCZTZCY.mjs.map +0 -1
- package/dist/chunk-VV56AVPB.mjs +0 -125
- package/dist/chunk-VV56AVPB.mjs.map +0 -1
- package/dist/chunk-WF65O6HX.mjs +0 -66
- package/dist/chunk-WF65O6HX.mjs.map +0 -1
- package/dist/chunk-XDFVCQD3.mjs +0 -27
- package/dist/chunk-XDFVCQD3.mjs.map +0 -1
- package/dist/chunk-YCG6SNAU.mjs +0 -759
- package/dist/chunk-YCG6SNAU.mjs.map +0 -1
- package/dist/chunk-YTQHRJUA.mjs +0 -86
- package/dist/chunk-YTQHRJUA.mjs.map +0 -1
- package/dist/chunk-YYN33GSG.mjs +0 -73
- package/dist/chunk-YYN33GSG.mjs.map +0 -1
- package/dist/chunk-Z6JV2LRY.mjs +0 -37
- package/dist/chunk-Z6JV2LRY.mjs.map +0 -1
- package/dist/chunk-ZVF5Q6IH.mjs +0 -29
- package/dist/chunk-ZVF5Q6IH.mjs.map +0 -1
- package/dist/chunk-ZYTXB6HH.mjs +0 -151
- package/dist/chunk-ZYTXB6HH.mjs.map +0 -1
- package/dist/components/CopilotListeners.d.ts +0 -3
- package/dist/components/CopilotListeners.js +0 -101
- package/dist/components/CopilotListeners.js.map +0 -1
- package/dist/components/CopilotListeners.mjs +0 -9
- package/dist/components/CopilotListeners.mjs.map +0 -1
- package/dist/components/copilot-provider/copilot-messages.d.ts +0 -24
- package/dist/components/copilot-provider/copilot-messages.js +0 -351
- package/dist/components/copilot-provider/copilot-messages.js.map +0 -1
- package/dist/components/copilot-provider/copilot-messages.mjs +0 -16
- package/dist/components/copilot-provider/copilot-messages.mjs.map +0 -1
- package/dist/components/copilot-provider/copilotkit-props.d.ts +0 -160
- package/dist/components/copilot-provider/copilotkit-props.js +0 -19
- package/dist/components/copilot-provider/copilotkit-props.js.map +0 -1
- package/dist/components/copilot-provider/copilotkit-props.mjs +0 -1
- package/dist/components/copilot-provider/copilotkit-props.mjs.map +0 -1
- package/dist/components/copilot-provider/copilotkit.d.ts +0 -19
- package/dist/components/copilot-provider/copilotkit.js +0 -1960
- package/dist/components/copilot-provider/copilotkit.js.map +0 -1
- package/dist/components/copilot-provider/copilotkit.mjs +0 -31
- package/dist/components/copilot-provider/copilotkit.mjs.map +0 -1
- package/dist/components/copilot-provider/index.d.ts +0 -14
- package/dist/components/copilot-provider/index.js +0 -1960
- package/dist/components/copilot-provider/index.js.map +0 -1
- package/dist/components/copilot-provider/index.mjs +0 -30
- package/dist/components/copilot-provider/index.mjs.map +0 -1
- package/dist/components/dev-console/console-trigger.d.ts +0 -8
- package/dist/components/dev-console/console-trigger.js +0 -1202
- package/dist/components/dev-console/console-trigger.js.map +0 -1
- package/dist/components/dev-console/console-trigger.mjs +0 -233
- package/dist/components/dev-console/console-trigger.mjs.map +0 -1
- package/dist/components/dev-console/developer-console-modal.d.ts +0 -10
- package/dist/components/dev-console/developer-console-modal.js +0 -987
- package/dist/components/dev-console/developer-console-modal.js.map +0 -1
- package/dist/components/dev-console/developer-console-modal.mjs +0 -12
- package/dist/components/dev-console/developer-console-modal.mjs.map +0 -1
- package/dist/components/dev-console/icons.d.ts +0 -9
- package/dist/components/dev-console/icons.js +0 -131
- package/dist/components/dev-console/icons.js.map +0 -1
- package/dist/components/dev-console/icons.mjs +0 -16
- package/dist/components/dev-console/icons.mjs.map +0 -1
- package/dist/components/error-boundary/error-boundary.d.ts +0 -31
- package/dist/components/error-boundary/error-boundary.js +0 -500
- package/dist/components/error-boundary/error-boundary.js.map +0 -1
- package/dist/components/error-boundary/error-boundary.mjs +0 -15
- package/dist/components/error-boundary/error-boundary.mjs.map +0 -1
- package/dist/components/error-boundary/error-utils.d.ts +0 -11
- package/dist/components/error-boundary/error-utils.js +0 -190
- package/dist/components/error-boundary/error-utils.js.map +0 -1
- package/dist/components/error-boundary/error-utils.mjs +0 -14
- package/dist/components/error-boundary/error-utils.mjs.map +0 -1
- package/dist/components/index.d.ts +0 -14
- package/dist/components/index.js +0 -1960
- package/dist/components/index.js.map +0 -1
- package/dist/components/index.mjs +0 -31
- package/dist/components/index.mjs.map +0 -1
- package/dist/components/toast/exclamation-mark-icon.d.ts +0 -9
- package/dist/components/toast/exclamation-mark-icon.js +0 -55
- package/dist/components/toast/exclamation-mark-icon.js.map +0 -1
- package/dist/components/toast/exclamation-mark-icon.mjs +0 -8
- package/dist/components/toast/exclamation-mark-icon.mjs.map +0 -1
- package/dist/components/toast/toast-provider.d.ts +0 -27
- package/dist/components/toast/toast-provider.js +0 -347
- package/dist/components/toast/toast-provider.js.map +0 -1
- package/dist/components/toast/toast-provider.mjs +0 -10
- package/dist/components/toast/toast-provider.mjs.map +0 -1
- package/dist/components/usage-banner.d.ts +0 -29
- package/dist/components/usage-banner.js +0 -247
- package/dist/components/usage-banner.js.map +0 -1
- package/dist/components/usage-banner.mjs +0 -12
- package/dist/components/usage-banner.mjs.map +0 -1
- package/dist/context/coagent-state-renders-context.d.ts +0 -24
- package/dist/context/coagent-state-renders-context.js +0 -91
- package/dist/context/coagent-state-renders-context.js.map +0 -1
- package/dist/context/coagent-state-renders-context.mjs +0 -12
- package/dist/context/coagent-state-renders-context.mjs.map +0 -1
- package/dist/context/copilot-context.d.ts +0 -10
- package/dist/context/copilot-context.js +0 -161
- package/dist/context/copilot-context.js.map +0 -1
- package/dist/context/copilot-context.mjs +0 -10
- package/dist/context/copilot-context.mjs.map +0 -1
- package/dist/context/copilot-messages-context.d.ts +0 -18
- package/dist/context/copilot-messages-context.js +0 -60
- package/dist/context/copilot-messages-context.js.map +0 -1
- package/dist/context/copilot-messages-context.mjs +0 -10
- package/dist/context/copilot-messages-context.mjs.map +0 -1
- package/dist/context/index.d.ts +0 -15
- package/dist/context/index.js +0 -285
- package/dist/context/index.js.map +0 -1
- package/dist/context/index.mjs +0 -33
- package/dist/context/index.mjs.map +0 -1
- package/dist/context/threads-context.d.ts +0 -16
- package/dist/context/threads-context.js +0 -59
- package/dist/context/threads-context.js.map +0 -1
- package/dist/context/threads-context.mjs +0 -12
- package/dist/context/threads-context.mjs.map +0 -1
- package/dist/copilot-context-ec77e921.d.ts +0 -209
- package/dist/hooks/index.d.ts +0 -33
- package/dist/hooks/index.js +0 -1774
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/index.mjs +0 -91
- package/dist/hooks/index.mjs.map +0 -1
- package/dist/hooks/use-agent-nodename.d.ts +0 -3
- package/dist/hooks/use-agent-nodename.js +0 -56
- package/dist/hooks/use-agent-nodename.js.map +0 -1
- package/dist/hooks/use-agent-nodename.mjs +0 -8
- package/dist/hooks/use-agent-nodename.mjs.map +0 -1
- package/dist/hooks/use-coagent-state-render-bridge.d.ts +0 -100
- package/dist/hooks/use-coagent-state-render-bridge.js +0 -214
- package/dist/hooks/use-coagent-state-render-bridge.js.map +0 -1
- package/dist/hooks/use-coagent-state-render-bridge.mjs +0 -15
- package/dist/hooks/use-coagent-state-render-bridge.mjs.map +0 -1
- package/dist/hooks/use-coagent-state-render.d.ts +0 -55
- package/dist/hooks/use-coagent-state-render.js +0 -255
- package/dist/hooks/use-coagent-state-render.js.map +0 -1
- package/dist/hooks/use-coagent-state-render.mjs +0 -11
- package/dist/hooks/use-coagent-state-render.mjs.map +0 -1
- package/dist/hooks/use-coagent.d.ts +0 -192
- package/dist/hooks/use-coagent.js +0 -233
- package/dist/hooks/use-coagent.js.map +0 -1
- package/dist/hooks/use-coagent.mjs +0 -9
- package/dist/hooks/use-coagent.mjs.map +0 -1
- package/dist/hooks/use-configure-chat-suggestions.d.ts +0 -36
- package/dist/hooks/use-configure-chat-suggestions.js +0 -79
- package/dist/hooks/use-configure-chat-suggestions.js.map +0 -1
- package/dist/hooks/use-configure-chat-suggestions.mjs +0 -47
- package/dist/hooks/use-configure-chat-suggestions.mjs.map +0 -1
- package/dist/hooks/use-copilot-action.d.ts +0 -103
- package/dist/hooks/use-copilot-action.js +0 -295
- package/dist/hooks/use-copilot-action.js.map +0 -1
- package/dist/hooks/use-copilot-action.mjs +0 -11
- package/dist/hooks/use-copilot-action.mjs.map +0 -1
- package/dist/hooks/use-copilot-additional-instructions.d.ts +0 -26
- package/dist/hooks/use-copilot-additional-instructions.js +0 -177
- package/dist/hooks/use-copilot-additional-instructions.js.map +0 -1
- package/dist/hooks/use-copilot-additional-instructions.mjs +0 -9
- package/dist/hooks/use-copilot-additional-instructions.mjs.map +0 -1
- package/dist/hooks/use-copilot-authenticated-action.d.ts +0 -18
- package/dist/hooks/use-copilot-authenticated-action.js +0 -462
- package/dist/hooks/use-copilot-authenticated-action.js.map +0 -1
- package/dist/hooks/use-copilot-authenticated-action.mjs +0 -13
- package/dist/hooks/use-copilot-authenticated-action.mjs.map +0 -1
- package/dist/hooks/use-copilot-chat-headless_c.d.ts +0 -25
- package/dist/hooks/use-copilot-chat-headless_c.js +0 -1044
- package/dist/hooks/use-copilot-chat-headless_c.js.map +0 -1
- package/dist/hooks/use-copilot-chat-headless_c.mjs +0 -24
- package/dist/hooks/use-copilot-chat-headless_c.mjs.map +0 -1
- package/dist/hooks/use-copilot-chat-suggestions.d.ts +0 -35
- package/dist/hooks/use-copilot-chat-suggestions.js +0 -60
- package/dist/hooks/use-copilot-chat-suggestions.js.map +0 -1
- package/dist/hooks/use-copilot-chat-suggestions.mjs +0 -8
- package/dist/hooks/use-copilot-chat-suggestions.mjs.map +0 -1
- package/dist/hooks/use-copilot-chat.d.ts +0 -92
- package/dist/hooks/use-copilot-chat.js +0 -978
- package/dist/hooks/use-copilot-chat.js.map +0 -1
- package/dist/hooks/use-copilot-chat.mjs +0 -21
- package/dist/hooks/use-copilot-chat.mjs.map +0 -1
- package/dist/hooks/use-copilot-chat_internal.d.ts +0 -244
- package/dist/hooks/use-copilot-chat_internal.js +0 -976
- package/dist/hooks/use-copilot-chat_internal.js.map +0 -1
- package/dist/hooks/use-copilot-chat_internal.mjs +0 -22
- package/dist/hooks/use-copilot-chat_internal.mjs.map +0 -1
- package/dist/hooks/use-copilot-readable.d.ts +0 -37
- package/dist/hooks/use-copilot-readable.js +0 -61
- package/dist/hooks/use-copilot-readable.js.map +0 -1
- package/dist/hooks/use-copilot-readable.mjs +0 -8
- package/dist/hooks/use-copilot-readable.mjs.map +0 -1
- package/dist/hooks/use-copilot-runtime-client.d.ts +0 -10
- package/dist/hooks/use-copilot-runtime-client.js +0 -203
- package/dist/hooks/use-copilot-runtime-client.js.map +0 -1
- package/dist/hooks/use-copilot-runtime-client.mjs +0 -9
- package/dist/hooks/use-copilot-runtime-client.mjs.map +0 -1
- package/dist/hooks/use-default-tool.d.ts +0 -8
- package/dist/hooks/use-default-tool.js +0 -302
- package/dist/hooks/use-default-tool.js.map +0 -1
- package/dist/hooks/use-default-tool.mjs +0 -12
- package/dist/hooks/use-default-tool.mjs.map +0 -1
- package/dist/hooks/use-flat-category-store.d.ts +0 -9
- package/dist/hooks/use-flat-category-store.js +0 -93
- package/dist/hooks/use-flat-category-store.js.map +0 -1
- package/dist/hooks/use-flat-category-store.mjs +0 -8
- package/dist/hooks/use-flat-category-store.mjs.map +0 -1
- package/dist/hooks/use-frontend-tool.d.ts +0 -11
- package/dist/hooks/use-frontend-tool.js +0 -104
- package/dist/hooks/use-frontend-tool.js.map +0 -1
- package/dist/hooks/use-frontend-tool.mjs +0 -8
- package/dist/hooks/use-frontend-tool.mjs.map +0 -1
- package/dist/hooks/use-human-in-the-loop.d.ts +0 -13
- package/dist/hooks/use-human-in-the-loop.js +0 -122
- package/dist/hooks/use-human-in-the-loop.js.map +0 -1
- package/dist/hooks/use-human-in-the-loop.mjs +0 -8
- package/dist/hooks/use-human-in-the-loop.mjs.map +0 -1
- package/dist/hooks/use-langgraph-interrupt-render.d.ts +0 -6
- package/dist/hooks/use-langgraph-interrupt-render.js +0 -318
- package/dist/hooks/use-langgraph-interrupt-render.js.map +0 -1
- package/dist/hooks/use-langgraph-interrupt-render.mjs +0 -14
- package/dist/hooks/use-langgraph-interrupt-render.mjs.map +0 -1
- package/dist/hooks/use-langgraph-interrupt.d.ts +0 -14
- package/dist/hooks/use-langgraph-interrupt.js +0 -201
- package/dist/hooks/use-langgraph-interrupt.js.map +0 -1
- package/dist/hooks/use-langgraph-interrupt.mjs +0 -10
- package/dist/hooks/use-langgraph-interrupt.mjs.map +0 -1
- package/dist/hooks/use-lazy-tool-renderer.d.ts +0 -6
- package/dist/hooks/use-lazy-tool-renderer.js +0 -53
- package/dist/hooks/use-lazy-tool-renderer.js.map +0 -1
- package/dist/hooks/use-lazy-tool-renderer.mjs +0 -8
- package/dist/hooks/use-lazy-tool-renderer.mjs.map +0 -1
- package/dist/hooks/use-make-copilot-document-readable.d.ts +0 -12
- package/dist/hooks/use-make-copilot-document-readable.js +0 -176
- package/dist/hooks/use-make-copilot-document-readable.js.map +0 -1
- package/dist/hooks/use-make-copilot-document-readable.mjs +0 -9
- package/dist/hooks/use-make-copilot-document-readable.mjs.map +0 -1
- package/dist/hooks/use-render-tool-call.d.ts +0 -12
- package/dist/hooks/use-render-tool-call.js +0 -90
- package/dist/hooks/use-render-tool-call.js.map +0 -1
- package/dist/hooks/use-render-tool-call.mjs +0 -8
- package/dist/hooks/use-render-tool-call.mjs.map +0 -1
- package/dist/hooks/use-tree.d.ts +0 -19
- package/dist/hooks/use-tree.js +0 -175
- package/dist/hooks/use-tree.js.map +0 -1
- package/dist/hooks/use-tree.mjs +0 -8
- package/dist/hooks/use-tree.mjs.map +0 -1
- package/dist/index.d.ts +0 -43
- package/dist/index.js +0 -3528
- package/dist/index.js.map +0 -1
- package/dist/lib/copilot-task.d.ts +0 -97
- package/dist/lib/copilot-task.js +0 -194
- package/dist/lib/copilot-task.js.map +0 -1
- package/dist/lib/copilot-task.mjs +0 -31
- package/dist/lib/copilot-task.mjs.map +0 -1
- package/dist/lib/index.d.ts +0 -11
- package/dist/lib/index.js +0 -196
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/index.mjs +0 -32
- package/dist/lib/index.mjs.map +0 -1
- package/dist/lib/status-checker.d.ts +0 -17
- package/dist/lib/status-checker.js +0 -102
- package/dist/lib/status-checker.js.map +0 -1
- package/dist/lib/status-checker.mjs +0 -8
- package/dist/lib/status-checker.mjs.map +0 -1
- package/dist/setupTests.d.ts +0 -2
- package/dist/setupTests.js +0 -26
- package/dist/setupTests.js.map +0 -1
- package/dist/setupTests.mjs +0 -24
- package/dist/setupTests.mjs.map +0 -1
- package/dist/types/chat-suggestion-configuration.d.ts +0 -22
- package/dist/types/chat-suggestion-configuration.js +0 -19
- package/dist/types/chat-suggestion-configuration.js.map +0 -1
- package/dist/types/chat-suggestion-configuration.mjs +0 -1
- package/dist/types/chat-suggestion-configuration.mjs.map +0 -1
- package/dist/types/coagent-action.d.ts +0 -29
- package/dist/types/coagent-action.js +0 -19
- package/dist/types/coagent-action.js.map +0 -1
- package/dist/types/coagent-action.mjs +0 -1
- package/dist/types/coagent-action.mjs.map +0 -1
- package/dist/types/coagent-state.d.ts +0 -15
- package/dist/types/coagent-state.js +0 -19
- package/dist/types/coagent-state.js.map +0 -1
- package/dist/types/coagent-state.mjs +0 -1
- package/dist/types/coagent-state.mjs.map +0 -1
- package/dist/types/crew.d.ts +0 -79
- package/dist/types/crew.js +0 -19
- package/dist/types/crew.js.map +0 -1
- package/dist/types/crew.mjs +0 -2
- package/dist/types/crew.mjs.map +0 -1
- package/dist/types/document-pointer.d.ts +0 -9
- package/dist/types/document-pointer.js +0 -19
- package/dist/types/document-pointer.js.map +0 -1
- package/dist/types/document-pointer.mjs +0 -1
- package/dist/types/document-pointer.mjs.map +0 -1
- package/dist/types/frontend-action.d.ts +0 -127
- package/dist/types/frontend-action.js +0 -53
- package/dist/types/frontend-action.js.map +0 -1
- package/dist/types/frontend-action.mjs +0 -8
- package/dist/types/frontend-action.mjs.map +0 -1
- package/dist/types/index.d.ts +0 -12
- package/dist/types/index.js +0 -19
- package/dist/types/index.js.map +0 -1
- package/dist/types/index.mjs +0 -4
- package/dist/types/index.mjs.map +0 -1
- package/dist/types/interrupt-action.d.ts +0 -10
- package/dist/types/interrupt-action.js +0 -19
- package/dist/types/interrupt-action.js.map +0 -1
- package/dist/types/interrupt-action.mjs +0 -2
- package/dist/types/interrupt-action.mjs.map +0 -1
- package/dist/types/system-message.d.ts +0 -3
- package/dist/types/system-message.js +0 -19
- package/dist/types/system-message.js.map +0 -1
- package/dist/types/system-message.mjs +0 -1
- package/dist/types/system-message.mjs.map +0 -1
- package/dist/utils/dev-console.d.ts +0 -3
- package/dist/utils/dev-console.js +0 -41
- package/dist/utils/dev-console.js.map +0 -1
- package/dist/utils/dev-console.mjs +0 -8
- package/dist/utils/dev-console.mjs.map +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -52
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/index.mjs +0 -13
- package/dist/utils/index.mjs.map +0 -1
- package/dist/utils/suggestions-constants.d.ts +0 -9
- package/dist/utils/suggestions-constants.js +0 -35
- package/dist/utils/suggestions-constants.js.map +0 -1
- package/dist/utils/suggestions-constants.mjs +0 -8
- package/dist/utils/suggestions-constants.mjs.map +0 -1
- package/dist/utils/utils.d.ts +0 -2
- package/dist/utils/utils.js +0 -19
- package/dist/utils/utils.js.map +0 -1
- package/dist/utils/utils.mjs +0 -1
- package/dist/utils/utils.mjs.map +0 -1
- package/dist/v2/index.css +0 -4
- package/dist/v2/index.css.map +0 -1
- package/dist/v2/index.d.ts +0 -2
- package/dist/v2/index.js +0 -27
- package/dist/v2/index.js.map +0 -1
- package/dist/v2/index.mjs +0 -6
- package/dist/v2/index.mjs.map +0 -1
- package/jest.config.js +0 -25
- package/src/components/CopilotListeners.tsx +0 -81
- package/src/components/copilot-provider/__tests__/copilotkit-error.test.tsx +0 -75
- package/src/components/copilot-provider/copilot-messages.tsx +0 -274
- package/src/components/copilot-provider/copilotkit-props.tsx +0 -169
- package/src/components/copilot-provider/copilotkit.tsx +0 -671
- package/src/components/copilot-provider/index.ts +0 -3
- package/src/components/dev-console/console-trigger.tsx +0 -254
- package/src/components/dev-console/developer-console-modal.tsx +0 -866
- package/src/components/dev-console/icons.tsx +0 -101
- package/src/components/error-boundary/error-boundary.tsx +0 -91
- package/src/components/error-boundary/error-utils.tsx +0 -100
- package/src/components/index.ts +0 -1
- package/src/components/toast/exclamation-mark-icon.tsx +0 -27
- package/src/components/toast/toast-provider.tsx +0 -363
- package/src/components/usage-banner.tsx +0 -259
- package/src/context/coagent-state-renders-context.tsx +0 -76
- package/src/context/copilot-context.tsx +0 -332
- package/src/context/copilot-messages-context.tsx +0 -35
- package/src/context/index.ts +0 -16
- package/src/context/threads-context.tsx +0 -41
- package/src/hooks/__tests__/use-coagent-config.test.ts +0 -351
- package/src/hooks/index.ts +0 -34
- package/src/hooks/use-agent-nodename.ts +0 -30
- package/src/hooks/use-coagent-state-render-bridge.tsx +0 -293
- package/src/hooks/use-coagent-state-render.ts +0 -152
- package/src/hooks/use-coagent.ts +0 -366
- package/src/hooks/use-configure-chat-suggestions.tsx +0 -86
- package/src/hooks/use-copilot-action.ts +0 -236
- package/src/hooks/use-copilot-additional-instructions.ts +0 -85
- package/src/hooks/use-copilot-authenticated-action.ts +0 -70
- package/src/hooks/use-copilot-chat-headless_c.ts +0 -258
- package/src/hooks/use-copilot-chat-suggestions.tsx +0 -124
- package/src/hooks/use-copilot-chat.ts +0 -130
- package/src/hooks/use-copilot-chat_internal.ts +0 -696
- package/src/hooks/use-copilot-readable.ts +0 -135
- package/src/hooks/use-copilot-runtime-client.ts +0 -164
- package/src/hooks/use-default-tool.ts +0 -7
- package/src/hooks/use-flat-category-store.ts +0 -105
- package/src/hooks/use-frontend-tool.ts +0 -96
- package/src/hooks/use-human-in-the-loop.ts +0 -122
- package/src/hooks/use-langgraph-interrupt-render.ts +0 -136
- package/src/hooks/use-langgraph-interrupt.ts +0 -36
- package/src/hooks/use-lazy-tool-renderer.tsx +0 -30
- package/src/hooks/use-make-copilot-document-readable.ts +0 -30
- package/src/hooks/use-render-tool-call.ts +0 -80
- package/src/hooks/use-tree.ts +0 -207
- package/src/index.tsx +0 -7
- package/src/lib/copilot-task.ts +0 -201
- package/src/lib/index.ts +0 -1
- package/src/lib/status-checker.ts +0 -64
- package/src/setupTests.ts +0 -26
- package/src/types/chat-suggestion-configuration.ts +0 -23
- package/src/types/coagent-action.ts +0 -31
- package/src/types/coagent-state.ts +0 -13
- package/src/types/crew.ts +0 -89
- package/src/types/document-pointer.ts +0 -7
- package/src/types/frontend-action.ts +0 -202
- package/src/types/index.ts +0 -17
- package/src/types/interrupt-action.ts +0 -43
- package/src/types/system-message.ts +0 -4
- package/src/utils/dev-console.ts +0 -19
- package/src/utils/index.ts +0 -2
- package/src/utils/suggestions-constants.ts +0 -8
- package/src/utils/utils.test.ts +0 -7
- package/src/utils/utils.ts +0 -8
- package/src/v2/index.css +0 -1
- package/src/v2/index.ts +0 -4
- package/tsconfig.json +0 -8
- package/tsup.config.ts +0 -16
- package/typedoc.json +0 -4
|
@@ -0,0 +1,1927 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: ((k) => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
let _copilotkit_react_core_context = require("@copilotkit/react-core/context");
|
|
30
|
+
let react = require("react");
|
|
31
|
+
react = __toESM(react);
|
|
32
|
+
let _copilotkit_shared = require("@copilotkit/shared");
|
|
33
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
34
|
+
let _copilotkit_core = require("@copilotkit/core");
|
|
35
|
+
let _ag_ui_client = require("@ag-ui/client");
|
|
36
|
+
let zod = require("zod");
|
|
37
|
+
let _ag_ui_core = require("@ag-ui/core");
|
|
38
|
+
|
|
39
|
+
//#region src/lib/shallow-stable-ref.ts
|
|
40
|
+
/**
|
|
41
|
+
* Shallow equality comparison for objects.
|
|
42
|
+
*/
|
|
43
|
+
function shallowEqual(obj1, obj2) {
|
|
44
|
+
const keys1 = Object.keys(obj1);
|
|
45
|
+
const keys2 = Object.keys(obj2);
|
|
46
|
+
if (keys1.length !== keys2.length) return false;
|
|
47
|
+
for (const key of keys1) if (obj1[key] !== obj2[key]) return false;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
|
|
52
|
+
* class instances, and other exotic objects that happen to have typeof "object".
|
|
53
|
+
*/
|
|
54
|
+
function isPlainObject$1(obj) {
|
|
55
|
+
return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the same reference as long as the value is shallowly equal to the
|
|
59
|
+
* previous render's value.
|
|
60
|
+
*
|
|
61
|
+
* - Identical references bail out immediately (O(1)).
|
|
62
|
+
* - Plain objects ({}) are shallow-compared key-by-key.
|
|
63
|
+
* - Arrays, Dates, class instances, functions, and primitives are compared by
|
|
64
|
+
* reference only — shallowEqual is never called on non-plain objects, which
|
|
65
|
+
* avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).
|
|
66
|
+
*
|
|
67
|
+
* Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow
|
|
68
|
+
* equality check isn't defeated by a new object reference on every render.
|
|
69
|
+
*/
|
|
70
|
+
function useShallowStableRef(value) {
|
|
71
|
+
const ref = (0, react.useRef)(value);
|
|
72
|
+
if (ref.current === value) return ref.current;
|
|
73
|
+
if (isPlainObject$1(ref.current) && isPlainObject$1(value)) {
|
|
74
|
+
if (shallowEqual(ref.current, value)) return ref.current;
|
|
75
|
+
}
|
|
76
|
+
ref.current = value;
|
|
77
|
+
return ref.current;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/providers/CopilotChatConfigurationProvider.tsx
|
|
82
|
+
const CopilotChatDefaultLabels = {
|
|
83
|
+
chatInputPlaceholder: "Type a message...",
|
|
84
|
+
chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
|
|
85
|
+
chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
|
|
86
|
+
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
|
87
|
+
chatInputToolbarAddButtonLabel: "Add attachments",
|
|
88
|
+
chatInputToolbarToolsButtonLabel: "Tools",
|
|
89
|
+
chatInputToolbarSendButtonLabel: "Send message",
|
|
90
|
+
chatInputToolbarStopButtonLabel: "Stop",
|
|
91
|
+
assistantMessageToolbarCopyCodeLabel: "Copy",
|
|
92
|
+
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
|
93
|
+
assistantMessageToolbarCopyMessageLabel: "Copy",
|
|
94
|
+
assistantMessageToolbarInspectorLabel: "View in Inspector",
|
|
95
|
+
assistantMessageToolbarInspectorDescription: "Open this message in the Inspector",
|
|
96
|
+
assistantMessageToolbarInspectorLocalOnlyLabel: "Local only",
|
|
97
|
+
assistantMessageToolbarInspectorLocalOnlyDescription: "Only visible on localhost or loopback hosts in development. Never shown in production.",
|
|
98
|
+
assistantMessageToolbarInspectorTitle: "CopilotKit Inspector",
|
|
99
|
+
assistantMessageToolbarInspectorHideLabel: "Hide this icon",
|
|
100
|
+
assistantMessageToolbarInspectorHideDescription: "Until you reload this page",
|
|
101
|
+
assistantMessageToolbarThumbsUpLabel: "Good response",
|
|
102
|
+
assistantMessageToolbarThumbsDownLabel: "Bad response",
|
|
103
|
+
assistantMessageFeedbackCommentPlaceholder: "Add a comment (optional)",
|
|
104
|
+
assistantMessageFeedbackCommentSubmitLabel: "Send comment",
|
|
105
|
+
assistantMessageToolbarReadAloudLabel: "Read aloud",
|
|
106
|
+
assistantMessageToolbarRegenerateLabel: "Regenerate",
|
|
107
|
+
userMessageToolbarCopyMessageLabel: "Copy",
|
|
108
|
+
userMessageToolbarEditMessageLabel: "Edit",
|
|
109
|
+
userMessageToolbarPreviousBranchLabel: "Previous branch",
|
|
110
|
+
userMessageToolbarNextBranchLabel: "Next branch",
|
|
111
|
+
chatDisclaimerText: "AI can make mistakes. Please verify important information.",
|
|
112
|
+
chatToggleOpenLabel: "Open chat",
|
|
113
|
+
chatToggleCloseLabel: "Close chat",
|
|
114
|
+
chatScrollToBottomLabel: "Scroll to bottom",
|
|
115
|
+
modalHeaderTitle: "CopilotKit Chat",
|
|
116
|
+
welcomeMessageText: "How can I help you today?",
|
|
117
|
+
reasoningMessageThinkingLabel: "Thinking…",
|
|
118
|
+
chatInputSlashMenuLabel: "Slash commands",
|
|
119
|
+
chatInputSlashMenuEmptyText: "No commands found",
|
|
120
|
+
attachmentRemoveButtonLabel: "Remove attachment",
|
|
121
|
+
attachmentPlayVideoButtonLabel: "Play video",
|
|
122
|
+
attachmentPreviewCloseButtonLabel: "Close preview",
|
|
123
|
+
modalHeaderCloseButtonLabel: "Close",
|
|
124
|
+
modalHeaderThreadsButtonLabel: "Open threads",
|
|
125
|
+
sidebarLabel: "Copilot chat sidebar"
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Mobile breakpoint below which the chat modal and the thread-list drawer are
|
|
129
|
+
* mutually exclusive. At or above this width both surfaces may coexist. This
|
|
130
|
+
* mirrors the `(max-width: 767px)` / `(min-width: 768px)` split already used by
|
|
131
|
+
* CopilotChatInput and CopilotSidebarView.
|
|
132
|
+
*/
|
|
133
|
+
const MOBILE_MAX_WIDTH_PX = 767;
|
|
134
|
+
/**
|
|
135
|
+
* Reports whether the current viewport is in the mobile range (`<768px`), where
|
|
136
|
+
* the chat modal and drawer must not be open simultaneously. SSR-safe and
|
|
137
|
+
* defensive against environments without `matchMedia` (treated as desktop, so
|
|
138
|
+
* no mutual-exclusion constraint is applied).
|
|
139
|
+
*
|
|
140
|
+
* @returns `true` when the viewport is mobile-width, `false` otherwise.
|
|
141
|
+
*/
|
|
142
|
+
function isMobileViewport() {
|
|
143
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
144
|
+
return window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH_PX}px)`).matches;
|
|
145
|
+
}
|
|
146
|
+
const CopilotChatConfiguration = (0, react.createContext)(null);
|
|
147
|
+
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, hasExplicitThreadId, isModalDefaultOpen }) => {
|
|
148
|
+
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
149
|
+
const stableLabels = useShallowStableRef(labels);
|
|
150
|
+
const mergedLabels = (0, react.useMemo)(() => ({
|
|
151
|
+
...CopilotChatDefaultLabels,
|
|
152
|
+
...parentConfig?.labels,
|
|
153
|
+
...stableLabels
|
|
154
|
+
}), [stableLabels, parentConfig?.labels]);
|
|
155
|
+
const providerAgentId = (0, _copilotkit_react_core_context.useDefaultAgentId)();
|
|
156
|
+
const resolvedAgentId = agentId ?? parentConfig?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
157
|
+
const threadIdPropIsAuthoritative = threadId !== void 0 && hasExplicitThreadId !== false;
|
|
158
|
+
const isThreadIdControlled = threadIdPropIsAuthoritative;
|
|
159
|
+
const [activeThreadOverride, setActiveThreadOverride] = (0, react.useState)(null);
|
|
160
|
+
const resolvedThreadId = (0, react.useMemo)(() => {
|
|
161
|
+
if (threadIdPropIsAuthoritative) return threadId;
|
|
162
|
+
if (activeThreadOverride) return activeThreadOverride.threadId;
|
|
163
|
+
if (parentConfig?.threadId) return parentConfig.threadId;
|
|
164
|
+
if (threadId) return threadId;
|
|
165
|
+
return (0, _copilotkit_shared.randomUUID)();
|
|
166
|
+
}, [
|
|
167
|
+
threadIdPropIsAuthoritative,
|
|
168
|
+
threadId,
|
|
169
|
+
parentConfig?.threadId,
|
|
170
|
+
activeThreadOverride
|
|
171
|
+
]);
|
|
172
|
+
const copilotkit = (0, react.useContext)(_copilotkit_react_core_context.CopilotKitContext)?.copilotkit;
|
|
173
|
+
const openThreadRef = (0, react.useRef)(null);
|
|
174
|
+
const latestThreadIdRef = (0, react.useRef)(resolvedThreadId);
|
|
175
|
+
latestThreadIdRef.current = resolvedThreadId;
|
|
176
|
+
(0, react.useEffect)(() => {
|
|
177
|
+
if (copilotkit === void 0) return;
|
|
178
|
+
const registration = copilotkit.registerOpenThread({
|
|
179
|
+
agentId: resolvedAgentId,
|
|
180
|
+
threadId: latestThreadIdRef.current
|
|
181
|
+
});
|
|
182
|
+
openThreadRef.current = registration;
|
|
183
|
+
return () => {
|
|
184
|
+
registration.unregister();
|
|
185
|
+
openThreadRef.current = null;
|
|
186
|
+
};
|
|
187
|
+
}, [copilotkit, resolvedAgentId]);
|
|
188
|
+
(0, react.useEffect)(() => {
|
|
189
|
+
openThreadRef.current?.update(resolvedThreadId);
|
|
190
|
+
}, [resolvedThreadId]);
|
|
191
|
+
const resolvedHasExplicitThreadId = (threadIdPropIsAuthoritative ? true : activeThreadOverride?.explicit ?? hasExplicitThreadId ?? false) || !!parentConfig?.hasExplicitThreadId;
|
|
192
|
+
const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen ?? true);
|
|
193
|
+
const hasExplicitDefault = isModalDefaultOpen !== void 0;
|
|
194
|
+
const setAndSync = (0, react.useCallback)((open) => {
|
|
195
|
+
setInternalModalOpen(open);
|
|
196
|
+
parentConfig?.setModalOpen(open);
|
|
197
|
+
}, [parentConfig?.setModalOpen]);
|
|
198
|
+
const isMounted = (0, react.useRef)(false);
|
|
199
|
+
(0, react.useEffect)(() => {
|
|
200
|
+
if (!hasExplicitDefault) return;
|
|
201
|
+
if (!isMounted.current) {
|
|
202
|
+
isMounted.current = true;
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (parentConfig?.isModalOpen === void 0) return;
|
|
206
|
+
setInternalModalOpen(parentConfig.isModalOpen);
|
|
207
|
+
}, [parentConfig?.isModalOpen, hasExplicitDefault]);
|
|
208
|
+
const resolvedIsModalOpen = hasExplicitDefault ? internalModalOpen : parentConfig?.isModalOpen ?? internalModalOpen;
|
|
209
|
+
const resolvedSetModalOpen = hasExplicitDefault ? setAndSync : parentConfig?.setModalOpen ?? setInternalModalOpen;
|
|
210
|
+
const [ownDrawerOpen, setOwnDrawerOpen] = (0, react.useState)(false);
|
|
211
|
+
const [ownDrawerCount, setOwnDrawerCount] = (0, react.useState)(0);
|
|
212
|
+
const modalCloseRef = (0, react.useRef)(() => {});
|
|
213
|
+
modalCloseRef.current = resolvedSetModalOpen;
|
|
214
|
+
const registeredModalClosersRef = (0, react.useRef)([]);
|
|
215
|
+
const ownRegisterModalCloser = (0, react.useCallback)((closeModal) => {
|
|
216
|
+
registeredModalClosersRef.current.push(closeModal);
|
|
217
|
+
return () => {
|
|
218
|
+
registeredModalClosersRef.current = registeredModalClosersRef.current.filter((entry) => entry !== closeModal);
|
|
219
|
+
};
|
|
220
|
+
}, []);
|
|
221
|
+
const ownSetDrawerOpen = (0, react.useCallback)((open) => {
|
|
222
|
+
setOwnDrawerOpen(open);
|
|
223
|
+
if (open && isMobileViewport()) {
|
|
224
|
+
const registered = registeredModalClosersRef.current;
|
|
225
|
+
(registered.length > 0 ? registered[registered.length - 1] : modalCloseRef.current)(false);
|
|
226
|
+
}
|
|
227
|
+
}, []);
|
|
228
|
+
const ownRegisterDrawer = (0, react.useCallback)(() => {
|
|
229
|
+
setOwnDrawerCount((count) => count + 1);
|
|
230
|
+
return () => {
|
|
231
|
+
setOwnDrawerCount((count) => Math.max(0, count - 1));
|
|
232
|
+
};
|
|
233
|
+
}, []);
|
|
234
|
+
const resolvedDrawerOpen = parentConfig ? parentConfig.drawerOpen : ownDrawerOpen;
|
|
235
|
+
const resolvedSetDrawerOpen = parentConfig ? parentConfig.setDrawerOpen : ownSetDrawerOpen;
|
|
236
|
+
const resolvedDrawerRegistered = parentConfig ? parentConfig.drawerRegistered : ownDrawerCount > 0;
|
|
237
|
+
const resolvedRegisterDrawer = parentConfig ? parentConfig.registerDrawer : ownRegisterDrawer;
|
|
238
|
+
const resolvedRegisterModalCloser = parentConfig ? parentConfig.ɵregisterModalCloser : ownRegisterModalCloser;
|
|
239
|
+
(0, react.useEffect)(() => {
|
|
240
|
+
if (!hasExplicitDefault) return;
|
|
241
|
+
return resolvedRegisterModalCloser(resolvedSetModalOpen);
|
|
242
|
+
}, [
|
|
243
|
+
hasExplicitDefault,
|
|
244
|
+
resolvedRegisterModalCloser,
|
|
245
|
+
resolvedSetModalOpen
|
|
246
|
+
]);
|
|
247
|
+
const isThreadIdControlledRef = (0, react.useRef)(isThreadIdControlled);
|
|
248
|
+
isThreadIdControlledRef.current = isThreadIdControlled;
|
|
249
|
+
const ownSetActiveThreadId = (0, react.useCallback)((id, options) => {
|
|
250
|
+
setActiveThreadOverride({
|
|
251
|
+
threadId: id,
|
|
252
|
+
explicit: options?.explicit ?? true
|
|
253
|
+
});
|
|
254
|
+
}, []);
|
|
255
|
+
const ownStartNewThread = (0, react.useCallback)(() => {
|
|
256
|
+
setActiveThreadOverride({
|
|
257
|
+
threadId: (0, _copilotkit_shared.randomUUID)(),
|
|
258
|
+
explicit: false
|
|
259
|
+
});
|
|
260
|
+
}, []);
|
|
261
|
+
const parentSetActiveThreadId = parentConfig?.setActiveThreadId;
|
|
262
|
+
const parentStartNewThread = parentConfig?.startNewThread;
|
|
263
|
+
const resolvedSetActiveThreadId = (0, react.useCallback)((id, options) => {
|
|
264
|
+
if (isThreadIdControlledRef.current) {
|
|
265
|
+
console.warn("[CopilotKit] Ignoring setActiveThreadId(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (parentSetActiveThreadId) {
|
|
269
|
+
parentSetActiveThreadId(id, options);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
ownSetActiveThreadId(id, options);
|
|
273
|
+
}, [parentSetActiveThreadId, ownSetActiveThreadId]);
|
|
274
|
+
const resolvedStartNewThread = (0, react.useCallback)(() => {
|
|
275
|
+
if (isThreadIdControlledRef.current) {
|
|
276
|
+
console.warn("[CopilotKit] Ignoring startNewThread(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (parentStartNewThread) {
|
|
280
|
+
parentStartNewThread();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
ownStartNewThread();
|
|
284
|
+
}, [parentStartNewThread, ownStartNewThread]);
|
|
285
|
+
const setModalOpenWithDrawerExclusion = (0, react.useCallback)((open) => {
|
|
286
|
+
if (open && isMobileViewport()) resolvedSetDrawerOpen(false);
|
|
287
|
+
resolvedSetModalOpen(open);
|
|
288
|
+
}, [resolvedSetModalOpen, resolvedSetDrawerOpen]);
|
|
289
|
+
const configurationValue = (0, react.useMemo)(() => ({
|
|
290
|
+
labels: mergedLabels,
|
|
291
|
+
agentId: resolvedAgentId,
|
|
292
|
+
threadId: resolvedThreadId,
|
|
293
|
+
hasExplicitThreadId: resolvedHasExplicitThreadId,
|
|
294
|
+
isModalOpen: resolvedIsModalOpen,
|
|
295
|
+
setModalOpen: setModalOpenWithDrawerExclusion,
|
|
296
|
+
drawerOpen: resolvedDrawerOpen,
|
|
297
|
+
setDrawerOpen: resolvedSetDrawerOpen,
|
|
298
|
+
drawerRegistered: resolvedDrawerRegistered,
|
|
299
|
+
registerDrawer: resolvedRegisterDrawer,
|
|
300
|
+
ɵregisterModalCloser: resolvedRegisterModalCloser,
|
|
301
|
+
setActiveThreadId: resolvedSetActiveThreadId,
|
|
302
|
+
startNewThread: resolvedStartNewThread
|
|
303
|
+
}), [
|
|
304
|
+
mergedLabels,
|
|
305
|
+
resolvedAgentId,
|
|
306
|
+
resolvedThreadId,
|
|
307
|
+
resolvedHasExplicitThreadId,
|
|
308
|
+
resolvedIsModalOpen,
|
|
309
|
+
setModalOpenWithDrawerExclusion,
|
|
310
|
+
resolvedDrawerOpen,
|
|
311
|
+
resolvedSetDrawerOpen,
|
|
312
|
+
resolvedDrawerRegistered,
|
|
313
|
+
resolvedRegisterDrawer,
|
|
314
|
+
resolvedRegisterModalCloser,
|
|
315
|
+
resolvedSetActiveThreadId,
|
|
316
|
+
resolvedStartNewThread
|
|
317
|
+
]);
|
|
318
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
|
|
319
|
+
value: configurationValue,
|
|
320
|
+
children
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
const useCopilotChatConfiguration = () => {
|
|
324
|
+
return (0, react.useContext)(CopilotChatConfiguration);
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* Reports modal open/close requests to the host, and — when `open` is
|
|
328
|
+
* supplied — makes the modal state of an already-established chat
|
|
329
|
+
* configuration **controlled** for the subtree it wraps.
|
|
330
|
+
*
|
|
331
|
+
* This is deliberately a scope component rather than another mode inside
|
|
332
|
+
* {@link CopilotChatConfigurationProvider}. The provider resolves modal state
|
|
333
|
+
* across a nested chain (own state, parent sync, drawer mutual-exclusion, the
|
|
334
|
+
* modal-closer registry); a controlled branch inside that resolution would add
|
|
335
|
+
* a fourth interacting mode. Overriding the context for the subtree instead
|
|
336
|
+
* leaves every one of those paths untouched:
|
|
337
|
+
*
|
|
338
|
+
* - `isModalOpen` is replaced with the host's `open`, so the rendered surface
|
|
339
|
+
* follows the prop from the very first frame (no open-then-close flash).
|
|
340
|
+
* - `setModalOpen` still calls the underlying setter, so the existing
|
|
341
|
+
* parent-sync and drawer mutual-exclusion side effects continue to run, and
|
|
342
|
+
* *then* reports the request through `onOpenChange`.
|
|
343
|
+
* - The wrapped setter is registered as the modal closer, so the drawer's
|
|
344
|
+
* mobile mutual-exclusion reaches the host instead of silently flipping
|
|
345
|
+
* state that nothing displays.
|
|
346
|
+
*
|
|
347
|
+
* A host that supplies `open` and ignores `onOpenChange` gets a modal pinned
|
|
348
|
+
* to `open`, which is the standard controlled-component contract. A host that
|
|
349
|
+
* supplies only `onOpenChange` is notified while the modal keeps managing
|
|
350
|
+
* itself.
|
|
351
|
+
*
|
|
352
|
+
* Renders `children` unchanged when no chat configuration is in scope.
|
|
353
|
+
*/
|
|
354
|
+
const ControlledModalOpenScope = ({ children, open, onOpenChange }) => {
|
|
355
|
+
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
356
|
+
const parentSetModalOpen = parentConfig?.setModalOpen;
|
|
357
|
+
const registerModalCloser = parentConfig?.ɵregisterModalCloser;
|
|
358
|
+
const setModalOpen = (0, react.useCallback)((next) => {
|
|
359
|
+
parentSetModalOpen?.(next);
|
|
360
|
+
onOpenChange?.(next);
|
|
361
|
+
}, [parentSetModalOpen, onOpenChange]);
|
|
362
|
+
(0, react.useEffect)(() => {
|
|
363
|
+
if (!registerModalCloser) return;
|
|
364
|
+
return registerModalCloser(setModalOpen);
|
|
365
|
+
}, [registerModalCloser, setModalOpen]);
|
|
366
|
+
const configurationValue = (0, react.useMemo)(() => parentConfig ? {
|
|
367
|
+
...parentConfig,
|
|
368
|
+
isModalOpen: open ?? parentConfig.isModalOpen,
|
|
369
|
+
setModalOpen
|
|
370
|
+
} : null, [
|
|
371
|
+
parentConfig,
|
|
372
|
+
open,
|
|
373
|
+
setModalOpen
|
|
374
|
+
]);
|
|
375
|
+
if (!configurationValue) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
376
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
|
|
377
|
+
value: configurationValue,
|
|
378
|
+
children
|
|
379
|
+
});
|
|
380
|
+
};
|
|
381
|
+
ControlledModalOpenScope.displayName = "ControlledModalOpenScope";
|
|
382
|
+
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region src/hooks/use-agent.tsx
|
|
385
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
386
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
387
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
388
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
389
|
+
return UseAgentUpdate;
|
|
390
|
+
}({});
|
|
391
|
+
const ALL_UPDATES = [
|
|
392
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
393
|
+
UseAgentUpdate.OnStateChanged,
|
|
394
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
395
|
+
];
|
|
396
|
+
function useAgent({ agentId, threadId, runtimeAgentId, updates, throttleMs } = {}) {
|
|
397
|
+
if (threadId != null && runtimeAgentId == null) throw new Error(`useAgent: \`threadId\` requires \`runtimeAgentId\`. A threadId is written onto a single agent, but an agent resolved by agentId alone is shared, so scoping a thread to it would clobber other useAgent callers. Pass a distinct local \`agentId\` and the runtime agent to route to, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${agentId ?? "default"}", threadId }).`);
|
|
398
|
+
if (runtimeAgentId != null && threadId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires \`threadId\`. A proxied agent exists to scope a thread to a private instance; without a threadId it behaves like the shared agent while adding a registration and a local agentId to keep unique. Either pass the thread, e.g. useAgent({ agentId: "${agentId ?? "chat-1"}", runtimeAgentId: "${runtimeAgentId}", threadId }), or bind to the agent directly with useAgent({ agentId: "${runtimeAgentId}" }).`);
|
|
399
|
+
if (runtimeAgentId != null && agentId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires an explicit \`agentId\`. The proxied agent is registered under \`agentId\`, and the usual fallbacks (chat configuration, then "${_copilotkit_shared.DEFAULT_AGENT_ID}") name agents that already exist — registering over one throws or shadows it. Pick a local id for this hook, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${runtimeAgentId}", threadId }).`);
|
|
400
|
+
const chatConfig = useCopilotChatConfiguration();
|
|
401
|
+
const providerAgentId = (0, _copilotkit_react_core_context.useDefaultAgentId)();
|
|
402
|
+
const resolvedAgentId = agentId ?? chatConfig?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
403
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
404
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
405
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
406
|
+
const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
407
|
+
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
408
|
+
const [registeredProxyAgent, setRegisteredProxyAgent] = (0, react.useState)(null);
|
|
409
|
+
(0, react.useEffect)(() => {
|
|
410
|
+
if (runtimeAgentId == null) {
|
|
411
|
+
setRegisteredProxyAgent(null);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
const { agent: proxy, unregister } = copilotkit.registerProxiedAgent({
|
|
415
|
+
agentId: resolvedAgentId,
|
|
416
|
+
runtimeAgentId
|
|
417
|
+
});
|
|
418
|
+
provisionalAgentCache.current.delete(resolvedAgentId);
|
|
419
|
+
setRegisteredProxyAgent(proxy);
|
|
420
|
+
return () => {
|
|
421
|
+
unregister();
|
|
422
|
+
setRegisteredProxyAgent(null);
|
|
423
|
+
};
|
|
424
|
+
}, [
|
|
425
|
+
copilotkit,
|
|
426
|
+
resolvedAgentId,
|
|
427
|
+
runtimeAgentId
|
|
428
|
+
]);
|
|
429
|
+
const { agent, isReady } = (0, react.useMemo)(() => {
|
|
430
|
+
if (runtimeAgentId != null) {
|
|
431
|
+
if (registeredProxyAgent) {
|
|
432
|
+
provisionalAgentCache.current.delete(resolvedAgentId);
|
|
433
|
+
return {
|
|
434
|
+
agent: registeredProxyAgent,
|
|
435
|
+
isReady: true
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
const cached = provisionalAgentCache.current.get(resolvedAgentId);
|
|
439
|
+
if (cached) {
|
|
440
|
+
copilotkit.applyHeadersToAgent(cached);
|
|
441
|
+
return {
|
|
442
|
+
agent: cached,
|
|
443
|
+
isReady: false
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
447
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
448
|
+
agentId: resolvedAgentId,
|
|
449
|
+
runtimeAgentId,
|
|
450
|
+
transport: copilotkit.runtimeTransport,
|
|
451
|
+
runtimeMode: "pending"
|
|
452
|
+
});
|
|
453
|
+
copilotkit.applyHeadersToAgent(provisional);
|
|
454
|
+
provisionalAgentCache.current.set(resolvedAgentId, provisional);
|
|
455
|
+
return {
|
|
456
|
+
agent: provisional,
|
|
457
|
+
isReady: false
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
const existing = copilotkit.getAgent(resolvedAgentId);
|
|
461
|
+
if (existing) {
|
|
462
|
+
provisionalAgentCache.current.delete(resolvedAgentId);
|
|
463
|
+
return {
|
|
464
|
+
agent: existing,
|
|
465
|
+
isReady: true
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
469
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
470
|
+
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
471
|
+
const cached = provisionalAgentCache.current.get(resolvedAgentId);
|
|
472
|
+
if (cached) return {
|
|
473
|
+
agent: cached,
|
|
474
|
+
isReady: false
|
|
475
|
+
};
|
|
476
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
477
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
478
|
+
agentId: resolvedAgentId,
|
|
479
|
+
transport: copilotkit.runtimeTransport,
|
|
480
|
+
credentials: copilotkit.credentials,
|
|
481
|
+
runtimeMode: "pending"
|
|
482
|
+
});
|
|
483
|
+
copilotkit.applyHeadersToAgent(provisional);
|
|
484
|
+
provisionalAgentCache.current.set(resolvedAgentId, provisional);
|
|
485
|
+
return {
|
|
486
|
+
agent: provisional,
|
|
487
|
+
isReady: false
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
491
|
+
const cached = provisionalAgentCache.current.get(resolvedAgentId);
|
|
492
|
+
if (cached) return {
|
|
493
|
+
agent: cached,
|
|
494
|
+
isReady: false
|
|
495
|
+
};
|
|
496
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
497
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
498
|
+
agentId: resolvedAgentId,
|
|
499
|
+
transport: copilotkit.runtimeTransport,
|
|
500
|
+
credentials: copilotkit.credentials,
|
|
501
|
+
runtimeMode: "pending"
|
|
502
|
+
});
|
|
503
|
+
copilotkit.applyHeadersToAgent(provisional);
|
|
504
|
+
provisionalAgentCache.current.set(resolvedAgentId, provisional);
|
|
505
|
+
return {
|
|
506
|
+
agent: provisional,
|
|
507
|
+
isReady: false
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
511
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
512
|
+
throw new Error(`useAgent: Agent '${resolvedAgentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
513
|
+
}, [
|
|
514
|
+
resolvedAgentId,
|
|
515
|
+
runtimeAgentId,
|
|
516
|
+
registeredProxyAgent,
|
|
517
|
+
copilotkit.agents,
|
|
518
|
+
copilotkit.runtimeConnectionStatus,
|
|
519
|
+
copilotkit.runtimeUrl,
|
|
520
|
+
copilotkit.runtimeTransport,
|
|
521
|
+
copilotkit.credentials,
|
|
522
|
+
JSON.stringify(copilotkit.headers)
|
|
523
|
+
]);
|
|
524
|
+
(0, react.useEffect)(() => {
|
|
525
|
+
if (updateFlags.length === 0) return;
|
|
526
|
+
let active = true;
|
|
527
|
+
const handlers = {};
|
|
528
|
+
let batchScheduled = false;
|
|
529
|
+
const batchedForceUpdate = () => {
|
|
530
|
+
if (!active) return;
|
|
531
|
+
if (!batchScheduled) {
|
|
532
|
+
batchScheduled = true;
|
|
533
|
+
queueMicrotask(() => {
|
|
534
|
+
batchScheduled = false;
|
|
535
|
+
if (active) forceUpdate();
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = batchedForceUpdate;
|
|
540
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
541
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
542
|
+
handlers.onRunInitialized = batchedForceUpdate;
|
|
543
|
+
handlers.onRunStartedEvent = batchedForceUpdate;
|
|
544
|
+
handlers.onRunFinalized = batchedForceUpdate;
|
|
545
|
+
handlers.onRunFailed = batchedForceUpdate;
|
|
546
|
+
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
547
|
+
}
|
|
548
|
+
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
549
|
+
return () => {
|
|
550
|
+
active = false;
|
|
551
|
+
subscription.unsubscribe();
|
|
552
|
+
};
|
|
553
|
+
}, [
|
|
554
|
+
agent,
|
|
555
|
+
forceUpdate,
|
|
556
|
+
throttleMs,
|
|
557
|
+
providerThrottleMs,
|
|
558
|
+
updateFlags
|
|
559
|
+
]);
|
|
560
|
+
(0, react.useEffect)(() => {
|
|
561
|
+
if ((0, _copilotkit_core.ɵisHttpAgent)(agent)) copilotkit.applyHeadersToAgent(agent);
|
|
562
|
+
if (agent instanceof _copilotkit_core.ProxiedCopilotRuntimeAgent) agent.credentials = copilotkit.credentials;
|
|
563
|
+
}, [
|
|
564
|
+
agent,
|
|
565
|
+
JSON.stringify(copilotkit.headers),
|
|
566
|
+
copilotkit.credentials
|
|
567
|
+
]);
|
|
568
|
+
const configThreadId = chatConfig?.threadId;
|
|
569
|
+
const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;
|
|
570
|
+
const resolvedThreadId = threadId ?? (configHasExplicitThreadId ? configThreadId : void 0);
|
|
571
|
+
(0, react.useEffect)(() => {
|
|
572
|
+
if (!resolvedThreadId) return;
|
|
573
|
+
agent.threadId = resolvedThreadId;
|
|
574
|
+
}, [agent, resolvedThreadId]);
|
|
575
|
+
return {
|
|
576
|
+
agent,
|
|
577
|
+
isReady
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
//#endregion
|
|
582
|
+
//#region src/hooks/tool-registration.ts
|
|
583
|
+
/**
|
|
584
|
+
* Deps comparison shared by `useFrontendTool` (and through it
|
|
585
|
+
* `useHumanInTheLoop` and `useComponent`) and `useRenderTool`. Not part of the
|
|
586
|
+
* public API.
|
|
587
|
+
*/
|
|
588
|
+
const EMPTY_DEPS$1 = [];
|
|
589
|
+
function isPlainObject(value) {
|
|
590
|
+
const proto = Object.getPrototypeOf(value);
|
|
591
|
+
return proto === Object.prototype || proto === null;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Plain data (primitives, plain objects, arrays, dates) compares by value.
|
|
595
|
+
* Functions always compare equal: these hooks used to compare
|
|
596
|
+
* `JSON.stringify(deps)`, which turns every function into `null`, and a
|
|
597
|
+
* function that counted as changed would re-register on every render when it
|
|
598
|
+
* is written inline (and loop in a component that also reads
|
|
599
|
+
* `useRenderToolCall`). Everything else (class instances, maps, sets) compares
|
|
600
|
+
* by identity. A cycle inside plain data is safe: a pair already being
|
|
601
|
+
* compared counts as equal for that branch.
|
|
602
|
+
*/
|
|
603
|
+
function depEqual(a, b, seen) {
|
|
604
|
+
if (Object.is(a, b)) return true;
|
|
605
|
+
if (typeof a === "function" && typeof b === "function") return true;
|
|
606
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
607
|
+
if (a instanceof Date && b instanceof Date) return Object.is(a.getTime(), b.getTime());
|
|
608
|
+
const aIsArray = Array.isArray(a);
|
|
609
|
+
if (aIsArray !== Array.isArray(b)) return false;
|
|
610
|
+
if (!aIsArray && !(isPlainObject(a) && isPlainObject(b))) return false;
|
|
611
|
+
if (seen.get(a) === b) return true;
|
|
612
|
+
seen.set(a, b);
|
|
613
|
+
if (aIsArray) {
|
|
614
|
+
const left = a;
|
|
615
|
+
const right = b;
|
|
616
|
+
if (left.length !== right.length) return false;
|
|
617
|
+
for (let i = 0; i < left.length; i++) if (!depEqual(left[i], right[i], seen)) return false;
|
|
618
|
+
return true;
|
|
619
|
+
}
|
|
620
|
+
const left = a;
|
|
621
|
+
const right = b;
|
|
622
|
+
const leftKeys = Object.keys(left);
|
|
623
|
+
if (leftKeys.length !== Object.keys(right).length) return false;
|
|
624
|
+
for (const key of leftKeys) {
|
|
625
|
+
if (!Object.prototype.hasOwnProperty.call(right, key)) return false;
|
|
626
|
+
if (!depEqual(left[key], right[key], seen)) return false;
|
|
627
|
+
}
|
|
628
|
+
return true;
|
|
629
|
+
}
|
|
630
|
+
/** Whether two deps arrays are equal. A change in length is always a change. */
|
|
631
|
+
function depsEqual(prev, next) {
|
|
632
|
+
if (prev.length !== next.length) return false;
|
|
633
|
+
const seen = /* @__PURE__ */ new Map();
|
|
634
|
+
for (let i = 0; i < prev.length; i++) if (!depEqual(prev[i], next[i], seen)) return false;
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Turns a caller's `deps` array into a number that changes exactly when the
|
|
639
|
+
* deps change, by the rules of {@link depsEqual}. Put the number, not the
|
|
640
|
+
* array, in the registration effect's dependency list: that keeps the list a
|
|
641
|
+
* constant length and never serializes a value.
|
|
642
|
+
*/
|
|
643
|
+
function useDepsVersion(deps) {
|
|
644
|
+
const next = deps ?? EMPTY_DEPS$1;
|
|
645
|
+
const ref = (0, react.useRef)({
|
|
646
|
+
deps: next,
|
|
647
|
+
version: 0
|
|
648
|
+
});
|
|
649
|
+
if (ref.current.deps !== next && !depsEqual(ref.current.deps, next)) ref.current = {
|
|
650
|
+
deps: next,
|
|
651
|
+
version: ref.current.version + 1
|
|
652
|
+
};
|
|
653
|
+
return ref.current.version;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
//#endregion
|
|
657
|
+
//#region src/hooks/use-frontend-tool.tsx
|
|
658
|
+
function useFrontendTool(tool, deps) {
|
|
659
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
660
|
+
const depsVersion = useDepsVersion(deps);
|
|
661
|
+
(0, react.useLayoutEffect)(() => {
|
|
662
|
+
const name = tool.name;
|
|
663
|
+
if (copilotkit.getTool({
|
|
664
|
+
toolName: name,
|
|
665
|
+
agentId: tool.agentId
|
|
666
|
+
})) {
|
|
667
|
+
console.warn(`Tool '${name}' already exists for agent '${tool.agentId || "global"}'. Overriding with latest registration.`);
|
|
668
|
+
copilotkit.removeTool(name, tool.agentId);
|
|
669
|
+
}
|
|
670
|
+
copilotkit.addTool(tool);
|
|
671
|
+
if (tool.render) copilotkit.addHookRenderToolCall({
|
|
672
|
+
name,
|
|
673
|
+
args: tool.parameters,
|
|
674
|
+
agentId: tool.agentId,
|
|
675
|
+
render: tool.render
|
|
676
|
+
});
|
|
677
|
+
return () => {
|
|
678
|
+
copilotkit.removeTool(name, tool.agentId);
|
|
679
|
+
};
|
|
680
|
+
}, [
|
|
681
|
+
tool.name,
|
|
682
|
+
tool.available,
|
|
683
|
+
copilotkit,
|
|
684
|
+
depsVersion,
|
|
685
|
+
JSON.stringify(tool.webmcp ?? null)
|
|
686
|
+
]);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
//#endregion
|
|
690
|
+
//#region src/hooks/use-frontend-tools.tsx
|
|
691
|
+
const EMPTY_DEPS = [];
|
|
692
|
+
const EMPTY_TOOLS = [];
|
|
693
|
+
/**
|
|
694
|
+
* Register a list of frontend tools whose length can change between renders.
|
|
695
|
+
*
|
|
696
|
+
* `useFrontendTool` registers exactly one tool per call, so it cannot be called
|
|
697
|
+
* in a loop over a runtime-length list without breaking the rules of hooks.
|
|
698
|
+
* This hook runs a single effect over the whole array instead, which makes it
|
|
699
|
+
* safe to build the list from state, props, or a server response.
|
|
700
|
+
*
|
|
701
|
+
* Tools are keyed by `name` plus `agentId`, the same as `useFrontendTool`. A
|
|
702
|
+
* tool that disappears from the array is unregistered on the next render, and
|
|
703
|
+
* every tool is unregistered on unmount. Renderers stay registered after
|
|
704
|
+
* unmount so past tool calls still render in the chat history.
|
|
705
|
+
*
|
|
706
|
+
* @param tools - The tools to register. May be empty and may change length.
|
|
707
|
+
* @param deps - Extra dependencies that force re-registration, compared by
|
|
708
|
+
* identity like the second argument of `useEffect`. Use this when a handler
|
|
709
|
+
* closes over a value that is not part of the tool definition. Keep the array
|
|
710
|
+
* a constant length across renders.
|
|
711
|
+
*
|
|
712
|
+
* @example
|
|
713
|
+
* Register one tool per item in application state:
|
|
714
|
+
* ```tsx
|
|
715
|
+
* const [reports, setReports] = useState<Report[]>([]);
|
|
716
|
+
*
|
|
717
|
+
* useFrontendTools(
|
|
718
|
+
* reports.map((report) => ({
|
|
719
|
+
* name: `open_${report.id}`,
|
|
720
|
+
* description: `Open the ${report.title} report`,
|
|
721
|
+
* handler: async () => navigate(`/reports/${report.id}`),
|
|
722
|
+
* })),
|
|
723
|
+
* [navigate],
|
|
724
|
+
* );
|
|
725
|
+
* ```
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* Register tools described by the backend:
|
|
729
|
+
* ```tsx
|
|
730
|
+
* const { data } = useQuery(fetchToolDescriptors);
|
|
731
|
+
*
|
|
732
|
+
* useFrontendTools(
|
|
733
|
+
* (data ?? []).map((descriptor) => ({
|
|
734
|
+
* name: descriptor.name,
|
|
735
|
+
* description: descriptor.description,
|
|
736
|
+
* parameters: z.object({ query: z.string() }),
|
|
737
|
+
* handler: async ({ query }) => runDescriptor(descriptor.id, query),
|
|
738
|
+
* })),
|
|
739
|
+
* );
|
|
740
|
+
* ```
|
|
741
|
+
*/
|
|
742
|
+
function useFrontendTools(tools, deps) {
|
|
743
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
744
|
+
const toolList = tools ?? EMPTY_TOOLS;
|
|
745
|
+
const extraDeps = deps ?? EMPTY_DEPS;
|
|
746
|
+
(0, react.useLayoutEffect)(() => {
|
|
747
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
748
|
+
for (const tool of toolList) {
|
|
749
|
+
const key = `${tool.agentId ?? ""}:${tool.name}`;
|
|
750
|
+
if (deduped.has(key)) console.warn(`Tool '${tool.name}' is listed more than once for agent '${tool.agentId || "global"}' in the same useFrontendTools call. Using the last entry.`);
|
|
751
|
+
deduped.set(key, tool);
|
|
752
|
+
}
|
|
753
|
+
const registered = [...deduped.values()];
|
|
754
|
+
for (const tool of registered) {
|
|
755
|
+
if (copilotkit.getTool({
|
|
756
|
+
toolName: tool.name,
|
|
757
|
+
agentId: tool.agentId
|
|
758
|
+
})) {
|
|
759
|
+
console.warn(`Tool '${tool.name}' already exists for agent '${tool.agentId || "global"}'. Overriding with latest registration.`);
|
|
760
|
+
copilotkit.removeTool(tool.name, tool.agentId);
|
|
761
|
+
}
|
|
762
|
+
copilotkit.addTool(tool);
|
|
763
|
+
if (tool.render) copilotkit.addHookRenderToolCall({
|
|
764
|
+
name: tool.name,
|
|
765
|
+
args: tool.parameters,
|
|
766
|
+
agentId: tool.agentId,
|
|
767
|
+
render: tool.render
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
return () => {
|
|
771
|
+
for (const tool of registered) copilotkit.removeTool(tool.name, tool.agentId);
|
|
772
|
+
};
|
|
773
|
+
}, [
|
|
774
|
+
JSON.stringify(toolList.map((tool) => [
|
|
775
|
+
tool.name,
|
|
776
|
+
tool.description ?? null,
|
|
777
|
+
tool.agentId ?? null,
|
|
778
|
+
tool.available ?? null,
|
|
779
|
+
tool.webmcp ?? null
|
|
780
|
+
])),
|
|
781
|
+
copilotkit,
|
|
782
|
+
...extraDeps
|
|
783
|
+
]);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
//#endregion
|
|
787
|
+
//#region src/hooks/use-component.tsx
|
|
788
|
+
/**
|
|
789
|
+
* Registers a React component as a frontend tool renderer in chat.
|
|
790
|
+
*
|
|
791
|
+
* This hook is a convenience wrapper around `useFrontendTool` that:
|
|
792
|
+
* - builds a model-facing tool description,
|
|
793
|
+
* - forwards optional schema parameters (any Standard Schema V1 compatible library),
|
|
794
|
+
* - renders your component with tool call parameters.
|
|
795
|
+
*
|
|
796
|
+
* Use this when you want to display a typed visual component for a tool call
|
|
797
|
+
* without manually wiring a full frontend tool object.
|
|
798
|
+
*
|
|
799
|
+
* When `parameters` is provided, render props are inferred from the schema.
|
|
800
|
+
* When omitted, the render component may accept any props.
|
|
801
|
+
*
|
|
802
|
+
* @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.
|
|
803
|
+
* @param config - Tool registration config.
|
|
804
|
+
* @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).
|
|
805
|
+
*
|
|
806
|
+
* @example
|
|
807
|
+
* ```tsx
|
|
808
|
+
* // Without parameters — render accepts any props
|
|
809
|
+
* useComponent({
|
|
810
|
+
* name: "showGreeting",
|
|
811
|
+
* render: ({ message }: { message: string }) => <div>{message}</div>,
|
|
812
|
+
* });
|
|
813
|
+
* ```
|
|
814
|
+
*
|
|
815
|
+
* @example
|
|
816
|
+
* ```tsx
|
|
817
|
+
* // With parameters — render props inferred from schema
|
|
818
|
+
* useComponent({
|
|
819
|
+
* name: "showWeatherCard",
|
|
820
|
+
* parameters: z.object({ city: z.string() }),
|
|
821
|
+
* render: ({ city }) => <div>{city}</div>,
|
|
822
|
+
* });
|
|
823
|
+
* ```
|
|
824
|
+
*
|
|
825
|
+
* @example
|
|
826
|
+
* ```tsx
|
|
827
|
+
* useComponent(
|
|
828
|
+
* {
|
|
829
|
+
* name: "renderProfile",
|
|
830
|
+
* parameters: z.object({ userId: z.string() }),
|
|
831
|
+
* render: ProfileCard,
|
|
832
|
+
* agentId: "support-agent",
|
|
833
|
+
* },
|
|
834
|
+
* [selectedAgentId],
|
|
835
|
+
* );
|
|
836
|
+
* ```
|
|
837
|
+
*/
|
|
838
|
+
function useComponent(config, deps) {
|
|
839
|
+
const prefix = `Use this tool to display the "${config.name}" component in the chat. This tool renders a visual UI component for the user.`;
|
|
840
|
+
const fullDescription = config.description ? `${prefix}\n\n${config.description}` : prefix;
|
|
841
|
+
useFrontendTool({
|
|
842
|
+
name: config.name,
|
|
843
|
+
description: fullDescription,
|
|
844
|
+
parameters: config.parameters,
|
|
845
|
+
render: ({ args }) => {
|
|
846
|
+
const Component = config.render;
|
|
847
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...args });
|
|
848
|
+
},
|
|
849
|
+
agentId: config.agentId,
|
|
850
|
+
followUp: config.followUp
|
|
851
|
+
}, deps);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
//#endregion
|
|
855
|
+
//#region src/hooks/use-human-in-the-loop.tsx
|
|
856
|
+
/** Registration name of a catch-all tool: handles any otherwise-unhandled call. */
|
|
857
|
+
const WILDCARD_TOOL_NAME = "*";
|
|
858
|
+
function useHumanInTheLoop(tool, deps) {
|
|
859
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
860
|
+
const resolvePromiseRef = (0, react.useRef)(null);
|
|
861
|
+
const cleanupAbortRef = (0, react.useRef)(null);
|
|
862
|
+
const respond = (0, react.useCallback)(async (result) => {
|
|
863
|
+
if (resolvePromiseRef.current) {
|
|
864
|
+
cleanupAbortRef.current?.();
|
|
865
|
+
cleanupAbortRef.current = null;
|
|
866
|
+
resolvePromiseRef.current(result);
|
|
867
|
+
resolvePromiseRef.current = null;
|
|
868
|
+
}
|
|
869
|
+
}, []);
|
|
870
|
+
const handler = (0, react.useCallback)(async (_args, context) => {
|
|
871
|
+
const signal = context?.signal;
|
|
872
|
+
return new Promise((resolve, reject) => {
|
|
873
|
+
if (signal?.aborted) {
|
|
874
|
+
reject(/* @__PURE__ */ new Error("Human-in-the-loop interaction aborted"));
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
resolvePromiseRef.current = resolve;
|
|
878
|
+
if (signal) {
|
|
879
|
+
const onAbort = () => {
|
|
880
|
+
cleanupAbortRef.current = null;
|
|
881
|
+
resolvePromiseRef.current = null;
|
|
882
|
+
reject(/* @__PURE__ */ new Error("Human-in-the-loop interaction aborted"));
|
|
883
|
+
};
|
|
884
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
885
|
+
cleanupAbortRef.current = () => {
|
|
886
|
+
signal.removeEventListener("abort", onAbort);
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
}, []);
|
|
891
|
+
const RenderComponent = (0, react.useCallback)((props) => {
|
|
892
|
+
const ToolComponent = tool.render;
|
|
893
|
+
const name = tool.name === WILDCARD_TOOL_NAME ? props.name : tool.name;
|
|
894
|
+
if (props.status === _copilotkit_core.ToolCallStatus.InProgress) {
|
|
895
|
+
const enhancedProps = {
|
|
896
|
+
...props,
|
|
897
|
+
name,
|
|
898
|
+
description: tool.description || "",
|
|
899
|
+
agentId: tool.agentId,
|
|
900
|
+
respond: void 0
|
|
901
|
+
};
|
|
902
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
903
|
+
} else if (props.status === _copilotkit_core.ToolCallStatus.Executing) {
|
|
904
|
+
const enhancedProps = {
|
|
905
|
+
...props,
|
|
906
|
+
name,
|
|
907
|
+
description: tool.description || "",
|
|
908
|
+
agentId: tool.agentId,
|
|
909
|
+
respond
|
|
910
|
+
};
|
|
911
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
912
|
+
} else if (props.status === _copilotkit_core.ToolCallStatus.Complete) {
|
|
913
|
+
const enhancedProps = {
|
|
914
|
+
...props,
|
|
915
|
+
name,
|
|
916
|
+
description: tool.description || "",
|
|
917
|
+
agentId: tool.agentId,
|
|
918
|
+
respond: void 0
|
|
919
|
+
};
|
|
920
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
921
|
+
}
|
|
922
|
+
return props;
|
|
923
|
+
}, [
|
|
924
|
+
tool.render,
|
|
925
|
+
tool.name,
|
|
926
|
+
tool.description,
|
|
927
|
+
tool.agentId,
|
|
928
|
+
respond
|
|
929
|
+
]);
|
|
930
|
+
useFrontendTool({
|
|
931
|
+
...tool,
|
|
932
|
+
type: "human-in-the-loop",
|
|
933
|
+
handler,
|
|
934
|
+
render: RenderComponent
|
|
935
|
+
}, deps);
|
|
936
|
+
(0, react.useLayoutEffect)(() => {
|
|
937
|
+
return () => {
|
|
938
|
+
copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
|
|
939
|
+
};
|
|
940
|
+
}, [
|
|
941
|
+
copilotkit,
|
|
942
|
+
tool.name,
|
|
943
|
+
tool.agentId
|
|
944
|
+
]);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
//#endregion
|
|
948
|
+
//#region src/types/interrupt.ts
|
|
949
|
+
/** Name of the legacy custom event agents emit to signal an interrupt. */
|
|
950
|
+
const INTERRUPT_EVENT_NAME = "on_interrupt";
|
|
951
|
+
|
|
952
|
+
//#endregion
|
|
953
|
+
//#region src/hooks/use-interrupt.tsx
|
|
954
|
+
/** Recognize thenables returned by interrupt preprocessing handlers. */
|
|
955
|
+
function isPromiseLike(value) {
|
|
956
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
|
|
957
|
+
}
|
|
958
|
+
/** Derive the legacy-compatible `event` for any pending interrupt. */
|
|
959
|
+
function toLegacyEvent(pending) {
|
|
960
|
+
if (pending.kind === "legacy") return pending.event;
|
|
961
|
+
return {
|
|
962
|
+
name: INTERRUPT_EVENT_NAME,
|
|
963
|
+
value: pending.interrupts[0]
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Handles agent interrupts with optional filtering, preprocessing, and resume behavior.
|
|
968
|
+
*
|
|
969
|
+
* Supports both the AG-UI standard interrupt flow (`RUN_FINISHED` with
|
|
970
|
+
* `outcome.type === "interrupt"`) and the legacy custom-event flow
|
|
971
|
+
* (`on_interrupt`). For standard interrupts, `render` receives `interrupt`
|
|
972
|
+
* (the primary one) and `interrupts` (the full open set); call `resolve(payload)`
|
|
973
|
+
* to resume or `cancel()` to cancel. Resuming addresses the targeted interrupt
|
|
974
|
+
* and, once every open interrupt is addressed, submits a single spec `resume`
|
|
975
|
+
* array via `copilotkit.runAgent`.
|
|
976
|
+
*
|
|
977
|
+
* - `renderInChat: true` (default): the element is published into `<CopilotChat>`; returns `void`.
|
|
978
|
+
* - `renderInChat: false`: the hook returns the interrupt element for manual placement.
|
|
979
|
+
*
|
|
980
|
+
* @example
|
|
981
|
+
* ```tsx
|
|
982
|
+
* useInterrupt({
|
|
983
|
+
* render: ({ interrupt, resolve, cancel }) => (
|
|
984
|
+
* <div>
|
|
985
|
+
* <p>{interrupt?.message}</p>
|
|
986
|
+
* <button onClick={() => resolve({ approved: true })}>Approve</button>
|
|
987
|
+
* <button onClick={() => cancel()}>Cancel</button>
|
|
988
|
+
* </div>
|
|
989
|
+
* ),
|
|
990
|
+
* });
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
993
|
+
function useInterrupt(config) {
|
|
994
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
995
|
+
const { agent } = useAgent({
|
|
996
|
+
agentId: config.agentId,
|
|
997
|
+
updates: []
|
|
998
|
+
});
|
|
999
|
+
const [pending, setPending] = (0, react.useState)(null);
|
|
1000
|
+
const pendingRef = (0, react.useRef)(pending);
|
|
1001
|
+
pendingRef.current = pending;
|
|
1002
|
+
const [handlerResult, setHandlerResult] = (0, react.useState)(null);
|
|
1003
|
+
const interruptStateRef = (0, react.useRef)(new _copilotkit_core.ɵInterruptState());
|
|
1004
|
+
(0, react.useEffect)(() => {
|
|
1005
|
+
let localLegacy = null;
|
|
1006
|
+
let localStandard = null;
|
|
1007
|
+
const subscription = agent.subscribe({
|
|
1008
|
+
onCustomEvent: ({ event }) => {
|
|
1009
|
+
if (event.name === INTERRUPT_EVENT_NAME) localLegacy = {
|
|
1010
|
+
name: event.name,
|
|
1011
|
+
value: event.value
|
|
1012
|
+
};
|
|
1013
|
+
},
|
|
1014
|
+
onRunFinishedEvent: (params) => {
|
|
1015
|
+
if (params.outcome === "interrupt") localStandard = params.interrupts;
|
|
1016
|
+
},
|
|
1017
|
+
onRunStartedEvent: (params) => {
|
|
1018
|
+
if (!agent.pendingInterrupts?.length || params?.input?.resume !== void 0) (0, _copilotkit_core.ɵclearAgentInterruptState)(agent);
|
|
1019
|
+
localLegacy = null;
|
|
1020
|
+
localStandard = null;
|
|
1021
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1022
|
+
setPending(null);
|
|
1023
|
+
},
|
|
1024
|
+
onRunFinalized: () => {
|
|
1025
|
+
if (localStandard && localStandard.length > 0) {
|
|
1026
|
+
interruptStateRef.current = (0, _copilotkit_core.ɵgetAgentInterruptState)(agent, localStandard);
|
|
1027
|
+
setPending(interruptStateRef.current.pending);
|
|
1028
|
+
} else if (localLegacy) {
|
|
1029
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1030
|
+
interruptStateRef.current.setLegacy(localLegacy);
|
|
1031
|
+
setPending(interruptStateRef.current.pending);
|
|
1032
|
+
}
|
|
1033
|
+
localLegacy = null;
|
|
1034
|
+
localStandard = null;
|
|
1035
|
+
},
|
|
1036
|
+
onRunFailed: () => {
|
|
1037
|
+
localLegacy = null;
|
|
1038
|
+
localStandard = null;
|
|
1039
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1040
|
+
setPending(null);
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
interruptStateRef.current = agent.pendingInterrupts?.length ? (0, _copilotkit_core.ɵgetAgentInterruptState)(agent) : new _copilotkit_core.ɵInterruptState();
|
|
1044
|
+
setPending(interruptStateRef.current.pending);
|
|
1045
|
+
return () => {
|
|
1046
|
+
subscription.unsubscribe();
|
|
1047
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1048
|
+
};
|
|
1049
|
+
}, [agent]);
|
|
1050
|
+
/** Record an explicit answer and resume once the complete batch is addressed. */
|
|
1051
|
+
const resolve = (0, react.useCallback)(async (payload, interruptId) => {
|
|
1052
|
+
const current = pendingRef.current;
|
|
1053
|
+
if (!current) return;
|
|
1054
|
+
if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
|
|
1055
|
+
if (interruptStateRef.current.isCompletedToolCall(interruptId, agent.messages)) {
|
|
1056
|
+
console.warn("[CopilotKit] useInterrupt: ignoring an answer for an already completed frontend tool call.");
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
const decision = interruptStateRef.current.resolve(payload, interruptId, agent.messages);
|
|
1060
|
+
if (decision.kind === "legacy-resume") try {
|
|
1061
|
+
return await copilotkit.runAgent({
|
|
1062
|
+
agent,
|
|
1063
|
+
forwardedProps: { command: {
|
|
1064
|
+
resume: decision.payload,
|
|
1065
|
+
interruptEvent: decision.interruptValue
|
|
1066
|
+
} }
|
|
1067
|
+
});
|
|
1068
|
+
} catch (err) {
|
|
1069
|
+
console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
|
|
1070
|
+
setPending(null);
|
|
1071
|
+
throw err;
|
|
1072
|
+
}
|
|
1073
|
+
if (decision.kind === "expired") {
|
|
1074
|
+
console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
|
|
1075
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1076
|
+
setPending(null);
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (decision.kind !== "resume") return;
|
|
1080
|
+
for (const toolResult of decision.toolResults) agent.addMessage({
|
|
1081
|
+
id: (0, _ag_ui_client.randomUUID)(),
|
|
1082
|
+
role: "tool",
|
|
1083
|
+
toolCallId: toolResult.toolCallId,
|
|
1084
|
+
content: toolResult.content
|
|
1085
|
+
});
|
|
1086
|
+
try {
|
|
1087
|
+
return await copilotkit.runAgent({
|
|
1088
|
+
agent,
|
|
1089
|
+
resume: decision.resume
|
|
1090
|
+
});
|
|
1091
|
+
} catch (err) {
|
|
1092
|
+
console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
|
|
1093
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1094
|
+
setPending(null);
|
|
1095
|
+
throw err;
|
|
1096
|
+
}
|
|
1097
|
+
}, [agent, copilotkit]);
|
|
1098
|
+
/** Cancel a standard interrupt or dismiss a legacy interrupt locally. */
|
|
1099
|
+
const cancel = (0, react.useCallback)(async (interruptId) => {
|
|
1100
|
+
const current = pendingRef.current;
|
|
1101
|
+
if (!current) return;
|
|
1102
|
+
if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
|
|
1103
|
+
if (interruptStateRef.current.isCompletedToolCall(interruptId, agent.messages)) {
|
|
1104
|
+
console.warn("[CopilotKit] useInterrupt: ignoring an answer for an already completed frontend tool call.");
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const decision = interruptStateRef.current.cancel(interruptId, agent.messages);
|
|
1108
|
+
if (decision.kind === "dismiss") {
|
|
1109
|
+
console.warn("[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.");
|
|
1110
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1111
|
+
setPending(null);
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
if (decision.kind === "expired") {
|
|
1115
|
+
console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
|
|
1116
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1117
|
+
setPending(null);
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
if (decision.kind !== "resume") return;
|
|
1121
|
+
for (const toolResult of decision.toolResults) agent.addMessage({
|
|
1122
|
+
id: (0, _ag_ui_client.randomUUID)(),
|
|
1123
|
+
role: "tool",
|
|
1124
|
+
toolCallId: toolResult.toolCallId,
|
|
1125
|
+
content: toolResult.content
|
|
1126
|
+
});
|
|
1127
|
+
try {
|
|
1128
|
+
return await copilotkit.runAgent({
|
|
1129
|
+
agent,
|
|
1130
|
+
resume: decision.resume
|
|
1131
|
+
});
|
|
1132
|
+
} catch (err) {
|
|
1133
|
+
console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
|
|
1134
|
+
interruptStateRef.current = new _copilotkit_core.ɵInterruptState();
|
|
1135
|
+
setPending(null);
|
|
1136
|
+
throw err;
|
|
1137
|
+
}
|
|
1138
|
+
}, [agent, copilotkit]);
|
|
1139
|
+
const renderRef = (0, react.useRef)(config.render);
|
|
1140
|
+
renderRef.current = config.render;
|
|
1141
|
+
const enabledRef = (0, react.useRef)(config.enabled);
|
|
1142
|
+
enabledRef.current = config.enabled;
|
|
1143
|
+
const handlerRef = (0, react.useRef)(config.handler);
|
|
1144
|
+
handlerRef.current = config.handler;
|
|
1145
|
+
const resolveRef = (0, react.useRef)(resolve);
|
|
1146
|
+
resolveRef.current = resolve;
|
|
1147
|
+
const cancelRef = (0, react.useRef)(cancel);
|
|
1148
|
+
cancelRef.current = cancel;
|
|
1149
|
+
/** Evaluate the consumer filter, logging failures and disabling their UI. */
|
|
1150
|
+
const isEnabled = (event) => {
|
|
1151
|
+
const predicate = enabledRef.current;
|
|
1152
|
+
if (!predicate) return true;
|
|
1153
|
+
try {
|
|
1154
|
+
return predicate(event);
|
|
1155
|
+
} catch (err) {
|
|
1156
|
+
console.error("[CopilotKit] useInterrupt enabled predicate threw; treating interrupt as disabled:", err);
|
|
1157
|
+
return false;
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
(0, react.useEffect)(() => {
|
|
1161
|
+
if (!pending) {
|
|
1162
|
+
setHandlerResult(null);
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
const legacyEvent = toLegacyEvent(pending);
|
|
1166
|
+
if (!isEnabled(legacyEvent)) {
|
|
1167
|
+
setHandlerResult(null);
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
const handler = handlerRef.current;
|
|
1171
|
+
if (!handler) {
|
|
1172
|
+
setHandlerResult(null);
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
let cancelled = false;
|
|
1176
|
+
let maybePromise;
|
|
1177
|
+
try {
|
|
1178
|
+
maybePromise = handler({
|
|
1179
|
+
event: legacyEvent,
|
|
1180
|
+
interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
|
|
1181
|
+
interrupts: pending.kind === "standard" ? [...pending.interrupts] : [],
|
|
1182
|
+
resolve: resolveRef.current,
|
|
1183
|
+
cancel: cancelRef.current
|
|
1184
|
+
});
|
|
1185
|
+
} catch (err) {
|
|
1186
|
+
console.error("[CopilotKit] useInterrupt handler threw; result will be null:", err);
|
|
1187
|
+
if (!cancelled) setHandlerResult(null);
|
|
1188
|
+
return () => {
|
|
1189
|
+
cancelled = true;
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
if (isPromiseLike(maybePromise)) Promise.resolve(maybePromise).then((resolved) => {
|
|
1193
|
+
if (!cancelled) setHandlerResult(resolved);
|
|
1194
|
+
}).catch((err) => {
|
|
1195
|
+
console.error("[CopilotKit] useInterrupt handler rejected; result will be null:", err);
|
|
1196
|
+
if (!cancelled) setHandlerResult(null);
|
|
1197
|
+
});
|
|
1198
|
+
else setHandlerResult(maybePromise);
|
|
1199
|
+
return () => {
|
|
1200
|
+
cancelled = true;
|
|
1201
|
+
};
|
|
1202
|
+
}, [pending]);
|
|
1203
|
+
const element = (0, react.useMemo)(() => {
|
|
1204
|
+
if (!pending) return null;
|
|
1205
|
+
const legacyEvent = toLegacyEvent(pending);
|
|
1206
|
+
if (!isEnabled(legacyEvent)) return null;
|
|
1207
|
+
return renderRef.current({
|
|
1208
|
+
event: legacyEvent,
|
|
1209
|
+
interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
|
|
1210
|
+
interrupts: pending.kind === "standard" ? [...pending.interrupts] : [],
|
|
1211
|
+
result: handlerResult,
|
|
1212
|
+
resolve,
|
|
1213
|
+
cancel
|
|
1214
|
+
});
|
|
1215
|
+
}, [
|
|
1216
|
+
pending,
|
|
1217
|
+
handlerResult,
|
|
1218
|
+
resolve,
|
|
1219
|
+
cancel
|
|
1220
|
+
]);
|
|
1221
|
+
(0, react.useEffect)(() => {
|
|
1222
|
+
if (config.renderInChat === false) return;
|
|
1223
|
+
copilotkit.setInterruptElement(element);
|
|
1224
|
+
}, [
|
|
1225
|
+
element,
|
|
1226
|
+
config.renderInChat,
|
|
1227
|
+
copilotkit
|
|
1228
|
+
]);
|
|
1229
|
+
(0, react.useEffect)(() => {
|
|
1230
|
+
if (config.renderInChat === false) return;
|
|
1231
|
+
return () => {
|
|
1232
|
+
copilotkit.setInterruptElement(null);
|
|
1233
|
+
};
|
|
1234
|
+
}, []);
|
|
1235
|
+
if (config.renderInChat === false) return element;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
//#endregion
|
|
1239
|
+
//#region src/hooks/use-suggestions.tsx
|
|
1240
|
+
function useSuggestions({ agentId } = {}) {
|
|
1241
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1242
|
+
const config = useCopilotChatConfiguration();
|
|
1243
|
+
const providerAgentId = (0, _copilotkit_react_core_context.useDefaultAgentId)();
|
|
1244
|
+
const resolvedAgentId = (0, react.useMemo)(() => agentId ?? config?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [
|
|
1245
|
+
agentId,
|
|
1246
|
+
config?.agentId,
|
|
1247
|
+
providerAgentId
|
|
1248
|
+
]);
|
|
1249
|
+
const [suggestions, setSuggestions] = (0, react.useState)(() => {
|
|
1250
|
+
return copilotkit.getSuggestions(resolvedAgentId).suggestions;
|
|
1251
|
+
});
|
|
1252
|
+
const [isLoading, setIsLoading] = (0, react.useState)(() => {
|
|
1253
|
+
return copilotkit.getSuggestions(resolvedAgentId).isLoading;
|
|
1254
|
+
});
|
|
1255
|
+
(0, react.useEffect)(() => {
|
|
1256
|
+
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
1257
|
+
setSuggestions(result.suggestions);
|
|
1258
|
+
setIsLoading(result.isLoading);
|
|
1259
|
+
}, [copilotkit, resolvedAgentId]);
|
|
1260
|
+
(0, react.useEffect)(() => {
|
|
1261
|
+
const subscription = copilotkit.subscribe({
|
|
1262
|
+
onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {
|
|
1263
|
+
if (changedAgentId !== resolvedAgentId) return;
|
|
1264
|
+
setSuggestions(suggestions);
|
|
1265
|
+
},
|
|
1266
|
+
onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {
|
|
1267
|
+
if (changedAgentId !== resolvedAgentId) return;
|
|
1268
|
+
setIsLoading(true);
|
|
1269
|
+
},
|
|
1270
|
+
onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {
|
|
1271
|
+
if (changedAgentId !== resolvedAgentId) return;
|
|
1272
|
+
setIsLoading(false);
|
|
1273
|
+
},
|
|
1274
|
+
onSuggestionsConfigChanged: () => {
|
|
1275
|
+
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
1276
|
+
setSuggestions(result.suggestions);
|
|
1277
|
+
setIsLoading(result.isLoading);
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
return () => {
|
|
1281
|
+
subscription.unsubscribe();
|
|
1282
|
+
};
|
|
1283
|
+
}, [copilotkit, resolvedAgentId]);
|
|
1284
|
+
return {
|
|
1285
|
+
suggestions,
|
|
1286
|
+
reloadSuggestions: (0, react.useCallback)(() => {
|
|
1287
|
+
copilotkit.reloadSuggestions(resolvedAgentId);
|
|
1288
|
+
}, [copilotkit, resolvedAgentId]),
|
|
1289
|
+
clearSuggestions: (0, react.useCallback)(() => {
|
|
1290
|
+
copilotkit.clearSuggestions(resolvedAgentId);
|
|
1291
|
+
}, [copilotkit, resolvedAgentId]),
|
|
1292
|
+
isLoading
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
//#endregion
|
|
1297
|
+
//#region src/hooks/use-configure-suggestions.tsx
|
|
1298
|
+
function useConfigureSuggestions(config, deps) {
|
|
1299
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1300
|
+
const chatConfig = useCopilotChatConfiguration();
|
|
1301
|
+
const extraDeps = deps ?? [];
|
|
1302
|
+
const resolvedConsumerAgentId = (0, react.useMemo)(() => chatConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [chatConfig?.agentId]);
|
|
1303
|
+
const rawConsumerAgentId = (0, react.useMemo)(() => config ? config.consumerAgentId : void 0, [config]);
|
|
1304
|
+
const normalizationCacheRef = (0, react.useRef)({
|
|
1305
|
+
serialized: null,
|
|
1306
|
+
config: null
|
|
1307
|
+
});
|
|
1308
|
+
const { normalizedConfig, serializedConfig } = (0, react.useMemo)(() => {
|
|
1309
|
+
if (!config) {
|
|
1310
|
+
normalizationCacheRef.current = {
|
|
1311
|
+
serialized: null,
|
|
1312
|
+
config: null
|
|
1313
|
+
};
|
|
1314
|
+
return {
|
|
1315
|
+
normalizedConfig: null,
|
|
1316
|
+
serializedConfig: null
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
if (config.available === "disabled") {
|
|
1320
|
+
normalizationCacheRef.current = {
|
|
1321
|
+
serialized: null,
|
|
1322
|
+
config: null
|
|
1323
|
+
};
|
|
1324
|
+
return {
|
|
1325
|
+
normalizedConfig: null,
|
|
1326
|
+
serializedConfig: null
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
let built;
|
|
1330
|
+
if (isDynamicConfig(config)) built = { ...config };
|
|
1331
|
+
else {
|
|
1332
|
+
const normalizedSuggestions = normalizeStaticSuggestions(config.suggestions);
|
|
1333
|
+
built = {
|
|
1334
|
+
...config,
|
|
1335
|
+
suggestions: normalizedSuggestions
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
const serialized = JSON.stringify(built);
|
|
1339
|
+
const cache = normalizationCacheRef.current;
|
|
1340
|
+
if (cache.serialized === serialized && cache.config) return {
|
|
1341
|
+
normalizedConfig: cache.config,
|
|
1342
|
+
serializedConfig: serialized
|
|
1343
|
+
};
|
|
1344
|
+
normalizationCacheRef.current = {
|
|
1345
|
+
serialized,
|
|
1346
|
+
config: built
|
|
1347
|
+
};
|
|
1348
|
+
return {
|
|
1349
|
+
normalizedConfig: built,
|
|
1350
|
+
serializedConfig: serialized
|
|
1351
|
+
};
|
|
1352
|
+
}, [
|
|
1353
|
+
config,
|
|
1354
|
+
resolvedConsumerAgentId,
|
|
1355
|
+
...extraDeps
|
|
1356
|
+
]);
|
|
1357
|
+
const latestConfigRef = (0, react.useRef)(null);
|
|
1358
|
+
latestConfigRef.current = normalizedConfig;
|
|
1359
|
+
const previousSerializedConfigRef = (0, react.useRef)(null);
|
|
1360
|
+
const targetAgentId = (0, react.useMemo)(() => {
|
|
1361
|
+
if (!normalizedConfig) return resolvedConsumerAgentId;
|
|
1362
|
+
const consumer = normalizedConfig.consumerAgentId;
|
|
1363
|
+
if (!consumer || consumer === "*") return resolvedConsumerAgentId;
|
|
1364
|
+
return consumer;
|
|
1365
|
+
}, [normalizedConfig, resolvedConsumerAgentId]);
|
|
1366
|
+
const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
|
|
1367
|
+
const isDynamicConfigType = (0, react.useMemo)(() => !!normalizedConfig && "instructions" in normalizedConfig, [normalizedConfig]);
|
|
1368
|
+
const requestReload = (0, react.useCallback)(() => {
|
|
1369
|
+
if (!normalizedConfig) return;
|
|
1370
|
+
if (isGlobalConfig) {
|
|
1371
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1372
|
+
const agents = Object.values(copilotkit.agents ?? {});
|
|
1373
|
+
for (const entry of agents) {
|
|
1374
|
+
const agentId = entry.agentId;
|
|
1375
|
+
if (!agentId) continue;
|
|
1376
|
+
seen.add(agentId);
|
|
1377
|
+
if (!entry.isRunning) copilotkit.reloadSuggestions(agentId);
|
|
1378
|
+
}
|
|
1379
|
+
if (targetAgentId && !seen.has(targetAgentId)) copilotkit.reloadSuggestions(targetAgentId);
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
if (!targetAgentId) return;
|
|
1383
|
+
copilotkit.reloadSuggestions(targetAgentId);
|
|
1384
|
+
}, [
|
|
1385
|
+
copilotkit,
|
|
1386
|
+
isGlobalConfig,
|
|
1387
|
+
normalizedConfig,
|
|
1388
|
+
targetAgentId
|
|
1389
|
+
]);
|
|
1390
|
+
(0, react.useEffect)(() => {
|
|
1391
|
+
if (!serializedConfig || !latestConfigRef.current) return;
|
|
1392
|
+
const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);
|
|
1393
|
+
requestReload();
|
|
1394
|
+
return () => {
|
|
1395
|
+
copilotkit.removeSuggestionsConfig(id);
|
|
1396
|
+
};
|
|
1397
|
+
}, [
|
|
1398
|
+
copilotkit,
|
|
1399
|
+
serializedConfig,
|
|
1400
|
+
requestReload
|
|
1401
|
+
]);
|
|
1402
|
+
(0, react.useEffect)(() => {
|
|
1403
|
+
if (!normalizedConfig) {
|
|
1404
|
+
previousSerializedConfigRef.current = null;
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
if (serializedConfig && previousSerializedConfigRef.current === serializedConfig) return;
|
|
1408
|
+
if (serializedConfig) previousSerializedConfigRef.current = serializedConfig;
|
|
1409
|
+
requestReload();
|
|
1410
|
+
}, [
|
|
1411
|
+
normalizedConfig,
|
|
1412
|
+
requestReload,
|
|
1413
|
+
serializedConfig
|
|
1414
|
+
]);
|
|
1415
|
+
(0, react.useEffect)(() => {
|
|
1416
|
+
if (!normalizedConfig || extraDeps.length === 0) return;
|
|
1417
|
+
requestReload();
|
|
1418
|
+
}, [
|
|
1419
|
+
extraDeps.length,
|
|
1420
|
+
normalizedConfig,
|
|
1421
|
+
requestReload,
|
|
1422
|
+
...extraDeps
|
|
1423
|
+
]);
|
|
1424
|
+
(0, react.useEffect)(() => {
|
|
1425
|
+
if (!normalizedConfig || !isDynamicConfigType) return;
|
|
1426
|
+
if (!targetAgentId) return;
|
|
1427
|
+
if (!!copilotkit.getAgent(targetAgentId)) return;
|
|
1428
|
+
const subscription = copilotkit.subscribe({ onAgentsChanged: () => {
|
|
1429
|
+
if (copilotkit.getAgent(targetAgentId)) {
|
|
1430
|
+
requestReload();
|
|
1431
|
+
subscription.unsubscribe();
|
|
1432
|
+
}
|
|
1433
|
+
} });
|
|
1434
|
+
return () => {
|
|
1435
|
+
subscription.unsubscribe();
|
|
1436
|
+
};
|
|
1437
|
+
}, [
|
|
1438
|
+
copilotkit,
|
|
1439
|
+
normalizedConfig,
|
|
1440
|
+
isDynamicConfigType,
|
|
1441
|
+
targetAgentId,
|
|
1442
|
+
requestReload
|
|
1443
|
+
]);
|
|
1444
|
+
}
|
|
1445
|
+
function isDynamicConfig(config) {
|
|
1446
|
+
return "instructions" in config;
|
|
1447
|
+
}
|
|
1448
|
+
function normalizeStaticSuggestions(suggestions) {
|
|
1449
|
+
return suggestions.map((suggestion) => ({
|
|
1450
|
+
...suggestion,
|
|
1451
|
+
isLoading: suggestion.isLoading ?? false
|
|
1452
|
+
}));
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
//#endregion
|
|
1456
|
+
//#region src/hooks/use-agent-context.tsx
|
|
1457
|
+
function useAgentContext(context) {
|
|
1458
|
+
const { description, value } = context;
|
|
1459
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1460
|
+
const stringValue = (0, react.useMemo)(() => {
|
|
1461
|
+
if (typeof value === "string") return value;
|
|
1462
|
+
return JSON.stringify(value);
|
|
1463
|
+
}, [value]);
|
|
1464
|
+
(0, react.useLayoutEffect)(() => {
|
|
1465
|
+
if (!copilotkit) return;
|
|
1466
|
+
const id = copilotkit.addContext({
|
|
1467
|
+
description,
|
|
1468
|
+
value: stringValue
|
|
1469
|
+
});
|
|
1470
|
+
return () => {
|
|
1471
|
+
copilotkit.removeContext(id);
|
|
1472
|
+
};
|
|
1473
|
+
}, [
|
|
1474
|
+
description,
|
|
1475
|
+
stringValue,
|
|
1476
|
+
copilotkit
|
|
1477
|
+
]);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
//#endregion
|
|
1481
|
+
//#region src/hooks/use-threads.tsx
|
|
1482
|
+
function useThreadStoreSelector(store, selector) {
|
|
1483
|
+
return (0, react.useSyncExternalStore)((0, react.useCallback)((onStoreChange) => {
|
|
1484
|
+
const subscription = store.select(selector).subscribe(onStoreChange);
|
|
1485
|
+
return () => subscription.unsubscribe();
|
|
1486
|
+
}, [store, selector]), () => selector(store.getState()), () => selector(store.getServerState()));
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1489
|
+
* React hook for listing and managing CopilotKit Intelligence threads.
|
|
1490
|
+
*
|
|
1491
|
+
* On mount the hook fetches the thread list for the runtime-authenticated user
|
|
1492
|
+
* and the given `agentId`. When CopilotKit Intelligence exposes a WebSocket
|
|
1493
|
+
* URL, it also opens a realtime subscription so the `threads` array stays
|
|
1494
|
+
* current without polling — thread creates, renames, archives, and deletes
|
|
1495
|
+
* from any client are reflected immediately.
|
|
1496
|
+
*
|
|
1497
|
+
* Mutation methods (`renameThread`, `archiveThread`, `unarchiveThread`,
|
|
1498
|
+
* `deleteThread`) return promises that resolve once the platform confirms the
|
|
1499
|
+
* operation and reject with an `Error` on failure.
|
|
1500
|
+
*
|
|
1501
|
+
* @param input - Agent identifier and optional list controls.
|
|
1502
|
+
* @returns Thread list state and stable mutation callbacks.
|
|
1503
|
+
*
|
|
1504
|
+
* @example
|
|
1505
|
+
* ```tsx
|
|
1506
|
+
* import { useThreads } from "@copilotkit/react-core";
|
|
1507
|
+
*
|
|
1508
|
+
* function ThreadList() {
|
|
1509
|
+
* const { threads, isLoading, renameThread, deleteThread } = useThreads({
|
|
1510
|
+
* agentId: "agent-1",
|
|
1511
|
+
* });
|
|
1512
|
+
*
|
|
1513
|
+
* if (isLoading) return <p>Loading…</p>;
|
|
1514
|
+
*
|
|
1515
|
+
* return (
|
|
1516
|
+
* <ul>
|
|
1517
|
+
* {threads.map((t) => (
|
|
1518
|
+
* <li key={t.id}>
|
|
1519
|
+
* {t.name ?? "Untitled"}
|
|
1520
|
+
* <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
|
|
1521
|
+
* <button onClick={() => deleteThread(t.id)}>Delete</button>
|
|
1522
|
+
* </li>
|
|
1523
|
+
* ))}
|
|
1524
|
+
* </ul>
|
|
1525
|
+
* );
|
|
1526
|
+
* }
|
|
1527
|
+
* ```
|
|
1528
|
+
*/
|
|
1529
|
+
function useThreads({ agentId, includeArchived, limit, enabled = true }) {
|
|
1530
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1531
|
+
const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: copilotkit.ɵruntimeFetch }));
|
|
1532
|
+
const coreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreads);
|
|
1533
|
+
const threads = (0, react.useMemo)(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({
|
|
1534
|
+
id,
|
|
1535
|
+
agentId,
|
|
1536
|
+
name,
|
|
1537
|
+
archived,
|
|
1538
|
+
createdAt,
|
|
1539
|
+
updatedAt,
|
|
1540
|
+
...lastRunAt !== void 0 ? { lastRunAt } : {}
|
|
1541
|
+
})), [coreThreads]);
|
|
1542
|
+
const storeIsLoading = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsIsLoading);
|
|
1543
|
+
const storeError = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsError);
|
|
1544
|
+
const fetchMoreError = useThreadStoreSelector(store, _copilotkit_core.ɵselectFetchMoreError);
|
|
1545
|
+
const hasMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectHasNextPage);
|
|
1546
|
+
const isFetchingMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectIsFetchingNextPage);
|
|
1547
|
+
const isMutating = useThreadStoreSelector(store, _copilotkit_core.ɵselectIsMutating);
|
|
1548
|
+
const headersKey = copilotkit.ɵheadersGeneration;
|
|
1549
|
+
const runtimeStatus = copilotkit.runtimeConnectionStatus;
|
|
1550
|
+
const threadListEndpointSupported = copilotkit.threadEndpoints?.list !== false;
|
|
1551
|
+
const threadMutationsSupported = copilotkit.threadEndpoints?.mutations !== false;
|
|
1552
|
+
const threadEndpointsUnavailable = !!copilotkit.runtimeUrl && runtimeStatus === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected && !threadListEndpointSupported;
|
|
1553
|
+
const runtimeError = (0, react.useMemo)(() => {
|
|
1554
|
+
if (copilotkit.runtimeUrl) return null;
|
|
1555
|
+
return /* @__PURE__ */ new Error("Runtime URL is not configured");
|
|
1556
|
+
}, [copilotkit.runtimeUrl]);
|
|
1557
|
+
const threadEndpointsError = (0, react.useMemo)(() => {
|
|
1558
|
+
if (!threadEndpointsUnavailable) return null;
|
|
1559
|
+
return /* @__PURE__ */ new Error("Thread endpoints are not available on this CopilotKit runtime");
|
|
1560
|
+
}, [threadEndpointsUnavailable]);
|
|
1561
|
+
const threadMutationsError = (0, react.useMemo)(() => {
|
|
1562
|
+
if (threadMutationsSupported) return null;
|
|
1563
|
+
return /* @__PURE__ */ new Error("Thread mutations are not available on this CopilotKit runtime");
|
|
1564
|
+
}, [threadMutationsSupported]);
|
|
1565
|
+
const [hasDispatchedContext, setHasDispatchedContext] = (0, react.useState)(false);
|
|
1566
|
+
const preConnectLoading = enabled && !!copilotkit.runtimeUrl && !threadEndpointsUnavailable && !hasDispatchedContext;
|
|
1567
|
+
const [configErrorDismissed, setConfigErrorDismissed] = (0, react.useState)(false);
|
|
1568
|
+
(0, react.useEffect)(() => {
|
|
1569
|
+
setConfigErrorDismissed(false);
|
|
1570
|
+
}, [runtimeError, threadEndpointsError]);
|
|
1571
|
+
const activeRuntimeError = configErrorDismissed ? null : runtimeError;
|
|
1572
|
+
const activeThreadEndpointsError = configErrorDismissed ? null : threadEndpointsError;
|
|
1573
|
+
const isLoading = activeRuntimeError || activeThreadEndpointsError ? false : preConnectLoading || storeIsLoading;
|
|
1574
|
+
const error = activeRuntimeError ?? activeThreadEndpointsError ?? storeError;
|
|
1575
|
+
const listError = storeError;
|
|
1576
|
+
(0, react.useEffect)(() => {
|
|
1577
|
+
store.start();
|
|
1578
|
+
return () => {
|
|
1579
|
+
store.stop();
|
|
1580
|
+
};
|
|
1581
|
+
}, [store]);
|
|
1582
|
+
(0, react.useEffect)(() => {
|
|
1583
|
+
if (!enabled) return;
|
|
1584
|
+
copilotkit.registerThreadStore(agentId, store);
|
|
1585
|
+
return () => {
|
|
1586
|
+
copilotkit.unregisterThreadStore(agentId);
|
|
1587
|
+
};
|
|
1588
|
+
}, [
|
|
1589
|
+
copilotkit,
|
|
1590
|
+
agentId,
|
|
1591
|
+
store,
|
|
1592
|
+
enabled
|
|
1593
|
+
]);
|
|
1594
|
+
(0, react.useEffect)(() => {
|
|
1595
|
+
if (!enabled) {
|
|
1596
|
+
store.setContext(null);
|
|
1597
|
+
setHasDispatchedContext(false);
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
if (!copilotkit.runtimeUrl) {
|
|
1601
|
+
store.setContext(null);
|
|
1602
|
+
setHasDispatchedContext(false);
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
if (runtimeStatus !== _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected) return;
|
|
1606
|
+
if (!threadListEndpointSupported) {
|
|
1607
|
+
store.setContext(null);
|
|
1608
|
+
setHasDispatchedContext(false);
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
const context = {
|
|
1612
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
1613
|
+
wsUrl: copilotkit.intelligence?.wsUrl,
|
|
1614
|
+
agentId,
|
|
1615
|
+
includeArchived,
|
|
1616
|
+
limit
|
|
1617
|
+
};
|
|
1618
|
+
store.setContext(context);
|
|
1619
|
+
setHasDispatchedContext(true);
|
|
1620
|
+
}, [
|
|
1621
|
+
store,
|
|
1622
|
+
enabled,
|
|
1623
|
+
copilotkit.runtimeUrl,
|
|
1624
|
+
runtimeStatus,
|
|
1625
|
+
headersKey,
|
|
1626
|
+
copilotkit.intelligence?.wsUrl,
|
|
1627
|
+
threadListEndpointSupported,
|
|
1628
|
+
agentId,
|
|
1629
|
+
includeArchived,
|
|
1630
|
+
limit
|
|
1631
|
+
]);
|
|
1632
|
+
const guardMutation = (0, react.useCallback)((mutation) => {
|
|
1633
|
+
return (...args) => {
|
|
1634
|
+
if (threadMutationsError) return Promise.reject(threadMutationsError);
|
|
1635
|
+
return mutation(...args);
|
|
1636
|
+
};
|
|
1637
|
+
}, [threadMutationsError]);
|
|
1638
|
+
const renameThread = (0, react.useMemo)(() => guardMutation((threadId, name) => store.renameThread(threadId, name)), [store, guardMutation]);
|
|
1639
|
+
const archiveThread = (0, react.useMemo)(() => guardMutation((threadId) => store.archiveThread(threadId)), [store, guardMutation]);
|
|
1640
|
+
const unarchiveThread = (0, react.useMemo)(() => guardMutation((threadId) => store.unarchiveThread(threadId)), [store, guardMutation]);
|
|
1641
|
+
const deleteThread = (0, react.useMemo)(() => guardMutation((threadId) => store.deleteThread(threadId)), [store, guardMutation]);
|
|
1642
|
+
return {
|
|
1643
|
+
threads,
|
|
1644
|
+
isLoading,
|
|
1645
|
+
error,
|
|
1646
|
+
listError,
|
|
1647
|
+
fetchMoreError,
|
|
1648
|
+
hasMoreThreads,
|
|
1649
|
+
isFetchingMoreThreads,
|
|
1650
|
+
isMutating,
|
|
1651
|
+
fetchMoreThreads: (0, react.useCallback)(() => store.fetchNextPage(), [store]),
|
|
1652
|
+
refetchThreads: (0, react.useCallback)(() => store.refetchThreads(), [store]),
|
|
1653
|
+
startNewThread: (0, react.useCallback)(() => {
|
|
1654
|
+
setConfigErrorDismissed(true);
|
|
1655
|
+
store.startNewThread();
|
|
1656
|
+
}, [store]),
|
|
1657
|
+
renameThread,
|
|
1658
|
+
archiveThread,
|
|
1659
|
+
unarchiveThread,
|
|
1660
|
+
deleteThread
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
//#endregion
|
|
1665
|
+
//#region src/types/defineToolCallRenderer.ts
|
|
1666
|
+
function defineToolCallRenderer(def) {
|
|
1667
|
+
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
1668
|
+
return {
|
|
1669
|
+
name: def.name,
|
|
1670
|
+
args: argsSchema,
|
|
1671
|
+
render: def.render,
|
|
1672
|
+
...def.agentId ? { agentId: def.agentId } : {},
|
|
1673
|
+
...def.group ? { group: true } : {}
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
//#endregion
|
|
1678
|
+
//#region src/hooks/use-render-tool.tsx
|
|
1679
|
+
/**
|
|
1680
|
+
* Registers a renderer entry in CopilotKit's `renderToolCalls` registry.
|
|
1681
|
+
*
|
|
1682
|
+
* Key behavior:
|
|
1683
|
+
* - deduplicates by `agentId:name` (latest registration wins),
|
|
1684
|
+
* - keeps renderer entries on cleanup so historical chat tool calls can still render,
|
|
1685
|
+
* - refreshes registration when `deps` change.
|
|
1686
|
+
*
|
|
1687
|
+
* @typeParam S - Schema type describing tool call parameters.
|
|
1688
|
+
* @param config - Renderer config for wildcard or named tools.
|
|
1689
|
+
* @param deps - Optional dependencies to refresh registration.
|
|
1690
|
+
*
|
|
1691
|
+
* @example
|
|
1692
|
+
* ```tsx
|
|
1693
|
+
* useRenderTool(
|
|
1694
|
+
* {
|
|
1695
|
+
* name: "searchDocs",
|
|
1696
|
+
* parameters: z.object({ query: z.string() }),
|
|
1697
|
+
* render: ({ status, parameters, result }) => {
|
|
1698
|
+
* if (status === "executing") return <div>Searching {parameters.query}</div>;
|
|
1699
|
+
* if (status === "complete") return <div>{result}</div>;
|
|
1700
|
+
* return <div>Preparing...</div>;
|
|
1701
|
+
* },
|
|
1702
|
+
* },
|
|
1703
|
+
* [],
|
|
1704
|
+
* );
|
|
1705
|
+
* ```
|
|
1706
|
+
*
|
|
1707
|
+
* @example
|
|
1708
|
+
* ```tsx
|
|
1709
|
+
* useRenderTool(
|
|
1710
|
+
* {
|
|
1711
|
+
* name: "summarize",
|
|
1712
|
+
* parameters: z.object({ text: z.string() }),
|
|
1713
|
+
* agentId: "research-agent",
|
|
1714
|
+
* render: ({ name, status }) => <div>{name}: {status}</div>,
|
|
1715
|
+
* },
|
|
1716
|
+
* [selectedAgentId],
|
|
1717
|
+
* );
|
|
1718
|
+
* ```
|
|
1719
|
+
*/
|
|
1720
|
+
function useRenderTool(config, deps) {
|
|
1721
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1722
|
+
const depsVersion = useDepsVersion(deps);
|
|
1723
|
+
(0, react.useEffect)(() => {
|
|
1724
|
+
const renderer = config.name === "*" && !config.parameters ? defineToolCallRenderer({
|
|
1725
|
+
name: "*",
|
|
1726
|
+
render: (props) => config.render({
|
|
1727
|
+
...props,
|
|
1728
|
+
parameters: props.args
|
|
1729
|
+
}),
|
|
1730
|
+
...config.agentId ? { agentId: config.agentId } : {},
|
|
1731
|
+
group: config.group
|
|
1732
|
+
}) : defineToolCallRenderer({
|
|
1733
|
+
name: config.name,
|
|
1734
|
+
args: config.parameters,
|
|
1735
|
+
render: (props) => {
|
|
1736
|
+
if (props.status === _copilotkit_core.ToolCallStatus.InProgress) return config.render({
|
|
1737
|
+
...props,
|
|
1738
|
+
parameters: props.args
|
|
1739
|
+
});
|
|
1740
|
+
if (props.status === _copilotkit_core.ToolCallStatus.Executing) return config.render({
|
|
1741
|
+
...props,
|
|
1742
|
+
parameters: props.args
|
|
1743
|
+
});
|
|
1744
|
+
return config.render({
|
|
1745
|
+
...props,
|
|
1746
|
+
parameters: props.args
|
|
1747
|
+
});
|
|
1748
|
+
},
|
|
1749
|
+
...config.agentId ? { agentId: config.agentId } : {},
|
|
1750
|
+
group: config.group
|
|
1751
|
+
});
|
|
1752
|
+
copilotkit.addHookRenderToolCall(renderer);
|
|
1753
|
+
}, [
|
|
1754
|
+
config.name,
|
|
1755
|
+
config.group,
|
|
1756
|
+
copilotkit,
|
|
1757
|
+
depsVersion
|
|
1758
|
+
]);
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
//#endregion
|
|
1762
|
+
//#region src/hooks/use-render-tool-call.tsx
|
|
1763
|
+
/**
|
|
1764
|
+
* Memoized component that renders a single tool call.
|
|
1765
|
+
* This prevents unnecessary re-renders when parent components update
|
|
1766
|
+
* but the tool call data hasn't changed.
|
|
1767
|
+
*/
|
|
1768
|
+
const ToolCallRenderer = react.default.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
|
|
1769
|
+
const args = (0, react.useMemo)(() => (0, _copilotkit_shared.partialJSONParse)(toolCall.function.arguments), [toolCall.function.arguments]);
|
|
1770
|
+
const toolName = toolCall.function.name;
|
|
1771
|
+
if (toolMessage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1772
|
+
name: toolName,
|
|
1773
|
+
toolCallId: toolCall.id,
|
|
1774
|
+
args,
|
|
1775
|
+
status: _copilotkit_core.ToolCallStatus.Complete,
|
|
1776
|
+
result: (0, _ag_ui_core.contentToText)(toolMessage.content)
|
|
1777
|
+
});
|
|
1778
|
+
else if (isExecuting) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1779
|
+
name: toolName,
|
|
1780
|
+
toolCallId: toolCall.id,
|
|
1781
|
+
args,
|
|
1782
|
+
status: _copilotkit_core.ToolCallStatus.Executing,
|
|
1783
|
+
result: void 0
|
|
1784
|
+
});
|
|
1785
|
+
else return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1786
|
+
name: toolName,
|
|
1787
|
+
toolCallId: toolCall.id,
|
|
1788
|
+
args,
|
|
1789
|
+
status: _copilotkit_core.ToolCallStatus.InProgress,
|
|
1790
|
+
result: void 0
|
|
1791
|
+
});
|
|
1792
|
+
}, (prevProps, nextProps) => {
|
|
1793
|
+
if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
|
|
1794
|
+
if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
|
|
1795
|
+
if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
|
|
1796
|
+
if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
|
|
1797
|
+
if (prevProps.isExecuting !== nextProps.isExecuting) return false;
|
|
1798
|
+
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
1799
|
+
return true;
|
|
1800
|
+
});
|
|
1801
|
+
const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
|
|
1802
|
+
/**
|
|
1803
|
+
* Reports tool calls that resolved to no renderer.
|
|
1804
|
+
*
|
|
1805
|
+
* A tool call with no renderer paints an empty message container and says
|
|
1806
|
+
* nothing else, so the only signal a developer gets today is a blank space in
|
|
1807
|
+
* the chat. This names the call and the renderers that *are* registered, which
|
|
1808
|
+
* is the whole diagnosis when the cause is a name that does not match.
|
|
1809
|
+
*
|
|
1810
|
+
* @param toolNames - The unmatched tool names collected during render.
|
|
1811
|
+
* @param registered - The registry as it stands now, re-read at report time.
|
|
1812
|
+
* @param alreadyWarned - Names already reported, mutated to keep this once per name.
|
|
1813
|
+
*/
|
|
1814
|
+
function warnAboutUnrenderedToolCalls(toolNames, registered, alreadyWarned) {
|
|
1815
|
+
const registeredNames = Array.from(new Set(registered.map((rc) => rc.name)));
|
|
1816
|
+
const hasWildcard = registeredNames.includes("*");
|
|
1817
|
+
for (const toolName of toolNames) {
|
|
1818
|
+
if (hasWildcard || registeredNames.includes(toolName)) continue;
|
|
1819
|
+
if (alreadyWarned.has(toolName)) continue;
|
|
1820
|
+
alreadyWarned.add(toolName);
|
|
1821
|
+
console.warn(`[CopilotKit] The agent called the tool "${toolName}", and no renderer is registered for it, so that message rendered nothing. ` + (registeredNames.length === 0 ? "No tool-call renderers are registered. " : `Registered renderers: ${registeredNames.map((name) => `"${name}"`).join(", ")}. `) + `Register one with useRenderTool({ name: "${toolName}", ... }), or call useDefaultRenderTool() for a built-in card that covers every tool the agent calls. This warning is development-only.`);
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
/**
|
|
1825
|
+
* The tool-call renderers registered on the provider, kept current.
|
|
1826
|
+
* @internal
|
|
1827
|
+
*/
|
|
1828
|
+
function useToolCallRenderers() {
|
|
1829
|
+
const { copilotkit } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1830
|
+
return (0, react.useSyncExternalStore)((callback) => copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Hook that returns a function to render tool calls based on the render functions
|
|
1834
|
+
* defined in CopilotKitProvider.
|
|
1835
|
+
*
|
|
1836
|
+
* @returns A function that takes a tool call and optional tool message and returns the rendered component
|
|
1837
|
+
*/
|
|
1838
|
+
function useRenderToolCall() {
|
|
1839
|
+
const { copilotkit, executingToolCallIds } = (0, _copilotkit_react_core_context.useCopilotKit)();
|
|
1840
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1841
|
+
const unrenderedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
1842
|
+
const warnedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
1843
|
+
const renderToolCalls = useToolCallRenderers();
|
|
1844
|
+
const renderToolCall = (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
1845
|
+
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1846
|
+
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
1847
|
+
if (!renderConfig) {
|
|
1848
|
+
if (IS_DEVELOPMENT) unrenderedToolNames.current.add(toolCall.function.name);
|
|
1849
|
+
return null;
|
|
1850
|
+
}
|
|
1851
|
+
const RenderComponent = renderConfig.render;
|
|
1852
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRenderer, {
|
|
1853
|
+
toolCall,
|
|
1854
|
+
toolMessage,
|
|
1855
|
+
RenderComponent,
|
|
1856
|
+
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
1857
|
+
}, toolCall.id);
|
|
1858
|
+
}, [
|
|
1859
|
+
renderToolCalls,
|
|
1860
|
+
executingToolCallIds,
|
|
1861
|
+
agentId
|
|
1862
|
+
]);
|
|
1863
|
+
(0, react.useEffect)(() => {
|
|
1864
|
+
if (!IS_DEVELOPMENT) return;
|
|
1865
|
+
if (unrenderedToolNames.current.size === 0) return;
|
|
1866
|
+
const timer = setTimeout(() => {
|
|
1867
|
+
const pending = Array.from(unrenderedToolNames.current);
|
|
1868
|
+
unrenderedToolNames.current.clear();
|
|
1869
|
+
warnAboutUnrenderedToolCalls(pending, copilotkit.renderToolCalls, warnedToolNames.current);
|
|
1870
|
+
}, 0);
|
|
1871
|
+
return () => clearTimeout(timer);
|
|
1872
|
+
});
|
|
1873
|
+
return renderToolCall;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
//#endregion
|
|
1877
|
+
//#region src/hooks/use-capabilities.tsx
|
|
1878
|
+
/**
|
|
1879
|
+
* Returns the capabilities declared by the given agent (or the agent resolved
|
|
1880
|
+
* from the surrounding chat configuration, falling back to the default agent).
|
|
1881
|
+
* Capabilities are populated from the runtime `/info` response at connection
|
|
1882
|
+
* time. The hook reads them synchronously from the agent instance — there is
|
|
1883
|
+
* no separate loading state, but the value will be `undefined` until the
|
|
1884
|
+
* runtime handshake completes.
|
|
1885
|
+
*
|
|
1886
|
+
* @param agentId - Optional agent ID. If omitted, inherits the surrounding
|
|
1887
|
+
* chat configuration's agent, falling back to the default agent.
|
|
1888
|
+
* @returns The agent's capabilities, or `undefined` if the agent doesn't
|
|
1889
|
+
* declare capabilities.
|
|
1890
|
+
*/
|
|
1891
|
+
function useCapabilities(agentId) {
|
|
1892
|
+
const { agent } = useAgent({ agentId });
|
|
1893
|
+
if (agent && "capabilities" in agent) return agent.capabilities;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
//#endregion
|
|
1897
|
+
exports.CopilotChatConfigurationProvider = CopilotChatConfigurationProvider;
|
|
1898
|
+
exports.CopilotChatDefaultLabels = CopilotChatDefaultLabels;
|
|
1899
|
+
Object.defineProperty(exports, 'CopilotKitCoreReact', {
|
|
1900
|
+
enumerable: true,
|
|
1901
|
+
get: function () {
|
|
1902
|
+
return _copilotkit_react_core_context.CopilotKitCoreReact;
|
|
1903
|
+
}
|
|
1904
|
+
});
|
|
1905
|
+
exports.UseAgentUpdate = UseAgentUpdate;
|
|
1906
|
+
exports.defineToolCallRenderer = defineToolCallRenderer;
|
|
1907
|
+
exports.useAgent = useAgent;
|
|
1908
|
+
exports.useAgentContext = useAgentContext;
|
|
1909
|
+
exports.useCapabilities = useCapabilities;
|
|
1910
|
+
exports.useComponent = useComponent;
|
|
1911
|
+
exports.useConfigureSuggestions = useConfigureSuggestions;
|
|
1912
|
+
exports.useCopilotChatConfiguration = useCopilotChatConfiguration;
|
|
1913
|
+
Object.defineProperty(exports, 'useCopilotKit', {
|
|
1914
|
+
enumerable: true,
|
|
1915
|
+
get: function () {
|
|
1916
|
+
return _copilotkit_react_core_context.useCopilotKit;
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
exports.useFrontendTool = useFrontendTool;
|
|
1920
|
+
exports.useFrontendTools = useFrontendTools;
|
|
1921
|
+
exports.useHumanInTheLoop = useHumanInTheLoop;
|
|
1922
|
+
exports.useInterrupt = useInterrupt;
|
|
1923
|
+
exports.useRenderTool = useRenderTool;
|
|
1924
|
+
exports.useRenderToolCall = useRenderToolCall;
|
|
1925
|
+
exports.useSuggestions = useSuggestions;
|
|
1926
|
+
exports.useThreads = useThreads;
|
|
1927
|
+
//# sourceMappingURL=headless.cjs.map
|