@copilotkit/vue 1.67.1 → 1.68.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PARITY.md +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{use-render-activity-message-CaArNmtw.js → use-render-activity-message-DljRBrXN.js} +3401 -3370
- package/dist/use-render-activity-message-DljRBrXN.js.map +1 -0
- package/dist/use-render-activity-message-bkrPa-92.cjs +85 -0
- package/dist/use-render-activity-message-bkrPa-92.cjs.map +1 -0
- package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
- package/dist/v2/hooks/use-agent.d.ts +66 -5
- package/dist/v2/hooks/use-agent.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/CopilotChat.vue +14 -1
- package/src/v2/components/chat/CopilotChatMessageView.vue +5 -7
- package/src/v2/components/chat/__tests__/CopilotChat.clearOnFresh.test.ts +14 -25
- package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.ts +1 -2
- package/src/v2/components/chat/__tests__/CopilotChat.test.ts +2 -3
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +6 -6
- package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.ts +14 -0
- package/src/v2/hooks/__tests__/use-agent-thread-pinning.test.ts +179 -0
- package/src/v2/hooks/use-agent.ts +205 -78
- package/dist/use-render-activity-message-CNbp9Fob.cjs +0 -85
- package/dist/use-render-activity-message-CNbp9Fob.cjs.map +0 -1
- package/dist/use-render-activity-message-CaArNmtw.js.map +0 -1
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.ts +0 -433
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotChat.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/CopilotChat.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CopilotChat.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/CopilotChat.vue"],"names":[],"mappings":"AA+zBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAiBnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,6BAA6B,EAC7B,kCAAkC,EAClC,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,SAAS,CAAC;AAcjB,KAAK,WAAW,GAAG;IACjB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,OAAO,CAAC;IACnE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QACvB,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;KACpB,KAAK,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,6BAA6B,KAAK,OAAO,CAAC;IAC9D,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC;IACtD,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,kCAAkC,KAAK,OAAO,CAAC;IAC3E,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,iCAAiC,KAAK,OAAO,CAAC;IACzE,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;IAElC,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;CACtD,CAAC;AAwzBF,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;6EAQnB,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotChatMessageView.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/CopilotChatMessageView.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CopilotChatMessageView.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/CopilotChatMessageView.vue"],"names":[],"mappings":"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"}
|
|
@@ -5,9 +5,7 @@ export declare enum UseAgentUpdate {
|
|
|
5
5
|
OnStateChanged = "OnStateChanged",
|
|
6
6
|
OnRunStatusChanged = "OnRunStatusChanged"
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
agentId?: MaybeRefOrGetter<string | undefined>;
|
|
10
|
-
threadId?: MaybeRefOrGetter<string | undefined>;
|
|
8
|
+
interface UseAgentPropsBase {
|
|
11
9
|
updates?: UseAgentUpdate[];
|
|
12
10
|
/**
|
|
13
11
|
* Throttle interval (in milliseconds) for re-renders triggered by
|
|
@@ -33,8 +31,70 @@ export interface UseAgentProps {
|
|
|
33
31
|
*/
|
|
34
32
|
throttleMs?: MaybeRefOrGetter<number | undefined>;
|
|
35
33
|
}
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Thread-scoped variant. `agentId`, `runtimeAgentId` and `threadId` are a matched
|
|
36
|
+
* set: together they give this hook a private proxied agent — registered under the
|
|
37
|
+
* local `agentId`, routing outbound to `runtimeAgentId` — that is safe to pin a
|
|
38
|
+
* thread onto. Mirrors React's `UseAgentThreadScopedProps`.
|
|
39
|
+
*/
|
|
40
|
+
interface UseAgentThreadScopedProps {
|
|
41
|
+
/**
|
|
42
|
+
* The *local* registry id to register this hook's proxied agent under. Required
|
|
43
|
+
* here: the usual fallbacks (chat configuration, then `DEFAULT_AGENT_ID`) name
|
|
44
|
+
* agents that already exist, and registering over one of those throws.
|
|
45
|
+
*/
|
|
46
|
+
agentId: MaybeRefOrGetter<string>;
|
|
47
|
+
/**
|
|
48
|
+
* The runtime agent to route outbound requests to while this hook exposes a
|
|
49
|
+
* distinct local `agentId`. Registers a proxied agent via
|
|
50
|
+
* `CopilotKitCore.registerProxiedAgent`, so several frontend agents (e.g. one
|
|
51
|
+
* per open thread) can mount against one runtime agent.
|
|
52
|
+
*
|
|
53
|
+
* REQUIRES `threadId` — a private agent with no thread to scope behaves like
|
|
54
|
+
* the shared one, minus a registration and a local id to keep unique.
|
|
55
|
+
*/
|
|
56
|
+
runtimeAgentId: MaybeRefOrGetter<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Thread to scope the agent's run to. Written onto the underlying agent, so
|
|
59
|
+
* `/agent/run`, `/agent/connect` and `/agent/stop` address this thread.
|
|
60
|
+
*
|
|
61
|
+
* REQUIRES `runtimeAgentId` — an agent resolved by `agentId` alone is shared,
|
|
62
|
+
* so a per-hook thread written onto it would clobber every other holder.
|
|
63
|
+
*/
|
|
64
|
+
threadId: MaybeRefOrGetter<string>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Default variant: no thread scoping. Binds to the shared agent registered under
|
|
68
|
+
* `agentId` and takes its thread from the surrounding chat configuration, gated
|
|
69
|
+
* on `hasExplicitThreadId`. Mirrors React's `UseAgentUnscopedProps`.
|
|
70
|
+
*
|
|
71
|
+
* `threadId` and `runtimeAgentId` are typed `undefined` rather than omitted so
|
|
72
|
+
* that supplying either alone matches *neither* branch — that is the type-level
|
|
73
|
+
* enforcement of the all-or-nothing rule.
|
|
74
|
+
*/
|
|
75
|
+
interface UseAgentUnscopedProps {
|
|
76
|
+
/**
|
|
77
|
+
* Agent to bind to. Resolution precedence: this property, then the surrounding
|
|
78
|
+
* chat configuration's agentId, then the global default.
|
|
79
|
+
*/
|
|
80
|
+
agentId?: MaybeRefOrGetter<string | undefined>;
|
|
81
|
+
/** Requires `runtimeAgentId`. See {@link UseAgentThreadScopedProps.threadId}. */
|
|
82
|
+
threadId?: undefined;
|
|
83
|
+
/** Requires `threadId`. See {@link UseAgentThreadScopedProps.runtimeAgentId}. */
|
|
84
|
+
runtimeAgentId?: undefined;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Props for {@link useAgent}. Two valid shapes, nothing in between:
|
|
88
|
+
*
|
|
89
|
+
* - **Bind to an agent** — `useAgent()`, `useAgent({ agentId })`. The shared
|
|
90
|
+
* registry instance; the thread comes from the chat configuration.
|
|
91
|
+
* - **Bind a private agent to a thread** —
|
|
92
|
+
* `useAgent({ agentId, runtimeAgentId, threadId })`. All three required.
|
|
93
|
+
*
|
|
94
|
+
* So `{ agentId, threadId }`, `{ agentId, runtimeAgentId }` and
|
|
95
|
+
* `{ runtimeAgentId, threadId }` are all compile errors, matching React.
|
|
96
|
+
*/
|
|
97
|
+
export type UseAgentProps = UseAgentPropsBase & (UseAgentThreadScopedProps | UseAgentUnscopedProps);
|
|
38
98
|
/**
|
|
39
99
|
* Resolves and subscribes to a CopilotKit agent for the current Vue scope.
|
|
40
100
|
*
|
|
@@ -50,4 +110,5 @@ export declare function getThreadClone(registryAgent: AbstractAgent | undefined
|
|
|
50
110
|
export declare function useAgent(props?: UseAgentProps): {
|
|
51
111
|
agent: import("vue").ShallowRef<AbstractAgent | null, AbstractAgent | null>;
|
|
52
112
|
};
|
|
113
|
+
export {};
|
|
53
114
|
//# sourceMappingURL=use-agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent.d.ts","sourceRoot":"","sources":["../../../src/v2/hooks/use-agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAYnD,oBAAY,cAAc;IACxB,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;CAC1C;AAQD,
|
|
1
|
+
{"version":3,"file":"use-agent.d.ts","sourceRoot":"","sources":["../../../src/v2/hooks/use-agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAYnD,oBAAY,cAAc;IACxB,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;CAC1C;AAQD,UAAU,iBAAiB;IACzB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACnD;AAED;;;;;GAKG;AACH,UAAU,yBAAyB;IACjC;;;;OAIG;IACH,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClC;;;;;;;;OAQG;IACH,cAAc,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,UAAU,qBAAqB;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC/C,iFAAiF;IACjF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iFAAiF;IACjF,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAC3C,CAAC,yBAAyB,GAAG,qBAAqB,CAAC,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,KAAK,GAAE,aAAkB;;EAmVjD"}
|
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-bkrPa-92.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-DljRBrXN.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.
|
|
3
|
+
"version": "1.68.1",
|
|
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.
|
|
74
|
-
"@copilotkit/web-components": "1.
|
|
75
|
-
"@copilotkit/
|
|
76
|
-
"@copilotkit/
|
|
73
|
+
"@copilotkit/core": "1.68.1",
|
|
74
|
+
"@copilotkit/web-components": "1.68.1",
|
|
75
|
+
"@copilotkit/shared": "1.68.1",
|
|
76
|
+
"@copilotkit/web-inspector": "1.68.1"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@eslint/js": "^9.39.2",
|
|
@@ -141,9 +141,12 @@ const isConnecting = computed(
|
|
|
141
141
|
const stableLabels = useShallowStableRef(computed(() => props.labels));
|
|
142
142
|
const resolvedLabels = computed(() => stableLabels.value);
|
|
143
143
|
|
|
144
|
+
// `useAgent` takes no threadId: it pins one only from a surrounding chat
|
|
145
|
+
// configuration, and this call sits outside the provider rendered in this
|
|
146
|
+
// component's template, so it would never see the thread being rendered. The
|
|
147
|
+
// thread is assigned in the connect watcher below, mirroring React's CopilotChat.
|
|
144
148
|
const { agent } = useAgent({
|
|
145
149
|
agentId: resolvedAgentId,
|
|
146
|
-
threadId: resolvedThreadId,
|
|
147
150
|
throttleMs: computed(() => props.throttleMs),
|
|
148
151
|
});
|
|
149
152
|
const { suggestions: autoSuggestions } = useSuggestions({
|
|
@@ -312,6 +315,16 @@ watch(
|
|
|
312
315
|
if (!currentAgent) {
|
|
313
316
|
return;
|
|
314
317
|
}
|
|
318
|
+
|
|
319
|
+
// Pin the thread this chat renders onto its agent, before anything issues a
|
|
320
|
+
// request. `CopilotKitCore.connectAgent` reads `agent.threadId` synchronously
|
|
321
|
+
// to decide whether this is a fresh restore, so a later assignment would let
|
|
322
|
+
// /connect address the previous thread. Assigning inside this callback — as
|
|
323
|
+
// React does — makes the ordering unconditional instead of depending on
|
|
324
|
+
// watcher scheduling. Non-explicit threads skip /connect below, but the first
|
|
325
|
+
// runAgent still has to ship the thread the UI is rendering.
|
|
326
|
+
currentAgent.threadId = threadId;
|
|
327
|
+
|
|
315
328
|
// When the caller hasn't picked a specific thread, resolvedThreadId is
|
|
316
329
|
// a UUID minted locally. The backend has never seen it, so /connect
|
|
317
330
|
// would always 404 — skip the call. A real thread is only created
|
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
InterruptRenderProps,
|
|
15
15
|
VueCustomMessageRendererProps,
|
|
16
16
|
} from "../../types";
|
|
17
|
-
import { getThreadClone } from "../../hooks/use-agent";
|
|
18
17
|
import { useCopilotKit } from "../../providers/useCopilotKit";
|
|
19
18
|
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
20
19
|
import CopilotChatAssistantMessage from "./CopilotChatAssistantMessage.vue";
|
|
@@ -105,9 +104,9 @@ const resolvedAgentId = computed(
|
|
|
105
104
|
() => config.value?.agentId ?? DEFAULT_AGENT_ID,
|
|
106
105
|
);
|
|
107
106
|
const resolvedThreadAgent = computed(() => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return
|
|
107
|
+
// Read the registry so this recomputes when agents are added or replaced.
|
|
108
|
+
void copilotkit.value.agents;
|
|
109
|
+
return copilotkit.value.getAgent(resolvedAgentId.value);
|
|
111
110
|
});
|
|
112
111
|
|
|
113
112
|
watch(
|
|
@@ -117,9 +116,8 @@ watch(
|
|
|
117
116
|
() => copilotkit.value,
|
|
118
117
|
() => copilotkit.value.runtimeConnectionStatus,
|
|
119
118
|
],
|
|
120
|
-
(
|
|
121
|
-
const
|
|
122
|
-
const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
|
|
119
|
+
(_values, _prev, onCleanup) => {
|
|
120
|
+
const agent = resolvedThreadAgent.value;
|
|
123
121
|
if (!agent) return;
|
|
124
122
|
|
|
125
123
|
const sub = agent.subscribe({
|
|
@@ -7,7 +7,6 @@ import { useCopilotChatConfiguration } from "../../../providers/useCopilotChatCo
|
|
|
7
7
|
import { useCopilotKit } from "../../../providers/useCopilotKit";
|
|
8
8
|
import { StateCapturingAgent } from "../../../__tests__/utils/agents";
|
|
9
9
|
import CopilotChat from "../CopilotChat.vue";
|
|
10
|
-
import { getThreadClone } from "../../../hooks/use-agent";
|
|
11
10
|
|
|
12
11
|
// Proves the clear-on-fresh watch introduced in CopilotChat.vue:
|
|
13
12
|
// - does NOT clear messages on initial mount
|
|
@@ -17,6 +16,9 @@ import { getThreadClone } from "../../../hooks/use-agent";
|
|
|
17
16
|
describe("CopilotChat clear-on-fresh", () => {
|
|
18
17
|
it("does not clear messages on initial mount", async () => {
|
|
19
18
|
const agent = new StateCapturingAgent();
|
|
19
|
+
// Spy before mount: attaching afterwards can never observe a mount-time
|
|
20
|
+
// clear, which is exactly what this test exists to rule out.
|
|
21
|
+
const setMessagesSpy = vi.spyOn(agent, "setMessages");
|
|
20
22
|
|
|
21
23
|
let core:
|
|
22
24
|
| ReturnType<typeof useCopilotKit>["copilotkit"]["value"]
|
|
@@ -49,15 +51,9 @@ describe("CopilotChat clear-on-fresh", () => {
|
|
|
49
51
|
await flushPromises();
|
|
50
52
|
await nextTick();
|
|
51
53
|
|
|
52
|
-
const
|
|
53
|
-
const resolvedAgent = getThreadClone(registryAgent, "seed");
|
|
54
|
+
const resolvedAgent = core?.getAgent("default");
|
|
54
55
|
expect(resolvedAgent).toBeDefined();
|
|
55
|
-
|
|
56
|
-
// Attach the spy only after mount has settled so the clone's own
|
|
57
|
-
// construction-time `setMessages([])` reset (in `cloneForThread`,
|
|
58
|
-
// unrelated to the clear-on-fresh watch) isn't mistaken for a clear.
|
|
59
|
-
const setMessagesSpy = vi.spyOn(resolvedAgent!, "setMessages");
|
|
60
|
-
await nextTick();
|
|
56
|
+
expect(setMessagesSpy).not.toHaveBeenCalled();
|
|
61
57
|
|
|
62
58
|
expect(setMessagesSpy).not.toHaveBeenCalled();
|
|
63
59
|
});
|
|
@@ -110,7 +106,7 @@ describe("CopilotChat clear-on-fresh", () => {
|
|
|
110
106
|
await nextTick();
|
|
111
107
|
|
|
112
108
|
const registryAgent = core?.getAgent("default");
|
|
113
|
-
const seedAgent =
|
|
109
|
+
const seedAgent = registryAgent;
|
|
114
110
|
expect(seedAgent).toBeDefined();
|
|
115
111
|
expect(currentThreadId).toBe("seed");
|
|
116
112
|
|
|
@@ -122,19 +118,15 @@ describe("CopilotChat clear-on-fresh", () => {
|
|
|
122
118
|
expect(currentThreadId).toBeDefined();
|
|
123
119
|
expect(currentThreadId).not.toBe("seed");
|
|
124
120
|
const newAgentThreadId = currentThreadId!;
|
|
125
|
-
const newAgent =
|
|
121
|
+
const newAgent = registryAgent;
|
|
126
122
|
expect(newAgent).toBeDefined();
|
|
127
|
-
expect(newAgent).not.toBe(seedAgent);
|
|
128
123
|
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
// clone construction, since `cloneForThread` also resets to `[]`).
|
|
124
|
+
// The agent ends with no messages after the fresh switch. With one shared
|
|
125
|
+
// instance the clear-on-fresh watch is the only thing that can empty it.
|
|
132
126
|
expect(newAgent!.messages).toEqual([]);
|
|
133
127
|
|
|
134
|
-
// Move to a third, unrelated non-explicit thread
|
|
135
|
-
//
|
|
136
|
-
// `cloneForThread`'s construction reset entirely, since the clone
|
|
137
|
-
// already exists in the cache).
|
|
128
|
+
// Move to a third, unrelated non-explicit thread, then dirty the agent
|
|
129
|
+
// directly so the next transition has something real to clear.
|
|
138
130
|
expect(setActiveThreadId).toBeDefined();
|
|
139
131
|
setActiveThreadId!("elsewhere", { explicit: false });
|
|
140
132
|
await flushPromises();
|
|
@@ -144,12 +136,9 @@ describe("CopilotChat clear-on-fresh", () => {
|
|
|
144
136
|
newAgent!.setMessages([{ id: "m1", role: "user", content: "hi" } as never]);
|
|
145
137
|
expect(newAgent!.messages.length).toBe(1);
|
|
146
138
|
|
|
147
|
-
// Switch back
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
// must come from the clear-on-fresh watch, not from clone construction.
|
|
151
|
-
// This fails (messages stay dirty) if the watch's
|
|
152
|
-
// `currentAgent.setMessages([])` call is removed.
|
|
139
|
+
// Switch back non-explicitly. Any `setMessages([])` observed here must come
|
|
140
|
+
// from the clear-on-fresh watch; this fails (messages stay dirty) if the
|
|
141
|
+
// watch's `currentAgent.setMessages([])` call is removed.
|
|
153
142
|
setActiveThreadId!(newAgentThreadId, { explicit: false });
|
|
154
143
|
await flushPromises();
|
|
155
144
|
await nextTick();
|
|
@@ -4,7 +4,6 @@ import { h } from "vue";
|
|
|
4
4
|
import CopilotChat from "../CopilotChat.vue";
|
|
5
5
|
import { renderWithCopilotKit } from "../../../__tests__/utils/mount";
|
|
6
6
|
import { StateCapturingAgent } from "../../../__tests__/utils/agents";
|
|
7
|
-
import { getThreadClone } from "../../../hooks/use-agent";
|
|
8
7
|
|
|
9
8
|
describe("CopilotChat.slots.e2e", () => {
|
|
10
9
|
it("supports full chat-view override with callback payload", async () => {
|
|
@@ -133,7 +132,7 @@ describe("CopilotChat.slots.e2e", () => {
|
|
|
133
132
|
await flushPromises();
|
|
134
133
|
|
|
135
134
|
const registryAgent = getCore().getAgent("custom-agent");
|
|
136
|
-
const resolvedAgent =
|
|
135
|
+
const resolvedAgent = registryAgent;
|
|
137
136
|
expect(defaultAgent.messages).toHaveLength(0);
|
|
138
137
|
expect(resolvedAgent?.threadId).toBe("explicit-thread");
|
|
139
138
|
expect(resolvedAgent?.messages.some((m) => m.role === "user")).toBe(true);
|
|
@@ -9,7 +9,6 @@ import { useCopilotKit } from "../../../providers/useCopilotKit";
|
|
|
9
9
|
import { CopilotKitCoreVue } from "../../../lib/vue-core";
|
|
10
10
|
import CopilotChat from "../CopilotChat.vue";
|
|
11
11
|
import CopilotChatView from "../CopilotChatView.vue";
|
|
12
|
-
import { getThreadClone } from "../../../hooks/use-agent";
|
|
13
12
|
|
|
14
13
|
function mountChat(
|
|
15
14
|
props: Record<string, unknown> = {},
|
|
@@ -178,7 +177,7 @@ describe("CopilotChat", () => {
|
|
|
178
177
|
await flushPromises();
|
|
179
178
|
|
|
180
179
|
const registryAgent = core?.getAgent("custom-agent");
|
|
181
|
-
const resolvedAgent =
|
|
180
|
+
const resolvedAgent = registryAgent;
|
|
182
181
|
expect(resolvedAgent?.threadId).toBe("explicit-thread");
|
|
183
182
|
expect(resolvedAgent?.messages.some((m) => m.role === "user")).toBe(true);
|
|
184
183
|
expect(defaultAgent.messages).toHaveLength(0);
|
|
@@ -230,7 +229,7 @@ describe("CopilotChat", () => {
|
|
|
230
229
|
await flushPromises();
|
|
231
230
|
|
|
232
231
|
const registryAgent = core?.getAgent("default");
|
|
233
|
-
const resolvedAgent =
|
|
232
|
+
const resolvedAgent = registryAgent;
|
|
234
233
|
const abortRun = vi.fn();
|
|
235
234
|
if (registryAgent) {
|
|
236
235
|
registryAgent.abortRun = abortRun;
|
|
@@ -14,7 +14,6 @@ import { IntelligenceAgent } from "@copilotkit/core";
|
|
|
14
14
|
import CopilotChat from "../CopilotChat.vue";
|
|
15
15
|
import CopilotKitProvider from "../../../providers/CopilotKitProvider.vue";
|
|
16
16
|
import CopilotChatConfigurationProvider from "../../../providers/CopilotChatConfigurationProvider.vue";
|
|
17
|
-
import { getThreadClone } from "../../../hooks/use-agent";
|
|
18
17
|
import { useCopilotKit } from "../../../providers/useCopilotKit";
|
|
19
18
|
import { createA2UIMessageRenderer } from "../../../components/A2UIMessageRenderer";
|
|
20
19
|
import {
|
|
@@ -315,7 +314,7 @@ describe("CopilotChat activity message rendering", () => {
|
|
|
315
314
|
expect(screen.getByTestId("copilotkit-probe").textContent).toBe("true");
|
|
316
315
|
});
|
|
317
316
|
|
|
318
|
-
it("passes the
|
|
317
|
+
it("passes the registry agent to activity message renderers", async () => {
|
|
319
318
|
const agent = new MockStepwiseAgent();
|
|
320
319
|
const agentId = "action-agent";
|
|
321
320
|
agent.agentId = agentId;
|
|
@@ -367,10 +366,11 @@ describe("CopilotChat activity message rendering", () => {
|
|
|
367
366
|
expect(screen.getByTestId("action-button")).toBeDefined();
|
|
368
367
|
});
|
|
369
368
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
expect(
|
|
373
|
-
expect(toRaw(capturedAgent.value!)).
|
|
369
|
+
// Thread cloning is gone: renderers get the registry agent, with the
|
|
370
|
+
// thread pinned onto it rather than split across per-thread copies.
|
|
371
|
+
expect(capturedAgent.value).toBeDefined();
|
|
372
|
+
expect(toRaw(capturedAgent.value!)).toBe(agent);
|
|
373
|
+
expect(toRaw(capturedAgent.value!).threadId).toBe(threadId);
|
|
374
374
|
});
|
|
375
375
|
|
|
376
376
|
it("restores a completed A2UI surface after reconnect from an event-native baseline", async () => {
|
|
@@ -53,6 +53,20 @@ class MockMCPProxyAgent extends AbstractAgent {
|
|
|
53
53
|
await flushVueUpdates();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// Records what the renderer sent. This instrumentation also exists in the
|
|
57
|
+
// `clone()` override below, which is where it used to live exclusively — back
|
|
58
|
+
// when `useAgent` handed components a per-thread clone. Thread cloning is gone,
|
|
59
|
+
// so the class records for itself; `clone()` is left intact because
|
|
60
|
+
// `CopilotKitCore`'s SuggestionEngine still clones agents.
|
|
61
|
+
addMessage(message: Parameters<AbstractAgent["addMessage"]>[0]) {
|
|
62
|
+
this.addMessageCalls.push({
|
|
63
|
+
id: message.id,
|
|
64
|
+
role: message.role,
|
|
65
|
+
content: message.content,
|
|
66
|
+
});
|
|
67
|
+
return super.addMessage(message);
|
|
68
|
+
}
|
|
69
|
+
|
|
56
70
|
clone(): MockMCPProxyAgent {
|
|
57
71
|
const cloned = new MockMCPProxyAgent();
|
|
58
72
|
cloned.agentId = this.agentId;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { defineComponent, ref, shallowRef, toRaw } from "vue";
|
|
2
|
+
import { render, cleanup } from "@testing-library/vue";
|
|
3
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
4
|
+
import { AbstractAgent } from "@ag-ui/client";
|
|
5
|
+
import type { BaseEvent } from "@ag-ui/client";
|
|
6
|
+
import { CopilotKitCoreRuntimeConnectionStatus } from "@copilotkit/core";
|
|
7
|
+
import { Observable } from "rxjs";
|
|
8
|
+
import { useCopilotKit } from "../../providers/useCopilotKit";
|
|
9
|
+
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
10
|
+
import { useAgent } from "../use-agent";
|
|
11
|
+
|
|
12
|
+
vi.mock("../../providers/useCopilotKit", () => ({
|
|
13
|
+
useCopilotKit: vi.fn(),
|
|
14
|
+
}));
|
|
15
|
+
vi.mock("../../providers/useCopilotChatConfiguration", () => ({
|
|
16
|
+
useCopilotChatConfiguration: vi.fn(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
const mockUseCopilotKit = useCopilotKit as ReturnType<typeof vi.fn>;
|
|
20
|
+
const mockUseChatConfig = useCopilotChatConfiguration as ReturnType<
|
|
21
|
+
typeof vi.fn
|
|
22
|
+
>;
|
|
23
|
+
|
|
24
|
+
class SimpleAgent extends AbstractAgent {
|
|
25
|
+
run(): Observable<BaseEvent> {
|
|
26
|
+
return new Observable();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Replaces `use-agent-thread-isolation.test.ts`, which pinned the per-thread
|
|
32
|
+
* *cloning* `useAgent` used to do. Cloning is gone; the hook mirrors React:
|
|
33
|
+
* one shared instance per agentId with the chat configuration's thread pinned
|
|
34
|
+
* onto it (gated on `hasExplicitThreadId`), or — with the all-or-nothing
|
|
35
|
+
* `{ agentId, runtimeAgentId, threadId }` set — a private proxied agent.
|
|
36
|
+
*
|
|
37
|
+
* The invariant under test: never a copy, and a caller-chosen thread lands on
|
|
38
|
+
* the agent while an auto-minted placeholder does not.
|
|
39
|
+
*/
|
|
40
|
+
describe("useAgent agent resolution", () => {
|
|
41
|
+
let registryAgent: SimpleAgent;
|
|
42
|
+
let copilotkitRef: ReturnType<typeof shallowRef>;
|
|
43
|
+
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
registryAgent = new SimpleAgent();
|
|
46
|
+
registryAgent.agentId = "my-agent";
|
|
47
|
+
// `shallowRef`, matching production (`CopilotKitProvider.vue` provides
|
|
48
|
+
// `shallowRef<CopilotKitCoreVue>`). A deep `ref` would hand the hook
|
|
49
|
+
// reactive proxies of the core and of every agent, so the identity
|
|
50
|
+
// assertions below would compare proxies rather than the real instances.
|
|
51
|
+
copilotkitRef = shallowRef({
|
|
52
|
+
getAgent: vi.fn((id: string) =>
|
|
53
|
+
id === "my-agent" ? registryAgent : undefined,
|
|
54
|
+
),
|
|
55
|
+
runtimeUrl: "http://localhost:3000/api/copilotkit",
|
|
56
|
+
runtimeConnectionStatus: CopilotKitCoreRuntimeConnectionStatus.Connected,
|
|
57
|
+
runtimeTransport: "rest",
|
|
58
|
+
headers: {},
|
|
59
|
+
agents: { "my-agent": registryAgent },
|
|
60
|
+
defaultThrottleMs: undefined,
|
|
61
|
+
subscribeToAgentWithOptions: vi.fn(() => ({ unsubscribe: vi.fn() })),
|
|
62
|
+
});
|
|
63
|
+
mockUseCopilotKit.mockReturnValue({
|
|
64
|
+
copilotkit: copilotkitRef,
|
|
65
|
+
executingToolCallIds: ref(new Set()),
|
|
66
|
+
});
|
|
67
|
+
mockUseChatConfig.mockReturnValue(ref(null));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
cleanup();
|
|
72
|
+
vi.restoreAllMocks();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const mountProbe = () => {
|
|
76
|
+
let captured: AbstractAgent | null = null;
|
|
77
|
+
const Probe = defineComponent({
|
|
78
|
+
setup() {
|
|
79
|
+
captured = useAgent({ agentId: "my-agent" }).agent.value;
|
|
80
|
+
return () => null;
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
render(Probe);
|
|
84
|
+
return () => captured;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
it("returns the registry instance itself, never a copy", () => {
|
|
88
|
+
const captured = mountProbe();
|
|
89
|
+
expect(toRaw(captured()!)).toBe(registryAgent);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("returns the same instance to two hooks sharing an agentId", () => {
|
|
93
|
+
let first: AbstractAgent | null = null;
|
|
94
|
+
let second: AbstractAgent | null = null;
|
|
95
|
+
const Probe = defineComponent({
|
|
96
|
+
setup() {
|
|
97
|
+
first = useAgent({ agentId: "my-agent" }).agent.value;
|
|
98
|
+
second = useAgent({ agentId: "my-agent" }).agent.value;
|
|
99
|
+
return () => null;
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
render(Probe);
|
|
104
|
+
|
|
105
|
+
// Cloning used to make these two different objects keyed by thread.
|
|
106
|
+
expect(toRaw(first!)).toBe(toRaw(second!));
|
|
107
|
+
expect(toRaw(first!)).toBe(registryAgent);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("pins the chat configuration's thread when the caller chose it", () => {
|
|
111
|
+
mockUseChatConfig.mockReturnValue(
|
|
112
|
+
ref({
|
|
113
|
+
agentId: "my-agent",
|
|
114
|
+
threadId: "chosen-thread",
|
|
115
|
+
hasExplicitThreadId: true,
|
|
116
|
+
}),
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
mountProbe();
|
|
120
|
+
|
|
121
|
+
expect(registryAgent.threadId).toBe("chosen-thread");
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("leaves the agent's own thread alone for a non-explicit placeholder", () => {
|
|
125
|
+
// A ThreadsProvider-minted UUID is as meaningless to the backend as the
|
|
126
|
+
// agent's own, so it must not overwrite it.
|
|
127
|
+
const ownThreadId = registryAgent.threadId;
|
|
128
|
+
mockUseChatConfig.mockReturnValue(
|
|
129
|
+
ref({
|
|
130
|
+
agentId: "my-agent",
|
|
131
|
+
threadId: "placeholder-thread",
|
|
132
|
+
hasExplicitThreadId: false,
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
mountProbe();
|
|
137
|
+
|
|
138
|
+
expect(registryAgent.threadId).toBe(ownThreadId);
|
|
139
|
+
expect(registryAgent.threadId).not.toBe("placeholder-thread");
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe("all-or-nothing thread scoping (mirrors React)", () => {
|
|
143
|
+
const expectSetupThrow = (setup: () => void, message: RegExp) => {
|
|
144
|
+
const Probe = defineComponent({
|
|
145
|
+
setup() {
|
|
146
|
+
setup();
|
|
147
|
+
return () => null;
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
const spy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
151
|
+
try {
|
|
152
|
+
expect(() => render(Probe)).toThrow(message);
|
|
153
|
+
} finally {
|
|
154
|
+
spy.mockRestore();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
it("throws when threadId is passed without runtimeAgentId", () => {
|
|
159
|
+
expectSetupThrow(() => {
|
|
160
|
+
// @ts-expect-error threadId requires runtimeAgentId
|
|
161
|
+
useAgent({ agentId: "my-agent", threadId: "t1" });
|
|
162
|
+
}, /`threadId` requires `runtimeAgentId`/);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("throws when runtimeAgentId is passed without threadId", () => {
|
|
166
|
+
expectSetupThrow(() => {
|
|
167
|
+
// @ts-expect-error runtimeAgentId requires threadId
|
|
168
|
+
useAgent({ agentId: "chat-1", runtimeAgentId: "my-agent" });
|
|
169
|
+
}, /`runtimeAgentId` requires `threadId`/);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("throws when runtimeAgentId is passed without an explicit agentId", () => {
|
|
173
|
+
expectSetupThrow(() => {
|
|
174
|
+
// @ts-expect-error runtimeAgentId requires an explicit agentId
|
|
175
|
+
useAgent({ runtimeAgentId: "my-agent", threadId: "t1" });
|
|
176
|
+
}, /requires an explicit `agentId`/);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|