@copilotkit/vue 2.0.0-rc.20 → 2.0.0-rc.22
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/dist/index.cjs +1 -1
- package/dist/index.mjs +13 -13
- package/dist/use-render-activity-message-CyrhHFhA.js +16200 -0
- package/dist/use-render-activity-message-CyrhHFhA.js.map +1 -0
- package/dist/use-render-activity-message-EwHHrwQB.cjs +114 -0
- package/dist/use-render-activity-message-EwHHrwQB.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/MCPAppsActivityRenderer.d.ts.map +1 -1
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +7 -21
- 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 -138
- 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 +6 -1
- package/dist/v2/components/a2ui.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAttachmentQueue.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/CopilotChatInput.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.map +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.map +1 -1
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +1 -1
- 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 -2
- package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
- package/dist/v2/components/chat/index.d.ts +6 -6
- package/dist/v2/components/chat/tool-call-display-context.d.ts +3 -1
- 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.map +1 -1
- package/dist/v2/components/chat/types.d.ts +1 -1
- package/dist/v2/components/chat/types.d.ts.map +1 -1
- package/dist/v2/components/chat/use-lightbox.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-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-render-activity-message.d.ts.map +1 -1
- 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 +1 -1
- package/dist/v2/lib/vue-core.d.ts +12 -11
- 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 -124
- 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 +3 -1
- package/dist/v2/providers/markdown-renderer.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/package.json +8 -8
- 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/MCPAppsActivityRenderer.ts +75 -201
- package/src/v2/components/OpenGenerativeUIRenderer.ts +78 -80
- 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__/OpenGenerativeUIRenderer.test.ts +9 -2
- package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
- package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +1 -6
- package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -93
- package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
- package/src/v2/components/a2ui/catalog.ts +2 -3
- package/src/v2/components/a2ui/utils.ts +13 -67
- package/src/v2/components/a2ui.ts +14 -21
- package/src/v2/components/chat/CopilotChat.vue +136 -324
- package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +22 -45
- package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
- package/src/v2/components/chat/CopilotChatInput.vue +69 -407
- package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
- package/src/v2/components/chat/CopilotChatMessageView.vue +52 -112
- package/src/v2/components/chat/CopilotChatToolCallGroup.vue +14 -45
- package/src/v2/components/chat/CopilotChatToolCallItem.vue +6 -4
- package/src/v2/components/chat/CopilotChatToolCallsView.vue +16 -19
- package/src/v2/components/chat/CopilotChatView.vue +28 -23
- package/src/v2/components/chat/CopilotPopupViewInternal.vue +21 -97
- package/src/v2/components/chat/CopilotSidebarViewInternal.vue +24 -25
- package/src/v2/components/chat/CopilotThreadsDrawer.vue +37 -102
- package/src/v2/components/chat/StreamingMarkdownDefault.vue +13 -26
- package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
- package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +56 -0
- package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
- 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 +22 -71
- package/src/v2/components/chat/tool-call-display-context.ts +6 -1
- package/src/v2/components/chat/tool-call-group-parts.ts +13 -33
- package/src/v2/components/chat/types.ts +1 -1
- package/src/v2/components/chat/use-lightbox.ts +15 -33
- 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 +4 -0
- 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 +2 -1
- package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
- 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 +42 -166
- 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-human-in-the-loop.ts +11 -80
- package/src/v2/hooks/use-interrupt.ts +29 -308
- package/src/v2/hooks/use-render-activity-message.ts +17 -20
- package/src/v2/hooks/use-render-custom-messages.ts +20 -63
- package/src/v2/hooks/use-suggestions.ts +9 -33
- package/src/v2/hooks/use-threads.ts +43 -273
- package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
- package/src/v2/lib/vue-core.ts +67 -72
- package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
- package/src/v2/providers/CopilotKitProvider.types.ts +12 -127
- package/src/v2/providers/CopilotKitProvider.vue +188 -402
- package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
- package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +19 -1
- package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
- package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +45 -2
- package/src/v2/providers/chat-configuration-store-key.ts +9 -0
- package/src/v2/providers/markdown-renderer.ts +7 -1
- package/src/v2/providers/use-inspector-thread-override.ts +22 -80
- package/vite.config.ts +5 -1
- package/vitest.config.ts +12 -7
- package/dist/use-render-activity-message-CsWYyd6r.cjs +0 -91
- package/dist/use-render-activity-message-CsWYyd6r.cjs.map +0 -1
- package/dist/use-render-activity-message-DntKKNdd.js +0 -17418
- package/dist/use-render-activity-message-DntKKNdd.js.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/lib/is-mobile-viewport.d.ts +0 -2
- package/dist/v2/lib/is-mobile-viewport.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/normalize-auto-scroll.ts +0 -3
- package/src/v2/lib/is-mobile-viewport.ts +0 -5
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
defineComponent,
|
|
4
|
+
h,
|
|
5
|
+
onBeforeUnmount,
|
|
6
|
+
ref,
|
|
7
|
+
shallowRef,
|
|
8
|
+
watch,
|
|
9
|
+
} from "vue";
|
|
2
10
|
import type { PropType } from "vue";
|
|
3
11
|
import type { AbstractAgent } from "@ag-ui/client";
|
|
4
12
|
import type { VueActivityMessageRendererProps } from "../types";
|
|
@@ -27,12 +35,8 @@ export type {
|
|
|
27
35
|
} from "@copilotkit/mcp-apps-renderer/activity";
|
|
28
36
|
|
|
29
37
|
import type { MCPAppsActivityContent } from "@copilotkit/mcp-apps-renderer/activity";
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
import type {
|
|
33
|
-
McpAppSession,
|
|
34
|
-
FetchedResource,
|
|
35
|
-
} from "@copilotkit/mcp-apps-renderer";
|
|
38
|
+
import { ɵMcpAppHost } from "@copilotkit/mcp-apps-renderer/activity";
|
|
39
|
+
import type { ɵMcpAppHostState } from "@copilotkit/mcp-apps-renderer/activity";
|
|
36
40
|
|
|
37
41
|
/**
|
|
38
42
|
* MCP Apps Extension Activity Renderer
|
|
@@ -77,213 +81,82 @@ export const MCPAppsActivityRenderer = defineComponent({
|
|
|
77
81
|
setup(props) {
|
|
78
82
|
const { copilotkit } = useCopilotKit();
|
|
79
83
|
const containerRef = ref<HTMLDivElement | null>(null);
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const sessionRef = shallowRef<McpAppSession | null>(null);
|
|
93
|
-
const fetchedResource = shallowRef<FetchedResource | null>(null);
|
|
94
|
-
|
|
95
|
-
// The activity message id. Passed to the session so it self-subscribes to
|
|
96
|
-
// the agent's activity stream and pushes tool input/result itself (this
|
|
97
|
-
// adapter does not forward store-backed activities).
|
|
98
|
-
const messageId = computed(() => props.message?.id);
|
|
84
|
+
// The shared host owns the iframe, its size and its state, and binds the
|
|
85
|
+
// protocol session (loaded lazily); this component only draws the state.
|
|
86
|
+
const app = shallowRef<ɵMcpAppHost | null>(null);
|
|
87
|
+
// Set by the immediate watcher below, before the first render.
|
|
88
|
+
const state = shallowRef<ɵMcpAppHostState>({
|
|
89
|
+
loading: true,
|
|
90
|
+
error: null,
|
|
91
|
+
contentError: null,
|
|
92
|
+
size: {},
|
|
93
|
+
prefersBorder: false,
|
|
94
|
+
});
|
|
95
|
+
let unsubscribe: () => void = () => undefined;
|
|
99
96
|
|
|
100
|
-
//
|
|
101
|
-
// widget identity (resourceUri/serverHash/serverId) or the agent/host/message
|
|
102
|
-
// changes - NOT when tool input/result stream in (those are pushed without
|
|
103
|
-
// recreating the iframe). `flush: "post"` so the container element is mounted
|
|
104
|
-
// when the callback runs.
|
|
97
|
+
// A new host or sandbox setting needs a new host object.
|
|
105
98
|
watch(
|
|
106
|
-
[
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
() => props.content.resourceUri,
|
|
115
|
-
() => props.content.serverHash,
|
|
116
|
-
() => props.content.serverId,
|
|
117
|
-
() => props.allowSameOriginFallback,
|
|
118
|
-
],
|
|
119
|
-
([container, agent], _old, onCleanup) => {
|
|
120
|
-
if (!agent) {
|
|
121
|
-
error.value = new Error("No agent available to fetch resource");
|
|
122
|
-
isLoading.value = false;
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
if (!container) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
let mounted = true;
|
|
130
|
-
isLoading.value = true;
|
|
131
|
-
error.value = null;
|
|
132
|
-
contentError.value = null;
|
|
133
|
-
iframeSize.value = {};
|
|
134
|
-
fetchedResource.value = null;
|
|
135
|
-
|
|
136
|
-
// The host owns the iframe: create + mount it here (bindMcpApp only
|
|
137
|
-
// configures the sandbox contract + talks to it through the bridge).
|
|
138
|
-
const iframe = document.createElement("iframe");
|
|
139
|
-
iframe.style.width = "100%";
|
|
140
|
-
iframe.style.height = "100px";
|
|
141
|
-
iframe.style.border = "none";
|
|
142
|
-
iframe.style.backgroundColor = "transparent";
|
|
143
|
-
iframe.style.display = "block";
|
|
144
|
-
container.appendChild(iframe);
|
|
145
|
-
iframeRef.value = iframe;
|
|
146
|
-
|
|
147
|
-
// Register cleanup BEFORE the async import: if this watcher is
|
|
148
|
-
// invalidated (props change / unmount) while the import is in flight,
|
|
149
|
-
// `mounted` is already false when it resolves, so we never bind.
|
|
150
|
-
onCleanup(() => {
|
|
151
|
-
mounted = false;
|
|
152
|
-
sessionRef.value?.teardown();
|
|
153
|
-
sessionRef.value = null;
|
|
154
|
-
iframe.remove();
|
|
155
|
-
if (iframeRef.value === iframe) {
|
|
156
|
-
iframeRef.value = null;
|
|
157
|
-
}
|
|
99
|
+
[() => copilotkit.value, () => props.allowSameOriginFallback],
|
|
100
|
+
([core, allowSameOriginFallback]) => {
|
|
101
|
+
unsubscribe();
|
|
102
|
+
app.value?.destroy();
|
|
103
|
+
const created = new ɵMcpAppHost({
|
|
104
|
+
host: core,
|
|
105
|
+
sessionOptions: { allowSameOriginFallback },
|
|
106
|
+
importRenderer: () => import("@copilotkit/mcp-apps-renderer"),
|
|
158
107
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// behind a dynamic import() means a non-MCP app never pays for it.
|
|
165
|
-
const mod = await import("@copilotkit/mcp-apps-renderer").catch(
|
|
166
|
-
(importErr) => {
|
|
167
|
-
throw new Error(
|
|
168
|
-
"MCP Apps require '@copilotkit/mcp-apps-renderer' and its " +
|
|
169
|
-
"'@modelcontextprotocol/ext-apps' dependency. Reinstall your " +
|
|
170
|
-
"dependencies if this package is missing.",
|
|
171
|
-
{ cause: importErr },
|
|
172
|
-
);
|
|
173
|
-
},
|
|
174
|
-
);
|
|
175
|
-
if (!mounted) return;
|
|
176
|
-
|
|
177
|
-
const session = mod.bindMcpApp({
|
|
178
|
-
iframe,
|
|
179
|
-
getContent: () => props.content,
|
|
180
|
-
getAgent: () => props.agent,
|
|
181
|
-
host: copilotkit.value,
|
|
182
|
-
// Self-driving: the session subscribes to the agent's activity
|
|
183
|
-
// stream (filtered by messageId) and pushes tool input/result to
|
|
184
|
-
// the widget itself, so this adapter does not forward STORE-backed
|
|
185
|
-
// activities. It still calls syncContent for activities rendered
|
|
186
|
-
// from an external messages list (see the seed below).
|
|
187
|
-
messageId: messageId.value,
|
|
188
|
-
options: {
|
|
189
|
-
allowSameOriginFallback: props.allowSameOriginFallback,
|
|
190
|
-
},
|
|
191
|
-
hooks: {
|
|
192
|
-
onResource: (resource) => {
|
|
193
|
-
if (!mounted) return;
|
|
194
|
-
fetchedResource.value = resource;
|
|
195
|
-
isLoading.value = false;
|
|
196
|
-
},
|
|
197
|
-
onSizeChanged: (size) => {
|
|
198
|
-
if (mounted) iframeSize.value = size;
|
|
199
|
-
},
|
|
200
|
-
onContentError: (err) => {
|
|
201
|
-
if (mounted) contentError.value = err;
|
|
202
|
-
},
|
|
203
|
-
onError: (err) => {
|
|
204
|
-
if (!mounted) return;
|
|
205
|
-
error.value = err;
|
|
206
|
-
isLoading.value = false;
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
sessionRef.value = session;
|
|
211
|
-
// Seed the initial content now: the content watcher below does not
|
|
212
|
-
// re-run for unchanged props, so an activity rendered from an
|
|
213
|
-
// EXTERNAL messages list (absent from agent.messages) would never
|
|
214
|
-
// receive its initial tool input/result. Deduped + store precedence
|
|
215
|
-
// make this a no-op for agent-backed activities.
|
|
216
|
-
session.syncContent(props.content);
|
|
217
|
-
} catch (err) {
|
|
218
|
-
console.error("[MCPAppsRenderer] Setup error:", err);
|
|
219
|
-
if (mounted) {
|
|
220
|
-
error.value = err instanceof Error ? err : new Error(String(err));
|
|
221
|
-
isLoading.value = false;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
void setup();
|
|
108
|
+
unsubscribe = created.subscribe(() => {
|
|
109
|
+
state.value = created.getState();
|
|
110
|
+
});
|
|
111
|
+
state.value = created.getState();
|
|
112
|
+
app.value = created;
|
|
227
113
|
},
|
|
228
|
-
{ immediate: true
|
|
114
|
+
{ immediate: true },
|
|
229
115
|
);
|
|
230
|
-
|
|
231
|
-
// Size the iframe when the widget reports a new content size.
|
|
116
|
+
// `flush: "post"` so the container element is mounted when this runs.
|
|
232
117
|
watch(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
118
|
+
[
|
|
119
|
+
app,
|
|
120
|
+
() => props.agent,
|
|
121
|
+
() => props.message?.id,
|
|
122
|
+
() => props.content,
|
|
123
|
+
containerRef,
|
|
124
|
+
],
|
|
125
|
+
([host, agent, messageId, content, container]) => {
|
|
126
|
+
if (!host) return;
|
|
127
|
+
host.setAgent(agent);
|
|
128
|
+
host.setMessageId(messageId);
|
|
129
|
+
host.setContent(content);
|
|
130
|
+
host.setContainer(container);
|
|
245
131
|
},
|
|
246
|
-
{
|
|
132
|
+
{ immediate: true, flush: "post" },
|
|
247
133
|
);
|
|
134
|
+
onBeforeUnmount(() => {
|
|
135
|
+
unsubscribe();
|
|
136
|
+
app.value?.destroy();
|
|
137
|
+
});
|
|
248
138
|
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
sessionRef.value?.syncContent(props.content);
|
|
259
|
-
},
|
|
260
|
-
{ deep: true },
|
|
139
|
+
// prefersBorder: true = border and background; otherwise none.
|
|
140
|
+
const borderStyle = computed(() =>
|
|
141
|
+
state.value.prefersBorder
|
|
142
|
+
? {
|
|
143
|
+
borderRadius: "8px",
|
|
144
|
+
backgroundColor: "#f9f9f9",
|
|
145
|
+
border: "1px solid #e0e0e0",
|
|
146
|
+
}
|
|
147
|
+
: {},
|
|
261
148
|
);
|
|
262
149
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const prefersBorder = fetchedResource.value?._meta?.ui?.prefersBorder;
|
|
268
|
-
if (prefersBorder !== true) return {};
|
|
269
|
-
return {
|
|
270
|
-
borderRadius: "8px",
|
|
271
|
-
backgroundColor: "#f9f9f9",
|
|
272
|
-
border: "1px solid #e0e0e0",
|
|
273
|
-
};
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
return () =>
|
|
277
|
-
h(
|
|
150
|
+
return () => {
|
|
151
|
+
const { loading, error, contentError, size } = state.value;
|
|
152
|
+
const shownError = error ?? contentError;
|
|
153
|
+
return h(
|
|
278
154
|
"div",
|
|
279
155
|
{
|
|
280
156
|
ref: containerRef,
|
|
281
157
|
style: {
|
|
282
158
|
width: "100%",
|
|
283
|
-
height:
|
|
284
|
-
iframeSize.value.height !== undefined
|
|
285
|
-
? `${iframeSize.value.height}px`
|
|
286
|
-
: "auto",
|
|
159
|
+
height: size.height !== undefined ? `${size.height}px` : "auto",
|
|
287
160
|
minHeight: "100px",
|
|
288
161
|
overflow: "hidden",
|
|
289
162
|
position: "relative",
|
|
@@ -291,22 +164,23 @@ export const MCPAppsActivityRenderer = defineComponent({
|
|
|
291
164
|
},
|
|
292
165
|
},
|
|
293
166
|
[
|
|
294
|
-
|
|
167
|
+
loading
|
|
295
168
|
? h(
|
|
296
169
|
"div",
|
|
297
170
|
{ style: { padding: "1rem", color: "#666" } },
|
|
298
171
|
"Loading...",
|
|
299
172
|
)
|
|
300
173
|
: null,
|
|
301
|
-
|
|
174
|
+
shownError
|
|
302
175
|
? h(
|
|
303
176
|
"div",
|
|
304
177
|
{ style: { color: "red", padding: "1rem" } },
|
|
305
|
-
`Error: ${
|
|
178
|
+
`Error: ${shownError}`,
|
|
306
179
|
)
|
|
307
180
|
: null,
|
|
308
181
|
],
|
|
309
182
|
);
|
|
183
|
+
};
|
|
310
184
|
},
|
|
311
185
|
});
|
|
312
186
|
|
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
watch,
|
|
9
9
|
} from "vue";
|
|
10
10
|
import type { PropType } from "vue";
|
|
11
|
-
import * as z from "zod";
|
|
12
11
|
import {
|
|
13
12
|
OPEN_GENERATIVE_UI_ACTIVITY_TYPE,
|
|
14
13
|
ToolCallStatus,
|
|
14
|
+
ɵGENERATE_SANDBOXED_UI_ARGS_SCHEMA,
|
|
15
|
+
ɵOPEN_GENERATIVE_UI_CONTENT_SCHEMA,
|
|
15
16
|
ɵOpenGenerativeUIController,
|
|
17
|
+
ɵPlaceholderCycler,
|
|
16
18
|
} from "@copilotkit/core";
|
|
17
19
|
import type {
|
|
18
20
|
GenerateSandboxedUiArgs,
|
|
@@ -24,27 +26,14 @@ export type { GenerateSandboxedUiArgs, OpenGenerativeUIContent };
|
|
|
24
26
|
|
|
25
27
|
export const OpenGenerativeUIActivityType = OPEN_GENERATIVE_UI_ACTIVITY_TYPE;
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
generating: z.boolean().optional(),
|
|
30
|
-
css: z.string().optional(),
|
|
31
|
-
cssComplete: z.boolean().optional(),
|
|
32
|
-
html: z.array(z.string()).optional(),
|
|
33
|
-
htmlComplete: z.boolean().optional(),
|
|
34
|
-
jsFunctions: z.string().optional(),
|
|
35
|
-
jsFunctionsComplete: z.boolean().optional(),
|
|
36
|
-
jsExpressions: z.array(z.string()).optional(),
|
|
37
|
-
jsExpressionsComplete: z.boolean().optional(),
|
|
38
|
-
}) satisfies z.ZodType<OpenGenerativeUIContent>;
|
|
29
|
+
/** Validates Open Generative UI activity content (shared with React and Angular). */
|
|
30
|
+
export const OpenGenerativeUIContentSchema = ɵOPEN_GENERATIVE_UI_CONTENT_SCHEMA;
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
jsFunctions: z.string().optional(),
|
|
46
|
-
jsExpressions: z.array(z.string()).optional(),
|
|
47
|
-
}) satisfies z.ZodType<GenerateSandboxedUiArgs>;
|
|
32
|
+
/**
|
|
33
|
+
* Schema for the generateSandboxedUi tool call arguments (shared with React
|
|
34
|
+
* and Angular). It also describes the arguments to the model as JSON Schema.
|
|
35
|
+
*/
|
|
36
|
+
export const GenerateSandboxedUiArgsSchema = ɵGENERATE_SANDBOXED_UI_ARGS_SCHEMA;
|
|
48
37
|
|
|
49
38
|
/**
|
|
50
39
|
* Renders Open Generative UI content. The core controller throttles the
|
|
@@ -84,7 +73,7 @@ export const OpenGenerativeUIRenderer = defineComponent({
|
|
|
84
73
|
});
|
|
85
74
|
|
|
86
75
|
return () => {
|
|
87
|
-
const { phase,
|
|
76
|
+
const { phase, height, showSpinner, showOverlay } = state.value;
|
|
88
77
|
const hasVisibleSandbox = phase !== "placeholder";
|
|
89
78
|
return h(
|
|
90
79
|
"div",
|
|
@@ -105,48 +94,57 @@ export const OpenGenerativeUIRenderer = defineComponent({
|
|
|
105
94
|
},
|
|
106
95
|
},
|
|
107
96
|
[
|
|
108
|
-
|
|
109
|
-
? h(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
97
|
+
showOverlay
|
|
98
|
+
? h(
|
|
99
|
+
"div",
|
|
100
|
+
{
|
|
101
|
+
"data-testid": "open-generative-ui-progress-overlay",
|
|
102
|
+
style: {
|
|
103
|
+
position: "absolute",
|
|
104
|
+
inset: 0,
|
|
105
|
+
zIndex: 10,
|
|
106
|
+
pointerEvents: "all",
|
|
107
|
+
backgroundColor: "rgba(255, 255, 255, 0.5)",
|
|
108
|
+
display: "flex",
|
|
109
|
+
alignItems: "center",
|
|
110
|
+
justifyContent: "center",
|
|
118
111
|
},
|
|
119
|
-
[
|
|
120
|
-
h("circle", {
|
|
121
|
-
cx: "12",
|
|
122
|
-
cy: "12",
|
|
123
|
-
r: "10",
|
|
124
|
-
stroke: "#e0e0e0",
|
|
125
|
-
"stroke-width": "3",
|
|
126
|
-
}),
|
|
127
|
-
h("path", {
|
|
128
|
-
d: "M12 2a10 10 0 0 1 10 10",
|
|
129
|
-
stroke: "#999",
|
|
130
|
-
"stroke-width": "3",
|
|
131
|
-
"stroke-linecap": "round",
|
|
132
|
-
}),
|
|
133
|
-
],
|
|
134
|
-
),
|
|
135
|
-
h(
|
|
136
|
-
"style",
|
|
137
|
-
"@keyframes ck-spin { to { transform: rotate(360deg) } }",
|
|
138
|
-
),
|
|
139
|
-
])
|
|
140
|
-
: null,
|
|
141
|
-
generating
|
|
142
|
-
? h("div", {
|
|
143
|
-
"data-testid": "open-generative-ui-progress-overlay",
|
|
144
|
-
style: {
|
|
145
|
-
position: "absolute",
|
|
146
|
-
inset: 0,
|
|
147
|
-
backgroundColor: "rgba(255,255,255,0.45)",
|
|
148
112
|
},
|
|
149
|
-
|
|
113
|
+
showSpinner
|
|
114
|
+
? [
|
|
115
|
+
h(
|
|
116
|
+
"svg",
|
|
117
|
+
{
|
|
118
|
+
"data-testid": "open-generative-ui-spinner",
|
|
119
|
+
width: "48",
|
|
120
|
+
height: "48",
|
|
121
|
+
viewBox: "0 0 24 24",
|
|
122
|
+
fill: "none",
|
|
123
|
+
style: { animation: "ck-spin 1s linear infinite" },
|
|
124
|
+
},
|
|
125
|
+
[
|
|
126
|
+
h("circle", {
|
|
127
|
+
cx: "12",
|
|
128
|
+
cy: "12",
|
|
129
|
+
r: "10",
|
|
130
|
+
stroke: "#e0e0e0",
|
|
131
|
+
"stroke-width": "3",
|
|
132
|
+
}),
|
|
133
|
+
h("path", {
|
|
134
|
+
d: "M12 2a10 10 0 0 1 10 10",
|
|
135
|
+
stroke: "#999",
|
|
136
|
+
"stroke-width": "3",
|
|
137
|
+
"stroke-linecap": "round",
|
|
138
|
+
}),
|
|
139
|
+
],
|
|
140
|
+
),
|
|
141
|
+
h(
|
|
142
|
+
"style",
|
|
143
|
+
"@keyframes ck-spin { to { transform: rotate(360deg) } }",
|
|
144
|
+
),
|
|
145
|
+
]
|
|
146
|
+
: [],
|
|
147
|
+
)
|
|
150
148
|
: null,
|
|
151
149
|
],
|
|
152
150
|
);
|
|
@@ -186,35 +184,35 @@ export const OpenGenerativeUIToolRenderer = defineComponent({
|
|
|
186
184
|
result: { type: String as PropType<string | undefined>, required: false },
|
|
187
185
|
},
|
|
188
186
|
setup(props) {
|
|
189
|
-
const
|
|
190
|
-
|
|
187
|
+
const cycler = new ɵPlaceholderCycler();
|
|
188
|
+
const message = shallowRef(cycler.getSnapshot().message);
|
|
189
|
+
const unsubscribe = cycler.subscribe(() => {
|
|
190
|
+
message.value = cycler.getSnapshot().message;
|
|
191
|
+
});
|
|
191
192
|
watch(
|
|
192
|
-
() =>
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
visibleMessageIndex.value =
|
|
199
|
-
(visibleMessageIndex.value + 1) % Math.max(messages.length, 1);
|
|
200
|
-
}, 5000);
|
|
201
|
-
onCleanup(() => window.clearInterval(timer));
|
|
202
|
-
},
|
|
193
|
+
() =>
|
|
194
|
+
[
|
|
195
|
+
props.args.placeholderMessages,
|
|
196
|
+
props.status === ToolCallStatus.Complete,
|
|
197
|
+
] as const,
|
|
198
|
+
([messages, complete]) => cycler.update(messages, complete),
|
|
203
199
|
{ immediate: true },
|
|
204
200
|
);
|
|
201
|
+
onBeforeUnmount(() => {
|
|
202
|
+
unsubscribe();
|
|
203
|
+
cycler.dispose();
|
|
204
|
+
});
|
|
205
205
|
|
|
206
206
|
return () => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (!messages?.length) return null;
|
|
210
|
-
const currentMessage = messages[visibleMessageIndex.value] ?? messages[0];
|
|
207
|
+
// Nothing once complete — the activity renderer handles the UI.
|
|
208
|
+
if (message.value === undefined) return null;
|
|
211
209
|
return h(
|
|
212
210
|
"div",
|
|
213
211
|
{
|
|
214
212
|
style: { padding: "8px 12px", color: "#999", fontSize: "14px" },
|
|
215
213
|
"data-testid": "open-generative-ui-tool-placeholder",
|
|
216
214
|
},
|
|
217
|
-
|
|
215
|
+
message.value,
|
|
218
216
|
);
|
|
219
217
|
};
|
|
220
218
|
},
|