@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,17 +1,6 @@
|
|
|
1
|
-
import { computed, onScopeDispose,
|
|
1
|
+
import { computed, onScopeDispose, shallowRef, toValue, watch } from "vue";
|
|
2
2
|
import type { MaybeRefOrGetter, Ref } from "vue";
|
|
3
|
-
import {
|
|
4
|
-
CopilotKitCoreRuntimeConnectionStatus,
|
|
5
|
-
ɵcreateThreadStore,
|
|
6
|
-
ɵselectHasNextPage,
|
|
7
|
-
ɵselectIsFetchingNextPage,
|
|
8
|
-
ɵselectIsMutating,
|
|
9
|
-
ɵselectThreads,
|
|
10
|
-
ɵselectThreadsError,
|
|
11
|
-
ɵselectFetchMoreError,
|
|
12
|
-
ɵselectThreadsIsLoading,
|
|
13
|
-
} from "@copilotkit/core";
|
|
14
|
-
import type { ɵThreadRuntimeContext, ɵThreadStore } from "@copilotkit/core";
|
|
3
|
+
import { ɵThreadsController, ɵcreateThreadStore } from "@copilotkit/core";
|
|
15
4
|
import { useCopilotKit } from "../providers/useCopilotKit";
|
|
16
5
|
|
|
17
6
|
export interface Thread {
|
|
@@ -67,283 +56,64 @@ export interface UseThreadsResult {
|
|
|
67
56
|
deleteThread: (threadId: string) => Promise<void>;
|
|
68
57
|
}
|
|
69
58
|
|
|
70
|
-
function bindThreadStoreSelector<T>(
|
|
71
|
-
store: ɵThreadStore,
|
|
72
|
-
selector: (state: ReturnType<ɵThreadStore["getState"]>) => T,
|
|
73
|
-
target: Ref<T>,
|
|
74
|
-
): void {
|
|
75
|
-
target.value = selector(store.getState());
|
|
76
|
-
const subscription = store.select(selector).subscribe(() => {
|
|
77
|
-
target.value = selector(store.getState());
|
|
78
|
-
});
|
|
79
|
-
onScopeDispose(() => subscription.unsubscribe());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Vue composable for listing and managing CopilotKit Intelligence threads.
|
|
84
|
-
*
|
|
85
|
-
* The hook fetches threads for the runtime-authenticated user and the given
|
|
86
|
-
* `agentId`, then keeps the result in sync via the core thread store's realtime
|
|
87
|
-
* channel when available. Inputs accept refs/computeds to make thread context
|
|
88
|
-
* changes reactive.
|
|
89
|
-
*/
|
|
90
59
|
export function useThreads(input: UseThreadsInput): UseThreadsResult {
|
|
91
60
|
const { copilotkit } = useCopilotKit();
|
|
92
|
-
const
|
|
93
|
-
|
|
61
|
+
const readInput = () => ({
|
|
62
|
+
core: copilotkit.value,
|
|
63
|
+
agentId: toValue(input.agentId),
|
|
64
|
+
includeArchived: toValue(input.includeArchived),
|
|
65
|
+
limit: toValue(input.limit),
|
|
66
|
+
enabled: toValue(input.enabled) ?? true,
|
|
94
67
|
});
|
|
95
68
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Thread-endpoint capability, derived from the runtime's `/info` payload.
|
|
104
|
-
// `threadEndpoints` is `undefined` on legacy runtimes that don't advertise
|
|
105
|
-
// the capability, so we treat "not explicitly false" as supported (matching
|
|
106
|
-
// React's `!== false` semantics) to preserve legacy thread behavior.
|
|
107
|
-
const threadListEndpointSupported = computed(
|
|
108
|
-
() => copilotkit.value.threadEndpoints?.list !== false,
|
|
109
|
-
);
|
|
110
|
-
const threadMutationsSupported = computed(
|
|
111
|
-
() => copilotkit.value.threadEndpoints?.mutations !== false,
|
|
112
|
-
);
|
|
113
|
-
// Connected, but the runtime explicitly does not serve the list endpoint.
|
|
114
|
-
const threadEndpointsUnavailable = computed(
|
|
115
|
-
() =>
|
|
116
|
-
!!copilotkit.value.runtimeUrl &&
|
|
117
|
-
copilotkit.value.runtimeConnectionStatus ===
|
|
118
|
-
CopilotKitCoreRuntimeConnectionStatus.Connected &&
|
|
119
|
-
!threadListEndpointSupported.value,
|
|
120
|
-
);
|
|
121
|
-
const threadEndpointsError = computed<Error | null>(() =>
|
|
122
|
-
threadEndpointsUnavailable.value
|
|
123
|
-
? new Error(
|
|
124
|
-
"Thread endpoints are not available on this CopilotKit runtime",
|
|
125
|
-
)
|
|
126
|
-
: null,
|
|
127
|
-
);
|
|
128
|
-
const threadMutationsError = computed<Error | null>(() =>
|
|
129
|
-
threadMutationsSupported.value
|
|
130
|
-
? null
|
|
131
|
-
: new Error(
|
|
132
|
-
"Thread mutations are not available on this CopilotKit runtime",
|
|
133
|
-
),
|
|
69
|
+
// Core's ɵThreadsController owns the view model: thread projection, the
|
|
70
|
+
// configuration errors, the gated and de-duplicated context dispatch, the
|
|
71
|
+
// registry claim and the mutation guard. This composable feeds it and
|
|
72
|
+
// projects its snapshot.
|
|
73
|
+
const controller = new ɵThreadsController(
|
|
74
|
+
ɵcreateThreadStore({ fetch: copilotkit.value.ɵruntimeFetch }),
|
|
75
|
+
readInput(),
|
|
134
76
|
);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const headersKey = computed(() => copilotkit.value.ɵheadersGeneration);
|
|
141
|
-
|
|
142
|
-
const threads = ref<Thread[]>([]);
|
|
143
|
-
const storeIsLoading = ref(false);
|
|
144
|
-
const storeError = ref<Error | null>(null);
|
|
145
|
-
const fetchMoreError = ref<Error | null>(null);
|
|
146
|
-
const hasMoreThreads = ref(false);
|
|
147
|
-
const isFetchingMoreThreads = ref(false);
|
|
148
|
-
const isMutating = ref(false);
|
|
149
|
-
|
|
150
|
-
bindThreadStoreSelector(store, ɵselectThreads, threads as Ref<Thread[]>);
|
|
151
|
-
bindThreadStoreSelector(store, ɵselectThreadsIsLoading, storeIsLoading);
|
|
152
|
-
bindThreadStoreSelector(store, ɵselectThreadsError, storeError);
|
|
153
|
-
bindThreadStoreSelector(store, ɵselectFetchMoreError, fetchMoreError);
|
|
154
|
-
bindThreadStoreSelector(store, ɵselectHasNextPage, hasMoreThreads);
|
|
155
|
-
bindThreadStoreSelector(
|
|
156
|
-
store,
|
|
157
|
-
ɵselectIsFetchingNextPage,
|
|
158
|
-
isFetchingMoreThreads,
|
|
159
|
-
);
|
|
160
|
-
bindThreadStoreSelector(store, ɵselectIsMutating, isMutating);
|
|
161
|
-
|
|
162
|
-
store.start();
|
|
77
|
+
const snapshot = shallowRef(controller.getSnapshot());
|
|
78
|
+
const unsubscribe = controller.subscribe(() => {
|
|
79
|
+
snapshot.value = controller.getSnapshot();
|
|
80
|
+
});
|
|
81
|
+
const stop = controller.start();
|
|
163
82
|
onScopeDispose(() => {
|
|
164
|
-
|
|
83
|
+
stop();
|
|
84
|
+
unsubscribe();
|
|
85
|
+
controller.dispose();
|
|
165
86
|
});
|
|
166
87
|
|
|
167
|
-
// Register this store in core's single-slot thread-store registry so other
|
|
168
|
-
// surfaces (e.g. the chat view) can resolve the same store for the agent.
|
|
169
|
-
//
|
|
170
|
-
// Gated on `resolvedEnabled`: a disabled (e.g. unlicensed) drawer must not
|
|
171
|
-
// claim the agentId slot. The registry is single-slot/last-writer-wins, so
|
|
172
|
-
// registering an inert store would evict — and on unmount tear down — a
|
|
173
|
-
// co-mounted live store for the same agent. Staying unregistered while
|
|
174
|
-
// disabled leaves the live store's registration intact.
|
|
175
|
-
watch(
|
|
176
|
-
[resolvedEnabled, resolvedAgentId],
|
|
177
|
-
([enabled, agentId], _prev, onCleanup) => {
|
|
178
|
-
if (!enabled) return;
|
|
179
|
-
copilotkit.value.registerThreadStore(agentId, store);
|
|
180
|
-
onCleanup(() => {
|
|
181
|
-
copilotkit.value.unregisterThreadStore(agentId);
|
|
182
|
-
});
|
|
183
|
-
},
|
|
184
|
-
{ immediate: true },
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
// Tracks whether we've dispatched the first real context to the store.
|
|
188
|
-
// The store itself starts with `isLoading: false`, so before we dispatch
|
|
189
|
-
// consumers would otherwise see an empty, non-loading state (empty-list
|
|
190
|
-
// flash). While runtimeUrl is set and we haven't dispatched yet, we
|
|
191
|
-
// synthesize `isLoading: true` so the UI keeps its loading indicator until
|
|
192
|
-
// the first fetch is in flight (at which point the store's own
|
|
193
|
-
// isLoading takes over).
|
|
194
|
-
const hasDispatchedContext = ref(false);
|
|
195
|
-
|
|
196
|
-
// Defer setting the context until the runtime reports Connected. Before
|
|
197
|
-
// `/info` resolves we don't know `intelligence.wsUrl`, so dispatching the
|
|
198
|
-
// context early would issue a list fetch with `wsUrl: undefined`, then a
|
|
199
|
-
// second list fetch (and a `/threads/subscribe`) once the flag lands.
|
|
200
|
-
// Waiting lets the hook issue just one `/threads?…` + one `/threads/subscribe`.
|
|
201
|
-
//
|
|
202
|
-
// When `runtimeUrl` is absent we dispatch `null` to clear the store. For
|
|
203
|
-
// transient states (Disconnected/Connecting/Error with a URL still set) we
|
|
204
|
-
// leave the previously-dispatched context in place — any in-flight
|
|
205
|
-
// realtime subscription or cached thread list stays usable while the
|
|
206
|
-
// runtime recovers, and we don't re-trigger a fetch storm on transitions.
|
|
207
88
|
watch(
|
|
208
89
|
[
|
|
90
|
+
readInput,
|
|
209
91
|
() => copilotkit.value.runtimeUrl,
|
|
210
92
|
() => copilotkit.value.runtimeConnectionStatus,
|
|
211
|
-
|
|
93
|
+
() => copilotkit.value.ɵheadersGeneration,
|
|
212
94
|
() => copilotkit.value.intelligence?.wsUrl,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
resolvedLimit,
|
|
216
|
-
resolvedEnabled,
|
|
217
|
-
threadListEndpointSupported,
|
|
95
|
+
() => copilotkit.value.threadEndpoints?.list,
|
|
96
|
+
() => copilotkit.value.threadEndpoints?.mutations,
|
|
218
97
|
],
|
|
219
|
-
([
|
|
220
|
-
runtimeUrl,
|
|
221
|
-
runtimeStatus,
|
|
222
|
-
,
|
|
223
|
-
wsUrl,
|
|
224
|
-
agentId,
|
|
225
|
-
includeArchived,
|
|
226
|
-
limit,
|
|
227
|
-
enabled,
|
|
228
|
-
listEndpointSupported,
|
|
229
|
-
]) => {
|
|
230
|
-
if (!runtimeUrl || !enabled) {
|
|
231
|
-
store.setContext(null);
|
|
232
|
-
hasDispatchedContext.value = false;
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (runtimeStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Connected, but the runtime explicitly does not serve the list
|
|
241
|
-
// endpoint: stay inert so no `/threads` fetch fires. The
|
|
242
|
-
// `threadEndpointsError` surfaces via `error` instead.
|
|
243
|
-
if (!listEndpointSupported) {
|
|
244
|
-
store.setContext(null);
|
|
245
|
-
hasDispatchedContext.value = false;
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// No `headers` here: the store's `fetch` is `copilotkit.value.ɵruntimeFetch`,
|
|
250
|
-
// which already resolves and overlays the current core headers at send
|
|
251
|
-
// time (#1937) — a snapshot here would go stale the moment the builder
|
|
252
|
-
// returns something new.
|
|
253
|
-
const context: ɵThreadRuntimeContext = {
|
|
254
|
-
runtimeUrl,
|
|
255
|
-
wsUrl,
|
|
256
|
-
agentId,
|
|
257
|
-
includeArchived,
|
|
258
|
-
limit,
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
store.setContext(context);
|
|
262
|
-
hasDispatchedContext.value = true;
|
|
263
|
-
},
|
|
98
|
+
([next]) => controller.update(next),
|
|
264
99
|
{ immediate: true },
|
|
265
100
|
);
|
|
266
101
|
|
|
267
|
-
const runtimeError = computed<Error | null>(() =>
|
|
268
|
-
copilotkit.value.runtimeUrl
|
|
269
|
-
? null
|
|
270
|
-
: new Error("Runtime URL is not configured"),
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
const preConnectLoading = computed(
|
|
274
|
-
() =>
|
|
275
|
-
!!copilotkit.value.runtimeUrl &&
|
|
276
|
-
resolvedEnabled.value &&
|
|
277
|
-
!threadEndpointsUnavailable.value &&
|
|
278
|
-
!hasDispatchedContext.value,
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
const isLoading = computed(() =>
|
|
282
|
-
runtimeError.value || threadEndpointsError.value
|
|
283
|
-
? false
|
|
284
|
-
: preConnectLoading.value || storeIsLoading.value,
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
// Folds developer/config errors (missing runtime URL, runtime without
|
|
288
|
-
// thread endpoints) together with genuine store errors. `listError` below
|
|
289
|
-
// deliberately excludes the config errors.
|
|
290
|
-
const error = computed<Error | null>(
|
|
291
|
-
() => runtimeError.value ?? threadEndpointsError.value ?? storeError.value,
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
// Genuine store errors only. Unlike `error`, this omits the dev/config
|
|
295
|
-
// `runtimeError`/`threadEndpointsError` strings so they are never shown in
|
|
296
|
-
// user-facing error UI.
|
|
297
|
-
const listError = computed<Error | null>(() => storeError.value);
|
|
298
|
-
|
|
299
|
-
// Reject mutations locally (before touching the network) when the runtime
|
|
300
|
-
// reports mutations are unsupported, matching React's `guardMutation`.
|
|
301
|
-
function guardMutation<TArgs extends unknown[]>(
|
|
302
|
-
mutation: (...args: TArgs) => Promise<void>,
|
|
303
|
-
): (...args: TArgs) => Promise<void> {
|
|
304
|
-
return (...args: TArgs) => {
|
|
305
|
-
if (threadMutationsError.value) {
|
|
306
|
-
return Promise.reject(threadMutationsError.value);
|
|
307
|
-
}
|
|
308
|
-
return mutation(...args);
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
|
|
312
102
|
return {
|
|
313
|
-
threads: computed(() =>
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
listError,
|
|
329
|
-
fetchMoreError,
|
|
330
|
-
hasMoreThreads,
|
|
331
|
-
isFetchingMoreThreads,
|
|
332
|
-
isMutating,
|
|
333
|
-
fetchMoreThreads: () => store.fetchNextPage(),
|
|
334
|
-
refetchThreads: () => store.refetchThreads(),
|
|
335
|
-
startNewThread: () => store.startNewThread(),
|
|
336
|
-
renameThread: guardMutation((threadId: string, name: string) =>
|
|
337
|
-
store.renameThread(threadId, name),
|
|
338
|
-
),
|
|
339
|
-
archiveThread: guardMutation((threadId: string) =>
|
|
340
|
-
store.archiveThread(threadId),
|
|
341
|
-
),
|
|
342
|
-
unarchiveThread: guardMutation((threadId: string) =>
|
|
343
|
-
store.unarchiveThread(threadId),
|
|
344
|
-
),
|
|
345
|
-
deleteThread: guardMutation((threadId: string) =>
|
|
346
|
-
store.deleteThread(threadId),
|
|
347
|
-
),
|
|
103
|
+
threads: computed(() => snapshot.value.threads),
|
|
104
|
+
isLoading: computed(() => snapshot.value.isLoading),
|
|
105
|
+
error: computed(() => snapshot.value.error),
|
|
106
|
+
listError: computed(() => snapshot.value.listError),
|
|
107
|
+
fetchMoreError: computed(() => snapshot.value.fetchMoreError),
|
|
108
|
+
hasMoreThreads: computed(() => snapshot.value.hasMoreThreads),
|
|
109
|
+
isFetchingMoreThreads: computed(() => snapshot.value.isFetchingMoreThreads),
|
|
110
|
+
isMutating: computed(() => snapshot.value.isMutating),
|
|
111
|
+
fetchMoreThreads: controller.fetchMoreThreads,
|
|
112
|
+
refetchThreads: controller.refetchThreads,
|
|
113
|
+
startNewThread: controller.startNewThread,
|
|
114
|
+
renameThread: controller.renameThread,
|
|
115
|
+
archiveThread: controller.archiveThread,
|
|
116
|
+
unarchiveThread: controller.unarchiveThread,
|
|
117
|
+
deleteThread: controller.deleteThread,
|
|
348
118
|
};
|
|
349
119
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
import { CopilotKitCoreVue } from "../vue-core";
|
|
4
|
+
import type { VueActivityMessageRenderer } from "../../types";
|
|
5
|
+
|
|
6
|
+
const planRenderer: VueActivityMessageRenderer<unknown> = {
|
|
7
|
+
activityType: "plan",
|
|
8
|
+
content: {
|
|
9
|
+
"~standard": {
|
|
10
|
+
version: 1,
|
|
11
|
+
vendor: "test",
|
|
12
|
+
validate: (value) => ({ value }),
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
render: () => null,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe("CopilotKitCoreVue renderer lists", () => {
|
|
19
|
+
it("notifies subscribers when activity renderers change", () => {
|
|
20
|
+
const core = new CopilotKitCoreVue({});
|
|
21
|
+
const seen: string[][] = [];
|
|
22
|
+
core.subscribe({
|
|
23
|
+
onRenderActivityMessagesChanged: ({ renderActivityMessages }) => {
|
|
24
|
+
seen.push(renderActivityMessages.map((r) => r.activityType));
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
core.setRenderActivityMessages([planRenderer]);
|
|
29
|
+
|
|
30
|
+
expect(seen).toEqual([["plan"]]);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("keeps working behind a Vue reactive proxy", () => {
|
|
34
|
+
const wrapped = ref(new CopilotKitCoreVue({}));
|
|
35
|
+
|
|
36
|
+
wrapped.value.addHookRenderToolCall({ name: "search", render: () => null });
|
|
37
|
+
|
|
38
|
+
expect(wrapped.value.renderToolCalls.map((r) => r.name)).toEqual([
|
|
39
|
+
"search",
|
|
40
|
+
]);
|
|
41
|
+
});
|
|
42
|
+
});
|
package/src/v2/lib/vue-core.ts
CHANGED
|
@@ -5,11 +5,12 @@ import type {
|
|
|
5
5
|
VueCustomMessageRenderer,
|
|
6
6
|
} from "../types";
|
|
7
7
|
import type { InterruptRenderProps } from "../types/interrupt";
|
|
8
|
-
import { CopilotKitCore } from "@copilotkit/core";
|
|
8
|
+
import { CopilotKitCore, ɵRendererRegistry } from "@copilotkit/core";
|
|
9
9
|
import type {
|
|
10
10
|
CopilotKitCoreConfig,
|
|
11
11
|
CopilotKitCoreSubscriber,
|
|
12
12
|
CopilotKitCoreSubscription,
|
|
13
|
+
ɵRendererKind,
|
|
13
14
|
} from "@copilotkit/core";
|
|
14
15
|
|
|
15
16
|
export interface CopilotKitCoreVueConfig extends CopilotKitCoreConfig {
|
|
@@ -27,6 +28,10 @@ export interface CopilotKitCoreVueSubscriber extends CopilotKitCoreSubscriber {
|
|
|
27
28
|
copilotkit: CopilotKitCoreVue;
|
|
28
29
|
renderCustomMessages: VueCustomMessageRenderer[];
|
|
29
30
|
}) => void | Promise<void>;
|
|
31
|
+
onRenderActivityMessagesChanged?: (event: {
|
|
32
|
+
copilotkit: CopilotKitCoreVue;
|
|
33
|
+
renderActivityMessages: VueActivityMessageRenderer<unknown>[];
|
|
34
|
+
}) => void | Promise<void>;
|
|
30
35
|
onInterruptStateChanged?: (event: {
|
|
31
36
|
copilotkit: CopilotKitCoreVue;
|
|
32
37
|
interruptState: InterruptRenderProps<unknown, unknown> | null;
|
|
@@ -34,119 +39,109 @@ export interface CopilotKitCoreVueSubscriber extends CopilotKitCoreSubscriber {
|
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
export class CopilotKitCoreVue extends CopilotKitCore {
|
|
37
|
-
private
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
private _renderCustomMessages: VueCustomMessageRenderer[] = [];
|
|
43
|
-
private _renderActivityMessages: VueActivityMessageRenderer<unknown>[] = [];
|
|
44
|
-
private _interruptState: InterruptRenderProps<unknown, unknown> | null = null;
|
|
42
|
+
private readonly _renderers: ɵRendererRegistry<
|
|
43
|
+
VueToolCallRenderer<unknown>,
|
|
44
|
+
VueActivityMessageRenderer<unknown>,
|
|
45
|
+
VueCustomMessageRenderer
|
|
46
|
+
>;
|
|
45
47
|
|
|
46
48
|
constructor(config: CopilotKitCoreVueConfig) {
|
|
47
49
|
// Tool handlers can change reactive state. `nextTick` lets Vue flush those
|
|
48
50
|
// updates before core starts the follow-up run.
|
|
49
51
|
super({ ...config, ɵwaitForFrameworkUpdates: () => nextTick() });
|
|
50
|
-
this.
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
this._renderers = new ɵRendererRegistry({
|
|
53
|
+
toolCalls: config.renderToolCalls,
|
|
54
|
+
activity: config.renderActivityMessages,
|
|
55
|
+
custom: config.renderCustomMessages,
|
|
56
|
+
});
|
|
57
|
+
this._renderers.subscribe((kind) => this.notifyRenderersChanged(kind));
|
|
58
|
+
// The props live in core's generic interrupt slot; keep the Vue
|
|
59
|
+
// subscriber event for existing listeners.
|
|
60
|
+
this.ɵsubscribeToInterruptPayload(() => {
|
|
61
|
+
void this.notifySubscribers((subscriber) => {
|
|
62
|
+
const vueSubscriber = subscriber as CopilotKitCoreVueSubscriber;
|
|
63
|
+
return vueSubscriber.onInterruptStateChanged?.({
|
|
64
|
+
copilotkit: this,
|
|
65
|
+
interruptState: this.interruptState,
|
|
66
|
+
});
|
|
67
|
+
}, "Subscriber onInterruptStateChanged error:");
|
|
68
|
+
});
|
|
53
69
|
}
|
|
54
70
|
|
|
55
|
-
get renderCustomMessages()
|
|
56
|
-
return this.
|
|
71
|
+
get renderCustomMessages() {
|
|
72
|
+
return this._renderers.custom;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
|
-
get renderActivityMessages()
|
|
60
|
-
|
|
61
|
-
> {
|
|
62
|
-
return this._renderActivityMessages;
|
|
75
|
+
get renderActivityMessages() {
|
|
76
|
+
return this._renderers.activity;
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
setRenderActivityMessages(
|
|
66
80
|
renderers: VueActivityMessageRenderer<unknown>[],
|
|
67
81
|
): void {
|
|
68
|
-
this.
|
|
82
|
+
this._renderers.setActivity(renderers);
|
|
69
83
|
}
|
|
70
84
|
|
|
71
85
|
setRenderCustomMessages(renderers: VueCustomMessageRenderer[]): void {
|
|
72
|
-
this.
|
|
73
|
-
void this.notifySubscribers((subscriber) => {
|
|
74
|
-
const vueSubscriber = subscriber as CopilotKitCoreVueSubscriber;
|
|
75
|
-
return vueSubscriber.onRenderCustomMessagesChanged?.({
|
|
76
|
-
copilotkit: this,
|
|
77
|
-
renderCustomMessages: [...this.renderCustomMessages],
|
|
78
|
-
});
|
|
79
|
-
}, "Subscriber onRenderCustomMessagesChanged error:");
|
|
86
|
+
this._renderers.setCustom(renderers);
|
|
80
87
|
}
|
|
81
88
|
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
/** The renderers the provider was given, without hook renderers. */
|
|
90
|
+
get propRenderToolCalls() {
|
|
91
|
+
return this._renderers.propToolCalls;
|
|
84
92
|
}
|
|
85
93
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
if (this._cachedMergedRenderToolCalls) {
|
|
91
|
-
return this._cachedMergedRenderToolCalls;
|
|
92
|
-
}
|
|
93
|
-
const merged = new Map<string, VueToolCallRenderer<unknown>>();
|
|
94
|
-
for (const rc of this._renderToolCalls) {
|
|
95
|
-
merged.set(`${rc.agentId ?? ""}:${rc.name}`, rc);
|
|
96
|
-
}
|
|
97
|
-
for (const [key, rc] of this._hookRenderToolCalls) {
|
|
98
|
-
merged.set(key, rc);
|
|
99
|
-
}
|
|
100
|
-
this._cachedMergedRenderToolCalls = Array.from(merged.values());
|
|
101
|
-
return this._cachedMergedRenderToolCalls;
|
|
94
|
+
/** Prop and hook renderers merged; a hook renderer wins over a prop one. */
|
|
95
|
+
get renderToolCalls() {
|
|
96
|
+
return this._renderers.toolCalls;
|
|
102
97
|
}
|
|
103
98
|
|
|
104
99
|
get interruptState(): InterruptRenderProps<unknown, unknown> | null {
|
|
105
|
-
return this
|
|
100
|
+
return this.ɵinterruptPayload as InterruptRenderProps<
|
|
101
|
+
unknown,
|
|
102
|
+
unknown
|
|
103
|
+
> | null;
|
|
106
104
|
}
|
|
107
105
|
|
|
108
106
|
setRenderToolCalls(renderToolCalls: VueToolCallRenderer<unknown>[]): void {
|
|
109
|
-
this.
|
|
110
|
-
this._cachedMergedRenderToolCalls = null;
|
|
111
|
-
this._notifyRenderToolCallsChanged();
|
|
107
|
+
this._renderers.setPropToolCalls(renderToolCalls);
|
|
112
108
|
}
|
|
113
109
|
|
|
114
110
|
addHookRenderToolCall(entry: VueToolCallRenderer<unknown>): void {
|
|
115
|
-
|
|
116
|
-
this._hookRenderToolCalls.set(key, entry);
|
|
117
|
-
this._cachedMergedRenderToolCalls = null;
|
|
118
|
-
this._notifyRenderToolCallsChanged();
|
|
111
|
+
this._renderers.addHookToolCall(entry);
|
|
119
112
|
}
|
|
120
113
|
|
|
121
114
|
removeHookRenderToolCall(name: string, agentId?: string): void {
|
|
122
|
-
|
|
123
|
-
if (this._hookRenderToolCalls.delete(key)) {
|
|
124
|
-
this._cachedMergedRenderToolCalls = null;
|
|
125
|
-
this._notifyRenderToolCallsChanged();
|
|
126
|
-
}
|
|
115
|
+
this._renderers.removeHookToolCall(name, agentId);
|
|
127
116
|
}
|
|
128
117
|
|
|
129
|
-
private
|
|
118
|
+
private notifyRenderersChanged(kind: ɵRendererKind): void {
|
|
130
119
|
void this.notifySubscribers((subscriber) => {
|
|
131
120
|
const vueSubscriber = subscriber as CopilotKitCoreVueSubscriber;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
121
|
+
switch (kind) {
|
|
122
|
+
case "toolCalls":
|
|
123
|
+
return vueSubscriber.onRenderToolCallsChanged?.({
|
|
124
|
+
copilotkit: this,
|
|
125
|
+
renderToolCalls: [...this.renderToolCalls],
|
|
126
|
+
});
|
|
127
|
+
case "activity":
|
|
128
|
+
return vueSubscriber.onRenderActivityMessagesChanged?.({
|
|
129
|
+
copilotkit: this,
|
|
130
|
+
renderActivityMessages: [...this.renderActivityMessages],
|
|
131
|
+
});
|
|
132
|
+
case "custom":
|
|
133
|
+
return vueSubscriber.onRenderCustomMessagesChanged?.({
|
|
134
|
+
copilotkit: this,
|
|
135
|
+
renderCustomMessages: [...this.renderCustomMessages],
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}, `Subscriber renderer change (${kind}) error:`);
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
setInterruptState(
|
|
140
142
|
interruptState: InterruptRenderProps<unknown, unknown> | null,
|
|
141
143
|
): void {
|
|
142
|
-
this
|
|
143
|
-
void this.notifySubscribers((subscriber) => {
|
|
144
|
-
const vueSubscriber = subscriber as CopilotKitCoreVueSubscriber;
|
|
145
|
-
return vueSubscriber.onInterruptStateChanged?.({
|
|
146
|
-
copilotkit: this,
|
|
147
|
-
interruptState: this._interruptState,
|
|
148
|
-
});
|
|
149
|
-
}, "Subscriber onInterruptStateChanged error:");
|
|
144
|
+
this.ɵsetInterruptPayload(interruptState);
|
|
150
145
|
}
|
|
151
146
|
|
|
152
147
|
subscribe(
|