@copilotkit/vue 1.62.2 → 1.62.3
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 +2 -2
- package/dist/{use-render-activity-message-hlNcbV9l.cjs → use-render-activity-message-CIvEoQzA.cjs} +20 -20
- package/dist/{use-render-activity-message-hlNcbV9l.cjs.map → use-render-activity-message-CIvEoQzA.cjs.map} +1 -1
- package/dist/{use-render-activity-message-DbGuwvBd.js → use-render-activity-message-CbKeqosY.js} +2521 -2511
- package/dist/{use-render-activity-message-DbGuwvBd.js.map → use-render-activity-message-CbKeqosY.js.map} +1 -1
- package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts +24 -1
- package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
- package/dist/v2/hooks/use-threads.d.ts +7 -0
- 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/package.json +5 -5
- package/src/v2/components/chat/CopilotThreadsDrawer.vue +51 -1
- package/src/v2/components/chat/__tests__/CopilotThreadsDrawer.test.ts +75 -0
- package/src/v2/hooks/__tests__/use-threads.test.ts +16 -4
- package/src/v2/hooks/use-threads.ts +11 -0
- package/vite.config.ts +7 -0
- package/dist/index-By5nIKxT.js +0 -1632
- package/dist/index-By5nIKxT.js.map +0 -1
- package/dist/index-LFxZI63k.cjs +0 -748
- package/dist/index-LFxZI63k.cjs.map +0 -1
|
@@ -6,6 +6,24 @@ type __VLS_Props = {
|
|
|
6
6
|
onLicensed?: () => void;
|
|
7
7
|
licenseUrl?: string;
|
|
8
8
|
label?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Heading rendered above the thread list (element attribute
|
|
11
|
+
* `recent-label`). Defaults to the element's own `"Recent Conversations"`
|
|
12
|
+
* when omitted.
|
|
13
|
+
*/
|
|
14
|
+
recentLabel?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the drawer offers a collapse toggle. Bound to the element's
|
|
17
|
+
* `collapsible` PROPERTY. When `false`, the drawer has no collapse toggle
|
|
18
|
+
* and is always expanded. Defaults to `true`.
|
|
19
|
+
*
|
|
20
|
+
* NOTE: this MUST carry an explicit `true` default below. Vue coerces an
|
|
21
|
+
* omitted `Boolean` prop to `false` (not `undefined`), so without the
|
|
22
|
+
* default the `!== undefined` guard would always fire and force the element
|
|
23
|
+
* to `collapsible=false` — silently disabling collapse. Defaulting to `true`
|
|
24
|
+
* restores the element's own default when the prop is omitted.
|
|
25
|
+
*/
|
|
26
|
+
collapsible?: boolean;
|
|
9
27
|
limit?: number;
|
|
10
28
|
dataTestId?: string;
|
|
11
29
|
};
|
|
@@ -29,7 +47,12 @@ type __VLS_Slots = {
|
|
|
29
47
|
thread: Thread;
|
|
30
48
|
}): unknown;
|
|
31
49
|
};
|
|
32
|
-
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
50
|
+
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
51
|
+
"collapse-change": (collapsed: boolean) => any;
|
|
52
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
53
|
+
"onCollapse-change"?: ((collapsed: boolean) => any) | undefined;
|
|
54
|
+
}>, {
|
|
55
|
+
collapsible: boolean;
|
|
33
56
|
dataTestId: string;
|
|
34
57
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
58
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotThreadsDrawer.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/CopilotThreadsDrawer.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CopilotThreadsDrawer.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/CopilotThreadsDrawer.vue"],"names":[],"mappings":"AA0WA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAItD,KAAK,WAAW,GAAG;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAgOJ,KAAK,WAAW,GAAG;IACjB,OAAO,IAAI,OAAO,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,GAAG,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;CACzC,CAAC;AAgIF,QAAA,MAAM,eAAe;;;;;iBApXH,OAAO;gBAER,MAAM;6EA0XrB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAa1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -31,6 +31,13 @@ export interface UseThreadsResult {
|
|
|
31
31
|
error: Ref<Error | null>;
|
|
32
32
|
/** Genuine list-load/mutation errors only — excludes dev/config errors. */
|
|
33
33
|
listError: Ref<Error | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Error from the most recent FAILED next-page (fetch-more) load, or `null`.
|
|
36
|
+
* Tracked separately from {@link listError} so a paginated-load failure
|
|
37
|
+
* shows an inline "couldn't load more" affordance while the loaded list
|
|
38
|
+
* stays visible. Cleared when a fetch-more is retried or succeeds.
|
|
39
|
+
*/
|
|
40
|
+
fetchMoreError: Ref<Error | null>;
|
|
34
41
|
hasMoreThreads: Ref<boolean>;
|
|
35
42
|
isFetchingMoreThreads: Ref<boolean>;
|
|
36
43
|
isMutating: Ref<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-threads.d.ts","sourceRoot":"","sources":["../../../src/v2/hooks/use-threads.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"use-threads.d.ts","sourceRoot":"","sources":["../../../src/v2/hooks/use-threads.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAejD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClC,eAAe,CAAC,EAAE,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACxD,KAAK,CAAC,EAAE,gBAAgB,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C;;;;OAIG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACvB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACzB,2EAA2E;IAC3E,SAAS,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAClC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,qBAAqB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACzB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAcD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAkQnE"}
|
package/dist/v2/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@copilotkit/core"),i=require("@ag-ui/client"),e=require("../use-render-activity-message-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@copilotkit/core"),i=require("@ag-ui/client"),e=require("../use-render-activity-message-CIvEoQzA.cjs"),n=require("@copilotkit/shared");exports.A2UIActivityContentSchema=e.A2UIActivityContentSchema;exports.A2UISurfaceActivityRenderer=e._sfc_main;exports.A2UISurfaceActivityType=e.A2UISurfaceActivityType;exports.CopilotChat=e.CopilotChat;exports.CopilotChatAssistantMessage=e._sfc_main$1;exports.CopilotChatAttachmentQueue=e._sfc_main$2;exports.CopilotChatAttachmentRenderer=e._sfc_main$3;exports.CopilotChatAudioRecorder=e._sfc_main$4;exports.CopilotChatConfigurationProvider=e._sfc_main$5;exports.CopilotChatDefaultLabels=e.CopilotChatDefaultLabels;exports.CopilotChatInput=e._sfc_main$6;exports.CopilotChatMessageView=e._sfc_main$7;exports.CopilotChatReasoningMessage=e._sfc_main$8;exports.CopilotChatSuggestionPill=e._sfc_main$9;exports.CopilotChatSuggestionView=e._sfc_main$10;exports.CopilotChatToggleButton=e.CopilotChatToggleButton;exports.CopilotChatToggleButtonCloseIcon=e.CopilotChatToggleButtonCloseIcon;exports.CopilotChatToggleButtonOpenIcon=e.CopilotChatToggleButtonOpenIcon;exports.CopilotChatToolCallsView=e._sfc_main$11;exports.CopilotChatUserMessage=e._sfc_main$12;exports.CopilotChatView=e._sfc_main$13;exports.CopilotKitCoreVue=e.CopilotKitCoreVue;exports.CopilotKitInspector=e._sfc_main$14;exports.CopilotKitProvider=e._sfc_main$15;exports.CopilotModalHeader=e.CopilotModalHeader;exports.CopilotPopup=e._sfc_main$16;exports.CopilotPopupView=e.CopilotPopupView;exports.CopilotSidebar=e._sfc_main$17;exports.CopilotSidebarView=e.CopilotSidebarView;exports.CopilotThreadsDrawer=e._sfc_main$18;exports.GenerateSandboxedUiArgsSchema=e.GenerateSandboxedUiArgsSchema;exports.LicenseContextKey=e.LicenseContextKey;exports.MCPAppsActivityContentSchema=e.MCPAppsActivityContentSchema;exports.MCPAppsActivityRenderer=e.MCPAppsActivityRenderer;exports.MCPAppsActivityType=e.MCPAppsActivityType;exports.OpenGenerativeUIActivityRenderer=e.OpenGenerativeUIActivityRenderer;exports.OpenGenerativeUIActivityType=e.OpenGenerativeUIActivityType;exports.OpenGenerativeUIContentSchema=e.OpenGenerativeUIContentSchema;exports.OpenGenerativeUIRenderer=e.OpenGenerativeUIRenderer;exports.OpenGenerativeUIToolRenderer=e.OpenGenerativeUIToolRenderer;exports.UseAgentUpdate=e.UseAgentUpdate;exports.createA2UIMessageRenderer=e.createA2UIMessageRenderer;exports.createDefaultLicenseRef=e.createDefaultLicenseRef;exports.defineToolCallRenderer=e.defineToolCallRenderer;exports.extractCompleteStyles=e.extractCompleteStyles;exports.getOperationSurfaceId=e.getOperationSurfaceId;exports.processPartialHtml=e.processPartialHtml;exports.useAgent=e.useAgent;exports.useAgentContext=e.useAgentContext;exports.useAttachments=e.useAttachments;exports.useCapabilities=e.useCapabilities;exports.useComponent=e.useComponent;exports.useConfigureSuggestions=e.useConfigureSuggestions;exports.useCopilotChatConfiguration=e.useCopilotChatConfiguration;exports.useCopilotKit=e.useCopilotKit;exports.useDefaultRenderTool=e.useDefaultRenderTool;exports.useFrontendTool=e.useFrontendTool;exports.useHumanInTheLoop=e.useHumanInTheLoop;exports.useInterrupt=e.useInterrupt;exports.useKatexStyles=e.useKatexStyles;exports.useKeyboardHeight=e.useKeyboardHeight;exports.useLicenseContext=e.useLicenseContext;exports.useRenderActivityMessage=e.useRenderActivityMessage;exports.useRenderCustomMessages=e.useRenderCustomMessages;exports.useRenderTool=e.useRenderTool;exports.useSandboxFunctions=e.useSandboxFunctions;exports.useSuggestions=e.useSuggestions;exports.useThreads=e.useThreads;exports.vueBasicCatalog=e.vueBasicCatalog;Object.defineProperty(exports,"createLicenseContextValue",{enumerable:!0,get:()=>n.createLicenseContextValue});Object.keys(o).forEach(t=>{t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:()=>o[t]})});Object.keys(i).forEach(t=>{t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:()=>i[t]})});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/v2/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "@copilotkit/core";
|
|
2
2
|
export * from "@ag-ui/client";
|
|
3
|
-
import { A as o, _ as i, a as n, C, b as r, c as p, d as l, e as u, f as c, g, h as d, i as h, j as A, k as v, l as S, m, n as y, o as I, p as f, q as R, r as T, s as U, t as x, u as M, v as P, w as b, x as V, y as w, z as K, B as O, G, L, M as B, D, E as H, O as F, F as Q, H as j, I as k, J as q, U as z, K as E, N as J, P as N, Q as W, R as X, S as Y, T as Z, V as _, W as $, X as ee, Y as ae, Z as te, $ as se, a0 as oe, a1 as ie, a2 as ne, a3 as Ce, a4 as re, a5 as pe, a6 as le, a7 as ue, a8 as ce, a9 as ge, aa as de, ab as he, ac as Ae, ad as ve, ae as Se } from "../use-render-activity-message-
|
|
3
|
+
import { A as o, _ as i, a as n, C, b as r, c as p, d as l, e as u, f as c, g, h as d, i as h, j as A, k as v, l as S, m, n as y, o as I, p as f, q as R, r as T, s as U, t as x, u as M, v as P, w as b, x as V, y as w, z as K, B as O, G, L, M as B, D, E as H, O as F, F as Q, H as j, I as k, J as q, U as z, K as E, N as J, P as N, Q as W, R as X, S as Y, T as Z, V as _, W as $, X as ee, Y as ae, Z as te, $ as se, a0 as oe, a1 as ie, a2 as ne, a3 as Ce, a4 as re, a5 as pe, a6 as le, a7 as ue, a8 as ce, a9 as ge, aa as de, ab as he, ac as Ae, ad as ve, ae as Se } from "../use-render-activity-message-CbKeqosY.js";
|
|
4
4
|
import { createLicenseContextValue as ye } from "@copilotkit/shared";
|
|
5
5
|
export {
|
|
6
6
|
o as A2UIActivityContentSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkit/vue",
|
|
3
|
-
"version": "1.62.
|
|
3
|
+
"version": "1.62.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vue 3 components and composables for CopilotKit",
|
|
6
6
|
"keywords": [
|
|
@@ -70,10 +70,10 @@
|
|
|
70
70
|
"streamdown-vue": "^1.0.29",
|
|
71
71
|
"zod": "^3.25.75",
|
|
72
72
|
"zod-to-json-schema": "^3.24.5",
|
|
73
|
-
"@copilotkit/core": "1.62.
|
|
74
|
-
"@copilotkit/
|
|
75
|
-
"@copilotkit/
|
|
76
|
-
"@copilotkit/web-
|
|
73
|
+
"@copilotkit/core": "1.62.3",
|
|
74
|
+
"@copilotkit/shared": "1.62.3",
|
|
75
|
+
"@copilotkit/web-inspector": "1.62.3",
|
|
76
|
+
"@copilotkit/web-components": "1.62.3"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@eslint/js": "^9.39.2",
|
|
@@ -16,6 +16,12 @@ import type {
|
|
|
16
16
|
RetryDetail,
|
|
17
17
|
OpenChangeDetail,
|
|
18
18
|
} from "@copilotkit/web-components/threads-drawer";
|
|
19
|
+
// TODO(ENT-1051): import `CollapseChangeDetail` from
|
|
20
|
+
// "@copilotkit/web-components/threads-drawer" once the parallel element PR that
|
|
21
|
+
// adds the collapse feature (property `collapsible` + event `collapse-change`)
|
|
22
|
+
// lands and is published; declared locally here because the built element types
|
|
23
|
+
// in this worktree predate it.
|
|
24
|
+
type CollapseChangeDetail = { collapsed: boolean };
|
|
19
25
|
import { DEFAULT_AGENT_ID } from "@copilotkit/shared";
|
|
20
26
|
import { useThreads } from "../../hooks/use-threads";
|
|
21
27
|
import type { Thread } from "../../hooks/use-threads";
|
|
@@ -30,12 +36,38 @@ const props = withDefaults(
|
|
|
30
36
|
onLicensed?: () => void;
|
|
31
37
|
licenseUrl?: string;
|
|
32
38
|
label?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Heading rendered above the thread list (element attribute
|
|
41
|
+
* `recent-label`). Defaults to the element's own `"Recent Conversations"`
|
|
42
|
+
* when omitted.
|
|
43
|
+
*/
|
|
44
|
+
recentLabel?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the drawer offers a collapse toggle. Bound to the element's
|
|
47
|
+
* `collapsible` PROPERTY. When `false`, the drawer has no collapse toggle
|
|
48
|
+
* and is always expanded. Defaults to `true`.
|
|
49
|
+
*
|
|
50
|
+
* NOTE: this MUST carry an explicit `true` default below. Vue coerces an
|
|
51
|
+
* omitted `Boolean` prop to `false` (not `undefined`), so without the
|
|
52
|
+
* default the `!== undefined` guard would always fire and force the element
|
|
53
|
+
* to `collapsible=false` — silently disabling collapse. Defaulting to `true`
|
|
54
|
+
* restores the element's own default when the prop is omitted.
|
|
55
|
+
*/
|
|
56
|
+
collapsible?: boolean;
|
|
33
57
|
limit?: number;
|
|
34
58
|
dataTestId?: string;
|
|
35
59
|
}>(),
|
|
36
|
-
{ dataTestId: "copilot-threads-drawer" },
|
|
60
|
+
{ dataTestId: "copilot-threads-drawer", collapsible: true },
|
|
37
61
|
);
|
|
38
62
|
|
|
63
|
+
const emit = defineEmits<{
|
|
64
|
+
/**
|
|
65
|
+
* Emitted when the drawer's collapsed state changes (mirrors the element's
|
|
66
|
+
* `collapse-change` event), carrying the new collapsed state.
|
|
67
|
+
*/
|
|
68
|
+
"collapse-change": [collapsed: boolean];
|
|
69
|
+
}>();
|
|
70
|
+
|
|
39
71
|
const config = useCopilotChatConfiguration();
|
|
40
72
|
const license = useLicenseContext();
|
|
41
73
|
|
|
@@ -115,9 +147,21 @@ watchEffect(
|
|
|
115
147
|
el.licensed = licensed.value || licensePending.value;
|
|
116
148
|
el.hasMore = threadsApi.hasMoreThreads.value;
|
|
117
149
|
el.fetchingMore = threadsApi.isFetchingMoreThreads.value;
|
|
150
|
+
// Dedicated fetch-more error channel: drives the element's inline
|
|
151
|
+
// "couldn't load more — retry" panel without disturbing the loaded list.
|
|
152
|
+
el.fetchMoreError = threadsApi.fetchMoreError.value?.message ?? null;
|
|
118
153
|
el.open = drawerOpen.value;
|
|
119
154
|
if (props.label !== undefined) el.label = props.label;
|
|
120
155
|
if (props.licenseUrl !== undefined) el.licenseUrl = props.licenseUrl;
|
|
156
|
+
// `collapsible` is a default-true boolean PROPERTY (like `licensed`); leave
|
|
157
|
+
// the element's own default in place when the prop is omitted.
|
|
158
|
+
if (props.collapsible !== undefined) {
|
|
159
|
+
// TODO(ENT-1051): drop the intersection cast once the published element
|
|
160
|
+
// type declares `collapsible` (see the local CollapseChangeDetail note).
|
|
161
|
+
(
|
|
162
|
+
el as CopilotKitThreadsDrawerElement & { collapsible: boolean }
|
|
163
|
+
).collapsible = props.collapsible;
|
|
164
|
+
}
|
|
121
165
|
},
|
|
122
166
|
{ flush: "post" },
|
|
123
167
|
);
|
|
@@ -213,6 +257,10 @@ function onDelete(event: Event) {
|
|
|
213
257
|
function onFilterChange() {
|
|
214
258
|
threadsApi.refetchThreads();
|
|
215
259
|
}
|
|
260
|
+
function onCollapseChange(event: Event) {
|
|
261
|
+
const { collapsed } = (event as CustomEvent<CollapseChangeDetail>).detail;
|
|
262
|
+
emit("collapse-change", collapsed);
|
|
263
|
+
}
|
|
216
264
|
function onRetry(event: Event) {
|
|
217
265
|
const { scope } = (event as CustomEvent<RetryDetail>).detail;
|
|
218
266
|
if (scope === "fetch-more") threadsApi.fetchMoreThreads();
|
|
@@ -255,12 +303,14 @@ defineSlots<{
|
|
|
255
303
|
v-if="mounted"
|
|
256
304
|
ref="elRef"
|
|
257
305
|
:data-testid="dataTestId"
|
|
306
|
+
:recent-label="recentLabel"
|
|
258
307
|
@thread-selected="onThreadSelected"
|
|
259
308
|
@new-thread="handleNewThread"
|
|
260
309
|
@archive="onArchive"
|
|
261
310
|
@unarchive="onUnarchive"
|
|
262
311
|
@delete="onDelete"
|
|
263
312
|
@filter-change="onFilterChange"
|
|
313
|
+
@collapse-change="onCollapseChange"
|
|
264
314
|
@retry="onRetry"
|
|
265
315
|
@load-more="onLoadMore"
|
|
266
316
|
@open-change="onOpenChange"
|
|
@@ -71,6 +71,7 @@ const useThreadsMocks = vi.hoisted(() => ({
|
|
|
71
71
|
fetchMoreThreads: vi.fn(),
|
|
72
72
|
refetchThreads: vi.fn(),
|
|
73
73
|
listError: { value: null as Error | null },
|
|
74
|
+
fetchMoreError: { value: null as Error | null },
|
|
74
75
|
error: { value: null as Error | null },
|
|
75
76
|
useThreadsInput: null as Record<string, unknown> | null,
|
|
76
77
|
// Mutable so individual tests (e.g. row-slot projection) can seed threads;
|
|
@@ -86,6 +87,7 @@ vi.mock("../../../hooks/use-threads", () => ({
|
|
|
86
87
|
isLoading: { value: false },
|
|
87
88
|
error: useThreadsMocks.error,
|
|
88
89
|
listError: useThreadsMocks.listError,
|
|
90
|
+
fetchMoreError: useThreadsMocks.fetchMoreError,
|
|
89
91
|
hasMoreThreads: { value: false },
|
|
90
92
|
isFetchingMoreThreads: { value: false },
|
|
91
93
|
isMutating: { value: false },
|
|
@@ -185,6 +187,7 @@ describe("CopilotThreadsDrawer", () => {
|
|
|
185
187
|
useThreadsMocks.fetchMoreThreads.mockClear();
|
|
186
188
|
useThreadsMocks.refetchThreads.mockClear();
|
|
187
189
|
useThreadsMocks.listError.value = null;
|
|
190
|
+
useThreadsMocks.fetchMoreError.value = null;
|
|
188
191
|
useThreadsMocks.error.value = null;
|
|
189
192
|
useThreadsMocks.useThreadsInput = null;
|
|
190
193
|
useThreadsMocks.threads.value = [];
|
|
@@ -664,6 +667,21 @@ describe("CopilotThreadsDrawer", () => {
|
|
|
664
667
|
wrapper.unmount();
|
|
665
668
|
});
|
|
666
669
|
|
|
670
|
+
it("forwards fetchMoreError to the element's fetchMoreError property without touching error", async () => {
|
|
671
|
+
useThreadsMocks.fetchMoreError.value = new Error("couldn't load more");
|
|
672
|
+
|
|
673
|
+
const wrapper = await mountDrawer();
|
|
674
|
+
|
|
675
|
+
const el = wrapper.find(COPILOTKIT_THREADS_DRAWER_TAG)
|
|
676
|
+
.element as unknown as CopilotKitThreadsDrawerElement;
|
|
677
|
+
|
|
678
|
+
expect(el.fetchMoreError).toBe("couldn't load more");
|
|
679
|
+
// The dedicated fetch-more channel must NOT bleed into the initial-list error.
|
|
680
|
+
expect(el.error).toBeNull();
|
|
681
|
+
|
|
682
|
+
wrapper.unmount();
|
|
683
|
+
});
|
|
684
|
+
|
|
667
685
|
it("suppresses a config/runtime error that is not a listError from the element's error string", async () => {
|
|
668
686
|
// Only the combined `error` channel carries a dev/config error; `listError`
|
|
669
687
|
// stays null because no genuine list-load failure occurred. The element
|
|
@@ -706,6 +724,63 @@ describe("CopilotThreadsDrawer", () => {
|
|
|
706
724
|
wrapper.unmount();
|
|
707
725
|
});
|
|
708
726
|
|
|
727
|
+
it("binds recent-label to the element", async () => {
|
|
728
|
+
const wrapper = await mountDrawer({ recentLabel: "History" });
|
|
729
|
+
|
|
730
|
+
const el = wrapper.find(COPILOTKIT_THREADS_DRAWER_TAG).element;
|
|
731
|
+
expect(el.getAttribute("recent-label")).toBe("History");
|
|
732
|
+
|
|
733
|
+
wrapper.unmount();
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it("sets the element's collapsible property to false when collapsible is false", async () => {
|
|
737
|
+
const wrapper = await mountDrawer({ collapsible: false });
|
|
738
|
+
|
|
739
|
+
const el = wrapper.find(COPILOTKIT_THREADS_DRAWER_TAG)
|
|
740
|
+
.element as unknown as {
|
|
741
|
+
collapsible: boolean;
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
expect(el.collapsible).toBe(false);
|
|
745
|
+
|
|
746
|
+
wrapper.unmount();
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
it("leaves the element collapsible (true) when the prop is omitted", async () => {
|
|
750
|
+
// Regression: Vue coerces an omitted Boolean prop to `false`, so without the
|
|
751
|
+
// wrapper's explicit `collapsible: true` withDefaults the element would be
|
|
752
|
+
// forced to `false` and the collapse toggle would silently vanish.
|
|
753
|
+
const wrapper = await mountDrawer({});
|
|
754
|
+
|
|
755
|
+
const el = wrapper.find(COPILOTKIT_THREADS_DRAWER_TAG)
|
|
756
|
+
.element as unknown as {
|
|
757
|
+
collapsible: boolean;
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
expect(el.collapsible).toBe(true);
|
|
761
|
+
|
|
762
|
+
wrapper.unmount();
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
it("re-emits the element's collapse-change event as collapse-change(collapsed)", async () => {
|
|
766
|
+
const wrapper = await mountDrawer();
|
|
767
|
+
|
|
768
|
+
const drawer = wrapper.findComponent(CopilotThreadsDrawer);
|
|
769
|
+
const el = wrapper.find(COPILOTKIT_THREADS_DRAWER_TAG).element;
|
|
770
|
+
el.dispatchEvent(
|
|
771
|
+
new CustomEvent("collapse-change", {
|
|
772
|
+
detail: { collapsed: true },
|
|
773
|
+
bubbles: true,
|
|
774
|
+
composed: true,
|
|
775
|
+
}),
|
|
776
|
+
);
|
|
777
|
+
await nextTick();
|
|
778
|
+
|
|
779
|
+
expect(drawer.emitted("collapse-change")?.[0]).toEqual([true]);
|
|
780
|
+
|
|
781
|
+
wrapper.unmount();
|
|
782
|
+
});
|
|
783
|
+
|
|
709
784
|
it("leaves the element's default licenseUrl when the prop is omitted", async () => {
|
|
710
785
|
const wrapper = await mountDrawer();
|
|
711
786
|
|
|
@@ -20,6 +20,7 @@ type ThreadState = {
|
|
|
20
20
|
threads: ThreadRecord[];
|
|
21
21
|
isLoading: boolean;
|
|
22
22
|
error: Error | null;
|
|
23
|
+
fetchMoreError: Error | null;
|
|
23
24
|
hasNextPage: boolean;
|
|
24
25
|
isFetchingNextPage: boolean;
|
|
25
26
|
isMutating: boolean;
|
|
@@ -106,6 +107,7 @@ vi.mock("@copilotkit/core", () => {
|
|
|
106
107
|
threads: [],
|
|
107
108
|
isLoading: false,
|
|
108
109
|
error: null,
|
|
110
|
+
fetchMoreError: null,
|
|
109
111
|
hasNextPage: false,
|
|
110
112
|
isFetchingNextPage: false,
|
|
111
113
|
isMutating: false,
|
|
@@ -121,6 +123,7 @@ vi.mock("@copilotkit/core", () => {
|
|
|
121
123
|
threads: [],
|
|
122
124
|
isLoading: false,
|
|
123
125
|
error: null,
|
|
126
|
+
fetchMoreError: null,
|
|
124
127
|
hasNextPage: false,
|
|
125
128
|
isFetchingNextPage: false,
|
|
126
129
|
isMutating: false,
|
|
@@ -271,11 +274,15 @@ vi.mock("@copilotkit/core", () => {
|
|
|
271
274
|
|
|
272
275
|
async unarchiveThread(threadId: string): Promise<void> {
|
|
273
276
|
const context = this.requireContext();
|
|
274
|
-
|
|
275
|
-
|
|
277
|
+
// Mirrors the real core store: unarchive is a PATCH to the thread with
|
|
278
|
+
// `{ archived: false }`, NOT a dedicated /unarchive sub-route (see
|
|
279
|
+
// core/src/__tests__/threads.test.ts).
|
|
280
|
+
await fetchMock(`${context.runtimeUrl}/threads/${threadId}`, {
|
|
281
|
+
method: "PATCH",
|
|
276
282
|
headers: context.headers,
|
|
277
283
|
body: JSON.stringify({
|
|
278
284
|
agentId: context.agentId,
|
|
285
|
+
archived: false,
|
|
279
286
|
}),
|
|
280
287
|
});
|
|
281
288
|
}
|
|
@@ -341,6 +348,7 @@ vi.mock("@copilotkit/core", () => {
|
|
|
341
348
|
ɵselectThreads: select((state) => state.threads),
|
|
342
349
|
ɵselectThreadsIsLoading: select((state) => state.isLoading),
|
|
343
350
|
ɵselectThreadsError: select((state) => state.error),
|
|
351
|
+
ɵselectFetchMoreError: select((state) => state.fetchMoreError),
|
|
344
352
|
ɵselectHasNextPage: select((state) => state.hasNextPage),
|
|
345
353
|
ɵselectIsFetchingNextPage: select((state) => state.isFetchingNextPage),
|
|
346
354
|
ɵselectIsMutating: select((state) => state.isMutating),
|
|
@@ -1146,10 +1154,14 @@ describe("useThreads", () => {
|
|
|
1146
1154
|
await getResult().unarchiveThread("t-1");
|
|
1147
1155
|
|
|
1148
1156
|
const [url, options] = fetchMock.mock.calls[2];
|
|
1149
|
-
|
|
1150
|
-
|
|
1157
|
+
// Unarchive is a PATCH to the thread with `{ archived: false }` (matching
|
|
1158
|
+
// the real core store), not a dedicated /unarchive sub-route.
|
|
1159
|
+
expect(url).toContain("/threads/t-1");
|
|
1160
|
+
expect(url).not.toContain("/unarchive");
|
|
1161
|
+
expect(options.method).toBe("PATCH");
|
|
1151
1162
|
expect(JSON.parse(options.body)).toMatchObject({
|
|
1152
1163
|
agentId: "agent-1",
|
|
1164
|
+
archived: false,
|
|
1153
1165
|
});
|
|
1154
1166
|
});
|
|
1155
1167
|
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ɵselectIsMutating,
|
|
9
9
|
ɵselectThreads,
|
|
10
10
|
ɵselectThreadsError,
|
|
11
|
+
ɵselectFetchMoreError,
|
|
11
12
|
ɵselectThreadsIsLoading,
|
|
12
13
|
} from "@copilotkit/core";
|
|
13
14
|
import type { ɵThreadRuntimeContext, ɵThreadStore } from "@copilotkit/core";
|
|
@@ -47,6 +48,13 @@ export interface UseThreadsResult {
|
|
|
47
48
|
error: Ref<Error | null>;
|
|
48
49
|
/** Genuine list-load/mutation errors only — excludes dev/config errors. */
|
|
49
50
|
listError: Ref<Error | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Error from the most recent FAILED next-page (fetch-more) load, or `null`.
|
|
53
|
+
* Tracked separately from {@link listError} so a paginated-load failure
|
|
54
|
+
* shows an inline "couldn't load more" affordance while the loaded list
|
|
55
|
+
* stays visible. Cleared when a fetch-more is retried or succeeds.
|
|
56
|
+
*/
|
|
57
|
+
fetchMoreError: Ref<Error | null>;
|
|
50
58
|
hasMoreThreads: Ref<boolean>;
|
|
51
59
|
isFetchingMoreThreads: Ref<boolean>;
|
|
52
60
|
isMutating: Ref<boolean>;
|
|
@@ -136,6 +144,7 @@ export function useThreads(input: UseThreadsInput): UseThreadsResult {
|
|
|
136
144
|
const threads = ref<Thread[]>([]);
|
|
137
145
|
const storeIsLoading = ref(false);
|
|
138
146
|
const storeError = ref<Error | null>(null);
|
|
147
|
+
const fetchMoreError = ref<Error | null>(null);
|
|
139
148
|
const hasMoreThreads = ref(false);
|
|
140
149
|
const isFetchingMoreThreads = ref(false);
|
|
141
150
|
const isMutating = ref(false);
|
|
@@ -143,6 +152,7 @@ export function useThreads(input: UseThreadsInput): UseThreadsResult {
|
|
|
143
152
|
bindThreadStoreSelector(store, ɵselectThreads, threads as Ref<Thread[]>);
|
|
144
153
|
bindThreadStoreSelector(store, ɵselectThreadsIsLoading, storeIsLoading);
|
|
145
154
|
bindThreadStoreSelector(store, ɵselectThreadsError, storeError);
|
|
155
|
+
bindThreadStoreSelector(store, ɵselectFetchMoreError, fetchMoreError);
|
|
146
156
|
bindThreadStoreSelector(store, ɵselectHasNextPage, hasMoreThreads);
|
|
147
157
|
bindThreadStoreSelector(
|
|
148
158
|
store,
|
|
@@ -315,6 +325,7 @@ export function useThreads(input: UseThreadsInput): UseThreadsResult {
|
|
|
315
325
|
isLoading,
|
|
316
326
|
error,
|
|
317
327
|
listError,
|
|
328
|
+
fetchMoreError,
|
|
318
329
|
hasMoreThreads,
|
|
319
330
|
isFetchingMoreThreads,
|
|
320
331
|
isMutating,
|
package/vite.config.ts
CHANGED
|
@@ -31,6 +31,13 @@ export default defineConfig({
|
|
|
31
31
|
"@copilotkit/core",
|
|
32
32
|
"@copilotkit/shared",
|
|
33
33
|
"@copilotkit/web-inspector",
|
|
34
|
+
// Keep @copilotkit/web-components (the Lit drawer element) + its subpaths
|
|
35
|
+
// external. It's a runtime dependency loaded via the drawer wrapper's
|
|
36
|
+
// client-only dynamic import; bundling it inline would ship a duplicate
|
|
37
|
+
// element + a second copy of lit-html, which breaks Vite/Nuxt consumers
|
|
38
|
+
// (duplicate top-level lit binding → "Identifier 'h' has already been
|
|
39
|
+
// declared") and risks double custom-element registration.
|
|
40
|
+
/^@copilotkit\/web-components(\/.*)?$/,
|
|
34
41
|
"@jetbrains/websandbox",
|
|
35
42
|
"streamdown-vue",
|
|
36
43
|
"katex",
|