@copilotkit/vue 1.57.1
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/AGENTS.md +50 -0
- package/CHANGELOG.md +13 -0
- package/PARITY.md +434 -0
- package/README.md +396 -0
- package/dist/components/copilot-provider/CopilotKit.vue.d.ts +20 -0
- package/dist/components/copilot-provider/CopilotKit.vue.d.ts.map +1 -0
- package/dist/components/copilot-provider/index.d.ts +3 -0
- package/dist/components/copilot-provider/index.d.ts.map +1 -0
- package/dist/components/copilot-provider/types.d.ts +22 -0
- package/dist/components/copilot-provider/types.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/use-copilot-action.d.ts +27 -0
- package/dist/hooks/use-copilot-action.d.ts.map +1 -0
- package/dist/hooks/use-copilot-readable.d.ts +20 -0
- package/dist/hooks/use-copilot-readable.d.ts.map +1 -0
- package/dist/hooks/use-frontend-tool.d.ts +21 -0
- package/dist/hooks/use-frontend-tool.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +252 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/use-render-activity-message-BRL1Rpl-.cjs +85 -0
- package/dist/use-render-activity-message-BRL1Rpl-.cjs.map +1 -0
- package/dist/use-render-activity-message-CqtxiFSs.js +8927 -0
- package/dist/use-render-activity-message-CqtxiFSs.js.map +1 -0
- package/dist/v2/components/A2UIMessageRenderer.d.ts +9 -0
- package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -0
- package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +16 -0
- package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -0
- package/dist/v2/components/CopilotKitInspector.vue.d.ts +7 -0
- package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -0
- package/dist/v2/components/InlineFeatureWarning.vue.d.ts +6 -0
- package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -0
- package/dist/v2/components/LicenseWarningBanner.vue.d.ts +18 -0
- package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -0
- package/dist/v2/components/MCPAppsActivityRenderer.d.ts +88 -0
- package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -0
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +154 -0
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -0
- package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +19 -0
- package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -0
- package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +16 -0
- package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -0
- package/dist/v2/components/a2ui/VueSurface.d.ts +62 -0
- package/dist/v2/components/a2ui/VueSurface.d.ts.map +1 -0
- package/dist/v2/components/a2ui/adapter.d.ts +38 -0
- package/dist/v2/components/a2ui/adapter.d.ts.map +1 -0
- package/dist/v2/components/a2ui/catalog.d.ts +29 -0
- package/dist/v2/components/a2ui/catalog.d.ts.map +1 -0
- package/dist/v2/components/a2ui/index.d.ts +5 -0
- package/dist/v2/components/a2ui/index.d.ts.map +1 -0
- package/dist/v2/components/a2ui/utils.d.ts +18 -0
- package/dist/v2/components/a2ui/utils.d.ts.map +1 -0
- package/dist/v2/components/a2ui.d.ts +12 -0
- package/dist/v2/components/a2ui.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChat.vue.d.ts +50 -0
- package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts +164 -0
- package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts +12 -0
- package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts +7 -0
- package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +12 -0
- package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +290 -0
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +72 -0
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts +65 -0
- package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts +27 -0
- package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts +26 -0
- package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts +17 -0
- package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatToggleButtonCloseIcon.d.ts +5 -0
- package/dist/v2/components/chat/CopilotChatToggleButtonCloseIcon.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatToggleButtonOpenIcon.d.ts +5 -0
- package/dist/v2/components/chat/CopilotChatToggleButtonOpenIcon.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +21 -0
- package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts +34 -0
- package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts +106 -0
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts +15 -0
- package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts +5 -0
- package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts +5 -0
- package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotPopup.vue.d.ts +50 -0
- package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +55 -0
- package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +55 -0
- package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts +28 -0
- package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +48 -0
- package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +62 -0
- package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +53 -0
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts +28 -0
- package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts.map +1 -0
- package/dist/v2/components/chat/audioRecorder.d.ts +11 -0
- package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -0
- package/dist/v2/components/chat/index.d.ts +682 -0
- package/dist/v2/components/chat/index.d.ts.map +1 -0
- package/dist/v2/components/chat/last-user-message-context.d.ts +29 -0
- package/dist/v2/components/chat/last-user-message-context.d.ts.map +1 -0
- package/dist/v2/components/chat/normalize-auto-scroll.d.ts +3 -0
- package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +1 -0
- package/dist/v2/components/chat/types.d.ts +380 -0
- package/dist/v2/components/chat/types.d.ts.map +1 -0
- package/dist/v2/components/icons/index.d.ts +2 -0
- package/dist/v2/components/icons/index.d.ts.map +1 -0
- package/dist/v2/components/index.d.ts +8 -0
- package/dist/v2/components/index.d.ts.map +1 -0
- package/dist/v2/hooks/index.d.ts +24 -0
- package/dist/v2/hooks/index.d.ts.map +1 -0
- package/dist/v2/hooks/use-agent-context.d.ts +24 -0
- package/dist/v2/hooks/use-agent-context.d.ts.map +1 -0
- package/dist/v2/hooks/use-agent.d.ts +53 -0
- package/dist/v2/hooks/use-agent.d.ts.map +1 -0
- package/dist/v2/hooks/use-attachments.d.ts +21 -0
- package/dist/v2/hooks/use-attachments.d.ts.map +1 -0
- package/dist/v2/hooks/use-capabilities.d.ts +16 -0
- package/dist/v2/hooks/use-capabilities.d.ts.map +1 -0
- package/dist/v2/hooks/use-component.d.ts +13 -0
- package/dist/v2/hooks/use-component.d.ts.map +1 -0
- package/dist/v2/hooks/use-configure-suggestions.d.ts +24 -0
- package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -0
- package/dist/v2/hooks/use-default-render-tool.d.ts +14 -0
- package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -0
- package/dist/v2/hooks/use-frontend-tool.d.ts +19 -0
- package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -0
- package/dist/v2/hooks/use-human-in-the-loop.d.ts +19 -0
- package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -0
- package/dist/v2/hooks/use-interrupt.d.ts +36 -0
- package/dist/v2/hooks/use-interrupt.d.ts.map +1 -0
- package/dist/v2/hooks/use-katex-styles.d.ts +22 -0
- package/dist/v2/hooks/use-katex-styles.d.ts.map +1 -0
- package/dist/v2/hooks/use-keyboard-height.d.ts +33 -0
- package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -0
- package/dist/v2/hooks/use-pin-to-send.d.ts +28 -0
- package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -0
- package/dist/v2/hooks/use-render-activity-message.d.ts +21 -0
- package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -0
- package/dist/v2/hooks/use-render-custom-messages.d.ts +27 -0
- package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -0
- package/dist/v2/hooks/use-render-tool.d.ts +36 -0
- package/dist/v2/hooks/use-render-tool.d.ts.map +1 -0
- package/dist/v2/hooks/use-suggestions.d.ts +26 -0
- package/dist/v2/hooks/use-suggestions.d.ts.map +1 -0
- package/dist/v2/hooks/use-threads.d.ts +42 -0
- package/dist/v2/hooks/use-threads.d.ts.map +1 -0
- package/dist/v2/index.cjs +2 -0
- package/dist/v2/index.cjs.map +1 -0
- package/dist/v2/index.d.cts +9 -0
- package/dist/v2/index.d.mts +9 -0
- package/dist/v2/index.d.ts +9 -0
- package/dist/v2/index.d.ts.map +1 -0
- package/dist/v2/index.mjs +75 -0
- package/dist/v2/index.mjs.map +1 -0
- package/dist/v2/lib/processPartialHtml.d.ts +3 -0
- package/dist/v2/lib/processPartialHtml.d.ts.map +1 -0
- package/dist/v2/lib/shallow-stable.d.ts +7 -0
- package/dist/v2/lib/shallow-stable.d.ts.map +1 -0
- package/dist/v2/lib/transcription-client.d.ts +19 -0
- package/dist/v2/lib/transcription-client.d.ts.map +1 -0
- package/dist/v2/lib/vue-core.d.ts +47 -0
- package/dist/v2/lib/vue-core.d.ts.map +1 -0
- package/dist/v2/providers/CopilotChatConfigurationProvider.types.d.ts +15 -0
- package/dist/v2/providers/CopilotChatConfigurationProvider.types.d.ts.map +1 -0
- package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts +17 -0
- package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -0
- package/dist/v2/providers/CopilotKitProvider.types.d.ts +61 -0
- package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -0
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts +37 -0
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -0
- package/dist/v2/providers/SandboxFunctionsContext.d.ts +4 -0
- package/dist/v2/providers/SandboxFunctionsContext.d.ts.map +1 -0
- package/dist/v2/providers/index.d.ts +13 -0
- package/dist/v2/providers/index.d.ts.map +1 -0
- package/dist/v2/providers/keys.d.ts +17 -0
- package/dist/v2/providers/keys.d.ts.map +1 -0
- package/dist/v2/providers/license-context.d.ts +7 -0
- package/dist/v2/providers/license-context.d.ts.map +1 -0
- package/dist/v2/providers/types.d.ts +38 -0
- package/dist/v2/providers/types.d.ts.map +1 -0
- package/dist/v2/providers/useCopilotChatConfiguration.d.ts +4 -0
- package/dist/v2/providers/useCopilotChatConfiguration.d.ts.map +1 -0
- package/dist/v2/providers/useCopilotKit.d.ts +2 -0
- package/dist/v2/providers/useCopilotKit.d.ts.map +1 -0
- package/dist/v2/providers/useLicenseContext.d.ts +14 -0
- package/dist/v2/providers/useLicenseContext.d.ts.map +1 -0
- package/dist/v2/types/a2ui.d.ts +5 -0
- package/dist/v2/types/a2ui.d.ts.map +1 -0
- package/dist/v2/types/defineToolCallRenderer.d.ts +15 -0
- package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -0
- package/dist/v2/types/frontend-tool.d.ts +6 -0
- package/dist/v2/types/frontend-tool.d.ts.map +1 -0
- package/dist/v2/types/human-in-the-loop.d.ts +29 -0
- package/dist/v2/types/human-in-the-loop.d.ts.map +1 -0
- package/dist/v2/types/index.d.ts +10 -0
- package/dist/v2/types/index.d.ts.map +1 -0
- package/dist/v2/types/interrupt.d.ts +14 -0
- package/dist/v2/types/interrupt.d.ts.map +1 -0
- package/dist/v2/types/sandbox-function.d.ts +8 -0
- package/dist/v2/types/sandbox-function.d.ts.map +1 -0
- package/dist/v2/types/vue-activity-message-renderer.d.ts +18 -0
- package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -0
- package/dist/v2/types/vue-custom-message-renderer.d.ts +19 -0
- package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -0
- package/dist/v2/types/vue-tool-call-renderer.d.ts +37 -0
- package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -0
- package/env.d.ts +7 -0
- package/eslint.config.mjs +42 -0
- package/package.json +130 -0
- package/scripts/scope-preflight.mjs +100 -0
- package/src/components/copilot-provider/CopilotKit.vue +18 -0
- package/src/components/copilot-provider/index.ts +2 -0
- package/src/components/copilot-provider/types.ts +24 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/use-copilot-action.ts +168 -0
- package/src/hooks/use-copilot-readable.ts +75 -0
- package/src/hooks/use-frontend-tool.ts +76 -0
- package/src/index.ts +12 -0
- package/src/styles/globals.css +314 -0
- package/src/v2/__tests__/exports.test.ts +35 -0
- package/src/v2/__tests__/mocks/web-inspector.ts +5 -0
- package/src/v2/__tests__/setup.ts +141 -0
- package/src/v2/__tests__/utils/agents.ts +391 -0
- package/src/v2/__tests__/utils/mount.ts +83 -0
- package/src/v2/__tests__/utils/test-helpers.ts +712 -0
- package/src/v2/components/A2UIMessageRenderer.ts +125 -0
- package/src/v2/components/A2UISurfaceActivityRenderer.vue +186 -0
- package/src/v2/components/CopilotKitInspector.vue +42 -0
- package/src/v2/components/InlineFeatureWarning.vue +35 -0
- package/src/v2/components/LicenseWarningBanner.vue +196 -0
- package/src/v2/components/MCPAppsActivityRenderer.ts +778 -0
- package/src/v2/components/OpenGenerativeUIRenderer.ts +550 -0
- package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +271 -0
- package/src/v2/components/__tests__/CopilotKitInspector.test.ts +57 -0
- package/src/v2/components/__tests__/MCPAppsActivityRenderer.e2e.test.ts +851 -0
- package/src/v2/components/__tests__/MCPAppsActivityRenderer.test.ts +237 -0
- package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +516 -0
- package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +295 -0
- package/src/v2/components/a2ui/A2UICatalogContext.ts +190 -0
- package/src/v2/components/a2ui/VueSurface.ts +144 -0
- package/src/v2/components/a2ui/adapter.ts +156 -0
- package/src/v2/components/a2ui/catalog.ts +858 -0
- package/src/v2/components/a2ui/index.ts +7 -0
- package/src/v2/components/a2ui/utils.ts +67 -0
- package/src/v2/components/a2ui.ts +30 -0
- package/src/v2/components/chat/CopilotChat.vue +777 -0
- package/src/v2/components/chat/CopilotChatAssistantMessage.vue +891 -0
- package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +411 -0
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +87 -0
- package/src/v2/components/chat/CopilotChatAudioRecorder.vue +269 -0
- package/src/v2/components/chat/CopilotChatInput.vue +1271 -0
- package/src/v2/components/chat/CopilotChatMessageView.vue +476 -0
- package/src/v2/components/chat/CopilotChatReasoningMessage.vue +247 -0
- package/src/v2/components/chat/CopilotChatSuggestionPill.vue +56 -0
- package/src/v2/components/chat/CopilotChatSuggestionView.vue +93 -0
- package/src/v2/components/chat/CopilotChatToggleButton.vue +145 -0
- package/src/v2/components/chat/CopilotChatToggleButtonCloseIcon.ts +17 -0
- package/src/v2/components/chat/CopilotChatToggleButtonOpenIcon.ts +18 -0
- package/src/v2/components/chat/CopilotChatToolCallsView.vue +161 -0
- package/src/v2/components/chat/CopilotChatUserMessage.vue +322 -0
- package/src/v2/components/chat/CopilotChatView.vue +740 -0
- package/src/v2/components/chat/CopilotModalHeader.vue +73 -0
- package/src/v2/components/chat/CopilotModalHeaderCloseButton.ts +38 -0
- package/src/v2/components/chat/CopilotModalHeaderTitle.ts +22 -0
- package/src/v2/components/chat/CopilotPopup.vue +182 -0
- package/src/v2/components/chat/CopilotPopupView.vue +168 -0
- package/src/v2/components/chat/CopilotPopupViewInternal.vue +453 -0
- package/src/v2/components/chat/CopilotPopupWelcomeScreen.vue +140 -0
- package/src/v2/components/chat/CopilotSidebar.vue +178 -0
- package/src/v2/components/chat/CopilotSidebarView.vue +172 -0
- package/src/v2/components/chat/CopilotSidebarViewInternal.vue +366 -0
- package/src/v2/components/chat/CopilotSidebarWelcomeScreen.vue +142 -0
- package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.ts +237 -0
- package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.ts +1240 -0
- package/src/v2/components/chat/__tests__/CopilotChat.licenseWarning.test.ts +138 -0
- package/src/v2/components/chat/__tests__/CopilotChat.onError.test.ts +85 -0
- package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.ts +141 -0
- package/src/v2/components/chat/__tests__/CopilotChat.test.ts +652 -0
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +683 -0
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.ts +768 -0
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.ts +1108 -0
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.thumbs.test.ts +87 -0
- package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +277 -0
- package/src/v2/components/chat/__tests__/CopilotChatAttachmentRenderer.test.ts +124 -0
- package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.ts +230 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.bottomAnchored.test.ts +83 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.ts +1139 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +1051 -0
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.ts +141 -0
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +494 -0
- package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.ts +181 -0
- package/src/v2/components/chat/__tests__/CopilotChatReasoningMessage.test.ts +73 -0
- package/src/v2/components/chat/__tests__/CopilotChatSuggestionPill.test.ts +73 -0
- package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.ts +674 -0
- package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.test.ts +91 -0
- package/src/v2/components/chat/__tests__/CopilotChatToggleButton.test.ts +93 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolCallsView.test.ts +382 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.ts +1019 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.ts +516 -0
- package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.ts +701 -0
- package/src/v2/components/chat/__tests__/CopilotChatUserMessage.test.ts +337 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.connectingGate.test.ts +135 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.ts +278 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.ts +1082 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +166 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.ts +1145 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.test.ts +374 -0
- package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.ts +636 -0
- package/src/v2/components/chat/__tests__/CopilotModalHeader.test.ts +112 -0
- package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +58 -0
- package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.ts +725 -0
- package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +112 -0
- package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +58 -0
- package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.ts +603 -0
- package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +214 -0
- package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.ts +394 -0
- package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.ts +82 -0
- package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +39 -0
- package/src/v2/components/chat/audioRecorder.ts +15 -0
- package/src/v2/components/chat/index.ts +52 -0
- package/src/v2/components/chat/last-user-message-context.ts +39 -0
- package/src/v2/components/chat/normalize-auto-scroll.ts +17 -0
- package/src/v2/components/chat/types.ts +481 -0
- package/src/v2/components/icons/__tests__/icons.test.ts +86 -0
- package/src/v2/components/icons/index.ts +22 -0
- package/src/v2/components/index.ts +7 -0
- package/src/v2/hooks/__tests__/standard-schema-types.test.ts +149 -0
- package/src/v2/hooks/__tests__/standard-schema.test.ts +315 -0
- package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.ts +144 -0
- package/src/v2/hooks/__tests__/use-agent-context.test.ts +271 -0
- package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +64 -0
- package/src/v2/hooks/__tests__/use-agent-stability.test.ts +268 -0
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.ts +433 -0
- package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +747 -0
- package/src/v2/hooks/__tests__/use-agent.e2e.test.ts +187 -0
- package/src/v2/hooks/__tests__/use-agent.test.ts +126 -0
- package/src/v2/hooks/__tests__/use-attachments.test.ts +181 -0
- package/src/v2/hooks/__tests__/use-component.test.ts +145 -0
- package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.ts +527 -0
- package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +399 -0
- package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +214 -0
- package/src/v2/hooks/__tests__/use-frontend-tool-available.test.ts +220 -0
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +2320 -0
- package/src/v2/hooks/__tests__/use-frontend-tool.test.ts +648 -0
- package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +1379 -0
- package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +282 -0
- package/src/v2/hooks/__tests__/use-interrupt.test.ts +345 -0
- package/src/v2/hooks/__tests__/use-katex-styles.test.ts +69 -0
- package/src/v2/hooks/__tests__/use-keyboard-height.test.ts +199 -0
- package/src/v2/hooks/__tests__/use-pin-to-send.test.ts +363 -0
- package/src/v2/hooks/__tests__/use-render-tool.test.ts +329 -0
- package/src/v2/hooks/__tests__/use-suggestions.e2e.test.ts +397 -0
- package/src/v2/hooks/__tests__/use-suggestions.test.ts +198 -0
- package/src/v2/hooks/__tests__/use-threads.test.ts +1041 -0
- package/src/v2/hooks/__tests__/zod-regression.test.ts +339 -0
- package/src/v2/hooks/index.ts +29 -0
- package/src/v2/hooks/use-agent-context.ts +55 -0
- package/src/v2/hooks/use-agent.ts +345 -0
- package/src/v2/hooks/use-attachments.ts +261 -0
- package/src/v2/hooks/use-capabilities.ts +30 -0
- package/src/v2/hooks/use-component.ts +46 -0
- package/src/v2/hooks/use-configure-suggestions.ts +252 -0
- package/src/v2/hooks/use-default-render-tool.ts +130 -0
- package/src/v2/hooks/use-frontend-tool.ts +68 -0
- package/src/v2/hooks/use-human-in-the-loop.ts +90 -0
- package/src/v2/hooks/use-interrupt.ts +257 -0
- package/src/v2/hooks/use-katex-styles.ts +44 -0
- package/src/v2/hooks/use-keyboard-height.ts +87 -0
- package/src/v2/hooks/use-pin-to-send.ts +160 -0
- package/src/v2/hooks/use-render-activity-message.ts +92 -0
- package/src/v2/hooks/use-render-custom-messages.ts +129 -0
- package/src/v2/hooks/use-render-tool.ts +128 -0
- package/src/v2/hooks/use-suggestions.ts +98 -0
- package/src/v2/hooks/use-threads.ts +208 -0
- package/src/v2/index.ts +11 -0
- package/src/v2/lib/__tests__/processPartialHtml.test.ts +84 -0
- package/src/v2/lib/__tests__/transcription-client.test.ts +65 -0
- package/src/v2/lib/processPartialHtml.ts +21 -0
- package/src/v2/lib/shallow-stable.ts +54 -0
- package/src/v2/lib/transcription-client.ts +151 -0
- package/src/v2/lib/vue-core.ts +161 -0
- package/src/v2/providers/CopilotChatConfigurationProvider.types.ts +15 -0
- package/src/v2/providers/CopilotChatConfigurationProvider.vue +95 -0
- package/src/v2/providers/CopilotKitProvider.types.ts +66 -0
- package/src/v2/providers/CopilotKitProvider.vue +653 -0
- package/src/v2/providers/SandboxFunctionsContext.ts +11 -0
- package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +309 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.debug.test.ts +295 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.license.test.ts +110 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.ts +67 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.ts +901 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +141 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.ts +871 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +603 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.ts +104 -0
- package/src/v2/providers/index.ts +21 -0
- package/src/v2/providers/keys.ts +25 -0
- package/src/v2/providers/license-context.ts +16 -0
- package/src/v2/providers/types.ts +40 -0
- package/src/v2/providers/useCopilotChatConfiguration.ts +11 -0
- package/src/v2/providers/useCopilotKit.ts +11 -0
- package/src/v2/providers/useLicenseContext.ts +21 -0
- package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +157 -0
- package/src/v2/types/a2ui.ts +5 -0
- package/src/v2/types/defineToolCallRenderer.ts +32 -0
- package/src/v2/types/frontend-tool.ts +8 -0
- package/src/v2/types/human-in-the-loop.ts +38 -0
- package/src/v2/types/index.ts +9 -0
- package/src/v2/types/interrupt.ts +15 -0
- package/src/v2/types/sandbox-function.ts +8 -0
- package/src/v2/types/vue-activity-message-renderer.ts +22 -0
- package/src/v2/types/vue-custom-message-renderer.ts +24 -0
- package/src/v2/types/vue-tool-call-renderer.ts +44 -0
- package/tsconfig.json +27 -0
- package/vite.config.ts +49 -0
- package/vitest.config.ts +23 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { computed, onScopeDispose, shallowRef, watch } from "vue";
|
|
2
|
+
import type { ComputedRef, Ref } from "vue";
|
|
3
|
+
import { useCopilotKit } from "../providers/useCopilotKit";
|
|
4
|
+
import { useAgent } from "./use-agent";
|
|
5
|
+
import type {
|
|
6
|
+
InterruptEvent,
|
|
7
|
+
InterruptHandlerProps,
|
|
8
|
+
InterruptRenderProps,
|
|
9
|
+
} from "../types/interrupt";
|
|
10
|
+
|
|
11
|
+
export type { InterruptEvent, InterruptHandlerProps, InterruptRenderProps };
|
|
12
|
+
|
|
13
|
+
const INTERRUPT_EVENT_NAME = "on_interrupt";
|
|
14
|
+
|
|
15
|
+
type InterruptHandlerFn<TValue, TResult> = (
|
|
16
|
+
props: InterruptHandlerProps<TValue>,
|
|
17
|
+
) => TResult | PromiseLike<TResult>;
|
|
18
|
+
|
|
19
|
+
type InterruptResultFromHandler<THandler> = THandler extends (
|
|
20
|
+
...args: never[]
|
|
21
|
+
) => infer TResult
|
|
22
|
+
? TResult extends PromiseLike<infer TResolved>
|
|
23
|
+
? TResolved | null
|
|
24
|
+
: TResult | null
|
|
25
|
+
: null;
|
|
26
|
+
|
|
27
|
+
type InterruptResult<TValue, TResult> = InterruptResultFromHandler<
|
|
28
|
+
InterruptHandlerFn<TValue, TResult>
|
|
29
|
+
>;
|
|
30
|
+
|
|
31
|
+
export interface UseInterruptConfig<TValue = unknown, TResult = never> {
|
|
32
|
+
handler?: InterruptHandlerFn<TValue, TResult>;
|
|
33
|
+
enabled?: (event: InterruptEvent<TValue>) => boolean;
|
|
34
|
+
agentId?: string;
|
|
35
|
+
renderInChat?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface UseInterruptResult<TValue = unknown, TResult = never> {
|
|
39
|
+
interrupt: Ref<InterruptEvent<TValue> | null>;
|
|
40
|
+
result: Ref<InterruptResult<TValue, TResult>>;
|
|
41
|
+
hasInterrupt: ComputedRef<boolean>;
|
|
42
|
+
resolveInterrupt: (response: unknown) => void;
|
|
43
|
+
slotProps: ComputedRef<InterruptRenderProps<
|
|
44
|
+
TValue,
|
|
45
|
+
InterruptResult<TValue, TResult>
|
|
46
|
+
> | null>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function isPromiseLike<TValue>(
|
|
50
|
+
value: TValue | PromiseLike<TValue>,
|
|
51
|
+
): value is PromiseLike<TValue> {
|
|
52
|
+
return (
|
|
53
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
54
|
+
value !== null &&
|
|
55
|
+
typeof Reflect.get(value, "then") === "function"
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function normalizeAsyncResult<TValue>(
|
|
60
|
+
value: PromiseLike<TValue>,
|
|
61
|
+
): Promise<TValue> {
|
|
62
|
+
if (value instanceof Promise) {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return new Promise<TValue>((resolve, reject) => {
|
|
67
|
+
try {
|
|
68
|
+
value.then(resolve, reject);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
reject(error);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Vue composable for handling `on_interrupt` custom events from an agent.
|
|
77
|
+
*
|
|
78
|
+
* It tracks the latest pending interrupt, optionally derives UI data via
|
|
79
|
+
* `handler`, and can publish slot state into `CopilotChat` so consumers render
|
|
80
|
+
* interrupts through the `#interrupt` slot instead of render functions/TSX.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const { interrupt, hasInterrupt, resolveInterrupt } = useInterrupt({
|
|
85
|
+
* handler: ({ event }) => ({ label: String(event.value) }),
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export function useInterrupt<TValue = unknown, TResult = never>(
|
|
90
|
+
config: UseInterruptConfig<TValue, TResult> = {},
|
|
91
|
+
): UseInterruptResult<TValue, TResult> {
|
|
92
|
+
const { copilotkit } = useCopilotKit();
|
|
93
|
+
const { agent } = useAgent({ agentId: config.agentId });
|
|
94
|
+
const interrupt = shallowRef<InterruptEvent<TValue> | null>(null);
|
|
95
|
+
const result = shallowRef<InterruptResult<TValue, TResult>>(null);
|
|
96
|
+
|
|
97
|
+
watch(
|
|
98
|
+
agent,
|
|
99
|
+
(resolvedAgent, _previousAgent, onCleanup) => {
|
|
100
|
+
if (!resolvedAgent) {
|
|
101
|
+
interrupt.value = null;
|
|
102
|
+
result.value = null;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let localInterrupt: InterruptEvent<TValue> | null = null;
|
|
107
|
+
const subscription = resolvedAgent.subscribe({
|
|
108
|
+
onCustomEvent: ({ event }) => {
|
|
109
|
+
if (event.name === INTERRUPT_EVENT_NAME) {
|
|
110
|
+
localInterrupt = {
|
|
111
|
+
name: event.name,
|
|
112
|
+
value: event.value as TValue,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
onRunStartedEvent: () => {
|
|
117
|
+
localInterrupt = null;
|
|
118
|
+
interrupt.value = null;
|
|
119
|
+
},
|
|
120
|
+
onRunFinalized: () => {
|
|
121
|
+
if (localInterrupt) {
|
|
122
|
+
interrupt.value = localInterrupt;
|
|
123
|
+
localInterrupt = null;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
onRunFailed: () => {
|
|
127
|
+
localInterrupt = null;
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
onCleanup(() => subscription.unsubscribe());
|
|
132
|
+
},
|
|
133
|
+
{ immediate: true },
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const resolveInterrupt = (response: unknown) => {
|
|
137
|
+
const resolvedAgent = agent.value;
|
|
138
|
+
if (!resolvedAgent) return;
|
|
139
|
+
|
|
140
|
+
const interruptEventValue = interrupt.value?.value;
|
|
141
|
+
interrupt.value = null;
|
|
142
|
+
void copilotkit.value.runAgent({
|
|
143
|
+
agent: resolvedAgent,
|
|
144
|
+
forwardedProps: {
|
|
145
|
+
command: {
|
|
146
|
+
resume: response,
|
|
147
|
+
interruptEvent: interruptEventValue,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
}).catch((error) => {
|
|
151
|
+
console.error("[CopilotKit] useInterrupt: failed to resume agent:", error);
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
watch(
|
|
156
|
+
interrupt,
|
|
157
|
+
(pendingEvent, _previous, onCleanup) => {
|
|
158
|
+
if (!pendingEvent) {
|
|
159
|
+
result.value = null;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (config.enabled && !config.enabled(pendingEvent)) {
|
|
163
|
+
result.value = null;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const handler = config.handler;
|
|
167
|
+
if (!handler) {
|
|
168
|
+
result.value = null;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let cancelled = false;
|
|
173
|
+
const maybePromise = handler({
|
|
174
|
+
event: pendingEvent,
|
|
175
|
+
resolve: resolveInterrupt,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (isPromiseLike(maybePromise)) {
|
|
179
|
+
normalizeAsyncResult(maybePromise)
|
|
180
|
+
.then((resolved) => {
|
|
181
|
+
if (!cancelled) {
|
|
182
|
+
result.value = resolved;
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
.catch((err) => {
|
|
186
|
+
if (!cancelled) {
|
|
187
|
+
console.error("[CopilotKit] useInterrupt handler failed:", err);
|
|
188
|
+
result.value = null;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
result.value = maybePromise;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
onCleanup(() => {
|
|
196
|
+
cancelled = true;
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
{ immediate: true },
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const slotProps = computed<InterruptRenderProps<
|
|
203
|
+
TValue,
|
|
204
|
+
InterruptResult<TValue, TResult>
|
|
205
|
+
> | null>(() => {
|
|
206
|
+
if (!interrupt.value) return null;
|
|
207
|
+
if (config.enabled && !config.enabled(interrupt.value)) return null;
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
event: interrupt.value,
|
|
211
|
+
result: result.value,
|
|
212
|
+
resolve: resolveInterrupt,
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
watch(
|
|
217
|
+
[() => copilotkit.value, slotProps, () => config.renderInChat !== false],
|
|
218
|
+
([core, nextSlotProps, shouldRenderInChat], _previous, onCleanup) => {
|
|
219
|
+
if (!shouldRenderInChat) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
core.setInterruptState(
|
|
224
|
+
nextSlotProps as InterruptRenderProps<any, any> | null,
|
|
225
|
+
);
|
|
226
|
+
const publishedState = nextSlotProps;
|
|
227
|
+
|
|
228
|
+
onCleanup(() => {
|
|
229
|
+
if (core.interruptState === publishedState) {
|
|
230
|
+
core.setInterruptState(null);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
{ immediate: true },
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
onScopeDispose(() => {
|
|
238
|
+
const core = copilotkit.value;
|
|
239
|
+
if (
|
|
240
|
+
config.renderInChat !== false &&
|
|
241
|
+
core.interruptState === slotProps.value
|
|
242
|
+
) {
|
|
243
|
+
core.setInterruptState(null);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
interrupt: interrupt as Ref<InterruptEvent<TValue> | null>,
|
|
249
|
+
result: result as Ref<InterruptResult<TValue, TResult>>,
|
|
250
|
+
hasInterrupt: computed(() => slotProps.value !== null),
|
|
251
|
+
resolveInterrupt,
|
|
252
|
+
slotProps: slotProps as ComputedRef<InterruptRenderProps<
|
|
253
|
+
TValue,
|
|
254
|
+
InterruptResult<TValue, TResult>
|
|
255
|
+
> | null>,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { onMounted } from "vue";
|
|
2
|
+
|
|
3
|
+
// Module-level singleton flag so the stylesheet is only injected once per
|
|
4
|
+
// module graph (matches the React singleton injection intent).
|
|
5
|
+
let injected = false;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Dynamically loads KaTeX CSS at runtime to avoid Next.js-style
|
|
9
|
+
* "Global CSS cannot be imported from within node_modules" build errors and
|
|
10
|
+
* to keep the CSS out of the static import graph.
|
|
11
|
+
*
|
|
12
|
+
* Uses a module-level singleton flag so the stylesheet is only loaded once,
|
|
13
|
+
* regardless of how many components call this composable.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors the React `useKatexStyles` hook: returns `void`, never throws, and
|
|
16
|
+
* logs a warning with equivalent intent if the dynamic import fails.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```vue
|
|
20
|
+
* <script setup lang="ts">
|
|
21
|
+
* import { useKatexStyles } from "@copilotkit/vue";
|
|
22
|
+
*
|
|
23
|
+
* useKatexStyles();
|
|
24
|
+
* </script>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function useKatexStyles(): void {
|
|
28
|
+
onMounted(() => {
|
|
29
|
+
if (injected || typeof document === "undefined") return;
|
|
30
|
+
injected = true;
|
|
31
|
+
|
|
32
|
+
// Dynamic import defers CSS loading to runtime, bypassing build-time
|
|
33
|
+
// static analysis that rejects global CSS from node_modules.
|
|
34
|
+
// The `@vite-ignore` + indirect specifier keeps TypeScript from trying
|
|
35
|
+
// to resolve a type declaration for the CSS module while still letting
|
|
36
|
+
// the bundler handle the actual side-effect import at runtime.
|
|
37
|
+
const katexStylesSpecifier = "katex/dist/katex.min.css";
|
|
38
|
+
void import(/* @vite-ignore */ katexStylesSpecifier).catch(() => {
|
|
39
|
+
console.warn(
|
|
40
|
+
"[CopilotKit] Failed to load katex styles — math content may render without formatting",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { onBeforeUnmount, onMounted, readonly, ref, type Ref } from "vue";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vue-idiomatic result of {@link useKeyboardHeight}. Fields mirror the React
|
|
5
|
+
* `KeyboardState` shape (`isKeyboardOpen`, `keyboardHeight`, `availableHeight`,
|
|
6
|
+
* `viewportHeight`) and are exposed as readonly refs so consumers can bind them
|
|
7
|
+
* reactively inside templates or computed values.
|
|
8
|
+
*/
|
|
9
|
+
export interface KeyboardState {
|
|
10
|
+
isKeyboardOpen: Readonly<Ref<boolean>>;
|
|
11
|
+
keyboardHeight: Readonly<Ref<number>>;
|
|
12
|
+
availableHeight: Readonly<Ref<number>>;
|
|
13
|
+
viewportHeight: Readonly<Ref<number>>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Composable to detect mobile keyboard appearance and calculate available
|
|
18
|
+
* viewport height. Uses the Visual Viewport API to track keyboard state on
|
|
19
|
+
* mobile devices.
|
|
20
|
+
*
|
|
21
|
+
* Mirrors the React `useKeyboardHeight` hook: returns `keyboardHeight` as the
|
|
22
|
+
* difference between `window.innerHeight` and `visualViewport.height`, clamped
|
|
23
|
+
* to `0`, and reports the keyboard as open when the diff exceeds `150` px.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```vue
|
|
27
|
+
* <script setup lang="ts">
|
|
28
|
+
* import { useKeyboardHeight } from "@copilotkit/vue";
|
|
29
|
+
*
|
|
30
|
+
* const { isKeyboardOpen, keyboardHeight } = useKeyboardHeight();
|
|
31
|
+
* </script>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function useKeyboardHeight(): KeyboardState {
|
|
35
|
+
const initialHeight = typeof window !== "undefined" ? window.innerHeight : 0;
|
|
36
|
+
const isKeyboardOpen = ref(false);
|
|
37
|
+
const keyboardHeight = ref(0);
|
|
38
|
+
const availableHeight = ref(initialHeight);
|
|
39
|
+
const viewportHeight = ref(initialHeight);
|
|
40
|
+
|
|
41
|
+
const updateKeyboardState = () => {
|
|
42
|
+
if (typeof window === "undefined") return;
|
|
43
|
+
const visualViewport = window.visualViewport;
|
|
44
|
+
if (!visualViewport) return;
|
|
45
|
+
|
|
46
|
+
const layoutHeight = window.innerHeight;
|
|
47
|
+
const visualHeight = visualViewport.height;
|
|
48
|
+
|
|
49
|
+
// Keyboard height = layout viewport minus visual viewport, clamped to 0.
|
|
50
|
+
const nextKeyboardHeight = Math.max(0, layoutHeight - visualHeight);
|
|
51
|
+
// Only treat the keyboard as open past the 150px threshold, matching
|
|
52
|
+
// the React implementation's mobile heuristic.
|
|
53
|
+
const nextIsOpen = nextKeyboardHeight > 150;
|
|
54
|
+
|
|
55
|
+
keyboardHeight.value = nextKeyboardHeight;
|
|
56
|
+
isKeyboardOpen.value = nextIsOpen;
|
|
57
|
+
availableHeight.value = visualHeight;
|
|
58
|
+
viewportHeight.value = layoutHeight;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
let visualViewport: VisualViewport | null = null;
|
|
62
|
+
|
|
63
|
+
onMounted(() => {
|
|
64
|
+
if (typeof window === "undefined") return;
|
|
65
|
+
visualViewport = window.visualViewport ?? null;
|
|
66
|
+
if (!visualViewport) return;
|
|
67
|
+
|
|
68
|
+
updateKeyboardState();
|
|
69
|
+
|
|
70
|
+
visualViewport.addEventListener("resize", updateKeyboardState);
|
|
71
|
+
visualViewport.addEventListener("scroll", updateKeyboardState);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
onBeforeUnmount(() => {
|
|
75
|
+
if (!visualViewport) return;
|
|
76
|
+
visualViewport.removeEventListener("resize", updateKeyboardState);
|
|
77
|
+
visualViewport.removeEventListener("scroll", updateKeyboardState);
|
|
78
|
+
visualViewport = null;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
isKeyboardOpen: readonly(isKeyboardOpen),
|
|
83
|
+
keyboardHeight: readonly(keyboardHeight),
|
|
84
|
+
availableHeight: readonly(availableHeight),
|
|
85
|
+
viewportHeight: readonly(viewportHeight),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { inject, watch, type Ref } from "vue";
|
|
2
|
+
import {
|
|
3
|
+
LastUserMessageKey,
|
|
4
|
+
createDefaultLastUserMessageRef,
|
|
5
|
+
} from "../components/chat/last-user-message-context";
|
|
6
|
+
|
|
7
|
+
export interface UsePinToSendOptions {
|
|
8
|
+
scrollRef: Ref<HTMLElement | null>;
|
|
9
|
+
contentRef: Ref<HTMLElement | null>;
|
|
10
|
+
spacerRef: Ref<HTMLElement | null>;
|
|
11
|
+
topOffset?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Vue counterpart of React's `usePinToSend` (`packages/react-core/src/v2/hooks/use-pin-to-send.ts`).
|
|
16
|
+
*
|
|
17
|
+
* Anchors the chat scroll container so the most recent user message stays
|
|
18
|
+
* pinned near the top of the viewport while the assistant streams a
|
|
19
|
+
* response beneath it.
|
|
20
|
+
*
|
|
21
|
+
* Implementation parity with React:
|
|
22
|
+
* - Reads the latest user message via the `LastUserMessageContext`
|
|
23
|
+
* equivalent (`LastUserMessageKey` + `Ref<LastUserMessageState>`).
|
|
24
|
+
* - On each `sendNonce` increment, sizes the spacer to
|
|
25
|
+
* `viewportHeight - bubbleHeight - topOffset` and scrolls so the bubble
|
|
26
|
+
* sits `topOffset` from the viewport top (padding above the bubble is
|
|
27
|
+
* pushed off-screen).
|
|
28
|
+
* - Installs a shrink-only `ResizeObserver` on `contentRef` that collapses
|
|
29
|
+
* the spacer as the assistant response grows; never grows it back.
|
|
30
|
+
* - Cancels the scheduled `requestAnimationFrame` and disconnects the
|
|
31
|
+
* `ResizeObserver` on subsequent re-runs and on scope dispose.
|
|
32
|
+
*/
|
|
33
|
+
export function usePinToSend({
|
|
34
|
+
scrollRef,
|
|
35
|
+
contentRef,
|
|
36
|
+
spacerRef,
|
|
37
|
+
topOffset = 16,
|
|
38
|
+
}: UsePinToSendOptions): void {
|
|
39
|
+
const lastUserMessage = inject(
|
|
40
|
+
LastUserMessageKey,
|
|
41
|
+
createDefaultLastUserMessageRef(),
|
|
42
|
+
true,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
let lastNonce = -1;
|
|
46
|
+
let currentSpacerHeight = 0;
|
|
47
|
+
let raf: number | null = null;
|
|
48
|
+
let ro: ResizeObserver | null = null;
|
|
49
|
+
|
|
50
|
+
function teardown() {
|
|
51
|
+
if (raf !== null && typeof cancelAnimationFrame === "function") {
|
|
52
|
+
cancelAnimationFrame(raf);
|
|
53
|
+
}
|
|
54
|
+
raf = null;
|
|
55
|
+
ro?.disconnect();
|
|
56
|
+
ro = null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
watch(
|
|
60
|
+
[
|
|
61
|
+
() => lastUserMessage.value.id,
|
|
62
|
+
() => lastUserMessage.value.sendNonce,
|
|
63
|
+
scrollRef,
|
|
64
|
+
contentRef,
|
|
65
|
+
spacerRef,
|
|
66
|
+
() => topOffset,
|
|
67
|
+
],
|
|
68
|
+
([id, sendNonce, scrollEl, contentEl, spacerEl], _old, onCleanup) => {
|
|
69
|
+
// Always tear down the previous run's RAF / ResizeObserver before
|
|
70
|
+
// evaluating any of the early-exit guards below. Mirrors React
|
|
71
|
+
// `useEffect` cleanup semantics: the prior run's cleanup runs before
|
|
72
|
+
// the next callback executes regardless of why the deps changed.
|
|
73
|
+
// Without this, a reactive `autoScroll` mode change (e.g. switching
|
|
74
|
+
// away from `"pin-to-send"`) or a `ref` swap that doesn't bump
|
|
75
|
+
// `sendNonce` would leak the stale content-element observer because
|
|
76
|
+
// the nonce guard skips the body. Registering via `onCleanup` also
|
|
77
|
+
// covers watcher stop on scope dispose, so an explicit
|
|
78
|
+
// `onScopeDispose(teardown)` is no longer required.
|
|
79
|
+
onCleanup(teardown);
|
|
80
|
+
|
|
81
|
+
if (sendNonce === lastNonce) return;
|
|
82
|
+
lastNonce = sendNonce;
|
|
83
|
+
|
|
84
|
+
if (!id) return;
|
|
85
|
+
if (!scrollEl || !contentEl || !spacerEl) return;
|
|
86
|
+
|
|
87
|
+
const escaped =
|
|
88
|
+
typeof CSS !== "undefined" && typeof CSS.escape === "function"
|
|
89
|
+
? CSS.escape(id)
|
|
90
|
+
: id.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
91
|
+
const targetEl = contentEl.querySelector<HTMLElement>(
|
|
92
|
+
`[data-message-id="${escaped}"]`,
|
|
93
|
+
);
|
|
94
|
+
if (!targetEl) return;
|
|
95
|
+
|
|
96
|
+
// The target message's element has a top padding (e.g. `pt-10`) that
|
|
97
|
+
// creates breathing room above the visible bubble. When we "anchor at
|
|
98
|
+
// the top", we mean anchor the *bubble*, not the element's padded box.
|
|
99
|
+
// So we scroll past the padding (it goes above the viewport, hiding
|
|
100
|
+
// whatever was above the element too — including the previous message's
|
|
101
|
+
// trailing copy button).
|
|
102
|
+
const viewportHeight = scrollEl.clientHeight;
|
|
103
|
+
const userMessageHeight = targetEl.getBoundingClientRect().height;
|
|
104
|
+
const paddingTop = parseFloat(getComputedStyle(targetEl).paddingTop) || 0;
|
|
105
|
+
const bubbleHeight = Math.max(0, userMessageHeight - paddingTop);
|
|
106
|
+
const spacerHeight = Math.max(
|
|
107
|
+
0,
|
|
108
|
+
viewportHeight - bubbleHeight - topOffset,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
spacerEl.style.height = `${spacerHeight}px`;
|
|
112
|
+
currentSpacerHeight = spacerHeight;
|
|
113
|
+
|
|
114
|
+
if (typeof requestAnimationFrame === "function") {
|
|
115
|
+
raf = requestAnimationFrame(() => {
|
|
116
|
+
// Scroll so the BUBBLE is `topOffset` from the viewport top — the
|
|
117
|
+
// padding above the bubble ends up scrolled off-screen.
|
|
118
|
+
const targetTop =
|
|
119
|
+
computeOffsetTop(targetEl, scrollEl) + paddingTop - topOffset;
|
|
120
|
+
scrollEl.scrollTo({
|
|
121
|
+
top: Math.max(0, targetTop),
|
|
122
|
+
behavior: "smooth",
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Shrink-only ResizeObserver: as the assistant response grows below the
|
|
128
|
+
// anchored user message, collapse the spacer by the same amount so total
|
|
129
|
+
// scrollable space below the bubble stays constant (and the bubble stays
|
|
130
|
+
// pinned). Never grow the spacer after initial sizing.
|
|
131
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
132
|
+
ro = new ResizeObserver(() => {
|
|
133
|
+
if (!contentEl || !spacerEl || !scrollEl) return;
|
|
134
|
+
const contentHeight = contentEl.getBoundingClientRect().height;
|
|
135
|
+
const targetOffsetWithinContent = computeOffsetTop(
|
|
136
|
+
targetEl,
|
|
137
|
+
contentEl,
|
|
138
|
+
);
|
|
139
|
+
const consumedBelow =
|
|
140
|
+
contentHeight - targetOffsetWithinContent - userMessageHeight;
|
|
141
|
+
const remaining = Math.max(0, spacerHeight - consumedBelow);
|
|
142
|
+
if (remaining < currentSpacerHeight) {
|
|
143
|
+
spacerEl.style.height = `${remaining}px`;
|
|
144
|
+
currentSpacerHeight = remaining;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
ro.observe(contentEl);
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{ immediate: true, flush: "post" },
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Compute the offset of el relative to stopAt, accounting for stopAt's current scrollTop.
|
|
155
|
+
// Uses getBoundingClientRect so it works regardless of CSS positioning (including position:static).
|
|
156
|
+
function computeOffsetTop(el: HTMLElement, stopAt: HTMLElement): number {
|
|
157
|
+
const elRect = el.getBoundingClientRect();
|
|
158
|
+
const stopRect = stopAt.getBoundingClientRect();
|
|
159
|
+
return elRect.top - stopRect.top + stopAt.scrollTop;
|
|
160
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import type { Component } from "vue";
|
|
3
|
+
import type { ActivityMessage } from "@ag-ui/core";
|
|
4
|
+
import type { AbstractAgent } from "@ag-ui/client";
|
|
5
|
+
import { DEFAULT_AGENT_ID } from "@copilotkit/shared";
|
|
6
|
+
import { useCopilotKit } from "../providers/useCopilotKit";
|
|
7
|
+
import { useCopilotChatConfiguration } from "../providers/useCopilotChatConfiguration";
|
|
8
|
+
import type {
|
|
9
|
+
VueActivityMessageRenderer,
|
|
10
|
+
VueActivityMessageRendererProps,
|
|
11
|
+
} from "../types";
|
|
12
|
+
|
|
13
|
+
interface ActivityRendererResult {
|
|
14
|
+
renderer: Component<VueActivityMessageRendererProps<unknown>>;
|
|
15
|
+
props: VueActivityMessageRendererProps<unknown>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns helpers for rendering activity messages.
|
|
20
|
+
*
|
|
21
|
+
* Matches the React `useRenderActivityMessage` API: `findRenderer` locates a
|
|
22
|
+
* registered renderer by activity type (preferring agent-scoped over global,
|
|
23
|
+
* with `"*"` as a wildcard fallback), and `renderActivityMessage` resolves the
|
|
24
|
+
* renderer and validates the content schema.
|
|
25
|
+
*/
|
|
26
|
+
export function useRenderActivityMessage() {
|
|
27
|
+
const { copilotkit } = useCopilotKit();
|
|
28
|
+
const config = useCopilotChatConfiguration();
|
|
29
|
+
const agentId = computed(
|
|
30
|
+
() => config.value?.agentId ?? DEFAULT_AGENT_ID,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const renderers = computed(() => [...copilotkit.value.renderActivityMessages]);
|
|
34
|
+
|
|
35
|
+
function findRenderer(
|
|
36
|
+
activityType: string,
|
|
37
|
+
): VueActivityMessageRenderer<unknown> | null {
|
|
38
|
+
const list = renderers.value;
|
|
39
|
+
if (!list.length) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const matches = list.filter(
|
|
44
|
+
(renderer) => renderer.activityType === activityType,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
matches.find((candidate) => candidate.agentId === agentId.value) ??
|
|
49
|
+
matches.find((candidate) => candidate.agentId === undefined) ??
|
|
50
|
+
list.find((candidate) => candidate.activityType === "*") ??
|
|
51
|
+
null
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function renderActivityMessage(
|
|
56
|
+
message: ActivityMessage,
|
|
57
|
+
): ActivityRendererResult | null {
|
|
58
|
+
const renderer = findRenderer(message.activityType);
|
|
59
|
+
|
|
60
|
+
if (!renderer) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const parseResult = renderer.content.safeParse(message.content);
|
|
65
|
+
|
|
66
|
+
if (!parseResult.success) {
|
|
67
|
+
console.warn(
|
|
68
|
+
`Failed to parse content for activity message ` +
|
|
69
|
+
`'${message.activityType}':`,
|
|
70
|
+
parseResult.error,
|
|
71
|
+
);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const agent: AbstractAgent | undefined =
|
|
76
|
+
copilotkit.value.getAgent(agentId.value);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
renderer: renderer.render as Component<
|
|
80
|
+
VueActivityMessageRendererProps<unknown>
|
|
81
|
+
>,
|
|
82
|
+
props: {
|
|
83
|
+
activityType: message.activityType,
|
|
84
|
+
content: parseResult.data,
|
|
85
|
+
message,
|
|
86
|
+
agent,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { renderActivityMessage, findRenderer };
|
|
92
|
+
}
|