@copilotkit/vue 2.0.0-rc.20 → 2.0.0-rc.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +13 -13
- package/dist/use-render-activity-message-BAhbpSDh.js +16200 -0
- package/dist/use-render-activity-message-BAhbpSDh.js.map +1 -0
- package/dist/use-render-activity-message-DJ6q1qHV.cjs +114 -0
- package/dist/use-render-activity-message-DJ6q1qHV.cjs.map +1 -0
- package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
- package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
- package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
- package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
- package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
- package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
- package/dist/v2/components/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
|
@@ -12,7 +12,10 @@ import type { Observable } from "rxjs";
|
|
|
12
12
|
import { useConfigureSuggestions } from "../use-configure-suggestions";
|
|
13
13
|
import { useSuggestions } from "../use-suggestions";
|
|
14
14
|
import { useCopilotKit } from "../../providers/useCopilotKit";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
mountWithProvider,
|
|
17
|
+
renderWithCopilotKit,
|
|
18
|
+
} from "../../__tests__/utils/mount";
|
|
16
19
|
import {
|
|
17
20
|
StateCapturingAgent,
|
|
18
21
|
SuggestionsProviderAgent,
|
|
@@ -396,4 +399,30 @@ describe("useConfigureSuggestions", () => {
|
|
|
396
399
|
|
|
397
400
|
expect(wrapper.find("[data-testid=json]").text()).toContain("Deferred");
|
|
398
401
|
});
|
|
402
|
+
|
|
403
|
+
it("loads a global static config for the chat's agent before any agent registers", async () => {
|
|
404
|
+
const Harness = defineComponent({
|
|
405
|
+
setup() {
|
|
406
|
+
useConfigureSuggestions({
|
|
407
|
+
suggestions: [{ title: "Welcome", message: "Say hi" }],
|
|
408
|
+
available: "always",
|
|
409
|
+
});
|
|
410
|
+
const { suggestions } = useSuggestions({ agentId: "support" });
|
|
411
|
+
return () =>
|
|
412
|
+
h(
|
|
413
|
+
"span",
|
|
414
|
+
{ "data-testid": "titles" },
|
|
415
|
+
suggestions.value.map((suggestion) => suggestion.title).join(","),
|
|
416
|
+
);
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const { wrapper } = renderWithCopilotKit(() => h(Harness), {
|
|
421
|
+
agentId: "support",
|
|
422
|
+
agents: {},
|
|
423
|
+
});
|
|
424
|
+
await nextTick();
|
|
425
|
+
|
|
426
|
+
expect(wrapper.find("[data-testid=titles]").text()).toBe("Welcome");
|
|
427
|
+
});
|
|
399
428
|
});
|
|
@@ -530,10 +530,8 @@ describe("useDefaultRenderTool", () => {
|
|
|
530
530
|
expect(forwarded.result).toBe("ok");
|
|
531
531
|
});
|
|
532
532
|
|
|
533
|
-
// Fix #5: circular-ref parameters must not crash the vue render
|
|
534
|
-
it("default renderer survives circular-ref parameters
|
|
535
|
-
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
536
|
-
|
|
533
|
+
// Fix #5: circular-ref parameters must not crash the vue render.
|
|
534
|
+
it("default renderer survives circular-ref parameters", async () => {
|
|
537
535
|
const Harness = defineComponent({
|
|
538
536
|
setup() {
|
|
539
537
|
useDefaultRenderTool();
|
|
@@ -567,14 +565,16 @@ describe("useDefaultRenderTool", () => {
|
|
|
567
565
|
}),
|
|
568
566
|
).not.toThrow();
|
|
569
567
|
|
|
568
|
+
const wrapper = screen.getByTestId("copilot-tool-render");
|
|
569
|
+
expect(wrapper.getAttribute("data-args")).toBe(
|
|
570
|
+
'{"a":1,"self":"[Circular]"}',
|
|
571
|
+
);
|
|
572
|
+
|
|
570
573
|
const headerButton = screen
|
|
571
574
|
.getByTestId("copilot-tool-render-name")
|
|
572
575
|
.closest("button");
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
expect(warnSpy).toHaveBeenCalled();
|
|
578
|
-
warnSpy.mockRestore();
|
|
576
|
+
expect(headerButton).not.toBeNull();
|
|
577
|
+
await fireEvent.click(headerButton!);
|
|
578
|
+
expect(wrapper.textContent).toContain('"self": "[Circular]"');
|
|
579
579
|
});
|
|
580
580
|
});
|
|
@@ -887,6 +887,10 @@ describe("useFrontendTool E2E - Dynamic Registration", () => {
|
|
|
887
887
|
expect(firstVersion.textContent).toContain("before override");
|
|
888
888
|
});
|
|
889
889
|
|
|
890
|
+
await agent.emit(runFinishedEvent());
|
|
891
|
+
// The tool call starts a follow-up run. A send waits for the run in
|
|
892
|
+
// flight (#5195), so finish the follow-up before the next message.
|
|
893
|
+
await agent.emit(runStartedEvent());
|
|
890
894
|
await agent.emit(runFinishedEvent());
|
|
891
895
|
|
|
892
896
|
const overrideButton = screen.getByTestId("activate-override");
|
|
@@ -720,7 +720,12 @@ describe("useHumanInTheLoop E2E - HITL Tool Rendering", () => {
|
|
|
720
720
|
expect(screen.queryByTestId("hitl-enabled")).toBeNull();
|
|
721
721
|
});
|
|
722
722
|
|
|
723
|
-
|
|
723
|
+
// The first run still waits for the unanswered HITL prompt, and a send
|
|
724
|
+
// waits for the run in flight (#5195), so this message stays queued.
|
|
725
|
+
// What this test pins is that the unregistered tool no longer renders.
|
|
726
|
+
const input = await screen.findByRole("textbox");
|
|
727
|
+
await fireEvent.update(input, "Test after disable");
|
|
728
|
+
await fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
724
729
|
|
|
725
730
|
const messageId2 = testId("msg2");
|
|
726
731
|
const toolCallId2 = testId("tc2");
|
|
@@ -4,7 +4,22 @@ import { z } from "zod";
|
|
|
4
4
|
import type { AbstractAgent } from "@ag-ui/client";
|
|
5
5
|
import { useHumanInTheLoop } from "../use-human-in-the-loop";
|
|
6
6
|
import { mountWithProvider } from "../../__tests__/utils/mount";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
SequencedRunAgent,
|
|
9
|
+
StateCapturingAgent,
|
|
10
|
+
toolCallMessage,
|
|
11
|
+
} from "../../__tests__/utils/agents";
|
|
12
|
+
|
|
13
|
+
/** Handler context for one tool call; core always passes the call. */
|
|
14
|
+
function callContext(id: string, name = "tool") {
|
|
15
|
+
return {
|
|
16
|
+
toolCall: {
|
|
17
|
+
id,
|
|
18
|
+
type: "function" as const,
|
|
19
|
+
function: { name, arguments: "{}" },
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
8
23
|
|
|
9
24
|
describe("useHumanInTheLoop", () => {
|
|
10
25
|
beforeEach(() => {
|
|
@@ -53,7 +68,7 @@ describe("useHumanInTheLoop", () => {
|
|
|
53
68
|
|
|
54
69
|
const pending = registeredTool!.handler!(
|
|
55
70
|
{ question: "Proceed?" },
|
|
56
|
-
|
|
71
|
+
callContext("tc-approve"),
|
|
57
72
|
);
|
|
58
73
|
|
|
59
74
|
const executingVNode = renderer!.render({
|
|
@@ -107,8 +122,8 @@ describe("useHumanInTheLoop", () => {
|
|
|
107
122
|
const renderA = getCore().renderToolCalls.find((rc) => rc.name === "toolA");
|
|
108
123
|
const renderB = getCore().renderToolCalls.find((rc) => rc.name === "toolB");
|
|
109
124
|
|
|
110
|
-
const pA = toolA!.handler!({},
|
|
111
|
-
const pB = toolB!.handler!({},
|
|
125
|
+
const pA = toolA!.handler!({}, callContext("tc-a"));
|
|
126
|
+
const pB = toolB!.handler!({}, callContext("tc-b"));
|
|
112
127
|
|
|
113
128
|
const respondA = (
|
|
114
129
|
renderA!.render({
|
|
@@ -140,6 +155,72 @@ describe("useHumanInTheLoop", () => {
|
|
|
140
155
|
await expect(pB).resolves.toBe("B");
|
|
141
156
|
});
|
|
142
157
|
|
|
158
|
+
it("gives parallel calls of one tool their own respond", async () => {
|
|
159
|
+
const RenderComp = defineComponent({
|
|
160
|
+
props: ["respond"],
|
|
161
|
+
setup() {
|
|
162
|
+
return () => h("div");
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
const Child = defineComponent({
|
|
166
|
+
setup() {
|
|
167
|
+
useHumanInTheLoop({
|
|
168
|
+
name: "parallelTool",
|
|
169
|
+
parameters: z.object({}),
|
|
170
|
+
render: RenderComp,
|
|
171
|
+
});
|
|
172
|
+
return () => null;
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
const { getCore } = mountWithProvider(() => h(Child));
|
|
176
|
+
const handler = getCore().getTool({ toolName: "parallelTool" })!.handler!;
|
|
177
|
+
const renderer = getCore().renderToolCalls.find(
|
|
178
|
+
(rc) => rc.name === "parallelTool",
|
|
179
|
+
)!;
|
|
180
|
+
const respondFor = (toolCallId: string) =>
|
|
181
|
+
(
|
|
182
|
+
renderer.render({
|
|
183
|
+
name: "parallelTool",
|
|
184
|
+
toolCallId,
|
|
185
|
+
args: {},
|
|
186
|
+
status: "executing",
|
|
187
|
+
result: undefined,
|
|
188
|
+
}) as { props?: { respond?: (result: unknown) => Promise<void> } }
|
|
189
|
+
).props!.respond!;
|
|
190
|
+
|
|
191
|
+
const first = handler({}, callContext("call-1"));
|
|
192
|
+
const second = handler({}, callContext("call-2"));
|
|
193
|
+
await respondFor("call-2")("second");
|
|
194
|
+
await respondFor("call-1")("first");
|
|
195
|
+
|
|
196
|
+
await expect(first).resolves.toBe("first");
|
|
197
|
+
await expect(second).resolves.toBe("second");
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("passes the called tool's name to a catch-all render", () => {
|
|
201
|
+
const RenderComp = defineComponent({
|
|
202
|
+
setup() {
|
|
203
|
+
return () => h("div");
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
const Child = defineComponent({
|
|
207
|
+
setup() {
|
|
208
|
+
useHumanInTheLoop({ name: "*", render: RenderComp });
|
|
209
|
+
return () => null;
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
const { getCore } = mountWithProvider(() => h(Child));
|
|
213
|
+
const renderer = getCore().renderToolCalls.find((rc) => rc.name === "*")!;
|
|
214
|
+
const vnode = renderer.render({
|
|
215
|
+
name: "deleteFile",
|
|
216
|
+
toolCallId: "tc-any",
|
|
217
|
+
args: {},
|
|
218
|
+
status: "inProgress",
|
|
219
|
+
result: undefined,
|
|
220
|
+
}) as { props?: Record<string, unknown> };
|
|
221
|
+
expect(vnode.props?.name).toBe("deleteFile");
|
|
222
|
+
});
|
|
223
|
+
|
|
143
224
|
it("only exposes respond during executing status", () => {
|
|
144
225
|
const RenderComp = defineComponent({
|
|
145
226
|
props: ["respond"],
|
|
@@ -323,9 +404,9 @@ describe("useHumanInTheLoop", () => {
|
|
|
323
404
|
const controller = new AbortController();
|
|
324
405
|
controller.abort();
|
|
325
406
|
|
|
326
|
-
await expect(
|
|
327
|
-
|
|
328
|
-
);
|
|
407
|
+
await expect(
|
|
408
|
+
handler!({}, { ...callContext("tc-x"), signal: controller.signal }),
|
|
409
|
+
).rejects.toEqual(new Error("Human-in-the-loop interaction aborted"));
|
|
329
410
|
});
|
|
330
411
|
|
|
331
412
|
it("rejects once on abort, clears pending refs, and installs a one-shot listener", async () => {
|
|
@@ -344,7 +425,7 @@ describe("useHumanInTheLoop", () => {
|
|
|
344
425
|
}),
|
|
345
426
|
} as unknown as AbortSignal;
|
|
346
427
|
|
|
347
|
-
const pending = handler!({}, { signal });
|
|
428
|
+
const pending = handler!({}, { ...callContext("tc-aborted"), signal });
|
|
348
429
|
expect(listeners.size).toBe(1);
|
|
349
430
|
const onAbort = [...listeners][0];
|
|
350
431
|
onAbort();
|
|
@@ -379,7 +460,13 @@ describe("useHumanInTheLoop", () => {
|
|
|
379
460
|
}),
|
|
380
461
|
} as unknown as AbortSignal;
|
|
381
462
|
|
|
382
|
-
const pending = handler!(
|
|
463
|
+
const pending = handler!(
|
|
464
|
+
{},
|
|
465
|
+
{
|
|
466
|
+
...callContext("tc-respond"),
|
|
467
|
+
signal,
|
|
468
|
+
},
|
|
469
|
+
).then((result) => {
|
|
383
470
|
events.push(`resolved:${String(result)}`);
|
|
384
471
|
return result;
|
|
385
472
|
});
|
|
@@ -511,10 +598,98 @@ describe("useHumanInTheLoop", () => {
|
|
|
511
598
|
expect(vnode.props?.agentId).toBeUndefined();
|
|
512
599
|
});
|
|
513
600
|
|
|
601
|
+
it("lets a message queued behind an unanswered prompt send after the prompt unmounts", async () => {
|
|
602
|
+
const prompt = toolCallMessage("unmountApproval");
|
|
603
|
+
const toolCallId = (prompt as { toolCalls: { id: string }[] })
|
|
604
|
+
.toolCalls[0]!.id;
|
|
605
|
+
const agent = new SequencedRunAgent(
|
|
606
|
+
[
|
|
607
|
+
() => ({ result: undefined, newMessages: [prompt] }),
|
|
608
|
+
() => ({
|
|
609
|
+
result: undefined,
|
|
610
|
+
newMessages: [{ id: "reply", role: "assistant", content: "ok" }],
|
|
611
|
+
}),
|
|
612
|
+
],
|
|
613
|
+
"default",
|
|
614
|
+
);
|
|
615
|
+
const RenderComp = defineComponent({
|
|
616
|
+
setup() {
|
|
617
|
+
return () => h("div");
|
|
618
|
+
},
|
|
619
|
+
});
|
|
620
|
+
const shown = ref(true);
|
|
621
|
+
const Child = defineComponent({
|
|
622
|
+
setup() {
|
|
623
|
+
useHumanInTheLoop({
|
|
624
|
+
name: "unmountApproval",
|
|
625
|
+
parameters: z.object({}),
|
|
626
|
+
render: RenderComp,
|
|
627
|
+
});
|
|
628
|
+
return () => null;
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
const { getCore } = mountWithProvider(
|
|
632
|
+
() => (shown.value ? h(Child) : null),
|
|
633
|
+
{
|
|
634
|
+
agents__unsafe_dev_only: {
|
|
635
|
+
default: agent as unknown as AbstractAgent,
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
);
|
|
639
|
+
const core = getCore();
|
|
640
|
+
const sendMessage = async (content: string) => {
|
|
641
|
+
agent.addMessage({ id: content, role: "user", content });
|
|
642
|
+
await core.runAgent({ agent: agent as unknown as AbstractAgent });
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
const first = sendMessage("approve this");
|
|
646
|
+
const queued = first.then(() => sendMessage("next question"));
|
|
647
|
+
await vi.waitFor(() =>
|
|
648
|
+
expect(core.ɵhumanInTheLoop.isPending(toolCallId)).toBe(true),
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
shown.value = false;
|
|
652
|
+
await nextTick();
|
|
653
|
+
|
|
654
|
+
await expect(queued).resolves.toBeUndefined();
|
|
655
|
+
expect(agent.messages).toEqual(
|
|
656
|
+
expect.arrayContaining([
|
|
657
|
+
expect.objectContaining({
|
|
658
|
+
role: "tool",
|
|
659
|
+
toolCallId,
|
|
660
|
+
error: "Human-in-the-loop interaction aborted",
|
|
661
|
+
}),
|
|
662
|
+
expect.objectContaining({ id: "reply", content: "ok" }),
|
|
663
|
+
]),
|
|
664
|
+
);
|
|
665
|
+
});
|
|
666
|
+
|
|
514
667
|
it("does not settle a pending HITL promise when its renderer unmounts", async () => {
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
|
|
668
|
+
const RenderComp = defineComponent({
|
|
669
|
+
setup() {
|
|
670
|
+
return () => h("div");
|
|
671
|
+
},
|
|
672
|
+
});
|
|
673
|
+
const shown = ref(true);
|
|
674
|
+
const Child = defineComponent({
|
|
675
|
+
setup() {
|
|
676
|
+
useHumanInTheLoop({
|
|
677
|
+
name: "unmountTool",
|
|
678
|
+
parameters: z.object({}),
|
|
679
|
+
render: RenderComp,
|
|
680
|
+
});
|
|
681
|
+
return () => null;
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
const { getCore } = mountWithProvider(() =>
|
|
685
|
+
shown.value ? h(Child) : null,
|
|
686
|
+
);
|
|
687
|
+
const pending = getCore().getTool({ toolName: "unmountTool" })!.handler!(
|
|
688
|
+
{},
|
|
689
|
+
callContext("tc-unmount"),
|
|
690
|
+
);
|
|
691
|
+
shown.value = false;
|
|
692
|
+
await nextTick();
|
|
518
693
|
|
|
519
694
|
const outcome = await Promise.race([
|
|
520
695
|
pending.then(
|
|
@@ -347,6 +347,32 @@ describe("useInterrupt", () => {
|
|
|
347
347
|
expect(wrapper.get("[data-testid=interrupt-state]").text()).toBe("idle");
|
|
348
348
|
});
|
|
349
349
|
|
|
350
|
+
it("treats a throwing enabled predicate as disabled instead of crashing", async () => {
|
|
351
|
+
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
352
|
+
const wrapper = mountHarness({
|
|
353
|
+
enabled: () => {
|
|
354
|
+
throw new Error("predicate");
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
emitInterrupt("hidden");
|
|
358
|
+
await nextTick();
|
|
359
|
+
expect(wrapper.get("[data-testid=interrupt-state]").text()).toBe("idle");
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("shows the interrupt with a null result when the handler throws synchronously", async () => {
|
|
363
|
+
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
364
|
+
const wrapper = mountHarness({
|
|
365
|
+
handler: () => {
|
|
366
|
+
throw new Error("handler");
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
emitInterrupt("visible");
|
|
370
|
+
await nextTick();
|
|
371
|
+
expect(wrapper.get("[data-testid=interrupt-state]").text()).toBe(
|
|
372
|
+
"no-result:visible",
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
|
|
350
376
|
it("keeps the latest interrupt when multiple interrupts arrive within one run", async () => {
|
|
351
377
|
const wrapper = mountHarness({ renderInChat: false });
|
|
352
378
|
|
|
@@ -412,6 +438,77 @@ describe("useInterrupt", () => {
|
|
|
412
438
|
handlers.onRunFinalized?.();
|
|
413
439
|
}
|
|
414
440
|
|
|
441
|
+
it("picks up the agent's pending interrupts when it mounts", async () => {
|
|
442
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
443
|
+
(mockAgent as any).pendingInterrupts = [INT];
|
|
444
|
+
const wrapper = mountStandardHarness();
|
|
445
|
+
await nextTick();
|
|
446
|
+
expect(wrapper.find("[data-testid=active]").exists()).toBe(true);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it("appends a tool result for a frontend tool-call interrupt before resuming", async () => {
|
|
450
|
+
const addMessage = vi.fn();
|
|
451
|
+
Object.assign(mockAgent, { messages: [], addMessage });
|
|
452
|
+
const TOOL_INT: Interrupt = {
|
|
453
|
+
id: "tool-int",
|
|
454
|
+
reason: "tool_call",
|
|
455
|
+
toolCallId: "call-1",
|
|
456
|
+
};
|
|
457
|
+
const wrapper = mountStandardHarness();
|
|
458
|
+
fireStandardInterrupt([TOOL_INT]);
|
|
459
|
+
await nextTick();
|
|
460
|
+
|
|
461
|
+
await wrapper.get("[data-testid=resolve-btn]").trigger("click");
|
|
462
|
+
|
|
463
|
+
expect(addMessage).toHaveBeenCalledWith(
|
|
464
|
+
expect.objectContaining({
|
|
465
|
+
role: "tool",
|
|
466
|
+
toolCallId: "call-1",
|
|
467
|
+
content: JSON.stringify({ ok: true }),
|
|
468
|
+
}),
|
|
469
|
+
);
|
|
470
|
+
expect(runAgentMock).toHaveBeenCalledWith({
|
|
471
|
+
agent: mockAgent,
|
|
472
|
+
resume: [
|
|
473
|
+
{
|
|
474
|
+
interruptId: "tool-int",
|
|
475
|
+
status: "resolved",
|
|
476
|
+
payload: { ok: true },
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
});
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it("resumes when the only expired interrupt was cancelled", async () => {
|
|
483
|
+
const EXPIRED: Interrupt = {
|
|
484
|
+
id: "old",
|
|
485
|
+
reason: "confirmation",
|
|
486
|
+
expiresAt: "2000-01-01T00:00:00.000Z",
|
|
487
|
+
};
|
|
488
|
+
let api: ReturnType<typeof useInterrupt> | undefined;
|
|
489
|
+
mount(
|
|
490
|
+
defineComponent({
|
|
491
|
+
setup() {
|
|
492
|
+
api = useInterrupt({ renderInChat: false });
|
|
493
|
+
return () => null;
|
|
494
|
+
},
|
|
495
|
+
}),
|
|
496
|
+
);
|
|
497
|
+
fireStandardInterrupt([EXPIRED, INT]);
|
|
498
|
+
await nextTick();
|
|
499
|
+
|
|
500
|
+
await api!.cancel("old");
|
|
501
|
+
await api!.resolve("yes", INT.id);
|
|
502
|
+
|
|
503
|
+
expect(runAgentMock).toHaveBeenCalledWith({
|
|
504
|
+
agent: mockAgent,
|
|
505
|
+
resume: [
|
|
506
|
+
{ interruptId: "old", status: "cancelled" },
|
|
507
|
+
{ interruptId: INT.id, status: "resolved", payload: "yes" },
|
|
508
|
+
],
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
|
|
415
512
|
it("resolveInterrupt resumes with a resolved ResumeEntry", async () => {
|
|
416
513
|
runAgentMock.mockResolvedValue({ result: undefined, newMessages: [] });
|
|
417
514
|
const wrapper = mountStandardHarness();
|
|
@@ -99,7 +99,8 @@ describe("useRenderActivityMessage", () => {
|
|
|
99
99
|
|
|
100
100
|
expect(result).toBeNull();
|
|
101
101
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
102
|
-
"Failed to
|
|
102
|
+
"[CopilotKit] Failed to parse content for activity message 'progress':",
|
|
103
|
+
expect.any(Array),
|
|
103
104
|
);
|
|
104
105
|
});
|
|
105
106
|
});
|
|
@@ -4,6 +4,19 @@ import type { Ref } from "vue";
|
|
|
4
4
|
import { describe, expect, it, beforeEach, vi } from "vitest";
|
|
5
5
|
import { useCopilotKit } from "../../providers/useCopilotKit";
|
|
6
6
|
|
|
7
|
+
/** Core's `ɵruntimeInfo` snapshot, built from a fake core's runtime fields. */
|
|
8
|
+
function runtimeInfoOf(core: {
|
|
9
|
+
runtimeConnectionStatus: CopilotKitCoreRuntimeConnectionStatus;
|
|
10
|
+
threadEndpoints?: unknown;
|
|
11
|
+
intelligence?: unknown;
|
|
12
|
+
}) {
|
|
13
|
+
return {
|
|
14
|
+
status: core.runtimeConnectionStatus,
|
|
15
|
+
threadEndpoints: core.threadEndpoints,
|
|
16
|
+
intelligence: core.intelligence,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
type ThreadRecord = {
|
|
8
21
|
id: string;
|
|
9
22
|
organizationId: string;
|
|
@@ -54,7 +67,8 @@ function compareThreadsByActivity(left: ThreadRecord, right: ThreadRecord) {
|
|
|
54
67
|
return rightKey.localeCompare(leftKey);
|
|
55
68
|
}
|
|
56
69
|
|
|
57
|
-
vi.mock("@copilotkit/core", () => {
|
|
70
|
+
vi.mock("@copilotkit/core", async (importOriginal) => {
|
|
71
|
+
const actual = await importOriginal<typeof import("@copilotkit/core")>();
|
|
58
72
|
class MockChannel {
|
|
59
73
|
topic: string;
|
|
60
74
|
left = false;
|
|
@@ -118,6 +132,16 @@ vi.mock("@copilotkit/core", () => {
|
|
|
118
132
|
private listeners = new Set<() => void>();
|
|
119
133
|
private socket: MockSocket | null = null;
|
|
120
134
|
|
|
135
|
+
readonly selectors = {
|
|
136
|
+
threads: (state: ThreadState) => state.threads,
|
|
137
|
+
isLoading: (state: ThreadState) => state.isLoading,
|
|
138
|
+
error: (state: ThreadState) => state.error,
|
|
139
|
+
fetchMoreError: (state: ThreadState) => state.fetchMoreError,
|
|
140
|
+
hasNextPage: (state: ThreadState) => state.hasNextPage,
|
|
141
|
+
isFetchingNextPage: (state: ThreadState) => state.isFetchingNextPage,
|
|
142
|
+
isMutating: (state: ThreadState) => state.isMutating,
|
|
143
|
+
};
|
|
144
|
+
|
|
121
145
|
start(): void {}
|
|
122
146
|
|
|
123
147
|
stop(): void {
|
|
@@ -317,6 +341,10 @@ vi.mock("@copilotkit/core", () => {
|
|
|
317
341
|
return this.state;
|
|
318
342
|
}
|
|
319
343
|
|
|
344
|
+
getServerState(): ThreadState {
|
|
345
|
+
return { ...this.state, threads: [] };
|
|
346
|
+
}
|
|
347
|
+
|
|
320
348
|
select<T>(selector: (state: ThreadState) => T) {
|
|
321
349
|
return {
|
|
322
350
|
subscribe: (callback: () => void) => {
|
|
@@ -357,6 +385,8 @@ vi.mock("@copilotkit/core", () => {
|
|
|
357
385
|
ɵselectHasNextPage: select((state) => state.hasNextPage),
|
|
358
386
|
ɵselectIsFetchingNextPage: select((state) => state.isFetchingNextPage),
|
|
359
387
|
ɵselectIsMutating: select((state) => state.isMutating),
|
|
388
|
+
// The real view model, driving the mock store above.
|
|
389
|
+
ɵThreadsController: actual.ɵThreadsController,
|
|
360
390
|
};
|
|
361
391
|
});
|
|
362
392
|
|
|
@@ -394,6 +424,7 @@ const supportedThreadEndpoints: ThreadEndpointRuntimeInfo = {
|
|
|
394
424
|
|
|
395
425
|
type MockCopilotKit = {
|
|
396
426
|
runtimeUrl: string | undefined;
|
|
427
|
+
readonly ɵruntimeInfo: unknown;
|
|
397
428
|
runtimeConnectionStatus: CopilotKitCoreRuntimeConnectionStatus;
|
|
398
429
|
headers: Record<string, string>;
|
|
399
430
|
/**
|
|
@@ -417,6 +448,9 @@ function setupCopilotKit(
|
|
|
417
448
|
) {
|
|
418
449
|
const copilotkit = ref<MockCopilotKit>({
|
|
419
450
|
runtimeUrl,
|
|
451
|
+
get ɵruntimeInfo() {
|
|
452
|
+
return runtimeInfoOf(this);
|
|
453
|
+
},
|
|
420
454
|
runtimeConnectionStatus,
|
|
421
455
|
headers: { Authorization: "Bearer test-token" },
|
|
422
456
|
ɵheadersGeneration: 0,
|
|
@@ -965,6 +999,9 @@ describe("useThreads", () => {
|
|
|
965
999
|
// exactly one list fetch (+ one subscribe after it lands).
|
|
966
1000
|
copilotkit.value = {
|
|
967
1001
|
...copilotkit.value,
|
|
1002
|
+
get ɵruntimeInfo() {
|
|
1003
|
+
return runtimeInfoOf(this);
|
|
1004
|
+
},
|
|
968
1005
|
runtimeConnectionStatus:
|
|
969
1006
|
CopilotKitCoreRuntimeConnectionStatus.Connected,
|
|
970
1007
|
intelligence: { wsUrl: "ws://localhost:4000/client" },
|
|
@@ -1020,6 +1057,9 @@ describe("useThreads", () => {
|
|
|
1020
1057
|
|
|
1021
1058
|
copilotkit.value = {
|
|
1022
1059
|
...copilotkit.value,
|
|
1060
|
+
get ɵruntimeInfo() {
|
|
1061
|
+
return runtimeInfoOf(this);
|
|
1062
|
+
},
|
|
1023
1063
|
runtimeConnectionStatus:
|
|
1024
1064
|
CopilotKitCoreRuntimeConnectionStatus.Disconnected,
|
|
1025
1065
|
};
|
|
@@ -1216,8 +1256,9 @@ describe("useThreads", () => {
|
|
|
1216
1256
|
|
|
1217
1257
|
expect(fetchMock).not.toHaveBeenCalled();
|
|
1218
1258
|
expect(getResult().threads.value).toEqual([]);
|
|
1219
|
-
|
|
1220
|
-
|
|
1259
|
+
// Nothing was ever sent, so nothing is cleared either (no extra
|
|
1260
|
+
// queued list fetch).
|
|
1261
|
+
expect(getDispatchedContexts()).toEqual([]);
|
|
1221
1262
|
// A disabled consumer must not be stuck in a permanent loading state:
|
|
1222
1263
|
// preConnectLoading must factor in `enabled`, otherwise isLoading would
|
|
1223
1264
|
// stay true forever since hasDispatchedContext never gets set.
|
|
@@ -1240,7 +1281,7 @@ describe("useThreads", () => {
|
|
|
1240
1281
|
// Disabled: inert, not loading, no fetch.
|
|
1241
1282
|
expect(getResult().isLoading.value).toBe(false);
|
|
1242
1283
|
expect(fetchMock).not.toHaveBeenCalled();
|
|
1243
|
-
expect(getDispatchedContexts().
|
|
1284
|
+
expect(getDispatchedContexts().filter(Boolean)).toEqual([]);
|
|
1244
1285
|
|
|
1245
1286
|
// Re-enable: the pre-connect loading indicator must re-arm (i.e.
|
|
1246
1287
|
// hasDispatchedContext was reset to false on disable) so consumers see
|
|
@@ -1343,8 +1384,9 @@ describe("useThreads", () => {
|
|
|
1343
1384
|
|
|
1344
1385
|
expect(fetchMock).not.toHaveBeenCalled();
|
|
1345
1386
|
expect(getResult().threads.value).toEqual([]);
|
|
1346
|
-
|
|
1347
|
-
|
|
1387
|
+
// Nothing was ever sent, so nothing is cleared either (no extra
|
|
1388
|
+
// queued list fetch).
|
|
1389
|
+
expect(getDispatchedContexts()).toEqual([]);
|
|
1348
1390
|
expect(getResult().error.value?.message).toBe(
|
|
1349
1391
|
"Thread endpoints are not available on this CopilotKit runtime",
|
|
1350
1392
|
);
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { computed, toValue, watch } from "vue";
|
|
2
2
|
import type { MaybeRefOrGetter } from "vue";
|
|
3
|
+
import { ɵserializeContextValue } from "@copilotkit/core";
|
|
4
|
+
import type { ɵJsonSerializable } from "@copilotkit/core";
|
|
3
5
|
import { useCopilotKit } from "../providers/useCopilotKit";
|
|
4
6
|
|
|
5
|
-
export type JsonSerializable =
|
|
6
|
-
| string
|
|
7
|
-
| number
|
|
8
|
-
| boolean
|
|
9
|
-
| null
|
|
10
|
-
| JsonSerializable[]
|
|
11
|
-
| { [key: string]: JsonSerializable };
|
|
7
|
+
export type JsonSerializable = ɵJsonSerializable;
|
|
12
8
|
|
|
13
9
|
export interface AgentContextInput {
|
|
14
10
|
description: MaybeRefOrGetter<string>;
|
|
@@ -35,9 +31,7 @@ export function useAgentContext(context: AgentContextInput): void {
|
|
|
35
31
|
const resolvedValue = computed(() => toValue(context.value));
|
|
36
32
|
|
|
37
33
|
const stringValue = computed(() =>
|
|
38
|
-
|
|
39
|
-
? resolvedValue.value
|
|
40
|
-
: JSON.stringify(resolvedValue.value),
|
|
34
|
+
ɵserializeContextValue(resolvedValue.value),
|
|
41
35
|
);
|
|
42
36
|
|
|
43
37
|
watch(
|