@copilotkit/vue 2.0.0-rc.2 → 2.0.0-rc.21
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/PARITY.md +3 -3
- package/dist/hooks/use-copilot-action.d.ts.map +1 -1
- package/dist/hooks/use-frontend-tool.d.ts +1 -1
- package/dist/hooks/use-frontend-tool.d.ts.map +1 -1
- package/dist/hooks/zod-parameters.d.ts +14 -0
- package/dist/hooks/zod-parameters.d.ts.map +1 -0
- package/dist/index.cjs +1 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +365 -16920
- package/dist/index.mjs.map +1 -1
- package/dist/use-render-activity-message-BAhbpSDh.js +16200 -0
- package/dist/use-render-activity-message-BAhbpSDh.js.map +1 -0
- package/dist/use-render-activity-message-DJ6q1qHV.cjs +114 -0
- package/dist/use-render-activity-message-DJ6q1qHV.cjs.map +1 -0
- package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
- package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
- package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
- package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
- package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
- package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
- package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
- package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
- package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
- package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -1
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -59
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
- package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +0 -5
- package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
- package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +10 -15
- package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
- package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +14 -130
- package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
- package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
- package/dist/v2/components/a2ui/utils.d.ts +3 -15
- package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
- package/dist/v2/components/a2ui.d.ts +9 -8
- package/dist/v2/components/a2ui.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
- package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +4 -8
- package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +6 -270
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts +3 -3
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
- package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
- package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
- package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
- package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +6 -4
- package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +6 -4
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts +1 -0
- package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/audioRecorder.d.ts +3 -4
- package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -1
- package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +3 -3
- package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
- package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
- package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
- package/dist/v2/components/chat/index.d.ts +34 -31
- package/dist/v2/components/chat/index.d.ts.map +1 -1
- package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
- package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
- package/dist/v2/components/chat/message-feedback.d.ts +18 -49
- package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
- package/dist/v2/components/chat/tool-call-display-context.d.ts +4 -19
- package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
- package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
- package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
- package/dist/v2/components/chat/turn-work.d.ts +0 -2
- package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
- package/dist/v2/components/chat/types.d.ts +9 -4
- package/dist/v2/components/chat/types.d.ts.map +1 -1
- package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
- package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
- package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
- package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
- package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -1
- package/dist/v2/components/icons/index.d.ts +968 -1
- package/dist/v2/components/icons/index.d.ts.map +1 -1
- package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +1 -1
- package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -1
- package/dist/v2/hooks/use-agent-context.d.ts +2 -3
- package/dist/v2/hooks/use-agent-context.d.ts.map +1 -1
- package/dist/v2/hooks/use-agent.d.ts +4 -1
- package/dist/v2/hooks/use-agent.d.ts.map +1 -1
- package/dist/v2/hooks/use-attachments.d.ts +7 -0
- package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
- package/dist/v2/hooks/use-capabilities.d.ts.map +1 -1
- package/dist/v2/hooks/use-component.d.ts +1 -0
- package/dist/v2/hooks/use-component.d.ts.map +1 -1
- package/dist/v2/hooks/use-configure-suggestions.d.ts +4 -9
- package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
- package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
- package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
- package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
- package/dist/v2/hooks/use-human-in-the-loop.d.ts +2 -1
- package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -1
- package/dist/v2/hooks/use-interrupt.d.ts +0 -1
- package/dist/v2/hooks/use-interrupt.d.ts.map +1 -1
- package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
- package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
- package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
- package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
- package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
- package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
- package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
- package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
- package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
- package/dist/v2/hooks/use-threads.d.ts +0 -8
- package/dist/v2/hooks/use-threads.d.ts.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +197 -200
- package/dist/v2/index.mjs.map +1 -1
- package/dist/v2/lib/processPartialHtml.d.ts +1 -2
- package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
- package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
- package/dist/v2/lib/vue-core.d.ts +12 -12
- package/dist/v2/lib/vue-core.d.ts.map +1 -1
- package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.types.d.ts +9 -129
- package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts +9 -10
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
- package/dist/v2/providers/chat-configuration-store-key.d.ts +8 -0
- package/dist/v2/providers/chat-configuration-store-key.d.ts.map +1 -0
- package/dist/v2/providers/markdown-renderer.d.ts +4 -2
- package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
- package/dist/v2/providers/types.d.ts +3 -46
- package/dist/v2/providers/types.d.ts.map +1 -1
- package/dist/v2/providers/use-inspector-thread-override.d.ts +5 -0
- package/dist/v2/providers/use-inspector-thread-override.d.ts.map +1 -1
- package/dist/v2/types/human-in-the-loop.d.ts +8 -29
- package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
- package/dist/v2/types/interrupt.d.ts +1 -22
- package/dist/v2/types/interrupt.d.ts.map +1 -1
- package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
- package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
- package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
- package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
- package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
- package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
- package/package.json +10 -11
- package/src/__tests__/build-entries.test.ts +27 -0
- package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
- package/src/hooks/use-copilot-action.ts +2 -1
- package/src/hooks/use-frontend-tool.ts +3 -6
- package/src/hooks/zod-parameters.ts +162 -0
- package/src/v2/__tests__/exports.test.ts +10 -0
- package/src/v2/__tests__/mocks/web-inspector.ts +6 -0
- package/src/v2/__tests__/utils/test-helpers.ts +34 -4
- package/src/v2/components/A2UIMessageRenderer.ts +98 -68
- package/src/v2/components/A2UISurfaceActivityRenderer.vue +68 -103
- package/src/v2/components/CopilotKitInspector.vue +104 -51
- package/src/v2/components/InlineFeatureWarning.vue +20 -21
- package/src/v2/components/LicenseWarningBanner.vue +27 -135
- package/src/v2/components/MCPAppsActivityRenderer.ts +75 -201
- package/src/v2/components/OpenGenerativeUIRenderer.ts +122 -446
- package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +171 -8
- package/src/v2/components/__tests__/CopilotKitInspector.test.ts +42 -0
- package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
- package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +64 -8
- package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
- package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +2 -7
- package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -185
- package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
- package/src/v2/components/a2ui/catalog.ts +3 -3
- package/src/v2/components/a2ui/utils.ts +13 -65
- package/src/v2/components/a2ui.ts +15 -22
- package/src/v2/components/chat/CopilotChat.vue +147 -356
- package/src/v2/components/chat/CopilotChatAssistantMessage.vue +19 -43
- package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +36 -55
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
- package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
- package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +2 -2
- package/src/v2/components/chat/CopilotChatInput.vue +108 -436
- package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
- package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
- package/src/v2/components/chat/CopilotChatMessageView.vue +82 -210
- package/src/v2/components/chat/CopilotChatReasoningMessage.vue +7 -15
- package/src/v2/components/chat/CopilotChatToolCallGroup.vue +63 -71
- package/src/v2/components/chat/CopilotChatToolCallItem.vue +8 -6
- package/src/v2/components/chat/CopilotChatToolCallsView.vue +31 -32
- package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
- package/src/v2/components/chat/CopilotChatView.vue +33 -28
- package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
- package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
- package/src/v2/components/chat/CopilotPopup.vue +23 -25
- package/src/v2/components/chat/CopilotPopupView.vue +10 -39
- package/src/v2/components/chat/CopilotPopupViewInternal.vue +35 -131
- package/src/v2/components/chat/CopilotSidebar.vue +23 -25
- package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
- package/src/v2/components/chat/CopilotSidebarViewInternal.vue +38 -59
- package/src/v2/components/chat/CopilotThreadsDrawer.vue +37 -102
- package/src/v2/components/chat/StreamingMarkdownDefault.vue +15 -28
- package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
- package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
- package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +89 -1
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
- package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
- package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
- package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
- package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +32 -8
- package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +2 -1
- package/src/v2/components/chat/__tests__/StreamingMarkdownDefault.test.ts +54 -0
- package/src/v2/components/chat/audioRecorder.ts +4 -7
- package/src/v2/components/chat/copilotChatToolCallItemRender.ts +24 -89
- package/src/v2/components/chat/forwarded-slots.ts +17 -0
- package/src/v2/components/chat/index.ts +0 -1
- package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
- package/src/v2/components/chat/message-feedback.ts +62 -197
- package/src/v2/components/chat/tool-call-display-context.ts +6 -22
- package/src/v2/components/chat/tool-call-group-parts.ts +47 -108
- package/src/v2/components/chat/turn-work.ts +0 -9
- package/src/v2/components/chat/types.ts +12 -4
- package/src/v2/components/chat/use-chat-labels.ts +16 -0
- package/src/v2/components/chat/use-copy-feedback.ts +21 -0
- package/src/v2/components/chat/use-lightbox.ts +15 -33
- package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
- package/src/v2/components/icons/index.ts +109 -27
- package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +5 -3
- package/src/v2/hooks/__tests__/use-agent-stability.test.ts +25 -4
- package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +5 -1
- package/src/v2/hooks/__tests__/use-agent.test.ts +6 -3
- package/src/v2/hooks/__tests__/use-component.test.ts +21 -0
- package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +30 -1
- package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +10 -10
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +66 -1
- package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +6 -1
- package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +187 -12
- package/src/v2/hooks/__tests__/use-interrupt.test.ts +97 -0
- package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +106 -0
- package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
- package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
- package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
- package/src/v2/hooks/use-agent-context.ts +4 -10
- package/src/v2/hooks/use-agent.ts +86 -290
- package/src/v2/hooks/use-attachments.ts +48 -168
- package/src/v2/hooks/use-capabilities.ts +2 -7
- package/src/v2/hooks/use-component.ts +7 -4
- package/src/v2/hooks/use-configure-suggestions.ts +28 -218
- package/src/v2/hooks/use-default-render-tool.ts +34 -94
- package/src/v2/hooks/use-frontend-tool.ts +10 -10
- package/src/v2/hooks/use-human-in-the-loop.ts +11 -80
- package/src/v2/hooks/use-interrupt.ts +29 -308
- package/src/v2/hooks/use-keyboard-height.ts +17 -40
- package/src/v2/hooks/use-pin-to-send.ts +15 -99
- package/src/v2/hooks/use-render-activity-message.ts +31 -55
- package/src/v2/hooks/use-render-custom-messages.ts +24 -88
- package/src/v2/hooks/use-suggestions.ts +9 -33
- package/src/v2/hooks/use-threads.ts +43 -273
- package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
- package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
- package/src/v2/lib/processPartialHtml.ts +6 -21
- package/src/v2/lib/shallow-stable.ts +2 -16
- package/src/v2/lib/vue-core.ts +69 -78
- package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
- package/src/v2/providers/CopilotKitProvider.types.ts +12 -132
- package/src/v2/providers/CopilotKitProvider.vue +237 -510
- package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
- package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +20 -2
- package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
- package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
- package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
- package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +53 -26
- package/src/v2/providers/chat-configuration-store-key.ts +9 -0
- package/src/v2/providers/markdown-renderer.ts +8 -2
- package/src/v2/providers/types.ts +3 -49
- package/src/v2/providers/use-inspector-thread-override.ts +22 -80
- package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
- package/src/v2/types/defineToolCallRenderer.ts +5 -4
- package/src/v2/types/human-in-the-loop.ts +8 -32
- package/src/v2/types/interrupt.ts +7 -31
- package/src/v2/types/vue-activity-message-renderer.ts +24 -15
- package/src/v2/types/vue-custom-message-renderer.ts +12 -16
- package/src/v2/types/vue-tool-call-renderer.ts +23 -38
- package/tsconfig.json +0 -1
- package/vite.config.ts +8 -5
- package/vitest.config.ts +12 -7
- package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
- package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
- package/dist/v2/components/chat/normalize-auto-scroll.d.ts +0 -3
- package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +0 -1
- package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
- package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
- package/dist/v2/lib/is-mobile-viewport.d.ts +0 -15
- package/dist/v2/lib/is-mobile-viewport.d.ts.map +0 -1
- package/dist/v2/lib/message-feedback.d.ts +0 -33
- package/dist/v2/lib/message-feedback.d.ts.map +0 -1
- package/dist/v2/lib/transcription-client.d.ts +0 -19
- package/dist/v2/lib/transcription-client.d.ts.map +0 -1
- package/src/v2/components/__tests__/A2UICatalogContext.test.ts +0 -63
- package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +0 -175
- package/src/v2/components/chat/BasicMarkdown.vue +0 -160
- package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
- package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
- package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
- package/src/v2/components/chat/tool-call-layout.ts +0 -304
- package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
- package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
- package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
- package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
- package/src/v2/lib/is-mobile-viewport.ts +0 -23
- package/src/v2/lib/message-feedback.ts +0 -120
- package/src/v2/lib/transcription-client.ts +0 -151
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import {
|
|
3
3
|
computed,
|
|
4
4
|
inject,
|
|
5
|
-
onBeforeUnmount,
|
|
6
5
|
onUpdated,
|
|
7
6
|
ref,
|
|
8
7
|
shallowRef,
|
|
@@ -34,7 +33,12 @@ import CopilotChatInspectorButton from "./CopilotChatInspectorButton.vue";
|
|
|
34
33
|
import { useInspectorShortcutsHidden } from "./inspector-shortcuts";
|
|
35
34
|
import { InspectorKey } from "../../providers/keys";
|
|
36
35
|
import { useFeedbackComment, useMessageFeedback } from "./message-feedback";
|
|
37
|
-
import
|
|
36
|
+
import {
|
|
37
|
+
ɵhasAssistantMessageText,
|
|
38
|
+
ɵshouldShowAssistantToolbar,
|
|
39
|
+
} from "@copilotkit/core";
|
|
40
|
+
import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
|
|
41
|
+
import { useCopyFeedback } from "./use-copy-feedback";
|
|
38
42
|
import type {
|
|
39
43
|
CopilotChatAssistantMessageCopyButtonSlotProps,
|
|
40
44
|
CopilotChatAssistantMessageFeedbackCommentSlotProps,
|
|
@@ -109,8 +113,7 @@ const emit = defineEmits<{
|
|
|
109
113
|
|
|
110
114
|
const config = useCopilotChatConfiguration();
|
|
111
115
|
const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
|
|
112
|
-
const copied =
|
|
113
|
-
let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
116
|
+
const { copied, copy } = useCopyFeedback();
|
|
114
117
|
|
|
115
118
|
function normalizeContent(content: unknown): string {
|
|
116
119
|
if (!content) {
|
|
@@ -146,7 +149,9 @@ function normalizeContent(content: unknown): string {
|
|
|
146
149
|
const normalizedContent = computed(() =>
|
|
147
150
|
normalizeContent(props.message.content),
|
|
148
151
|
);
|
|
149
|
-
const hasContent = computed(() =>
|
|
152
|
+
const hasContent = computed(() =>
|
|
153
|
+
ɵhasAssistantMessageText(normalizedContent.value),
|
|
154
|
+
);
|
|
150
155
|
|
|
151
156
|
const providerMarkdownRenderer = useMarkdownRenderer();
|
|
152
157
|
const providerIsComponent = computed(() =>
|
|
@@ -190,11 +195,14 @@ const hasRegenerate = computed(() => typeof props.onRegenerate === "function");
|
|
|
190
195
|
const isLatestAssistantMessage = computed(
|
|
191
196
|
() => props.messages[props.messages.length - 1]?.id === props.message.id,
|
|
192
197
|
);
|
|
193
|
-
const shouldShowToolbar = computed(
|
|
194
|
-
(
|
|
195
|
-
props.toolbarVisible
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
const shouldShowToolbar = computed(() =>
|
|
199
|
+
ɵshouldShowAssistantToolbar({
|
|
200
|
+
toolbarVisible: props.toolbarVisible,
|
|
201
|
+
hasContent: hasContent.value,
|
|
202
|
+
showInspectorShortcut: showInspectorShortcut.value,
|
|
203
|
+
isRunning: props.isRunning,
|
|
204
|
+
isLatest: isLatestAssistantMessage.value,
|
|
205
|
+
}),
|
|
198
206
|
);
|
|
199
207
|
|
|
200
208
|
// A custom thumb that calls its handler without an event gives no element:
|
|
@@ -325,34 +333,8 @@ function handleInspect() {
|
|
|
325
333
|
});
|
|
326
334
|
}
|
|
327
335
|
|
|
328
|
-
function resetCopiedStateWithDelay() {
|
|
329
|
-
if (copiedResetTimeout) {
|
|
330
|
-
clearTimeout(copiedResetTimeout);
|
|
331
|
-
}
|
|
332
|
-
copied.value = true;
|
|
333
|
-
copiedResetTimeout = setTimeout(() => {
|
|
334
|
-
copied.value = false;
|
|
335
|
-
copiedResetTimeout = null;
|
|
336
|
-
}, 2000);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
336
|
async function handleCopyMessage() {
|
|
340
|
-
|
|
341
|
-
if (!content) return;
|
|
342
|
-
|
|
343
|
-
if (
|
|
344
|
-
typeof navigator === "undefined" ||
|
|
345
|
-
typeof navigator.clipboard?.writeText !== "function"
|
|
346
|
-
) {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
try {
|
|
351
|
-
await navigator.clipboard.writeText(content);
|
|
352
|
-
resetCopiedStateWithDelay();
|
|
353
|
-
} catch (error) {
|
|
354
|
-
console.error("Failed to copy to clipboard:", error);
|
|
355
|
-
}
|
|
337
|
+
await copy(normalizedContent.value);
|
|
356
338
|
}
|
|
357
339
|
|
|
358
340
|
function handleThumbsUp(event?: MouseEvent) {
|
|
@@ -371,12 +353,6 @@ function handleReadAloud() {
|
|
|
371
353
|
function handleRegenerate() {
|
|
372
354
|
emit("regenerate", props.message);
|
|
373
355
|
}
|
|
374
|
-
|
|
375
|
-
onBeforeUnmount(() => {
|
|
376
|
-
if (copiedResetTimeout) {
|
|
377
|
-
clearTimeout(copiedResetTimeout);
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
356
|
</script>
|
|
381
357
|
|
|
382
358
|
<template>
|
|
@@ -6,11 +6,15 @@ import {
|
|
|
6
6
|
getSourceUrl,
|
|
7
7
|
} from "@copilotkit/shared";
|
|
8
8
|
import type { Attachment } from "@copilotkit/shared";
|
|
9
|
+
import {
|
|
10
|
+
ɵcanPreviewDocument,
|
|
11
|
+
ɵcreateObjectUrlFromSource,
|
|
12
|
+
ɵdecodeTextSource,
|
|
13
|
+
} from "@copilotkit/core";
|
|
9
14
|
import type { CopilotChatAttachmentQueueProps } from "./types";
|
|
10
15
|
import { IconPlay } from "../icons";
|
|
11
16
|
import CopilotChatLightbox from "./CopilotChatLightbox.vue";
|
|
12
|
-
import {
|
|
13
|
-
import { CopilotChatDefaultLabels } from "../../providers/types";
|
|
17
|
+
import { useChatLabels } from "./use-chat-labels";
|
|
14
18
|
|
|
15
19
|
const props = withDefaults(defineProps<CopilotChatAttachmentQueueProps>(), {
|
|
16
20
|
attachments: () => [],
|
|
@@ -21,38 +25,32 @@ const emit = defineEmits<{
|
|
|
21
25
|
"remove-attachment": [id: string];
|
|
22
26
|
}>();
|
|
23
27
|
|
|
24
|
-
const
|
|
25
|
-
const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
|
|
28
|
+
const labels = useChatLabels();
|
|
26
29
|
|
|
27
30
|
const activeLightboxAttachment = ref<Attachment | null>(null);
|
|
28
31
|
const documentBlobUrl = ref<string | null>(null);
|
|
32
|
+
let revokeDocumentBlobUrl = () => {};
|
|
29
33
|
|
|
30
34
|
const lightboxLabel = computed(() => {
|
|
31
35
|
const attachment = activeLightboxAttachment.value;
|
|
32
36
|
if (!attachment) return undefined;
|
|
33
37
|
if (attachment.filename) return attachment.filename;
|
|
34
38
|
return attachment.type === "image"
|
|
35
|
-
?
|
|
39
|
+
? labels.value.attachmentImageAltText
|
|
36
40
|
: attachment.type === "video"
|
|
37
41
|
? "Video attachment"
|
|
38
|
-
:
|
|
42
|
+
: labels.value.attachmentDocumentLabel;
|
|
39
43
|
});
|
|
40
44
|
const isPreviewableDocument = computed(() => {
|
|
41
45
|
const attachment = activeLightboxAttachment.value;
|
|
42
46
|
if (!attachment || attachment.type !== "document") return false;
|
|
43
|
-
|
|
44
|
-
return isPdf(mimeType) || isText(mimeType);
|
|
47
|
+
return ɵcanPreviewDocument(attachment.source.mimeType) !== null;
|
|
45
48
|
});
|
|
46
49
|
const decodedTextPreview = computed(() => {
|
|
47
50
|
const attachment = activeLightboxAttachment.value;
|
|
48
51
|
if (!attachment || attachment.type !== "document") return null;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
return atob(attachment.source.value);
|
|
53
|
-
} catch {
|
|
54
|
-
return attachment.source.value;
|
|
55
|
-
}
|
|
52
|
+
if (ɵcanPreviewDocument(attachment.source.mimeType) !== "text") return null;
|
|
53
|
+
return ɵdecodeTextSource(attachment.source);
|
|
56
54
|
});
|
|
57
55
|
const lightboxDocumentSource = computed(() => {
|
|
58
56
|
const attachment = activeLightboxAttachment.value;
|
|
@@ -64,10 +62,7 @@ const lightboxDocumentSource = computed(() => {
|
|
|
64
62
|
watch(
|
|
65
63
|
activeLightboxAttachment,
|
|
66
64
|
(next, previous) => {
|
|
67
|
-
|
|
68
|
-
URL.revokeObjectURL(documentBlobUrl.value);
|
|
69
|
-
documentBlobUrl.value = null;
|
|
70
|
-
}
|
|
65
|
+
revokeDocumentBlobUrl();
|
|
71
66
|
|
|
72
67
|
if (
|
|
73
68
|
!next ||
|
|
@@ -78,22 +73,22 @@ watch(
|
|
|
78
73
|
return;
|
|
79
74
|
}
|
|
80
75
|
|
|
81
|
-
|
|
82
|
-
if (!isPdf(mimeType) && !isText(mimeType)) {
|
|
76
|
+
if (ɵcanPreviewDocument(next.source.mimeType) === null) {
|
|
83
77
|
return;
|
|
84
78
|
}
|
|
85
79
|
|
|
86
|
-
const
|
|
87
|
-
documentBlobUrl.value =
|
|
80
|
+
const objectUrl = ɵcreateObjectUrlFromSource(next.source);
|
|
81
|
+
documentBlobUrl.value = objectUrl?.url ?? null;
|
|
82
|
+
revokeDocumentBlobUrl = () => {
|
|
83
|
+
objectUrl?.revoke();
|
|
84
|
+
documentBlobUrl.value = null;
|
|
85
|
+
};
|
|
88
86
|
},
|
|
89
87
|
{ immediate: true },
|
|
90
88
|
);
|
|
91
89
|
|
|
92
90
|
onBeforeUnmount(() => {
|
|
93
|
-
|
|
94
|
-
URL.revokeObjectURL(documentBlobUrl.value);
|
|
95
|
-
documentBlobUrl.value = null;
|
|
96
|
-
}
|
|
91
|
+
revokeDocumentBlobUrl();
|
|
97
92
|
});
|
|
98
93
|
|
|
99
94
|
function openLightbox(attachment: Attachment) {
|
|
@@ -125,32 +120,12 @@ function cardClassName(attachment: Attachment) {
|
|
|
125
120
|
return "cpk-attachment-queue-item-document";
|
|
126
121
|
}
|
|
127
122
|
|
|
128
|
-
function isPdf(mimeType: string | undefined)
|
|
129
|
-
return
|
|
123
|
+
function isPdf(mimeType: string | undefined) {
|
|
124
|
+
return ɵcanPreviewDocument(mimeType) === "pdf";
|
|
130
125
|
}
|
|
131
126
|
|
|
132
|
-
function isText(mimeType: string | undefined)
|
|
133
|
-
return
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function createBlobUrl(
|
|
137
|
-
base64Value: string,
|
|
138
|
-
mimeType: string | undefined,
|
|
139
|
-
): string | null {
|
|
140
|
-
try {
|
|
141
|
-
const binary = atob(base64Value);
|
|
142
|
-
const bytes = new Uint8Array(binary.length);
|
|
143
|
-
for (let i = 0; i < binary.length; i += 1) {
|
|
144
|
-
bytes[i] = binary.charCodeAt(i);
|
|
145
|
-
}
|
|
146
|
-
const blob = new Blob([bytes], {
|
|
147
|
-
type: mimeType || "application/octet-stream",
|
|
148
|
-
});
|
|
149
|
-
return URL.createObjectURL(blob);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
console.error("[CopilotKit] Failed to decode attachment data:", error);
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
127
|
+
function isText(mimeType: string | undefined) {
|
|
128
|
+
return ɵcanPreviewDocument(mimeType) === "text";
|
|
154
129
|
}
|
|
155
130
|
</script>
|
|
156
131
|
|
|
@@ -267,7 +242,7 @@ function createBlobUrl(
|
|
|
267
242
|
class="cpk-attachment-queue-document-name"
|
|
268
243
|
data-testid="copilot-chat-attachment-document-filename"
|
|
269
244
|
>
|
|
270
|
-
{{ attachment.filename ||
|
|
245
|
+
{{ attachment.filename || labels.attachmentDocumentLabel }}
|
|
271
246
|
</span>
|
|
272
247
|
<span
|
|
273
248
|
v-if="attachment.size != null"
|
|
@@ -369,10 +344,16 @@ function createBlobUrl(
|
|
|
369
344
|
</div>
|
|
370
345
|
<div class="cpk-attachment-queue-document-card-details">
|
|
371
346
|
<div class="cpk-attachment-queue-document-card-name">
|
|
372
|
-
{{
|
|
347
|
+
{{
|
|
348
|
+
activeLightboxAttachment.filename ||
|
|
349
|
+
labels.attachmentDocumentLabel
|
|
350
|
+
}}
|
|
373
351
|
</div>
|
|
374
352
|
<div class="cpk-attachment-queue-document-card-meta">
|
|
375
|
-
{{
|
|
353
|
+
{{
|
|
354
|
+
activeLightboxAttachment.source.mimeType ||
|
|
355
|
+
labels.attachmentUnknownTypeText
|
|
356
|
+
}}
|
|
376
357
|
{{
|
|
377
358
|
activeLightboxAttachment.size != null
|
|
378
359
|
? ` · ${formatFileSize(activeLightboxAttachment.size)}`
|
|
@@ -381,7 +362,7 @@ function createBlobUrl(
|
|
|
381
362
|
</div>
|
|
382
363
|
</div>
|
|
383
364
|
<div class="cpk-attachment-queue-document-card-note">
|
|
384
|
-
|
|
365
|
+
{{ labels.attachmentNoPreviewText }}
|
|
385
366
|
</div>
|
|
386
367
|
</div>
|
|
387
368
|
</template>
|
|
@@ -4,19 +4,27 @@ import { getDocumentIcon, getSourceUrl } from "@copilotkit/shared";
|
|
|
4
4
|
import type { CopilotChatAttachmentRendererProps } from "./types";
|
|
5
5
|
import CopilotChatLightbox from "./CopilotChatLightbox.vue";
|
|
6
6
|
import { useLightbox } from "./use-lightbox";
|
|
7
|
+
import { useChatLabels } from "./use-chat-labels";
|
|
7
8
|
|
|
8
9
|
const props = withDefaults(defineProps<CopilotChatAttachmentRendererProps>(), {
|
|
9
10
|
filename: undefined,
|
|
10
11
|
className: "",
|
|
11
12
|
});
|
|
12
13
|
|
|
14
|
+
const labels = useChatLabels();
|
|
13
15
|
const imageLoadFailed = ref(false);
|
|
14
16
|
const sourceUrl = computed(() => getSourceUrl(props.source));
|
|
15
17
|
const documentLabel = computed(
|
|
16
|
-
() =>
|
|
18
|
+
() =>
|
|
19
|
+
props.filename ||
|
|
20
|
+
props.source.mimeType ||
|
|
21
|
+
labels.value.attachmentUnknownTypeText,
|
|
17
22
|
);
|
|
18
23
|
const documentAriaLabel = computed(
|
|
19
|
-
() =>
|
|
24
|
+
() =>
|
|
25
|
+
props.filename ||
|
|
26
|
+
props.source.mimeType ||
|
|
27
|
+
labels.value.attachmentDocumentAltText,
|
|
20
28
|
);
|
|
21
29
|
|
|
22
30
|
const imageButton = ref<HTMLButtonElement | null>(null);
|
|
@@ -43,7 +51,7 @@ const {
|
|
|
43
51
|
<img
|
|
44
52
|
ref="thumbnailRef"
|
|
45
53
|
:src="sourceUrl"
|
|
46
|
-
alt="
|
|
54
|
+
:alt="labels.attachmentImageAltText"
|
|
47
55
|
class="cpk-attachment-renderer cpk-attachment-renderer-image"
|
|
48
56
|
:class="props.className"
|
|
49
57
|
data-testid="copilot-chat-attachment-renderer-image"
|
|
@@ -52,14 +60,14 @@ const {
|
|
|
52
60
|
<!-- Teleported to the body; inside the button only to keep one root. -->
|
|
53
61
|
<CopilotChatLightbox
|
|
54
62
|
v-if="lightboxOpen"
|
|
55
|
-
label="
|
|
63
|
+
:label="labels.attachmentImageAltText"
|
|
56
64
|
:return-focus-to="imageButton"
|
|
57
65
|
@close="closeLightbox"
|
|
58
66
|
>
|
|
59
67
|
<img
|
|
60
68
|
:style="{ viewTransitionName: vtName }"
|
|
61
69
|
:src="sourceUrl"
|
|
62
|
-
alt="
|
|
70
|
+
:alt="labels.attachmentImageAltText"
|
|
63
71
|
class="cpk-attachment-renderer-lightbox-image"
|
|
64
72
|
data-testid="copilot-chat-attachment-renderer-lightbox-image"
|
|
65
73
|
/>
|
|
@@ -71,7 +79,7 @@ const {
|
|
|
71
79
|
:class="props.className"
|
|
72
80
|
data-testid="copilot-chat-attachment-renderer-image-fallback"
|
|
73
81
|
>
|
|
74
|
-
<span>
|
|
82
|
+
<span>{{ labels.attachmentImageLoadErrorText }}</span>
|
|
75
83
|
</div>
|
|
76
84
|
|
|
77
85
|
<div
|
|
@@ -1,264 +1,37 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Records from the microphone and draws the live level as a scrolling
|
|
4
|
+
* waveform. The recording itself is `ɵAudioRecorder` from
|
|
5
|
+
* `@copilotkit/core`; control it through the exposed ref.
|
|
6
|
+
*/
|
|
7
|
+
import { onBeforeUnmount, onMounted, ref, useAttrs } from "vue";
|
|
8
|
+
import { ɵAudioRecorder, ɵcreateWaveformRenderer } from "@copilotkit/core";
|
|
5
9
|
|
|
6
10
|
defineOptions({ inheritAttrs: false });
|
|
7
11
|
|
|
8
12
|
const attrs = useAttrs();
|
|
9
13
|
const canvasRef = ref<HTMLCanvasElement | null>(null);
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const streamRef = ref<MediaStream | null>(null);
|
|
13
|
-
const analyserRef = ref<AnalyserNode | null>(null);
|
|
14
|
-
const audioContextRef = ref<AudioContext | null>(null);
|
|
15
|
-
const animationIdRef = ref<number | null>(null);
|
|
16
|
-
const audioChunksRef = ref<Blob[]>([]);
|
|
17
|
-
const amplitudeHistoryRef = ref<number[]>([]);
|
|
18
|
-
const scrollOffsetRef = ref(0);
|
|
19
|
-
const smoothedAmplitudeRef = ref(0);
|
|
20
|
-
const fadeOpacityRef = ref(0);
|
|
14
|
+
const recorder = new ɵAudioRecorder();
|
|
15
|
+
let waveform: { dispose: () => void } | undefined;
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
animationIdRef.value = null;
|
|
17
|
+
onMounted(() => {
|
|
18
|
+
if (canvasRef.value) {
|
|
19
|
+
waveform = ɵcreateWaveformRenderer(canvasRef.value, recorder);
|
|
26
20
|
}
|
|
27
|
-
|
|
28
|
-
const recorder = mediaRecorderRef.value;
|
|
29
|
-
if (recorder && recorder.state !== "inactive") {
|
|
30
|
-
try {
|
|
31
|
-
recorder.stop();
|
|
32
|
-
} catch {
|
|
33
|
-
// ignore cleanup stop failures
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (streamRef.value) {
|
|
38
|
-
streamRef.value.getTracks().forEach((track) => track.stop());
|
|
39
|
-
streamRef.value = null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const audioContext = audioContextRef.value;
|
|
43
|
-
if (audioContext && audioContext.state !== "closed") {
|
|
44
|
-
audioContext.close().catch(() => {
|
|
45
|
-
// ignore close errors
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
mediaRecorderRef.value = null;
|
|
50
|
-
analyserRef.value = null;
|
|
51
|
-
audioContextRef.value = null;
|
|
52
|
-
audioChunksRef.value = [];
|
|
53
|
-
amplitudeHistoryRef.value = [];
|
|
54
|
-
scrollOffsetRef.value = 0;
|
|
55
|
-
smoothedAmplitudeRef.value = 0;
|
|
56
|
-
fadeOpacityRef.value = 0;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function start() {
|
|
60
|
-
if (recorderState.value !== "idle") {
|
|
61
|
-
throw new AudioRecorderError("Recorder is already active");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
66
|
-
streamRef.value = stream;
|
|
67
|
-
|
|
68
|
-
const audioContext = new AudioContext();
|
|
69
|
-
audioContextRef.value = audioContext;
|
|
70
|
-
const source = audioContext.createMediaStreamSource(stream);
|
|
71
|
-
const analyser = audioContext.createAnalyser();
|
|
72
|
-
analyser.fftSize = 2048;
|
|
73
|
-
source.connect(analyser);
|
|
74
|
-
analyserRef.value = analyser;
|
|
75
|
-
|
|
76
|
-
const mimeType = MediaRecorder.isTypeSupported("audio/webm;codecs=opus")
|
|
77
|
-
? "audio/webm;codecs=opus"
|
|
78
|
-
: MediaRecorder.isTypeSupported("audio/webm")
|
|
79
|
-
? "audio/webm"
|
|
80
|
-
: MediaRecorder.isTypeSupported("audio/mp4")
|
|
81
|
-
? "audio/mp4"
|
|
82
|
-
: "";
|
|
83
|
-
|
|
84
|
-
const options = mimeType ? { mimeType } : {};
|
|
85
|
-
const recorder = new MediaRecorder(stream, options);
|
|
86
|
-
mediaRecorderRef.value = recorder;
|
|
87
|
-
audioChunksRef.value = [];
|
|
88
|
-
|
|
89
|
-
recorder.ondataavailable = (event) => {
|
|
90
|
-
if (event.data.size > 0) {
|
|
91
|
-
audioChunksRef.value.push(event.data);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
recorder.start(100);
|
|
96
|
-
recorderState.value = "recording";
|
|
97
|
-
} catch (error) {
|
|
98
|
-
cleanup();
|
|
99
|
-
if (error instanceof Error && error.name === "NotAllowedError") {
|
|
100
|
-
throw new AudioRecorderError("Microphone permission denied");
|
|
101
|
-
}
|
|
102
|
-
if (error instanceof Error && error.name === "NotFoundError") {
|
|
103
|
-
throw new AudioRecorderError("No microphone found");
|
|
104
|
-
}
|
|
105
|
-
throw new AudioRecorderError(
|
|
106
|
-
error instanceof Error ? error.message : "Failed to start recording",
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function stop() {
|
|
112
|
-
return new Promise<Blob>((resolve, reject) => {
|
|
113
|
-
const recorder = mediaRecorderRef.value;
|
|
114
|
-
if (!recorder || recorderState.value !== "recording") {
|
|
115
|
-
reject(new AudioRecorderError("No active recording"));
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
recorderState.value = "processing";
|
|
120
|
-
recorder.onstop = () => {
|
|
121
|
-
const audioBlob = new Blob(audioChunksRef.value, {
|
|
122
|
-
type: recorder.mimeType || "audio/webm",
|
|
123
|
-
});
|
|
124
|
-
cleanup();
|
|
125
|
-
recorderState.value = "idle";
|
|
126
|
-
resolve(audioBlob);
|
|
127
|
-
};
|
|
128
|
-
recorder.onerror = () => {
|
|
129
|
-
cleanup();
|
|
130
|
-
recorderState.value = "idle";
|
|
131
|
-
reject(new AudioRecorderError("Recording failed"));
|
|
132
|
-
};
|
|
133
|
-
recorder.stop();
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function calculateAmplitude(dataArray: Uint8Array) {
|
|
138
|
-
let sum = 0;
|
|
139
|
-
for (let index = 0; index < dataArray.length; index += 1) {
|
|
140
|
-
const sample = (dataArray[index] ?? 128) / 128 - 1;
|
|
141
|
-
sum += sample * sample;
|
|
142
|
-
}
|
|
143
|
-
return Math.sqrt(sum / dataArray.length);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function drawFrame() {
|
|
147
|
-
const canvas = canvasRef.value;
|
|
148
|
-
if (!canvas) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const context = canvas.getContext("2d");
|
|
153
|
-
if (!context) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const rect = canvas.getBoundingClientRect();
|
|
158
|
-
const dpr = window.devicePixelRatio || 1;
|
|
159
|
-
if (
|
|
160
|
-
canvas.width !== rect.width * dpr ||
|
|
161
|
-
canvas.height !== rect.height * dpr
|
|
162
|
-
) {
|
|
163
|
-
canvas.width = rect.width * dpr;
|
|
164
|
-
canvas.height = rect.height * dpr;
|
|
165
|
-
context.scale(dpr, dpr);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const barWidth = 2;
|
|
169
|
-
const barGap = 1;
|
|
170
|
-
const barSpacing = barWidth + barGap;
|
|
171
|
-
const maxBars = Math.floor(rect.width / barSpacing) + 2;
|
|
172
|
-
|
|
173
|
-
if (analyserRef.value && recorderState.value === "recording") {
|
|
174
|
-
if (amplitudeHistoryRef.value.length === 0) {
|
|
175
|
-
amplitudeHistoryRef.value = Array.from({ length: maxBars }, () => 0);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (fadeOpacityRef.value < 1) {
|
|
179
|
-
fadeOpacityRef.value = Math.min(1, fadeOpacityRef.value + 0.03);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
scrollOffsetRef.value += 1 / 3;
|
|
183
|
-
const bufferLength = analyserRef.value.fftSize;
|
|
184
|
-
const dataArray = new Uint8Array(bufferLength);
|
|
185
|
-
analyserRef.value.getByteTimeDomainData(dataArray);
|
|
186
|
-
const rawAmplitude = calculateAmplitude(dataArray);
|
|
187
|
-
const attackSpeed = 0.12;
|
|
188
|
-
const decaySpeed = 0.08;
|
|
189
|
-
const speed =
|
|
190
|
-
rawAmplitude > smoothedAmplitudeRef.value ? attackSpeed : decaySpeed;
|
|
191
|
-
smoothedAmplitudeRef.value +=
|
|
192
|
-
(rawAmplitude - smoothedAmplitudeRef.value) * speed;
|
|
193
|
-
|
|
194
|
-
if (scrollOffsetRef.value >= barSpacing) {
|
|
195
|
-
scrollOffsetRef.value -= barSpacing;
|
|
196
|
-
amplitudeHistoryRef.value.push(smoothedAmplitudeRef.value);
|
|
197
|
-
if (amplitudeHistoryRef.value.length > maxBars) {
|
|
198
|
-
amplitudeHistoryRef.value = amplitudeHistoryRef.value.slice(-maxBars);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
context.clearRect(0, 0, rect.width, rect.height);
|
|
204
|
-
const computedStyle = window.getComputedStyle(canvas);
|
|
205
|
-
context.fillStyle = computedStyle.color;
|
|
206
|
-
context.globalAlpha = fadeOpacityRef.value;
|
|
207
|
-
|
|
208
|
-
const centerY = rect.height / 2;
|
|
209
|
-
const maxAmplitude = rect.height / 2 - 2;
|
|
210
|
-
const edgeFadeWidth = 12;
|
|
211
|
-
|
|
212
|
-
for (let index = 0; index < amplitudeHistoryRef.value.length; index += 1) {
|
|
213
|
-
const amplitude = amplitudeHistoryRef.value[index] ?? 0;
|
|
214
|
-
const scaledAmplitude = Math.min(amplitude * 4, 1);
|
|
215
|
-
const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);
|
|
216
|
-
const x =
|
|
217
|
-
rect.width -
|
|
218
|
-
(amplitudeHistoryRef.value.length - index) * barSpacing -
|
|
219
|
-
scrollOffsetRef.value;
|
|
220
|
-
const y = centerY - barHeight / 2;
|
|
221
|
-
if (x + barWidth <= 0 || x >= rect.width) {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
let edgeOpacity = 1;
|
|
226
|
-
if (x < edgeFadeWidth) {
|
|
227
|
-
edgeOpacity = Math.max(0, x / edgeFadeWidth);
|
|
228
|
-
} else if (x > rect.width - edgeFadeWidth) {
|
|
229
|
-
edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
context.globalAlpha = fadeOpacityRef.value * edgeOpacity;
|
|
233
|
-
context.fillRect(x, y, barWidth, barHeight);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
animationIdRef.value = requestAnimationFrame(drawFrame);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
watch(
|
|
240
|
-
recorderState,
|
|
241
|
-
() => {
|
|
242
|
-
if (animationIdRef.value !== null) {
|
|
243
|
-
cancelAnimationFrame(animationIdRef.value);
|
|
244
|
-
animationIdRef.value = null;
|
|
245
|
-
}
|
|
246
|
-
animationIdRef.value = requestAnimationFrame(drawFrame);
|
|
247
|
-
},
|
|
248
|
-
{ immediate: true },
|
|
249
|
-
);
|
|
21
|
+
});
|
|
250
22
|
|
|
251
23
|
onBeforeUnmount(() => {
|
|
252
|
-
|
|
24
|
+
waveform?.dispose();
|
|
25
|
+
recorder.dispose();
|
|
253
26
|
});
|
|
254
27
|
|
|
255
28
|
defineExpose({
|
|
256
29
|
get state() {
|
|
257
|
-
return
|
|
30
|
+
return recorder.getSnapshot();
|
|
258
31
|
},
|
|
259
|
-
start,
|
|
260
|
-
stop,
|
|
261
|
-
dispose:
|
|
32
|
+
start: () => recorder.start(),
|
|
33
|
+
stop: () => recorder.stop(),
|
|
34
|
+
dispose: () => recorder.dispose(),
|
|
262
35
|
});
|
|
263
36
|
</script>
|
|
264
37
|
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
import { computed, nextTick, ref, watch } from "vue";
|
|
13
13
|
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
14
14
|
import { CopilotChatDefaultLabels } from "../../providers/types";
|
|
15
|
-
import { MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH } from "
|
|
16
|
-
import type { MessageFeedbackRating } from "
|
|
15
|
+
import { ɵMESSAGE_FEEDBACK_MAX_COMMENT_LENGTH as MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH } from "@copilotkit/core";
|
|
16
|
+
import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
|
|
17
17
|
import CopilotPopover from "../ui/CopilotPopover.vue";
|
|
18
18
|
import { IconArrowUp } from "../icons";
|
|
19
19
|
import type { FeedbackComment } from "./message-feedback";
|