@copilotkit/vue 2.0.0-rc.2 → 2.0.0-rc.20
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 +353 -16908
- package/dist/index.mjs.map +1 -1
- package/dist/use-render-activity-message-CsWYyd6r.cjs +91 -0
- package/dist/use-render-activity-message-CsWYyd6r.cjs.map +1 -0
- package/dist/use-render-activity-message-DntKKNdd.js +17418 -0
- package/dist/use-render-activity-message-DntKKNdd.js.map +1 -0
- 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/OpenGenerativeUIRenderer.d.ts +13 -45
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
- package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +1 -1
- package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
- package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +13 -5
- 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.map +1 -1
- package/dist/v2/components/a2ui.d.ts +3 -7
- 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/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/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 +2 -2
- 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 +5 -3
- package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +5 -3
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +0 -1
- 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 +28 -25
- 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/normalize-auto-scroll.d.ts +2 -2
- package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +1 -1
- package/dist/v2/components/chat/tool-call-display-context.d.ts +2 -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 +8 -3
- 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/icons/index.d.ts +968 -1
- package/dist/v2/components/icons/index.d.ts.map +1 -1
- package/dist/v2/hooks/use-attachments.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-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/index.cjs +1 -1
- package/dist/v2/index.mjs +197 -200
- package/dist/v2/index.mjs.map +1 -1
- package/dist/v2/lib/is-mobile-viewport.d.ts +1 -14
- package/dist/v2/lib/is-mobile-viewport.d.ts.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 +0 -1
- package/dist/v2/lib/vue-core.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.types.d.ts +0 -5
- package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
- package/dist/v2/providers/markdown-renderer.d.ts +2 -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/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/components/A2UIMessageRenderer.ts +3 -3
- package/src/v2/components/InlineFeatureWarning.vue +20 -21
- package/src/v2/components/LicenseWarningBanner.vue +27 -135
- package/src/v2/components/OpenGenerativeUIRenderer.ts +51 -373
- package/src/v2/components/__tests__/A2UICatalogContext.test.ts +1 -1
- package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
- package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +55 -6
- package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +1 -1
- package/src/v2/components/a2ui/A2UICatalogContext.ts +10 -102
- package/src/v2/components/a2ui/A2UIRecoveryStates.ts +1 -1
- package/src/v2/components/a2ui/catalog.ts +1 -0
- package/src/v2/components/a2ui/utils.ts +2 -0
- package/src/v2/components/a2ui.ts +1 -1
- package/src/v2/components/chat/CopilotChat.vue +19 -40
- package/src/v2/components/chat/CopilotChatAssistantMessage.vue +19 -43
- package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +14 -10
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
- package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +2 -2
- package/src/v2/components/chat/CopilotChatInput.vue +40 -30
- package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
- package/src/v2/components/chat/CopilotChatMessageView.vue +72 -140
- package/src/v2/components/chat/CopilotChatReasoningMessage.vue +7 -15
- package/src/v2/components/chat/CopilotChatToolCallGroup.vue +60 -37
- package/src/v2/components/chat/CopilotChatToolCallItem.vue +3 -3
- package/src/v2/components/chat/CopilotChatToolCallsView.vue +15 -13
- package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
- package/src/v2/components/chat/CopilotChatView.vue +5 -5
- 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 +14 -34
- 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 +14 -34
- package/src/v2/components/chat/StreamingMarkdownDefault.vue +4 -4
- package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
- 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__/CopilotChatInput.test.ts +33 -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__/CopilotSidebar.test.ts +90 -1
- package/src/v2/components/chat/copilotChatToolCallItemRender.ts +3 -19
- 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/normalize-auto-scroll.ts +3 -17
- package/src/v2/components/chat/tool-call-display-context.ts +2 -23
- package/src/v2/components/chat/tool-call-group-parts.ts +44 -85
- 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/icons/__tests__/icons.test.ts +72 -68
- package/src/v2/components/icons/index.ts +109 -27
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +62 -1
- package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +105 -0
- package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
- package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
- package/src/v2/hooks/use-attachments.ts +6 -2
- package/src/v2/hooks/use-frontend-tool.ts +10 -10
- 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 +27 -48
- package/src/v2/hooks/use-render-custom-messages.ts +14 -35
- package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
- package/src/v2/lib/is-mobile-viewport.ts +5 -23
- package/src/v2/lib/processPartialHtml.ts +6 -21
- package/src/v2/lib/shallow-stable.ts +2 -16
- package/src/v2/lib/vue-core.ts +9 -13
- package/src/v2/providers/CopilotKitProvider.types.ts +0 -5
- package/src/v2/providers/CopilotKitProvider.vue +53 -112
- package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +1 -1
- 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.test.ts +17 -33
- package/src/v2/providers/markdown-renderer.ts +2 -2
- package/src/v2/providers/types.ts +3 -49
- 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 +3 -4
- 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/tool-call-layout.d.ts +0 -115
- package/dist/v2/components/chat/tool-call-layout.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/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/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/message-feedback.ts +0 -120
- package/src/v2/lib/transcription-client.ts +0 -151
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
defineComponent,
|
|
3
|
+
h,
|
|
4
|
+
onBeforeUnmount,
|
|
5
|
+
onMounted,
|
|
6
|
+
ref,
|
|
7
|
+
shallowRef,
|
|
8
|
+
watch,
|
|
9
|
+
} from "vue";
|
|
2
10
|
import type { PropType } from "vue";
|
|
3
|
-
import
|
|
4
|
-
import { ToolCallStatus } from "@copilotkit/core";
|
|
11
|
+
import * as z from "zod";
|
|
5
12
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
OPEN_GENERATIVE_UI_ACTIVITY_TYPE,
|
|
14
|
+
ToolCallStatus,
|
|
15
|
+
ɵOpenGenerativeUIController,
|
|
16
|
+
} from "@copilotkit/core";
|
|
17
|
+
import type {
|
|
18
|
+
GenerateSandboxedUiArgs,
|
|
19
|
+
OpenGenerativeUIContent,
|
|
20
|
+
} from "@copilotkit/core";
|
|
9
21
|
import { useSandboxFunctions } from "../providers/SandboxFunctionsContext";
|
|
10
22
|
|
|
11
|
-
export
|
|
23
|
+
export type { GenerateSandboxedUiArgs, OpenGenerativeUIContent };
|
|
24
|
+
|
|
25
|
+
export const OpenGenerativeUIActivityType = OPEN_GENERATIVE_UI_ACTIVITY_TYPE;
|
|
12
26
|
|
|
13
27
|
export const OpenGenerativeUIContentSchema = z.object({
|
|
14
28
|
initialHeight: z.number().optional(),
|
|
@@ -21,11 +35,7 @@ export const OpenGenerativeUIContentSchema = z.object({
|
|
|
21
35
|
jsFunctionsComplete: z.boolean().optional(),
|
|
22
36
|
jsExpressions: z.array(z.string()).optional(),
|
|
23
37
|
jsExpressionsComplete: z.boolean().optional(),
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
export type OpenGenerativeUIContent = z.infer<
|
|
27
|
-
typeof OpenGenerativeUIContentSchema
|
|
28
|
-
>;
|
|
38
|
+
}) satisfies z.ZodType<OpenGenerativeUIContent>;
|
|
29
39
|
|
|
30
40
|
export const GenerateSandboxedUiArgsSchema = z.object({
|
|
31
41
|
initialHeight: z.number().optional(),
|
|
@@ -34,68 +44,12 @@ export const GenerateSandboxedUiArgsSchema = z.object({
|
|
|
34
44
|
html: z.string().optional(),
|
|
35
45
|
jsFunctions: z.string().optional(),
|
|
36
46
|
jsExpressions: z.array(z.string()).optional(),
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
export type GenerateSandboxedUiArgs = z.infer<
|
|
40
|
-
typeof GenerateSandboxedUiArgsSchema
|
|
41
|
-
>;
|
|
42
|
-
|
|
43
|
-
function shouldFlushImmediately(
|
|
44
|
-
previous: OpenGenerativeUIContent | null,
|
|
45
|
-
next: OpenGenerativeUIContent,
|
|
46
|
-
): boolean {
|
|
47
|
-
if (next.cssComplete && (!previous || !previous.cssComplete)) return true;
|
|
48
|
-
if (next.htmlComplete) return true;
|
|
49
|
-
if (next.generating === false) return true;
|
|
50
|
-
if (next.jsFunctions && (!previous || !previous.jsFunctions)) return true;
|
|
51
|
-
if (
|
|
52
|
-
(next.jsExpressions?.length ?? 0) > (previous?.jsExpressions?.length ?? 0)
|
|
53
|
-
)
|
|
54
|
-
return true;
|
|
55
|
-
if (next.html?.length && (!previous || !previous.html?.length)) return true;
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function ensureHead(html: string): string {
|
|
60
|
-
if (/<head[\s>]/i.test(html)) return html;
|
|
61
|
-
return `<head></head>${html}`;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function injectCssIntoHtml(html: string, css: string): string {
|
|
65
|
-
const headCloseIdx = html.indexOf("</head>");
|
|
66
|
-
if (headCloseIdx !== -1) {
|
|
67
|
-
return (
|
|
68
|
-
html.slice(0, headCloseIdx) +
|
|
69
|
-
`<style>${css}</style>` +
|
|
70
|
-
html.slice(headCloseIdx)
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
return `<head><style>${css}</style></head>${html}`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
type SandboxInstance = {
|
|
77
|
-
iframe: HTMLIFrameElement;
|
|
78
|
-
promise: Promise<unknown>;
|
|
79
|
-
run: (code: string | Function) => Promise<unknown>;
|
|
80
|
-
destroy: () => void;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
type WebsandboxModule = {
|
|
84
|
-
create: (
|
|
85
|
-
localApi: Record<string, unknown>,
|
|
86
|
-
options: {
|
|
87
|
-
frameContainer: HTMLElement;
|
|
88
|
-
frameContent: string;
|
|
89
|
-
allowAdditionalAttributes: string;
|
|
90
|
-
},
|
|
91
|
-
) => SandboxInstance;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
async function loadWebsandbox(): Promise<WebsandboxModule> {
|
|
95
|
-
const mod = (await import("@jetbrains/websandbox")) as any;
|
|
96
|
-
return (mod.default?.default ?? mod.default) as WebsandboxModule;
|
|
97
|
-
}
|
|
47
|
+
}) satisfies z.ZodType<GenerateSandboxedUiArgs>;
|
|
98
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Renders Open Generative UI content. The core controller throttles the
|
|
51
|
+
* content and runs the websandbox iframes inside the container div.
|
|
52
|
+
*/
|
|
99
53
|
export const OpenGenerativeUIRenderer = defineComponent({
|
|
100
54
|
name: "OpenGenerativeUIRenderer",
|
|
101
55
|
props: {
|
|
@@ -107,307 +61,32 @@ export const OpenGenerativeUIRenderer = defineComponent({
|
|
|
107
61
|
setup(props) {
|
|
108
62
|
const sandboxFunctions = useSandboxFunctions();
|
|
109
63
|
const containerRef = ref<HTMLElement | null>(null);
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
const sandboxReady = ref(false);
|
|
116
|
-
const previewReady = ref(false);
|
|
117
|
-
const executedExpressionIndex = ref(0);
|
|
118
|
-
const jsFunctionsInjected = ref(false);
|
|
119
|
-
const pendingQueue = ref<string[]>([]);
|
|
120
|
-
|
|
121
|
-
const localApi = computed(() => {
|
|
122
|
-
const api: Record<string, unknown> = {};
|
|
123
|
-
for (const fn of sandboxFunctions.value) {
|
|
124
|
-
api[fn.name] = fn.handler;
|
|
125
|
-
}
|
|
126
|
-
return api;
|
|
64
|
+
const controller = new ɵOpenGenerativeUIController();
|
|
65
|
+
controller.setContent(props.content);
|
|
66
|
+
const state = shallowRef(controller.getState());
|
|
67
|
+
const unsubscribe = controller.subscribe(() => {
|
|
68
|
+
state.value = controller.getState();
|
|
127
69
|
});
|
|
128
70
|
|
|
129
71
|
watch(
|
|
130
72
|
() => props.content,
|
|
131
|
-
(
|
|
132
|
-
latestContent.value = next;
|
|
133
|
-
if (shouldFlushImmediately(throttledContent.value, next)) {
|
|
134
|
-
if (throttleTimer.value !== null) {
|
|
135
|
-
window.clearTimeout(throttleTimer.value);
|
|
136
|
-
throttleTimer.value = null;
|
|
137
|
-
}
|
|
138
|
-
throttledContent.value = next;
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (throttleTimer.value === null) {
|
|
142
|
-
throttleTimer.value = window.setTimeout(() => {
|
|
143
|
-
throttledContent.value = latestContent.value;
|
|
144
|
-
throttleTimer.value = null;
|
|
145
|
-
}, 1000);
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
{ immediate: true },
|
|
73
|
+
(content) => controller.setContent(content),
|
|
149
74
|
);
|
|
150
|
-
|
|
151
|
-
onBeforeUnmount(() => {
|
|
152
|
-
if (throttleTimer.value !== null) {
|
|
153
|
-
window.clearTimeout(throttleTimer.value);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
const partialHtml = computed(() => {
|
|
158
|
-
if (throttledContent.value.htmlComplete) return undefined;
|
|
159
|
-
if (!throttledContent.value.html?.length) return undefined;
|
|
160
|
-
return throttledContent.value.html.join("");
|
|
161
|
-
});
|
|
162
|
-
const previewBody = computed(() =>
|
|
163
|
-
partialHtml.value ? processPartialHtml(partialHtml.value) : undefined,
|
|
164
|
-
);
|
|
165
|
-
const previewStyles = computed(() =>
|
|
166
|
-
partialHtml.value ? extractCompleteStyles(partialHtml.value) : "",
|
|
167
|
-
);
|
|
168
|
-
const fullHtml = computed(() =>
|
|
169
|
-
throttledContent.value.htmlComplete && throttledContent.value.html?.length
|
|
170
|
-
? throttledContent.value.html.join("")
|
|
171
|
-
: undefined,
|
|
172
|
-
);
|
|
173
|
-
const css = computed(() =>
|
|
174
|
-
throttledContent.value.cssComplete
|
|
175
|
-
? throttledContent.value.css
|
|
176
|
-
: undefined,
|
|
177
|
-
);
|
|
178
|
-
const hasPreview = computed(
|
|
179
|
-
() =>
|
|
180
|
-
!!throttledContent.value.cssComplete &&
|
|
181
|
-
!!previewBody.value &&
|
|
182
|
-
previewBody.value.trim().length > 0,
|
|
183
|
-
);
|
|
184
|
-
const hasVisibleSandbox = computed(
|
|
185
|
-
() => !!fullHtml.value || hasPreview.value,
|
|
186
|
-
);
|
|
187
|
-
const resolvedHeight = computed(
|
|
188
|
-
() => `${throttledContent.value.initialHeight ?? 200}px`,
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
const destroyPreview = () => {
|
|
192
|
-
if (previewSandboxRef.value) {
|
|
193
|
-
previewSandboxRef.value.destroy();
|
|
194
|
-
previewSandboxRef.value = null;
|
|
195
|
-
}
|
|
196
|
-
previewReady.value = false;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const destroyFinal = () => {
|
|
200
|
-
if (sandboxRef.value) {
|
|
201
|
-
sandboxRef.value.destroy();
|
|
202
|
-
sandboxRef.value = null;
|
|
203
|
-
}
|
|
204
|
-
sandboxReady.value = false;
|
|
205
|
-
pendingQueue.value = [];
|
|
206
|
-
executedExpressionIndex.value = 0;
|
|
207
|
-
jsFunctionsInjected.value = false;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
75
|
watch(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
fullHtml,
|
|
214
|
-
css,
|
|
215
|
-
previewBody,
|
|
216
|
-
previewStyles,
|
|
217
|
-
() => containerRef.value,
|
|
218
|
-
],
|
|
219
|
-
async ([previewVisible, htmlComplete], _previous, onCleanup) => {
|
|
220
|
-
if (!previewVisible || htmlComplete || !containerRef.value) return;
|
|
221
|
-
if (previewSandboxRef.value) return;
|
|
222
|
-
|
|
223
|
-
let cancelled = false;
|
|
224
|
-
try {
|
|
225
|
-
const Websandbox = await loadWebsandbox();
|
|
226
|
-
if (cancelled || !containerRef.value) return;
|
|
227
|
-
|
|
228
|
-
const sandbox = Websandbox.create(
|
|
229
|
-
{},
|
|
230
|
-
{
|
|
231
|
-
frameContainer: containerRef.value,
|
|
232
|
-
frameContent: "<head></head><body></body>",
|
|
233
|
-
allowAdditionalAttributes: "",
|
|
234
|
-
},
|
|
235
|
-
);
|
|
236
|
-
previewSandboxRef.value = sandbox;
|
|
237
|
-
sandbox.iframe.setAttribute(
|
|
238
|
-
"data-testid",
|
|
239
|
-
"open-generative-ui-preview-sandbox",
|
|
240
|
-
);
|
|
241
|
-
sandbox.iframe.style.width = "100%";
|
|
242
|
-
sandbox.iframe.style.height = "100%";
|
|
243
|
-
sandbox.iframe.style.border = "none";
|
|
244
|
-
sandbox.iframe.style.backgroundColor = "transparent";
|
|
245
|
-
|
|
246
|
-
sandbox.promise.then(() => {
|
|
247
|
-
if (cancelled || !previewSandboxRef.value) return;
|
|
248
|
-
previewReady.value = true;
|
|
249
|
-
void sandbox.run(
|
|
250
|
-
"var s=document.createElement('style');s.textContent='html, body { overflow: hidden !important; }';document.head.appendChild(s);",
|
|
251
|
-
);
|
|
252
|
-
});
|
|
253
|
-
} catch (error) {
|
|
254
|
-
console.error(
|
|
255
|
-
"[OpenGenerativeUI] Failed to load sandbox module:",
|
|
256
|
-
error,
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
onCleanup(() => {
|
|
261
|
-
cancelled = true;
|
|
262
|
-
});
|
|
263
|
-
},
|
|
264
|
-
{ immediate: true },
|
|
265
|
-
);
|
|
266
|
-
|
|
267
|
-
watch(
|
|
268
|
-
[previewBody, previewStyles, css, previewReady],
|
|
269
|
-
([body, styles, cssText, ready]) => {
|
|
270
|
-
if (!previewSandboxRef.value || !ready) return;
|
|
271
|
-
const headParts: string[] = [];
|
|
272
|
-
if (cssText) headParts.push(`<style>${cssText}</style>`);
|
|
273
|
-
if (styles) headParts.push(styles);
|
|
274
|
-
if (headParts.length) {
|
|
275
|
-
void previewSandboxRef.value.run(
|
|
276
|
-
`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`,
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
if (body) {
|
|
280
|
-
void previewSandboxRef.value.run(
|
|
281
|
-
`document.body.innerHTML = ${JSON.stringify(body)}`,
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
},
|
|
76
|
+
sandboxFunctions,
|
|
77
|
+
(functions) => controller.setSandboxFunctions(functions),
|
|
285
78
|
{ immediate: true },
|
|
286
79
|
);
|
|
287
|
-
|
|
288
|
-
watch(
|
|
289
|
-
[fullHtml, css, localApi, () => containerRef.value],
|
|
290
|
-
async ([html, cssText, api], _previous, onCleanup) => {
|
|
291
|
-
destroyFinal();
|
|
292
|
-
if (!html || !containerRef.value) return;
|
|
293
|
-
destroyPreview();
|
|
294
|
-
|
|
295
|
-
let cancelled = false;
|
|
296
|
-
try {
|
|
297
|
-
const Websandbox = await loadWebsandbox();
|
|
298
|
-
if (cancelled || !containerRef.value) return;
|
|
299
|
-
const htmlWithHead = ensureHead(html);
|
|
300
|
-
const htmlWithCss = cssText
|
|
301
|
-
? injectCssIntoHtml(htmlWithHead, cssText)
|
|
302
|
-
: htmlWithHead;
|
|
303
|
-
const sandbox = Websandbox.create(api, {
|
|
304
|
-
frameContainer: containerRef.value,
|
|
305
|
-
frameContent: htmlWithCss,
|
|
306
|
-
allowAdditionalAttributes: "",
|
|
307
|
-
});
|
|
308
|
-
sandboxRef.value = sandbox;
|
|
309
|
-
sandbox.iframe.setAttribute(
|
|
310
|
-
"data-testid",
|
|
311
|
-
"open-generative-ui-final-sandbox",
|
|
312
|
-
);
|
|
313
|
-
sandbox.iframe.style.width = "100%";
|
|
314
|
-
sandbox.iframe.style.height = "100%";
|
|
315
|
-
sandbox.iframe.style.border = "none";
|
|
316
|
-
sandbox.iframe.style.backgroundColor = "transparent";
|
|
317
|
-
|
|
318
|
-
sandbox.promise.then(() => {
|
|
319
|
-
if (cancelled || !sandboxRef.value) return;
|
|
320
|
-
sandboxReady.value = true;
|
|
321
|
-
void sandbox.run(
|
|
322
|
-
"var s=document.createElement('style');s.textContent='html, body { overflow: hidden !important; }';document.head.appendChild(s);",
|
|
323
|
-
);
|
|
324
|
-
const functionsCode = throttledContent.value.jsFunctions;
|
|
325
|
-
if (functionsCode && !jsFunctionsInjected.value) {
|
|
326
|
-
jsFunctionsInjected.value = true;
|
|
327
|
-
pendingQueue.value.unshift(functionsCode);
|
|
328
|
-
}
|
|
329
|
-
const expressions = throttledContent.value.jsExpressions;
|
|
330
|
-
if (expressions?.length) {
|
|
331
|
-
const startIndex = executedExpressionIndex.value;
|
|
332
|
-
if (startIndex < expressions.length) {
|
|
333
|
-
pendingQueue.value.push(...expressions.slice(startIndex));
|
|
334
|
-
executedExpressionIndex.value = expressions.length;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
const queue = [...pendingQueue.value];
|
|
338
|
-
pendingQueue.value = [];
|
|
339
|
-
for (const code of queue) {
|
|
340
|
-
void sandbox.run(code);
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
} catch (error) {
|
|
344
|
-
console.error(
|
|
345
|
-
"[OpenGenerativeUI] Failed to load sandbox module:",
|
|
346
|
-
error,
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
onCleanup(() => {
|
|
351
|
-
cancelled = true;
|
|
352
|
-
});
|
|
353
|
-
},
|
|
354
|
-
{ immediate: true },
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
watch(
|
|
358
|
-
() => throttledContent.value.jsFunctions,
|
|
359
|
-
(functionsCode) => {
|
|
360
|
-
if (!functionsCode || jsFunctionsInjected.value) return;
|
|
361
|
-
jsFunctionsInjected.value = true;
|
|
362
|
-
if (sandboxReady.value && sandboxRef.value) {
|
|
363
|
-
void sandboxRef.value.run(functionsCode);
|
|
364
|
-
} else {
|
|
365
|
-
pendingQueue.value.push(functionsCode);
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
);
|
|
369
|
-
|
|
370
|
-
watch(
|
|
371
|
-
() => throttledContent.value.jsExpressions,
|
|
372
|
-
(expressions) => {
|
|
373
|
-
if (!expressions?.length) return;
|
|
374
|
-
const startIndex = executedExpressionIndex.value;
|
|
375
|
-
if (startIndex >= expressions.length) return;
|
|
376
|
-
const newExpressions = expressions.slice(startIndex);
|
|
377
|
-
executedExpressionIndex.value = expressions.length;
|
|
378
|
-
if (sandboxReady.value && sandboxRef.value) {
|
|
379
|
-
for (const expression of newExpressions) {
|
|
380
|
-
void sandboxRef.value.run(expression);
|
|
381
|
-
}
|
|
382
|
-
} else {
|
|
383
|
-
pendingQueue.value.push(...newExpressions);
|
|
384
|
-
}
|
|
385
|
-
},
|
|
386
|
-
{ deep: true },
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
const isGenerating = computed(
|
|
390
|
-
() => throttledContent.value.generating !== false,
|
|
391
|
-
);
|
|
392
|
-
watch(
|
|
393
|
-
[hasPreview, fullHtml],
|
|
394
|
-
([previewVisible, html]) => {
|
|
395
|
-
if (html) destroyPreview();
|
|
396
|
-
if (!previewVisible) destroyPreview();
|
|
397
|
-
},
|
|
398
|
-
{ immediate: true },
|
|
399
|
-
);
|
|
400
|
-
|
|
80
|
+
onMounted(() => controller.setHost(containerRef.value));
|
|
401
81
|
onBeforeUnmount(() => {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
destroyPreview();
|
|
406
|
-
destroyFinal();
|
|
82
|
+
unsubscribe();
|
|
83
|
+
controller.destroy();
|
|
407
84
|
});
|
|
408
85
|
|
|
409
|
-
return () =>
|
|
410
|
-
|
|
86
|
+
return () => {
|
|
87
|
+
const { phase, generating, height } = state.value;
|
|
88
|
+
const hasVisibleSandbox = phase !== "placeholder";
|
|
89
|
+
return h(
|
|
411
90
|
"div",
|
|
412
91
|
{
|
|
413
92
|
ref: containerRef,
|
|
@@ -415,20 +94,18 @@ export const OpenGenerativeUIRenderer = defineComponent({
|
|
|
415
94
|
style: {
|
|
416
95
|
position: "relative",
|
|
417
96
|
width: "100%",
|
|
418
|
-
height:
|
|
97
|
+
height: `${height}px`,
|
|
419
98
|
borderRadius: "8px",
|
|
420
|
-
backgroundColor: hasVisibleSandbox
|
|
421
|
-
|
|
422
|
-
: "#f5f5f5",
|
|
423
|
-
border: hasVisibleSandbox.value ? "none" : "1px solid #e0e0e0",
|
|
99
|
+
backgroundColor: hasVisibleSandbox ? "transparent" : "#f5f5f5",
|
|
100
|
+
border: hasVisibleSandbox ? "none" : "1px solid #e0e0e0",
|
|
424
101
|
overflow: "hidden",
|
|
425
|
-
display: hasVisibleSandbox
|
|
426
|
-
alignItems: hasVisibleSandbox
|
|
427
|
-
justifyContent: hasVisibleSandbox
|
|
102
|
+
display: hasVisibleSandbox ? "block" : "flex",
|
|
103
|
+
alignItems: hasVisibleSandbox ? undefined : "center",
|
|
104
|
+
justifyContent: hasVisibleSandbox ? undefined : "center",
|
|
428
105
|
},
|
|
429
106
|
},
|
|
430
107
|
[
|
|
431
|
-
!hasVisibleSandbox
|
|
108
|
+
!hasVisibleSandbox
|
|
432
109
|
? h("div", { "data-testid": "open-generative-ui-placeholder" }, [
|
|
433
110
|
h(
|
|
434
111
|
"svg",
|
|
@@ -461,7 +138,7 @@ export const OpenGenerativeUIRenderer = defineComponent({
|
|
|
461
138
|
),
|
|
462
139
|
])
|
|
463
140
|
: null,
|
|
464
|
-
|
|
141
|
+
generating
|
|
465
142
|
? h("div", {
|
|
466
143
|
"data-testid": "open-generative-ui-progress-overlay",
|
|
467
144
|
style: {
|
|
@@ -473,6 +150,7 @@ export const OpenGenerativeUIRenderer = defineComponent({
|
|
|
473
150
|
: null,
|
|
474
151
|
],
|
|
475
152
|
);
|
|
153
|
+
};
|
|
476
154
|
},
|
|
477
155
|
});
|
|
478
156
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { z } from "zod";
|
|
2
|
+
import { z } from "zod-v3";
|
|
3
3
|
import { Catalog } from "@a2ui/web_core/v0_9";
|
|
4
4
|
import type { ComponentApi } from "@a2ui/web_core/v0_9";
|
|
5
5
|
import { buildCatalogContextValue } from "../a2ui/A2UICatalogContext";
|
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { mount } from "@vue/test-utils";
|
|
2
2
|
import { describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { defineComponent, h } from "vue";
|
|
4
|
+
import type { CopilotChatLabels } from "@copilotkit/core";
|
|
5
|
+
import CopilotChatConfigurationProvider from "../../providers/CopilotChatConfigurationProvider.vue";
|
|
6
|
+
import InlineFeatureWarning from "../InlineFeatureWarning.vue";
|
|
3
7
|
import LicenseWarningBanner from "../LicenseWarningBanner.vue";
|
|
4
8
|
|
|
9
|
+
/** Mounts `child` inside a chat configuration with `labels`. */
|
|
10
|
+
function mountWithLabels(
|
|
11
|
+
labels: Partial<CopilotChatLabels>,
|
|
12
|
+
child: () => ReturnType<typeof h>,
|
|
13
|
+
) {
|
|
14
|
+
const Host = defineComponent({
|
|
15
|
+
setup: () => () =>
|
|
16
|
+
h(CopilotChatConfigurationProvider, { labels }, { default: child }),
|
|
17
|
+
});
|
|
18
|
+
return mount(Host);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// The banner text rules are covered next to core's ɵgetLicenseBannerSpec.
|
|
5
22
|
describe("LicenseWarningBanner", () => {
|
|
6
23
|
it("reactively renders and invokes the optional dismiss callback", async () => {
|
|
7
24
|
const onDismiss = vi.fn();
|
|
@@ -20,4 +37,47 @@ describe("LicenseWarningBanner", () => {
|
|
|
20
37
|
|
|
21
38
|
expect(wrapper.find("button").exists()).toBe(false);
|
|
22
39
|
});
|
|
40
|
+
|
|
41
|
+
it("shows the core spec's text and link", () => {
|
|
42
|
+
const wrapper = mount(LicenseWarningBanner, {
|
|
43
|
+
props: { type: "expiring", graceRemaining: 1 },
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(wrapper.get("span").text()).toBe(
|
|
47
|
+
"Your CopilotKit license expires in 1 day. Please renew.",
|
|
48
|
+
);
|
|
49
|
+
expect(wrapper.get("a").attributes("href")).toBe(
|
|
50
|
+
"https://dashboard.operations.copilotkit.ai",
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("uses the configured chat labels", () => {
|
|
55
|
+
const wrapper = mountWithLabels(
|
|
56
|
+
{ licenseInvalidText: "Token ungültig" },
|
|
57
|
+
() => h(LicenseWarningBanner, { type: "invalid" }),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
expect(wrapper.get("span").text()).toBe("Token ungültig");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("InlineFeatureWarning", () => {
|
|
65
|
+
it("shows the default feature-unlicensed label", () => {
|
|
66
|
+
const wrapper = mount(InlineFeatureWarning, {
|
|
67
|
+
props: { featureName: "Chat" },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(wrapper.text()).toContain(
|
|
71
|
+
'⚠ The "Chat" feature requires a CopilotKit license.',
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("uses the configured feature-unlicensed label", () => {
|
|
76
|
+
const wrapper = mountWithLabels(
|
|
77
|
+
{ licenseFeatureUnlicensedText: "{feature} braucht eine Lizenz." },
|
|
78
|
+
() => h(InlineFeatureWarning, { featureName: "Chat" }),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
expect(wrapper.text()).toContain("Chat braucht eine Lizenz.");
|
|
82
|
+
});
|
|
23
83
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type * as CoreModule from "@copilotkit/core";
|
|
2
3
|
import { render } from "@testing-library/vue";
|
|
3
4
|
import { ref } from "vue";
|
|
4
5
|
import type { Ref } from "vue";
|
|
@@ -37,12 +38,25 @@ const mockCreate = vi.fn<MockCreateFn>(() => ({
|
|
|
37
38
|
destroy: mockDestroy,
|
|
38
39
|
}));
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
// Run the real core controller against a fake websandbox
|
|
42
|
+
vi.mock("@copilotkit/core", async (importOriginal) => {
|
|
43
|
+
const actual = await importOriginal<typeof CoreModule>();
|
|
44
|
+
class TestOpenGenerativeUIController
|
|
45
|
+
extends actual.ɵOpenGenerativeUIController
|
|
46
|
+
{
|
|
47
|
+
constructor() {
|
|
48
|
+
super({
|
|
49
|
+
loadWebsandbox: async () => ({
|
|
50
|
+
create: (localApi, options) => mockCreate(localApi, options),
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
...actual,
|
|
57
|
+
ɵOpenGenerativeUIController: TestOpenGenerativeUIController,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
46
60
|
|
|
47
61
|
async function flushImport() {
|
|
48
62
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
@@ -178,6 +192,41 @@ describe("OpenGenerativeUIRenderer", () => {
|
|
|
178
192
|
expect(options.frameContent).toContain("v2");
|
|
179
193
|
});
|
|
180
194
|
|
|
195
|
+
it("sizes the container to the height the final sandbox reports", async () => {
|
|
196
|
+
const iframe = document.createElement("iframe");
|
|
197
|
+
mockCreate.mockImplementationOnce((_localApi, options) => {
|
|
198
|
+
(options.frameContainer as HTMLElement).appendChild(iframe);
|
|
199
|
+
return {
|
|
200
|
+
iframe,
|
|
201
|
+
promise: Promise.resolve(),
|
|
202
|
+
run: mockRun,
|
|
203
|
+
destroy: mockDestroy,
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
const { getByTestId } = renderRenderer({
|
|
207
|
+
initialHeight: 150,
|
|
208
|
+
html: ["<body><p>Chart</p></body>"],
|
|
209
|
+
htmlComplete: true,
|
|
210
|
+
generating: false,
|
|
211
|
+
});
|
|
212
|
+
await flushImport();
|
|
213
|
+
expect(getByTestId("open-generative-ui-renderer").style.height).toBe(
|
|
214
|
+
"150px",
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
window.dispatchEvent(
|
|
218
|
+
new MessageEvent("message", {
|
|
219
|
+
source: iframe.contentWindow,
|
|
220
|
+
data: { type: "__ck_resize", height: 420 },
|
|
221
|
+
}),
|
|
222
|
+
);
|
|
223
|
+
await flushImport();
|
|
224
|
+
|
|
225
|
+
expect(getByTestId("open-generative-ui-renderer").style.height).toBe(
|
|
226
|
+
"420px",
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
|
|
181
230
|
it("destroys sandbox on unmount", async () => {
|
|
182
231
|
const mounted = renderRenderer({
|
|
183
232
|
html: ["<head></head><body>bye</body>"],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { watch } from "vue";
|
|
2
2
|
import type { ShallowRef } from "vue";
|
|
3
|
-
import
|
|
3
|
+
import * as z from "zod";
|
|
4
4
|
import type { CopilotKitCoreVue } from "../../lib/vue-core";
|
|
5
5
|
import { defineToolCallRenderer } from "../../types/defineToolCallRenderer";
|
|
6
6
|
|