@copilotkit/react-core 1.1.1-feat-runtime-remote-actions.4 → 1.1.1-feat-runtime-remote-actions.5
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/CHANGELOG.md +9 -0
- package/dist/{chunk-2MQX7BJL.mjs → chunk-6GOM3DN7.mjs} +2 -2
- package/dist/{chunk-IF6P5ZXR.mjs → chunk-6UNB66M3.mjs} +38 -10
- package/dist/chunk-6UNB66M3.mjs.map +1 -0
- package/dist/{chunk-73KBO5JG.mjs → chunk-73YBF52D.mjs} +2 -2
- package/dist/chunk-BWYAGPEF.mjs +1 -0
- package/dist/{chunk-DZH3HSXW.mjs → chunk-CHOQ5C7K.mjs} +35 -8
- package/dist/chunk-CHOQ5C7K.mjs.map +1 -0
- package/dist/{chunk-33ERMMNX.mjs → chunk-DU7PVINC.mjs} +2 -2
- package/dist/chunk-IQH77T4S.mjs +44 -0
- package/dist/chunk-IQH77T4S.mjs.map +1 -0
- package/dist/{chunk-DB4VWZ5Q.mjs → chunk-LTA2O5WH.mjs} +11 -6
- package/dist/chunk-LTA2O5WH.mjs.map +1 -0
- package/dist/chunk-MTOHRBPJ.mjs +87 -0
- package/dist/chunk-MTOHRBPJ.mjs.map +1 -0
- package/dist/{chunk-52M7642J.mjs → chunk-PPYZB3IY.mjs} +52 -31
- package/dist/chunk-PPYZB3IY.mjs.map +1 -0
- package/dist/{chunk-H4XENJME.mjs → chunk-SYJIZLOI.mjs} +2 -2
- package/dist/{chunk-3K7JAFGM.mjs → chunk-TFSMXQYS.mjs} +2 -2
- package/dist/components/copilot-provider/copilotkit-props.d.ts +4 -0
- package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.js +46 -13
- package/dist/components/copilot-provider/copilotkit.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.mjs +2 -2
- package/dist/components/copilot-provider/index.js +46 -13
- package/dist/components/copilot-provider/index.js.map +1 -1
- package/dist/components/copilot-provider/index.mjs +2 -2
- package/dist/components/index.js +46 -13
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +2 -2
- package/dist/context/copilot-context.d.ts +18 -8
- package/dist/context/copilot-context.js +10 -5
- package/dist/context/copilot-context.js.map +1 -1
- package/dist/context/copilot-context.mjs +1 -1
- package/dist/context/index.d.ts +2 -1
- package/dist/context/index.js +10 -5
- package/dist/context/index.js.map +1 -1
- package/dist/context/index.mjs +1 -1
- package/dist/hooks/index.d.ts +4 -2
- package/dist/hooks/index.js +205 -89
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +17 -17
- package/dist/hooks/use-chat.d.ts +24 -7
- package/dist/hooks/use-chat.js +51 -30
- package/dist/hooks/use-chat.js.map +1 -1
- package/dist/hooks/use-chat.mjs +1 -1
- package/dist/hooks/use-coagent-action.d.ts +5 -0
- package/dist/hooks/{use-copilot-chat-ui.js → use-coagent-action.js} +48 -22
- package/dist/hooks/use-coagent-action.js.map +1 -0
- package/dist/hooks/use-coagent-action.mjs +9 -0
- package/dist/hooks/use-coagent.d.ts +14 -18
- package/dist/hooks/use-coagent.js +184 -17
- package/dist/hooks/use-coagent.js.map +1 -1
- package/dist/hooks/use-coagent.mjs +6 -20
- package/dist/hooks/use-coagent.mjs.map +1 -1
- package/dist/hooks/use-copilot-action.js +10 -5
- package/dist/hooks/use-copilot-action.js.map +1 -1
- package/dist/hooks/use-copilot-action.mjs +2 -2
- package/dist/hooks/use-copilot-chat.js +89 -37
- package/dist/hooks/use-copilot-chat.js.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +4 -4
- package/dist/hooks/use-copilot-readable.js +10 -5
- package/dist/hooks/use-copilot-readable.js.map +1 -1
- package/dist/hooks/use-copilot-readable.mjs +2 -2
- package/dist/hooks/use-make-copilot-document-readable.js +10 -5
- package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
- package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +263 -119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -21
- package/dist/lib/copilot-task.d.ts +2 -1
- package/dist/lib/copilot-task.js.map +1 -1
- package/dist/lib/copilot-task.mjs +3 -3
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +3 -3
- package/dist/types/coagent-action.d.ts +17 -0
- package/dist/types/coagent-action.js +19 -0
- package/dist/types/coagent-action.js.map +1 -0
- package/dist/types/coagent-action.mjs +1 -0
- package/dist/types/coagent-state.d.ts +11 -0
- package/dist/types/coagent-state.js +19 -0
- package/dist/types/coagent-state.js.map +1 -0
- package/dist/types/coagent-state.mjs +1 -0
- package/dist/types/coagent-state.mjs.map +1 -0
- package/dist/utils/extract.d.ts +2 -1
- package/dist/utils/extract.js.map +1 -1
- package/dist/utils/extract.mjs +3 -3
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +3 -3
- package/package.json +5 -5
- package/src/components/copilot-provider/copilotkit-props.tsx +5 -0
- package/src/components/copilot-provider/copilotkit.tsx +41 -9
- package/src/context/copilot-context.tsx +34 -15
- package/src/hooks/index.ts +2 -2
- package/src/hooks/use-chat.ts +88 -38
- package/src/hooks/use-coagent-action.ts +44 -0
- package/src/hooks/use-coagent.ts +111 -38
- package/src/hooks/use-copilot-chat.ts +29 -2
- package/src/types/coagent-action.ts +17 -0
- package/src/types/coagent-state.ts +9 -0
- package/dist/chunk-52M7642J.mjs.map +0 -1
- package/dist/chunk-6YOQY4WD.mjs +0 -20
- package/dist/chunk-6YOQY4WD.mjs.map +0 -1
- package/dist/chunk-A47L32JN.mjs +0 -52
- package/dist/chunk-A47L32JN.mjs.map +0 -1
- package/dist/chunk-AIWDXM7L.mjs +0 -1
- package/dist/chunk-DB4VWZ5Q.mjs.map +0 -1
- package/dist/chunk-DZH3HSXW.mjs.map +0 -1
- package/dist/chunk-IF6P5ZXR.mjs.map +0 -1
- package/dist/hooks/use-agent-state.d.ts +0 -12
- package/dist/hooks/use-agent-state.js +0 -499
- package/dist/hooks/use-agent-state.js.map +0 -1
- package/dist/hooks/use-agent-state.mjs +0 -19
- package/dist/hooks/use-copilot-chat-ui.d.ts +0 -13
- package/dist/hooks/use-copilot-chat-ui.js.map +0 -1
- package/dist/hooks/use-copilot-chat-ui.mjs +0 -10
- package/src/hooks/use-agent-state.ts +0 -63
- package/src/hooks/use-copilot-chat-ui.ts +0 -26
- /package/dist/{chunk-2MQX7BJL.mjs.map → chunk-6GOM3DN7.mjs.map} +0 -0
- /package/dist/{chunk-73KBO5JG.mjs.map → chunk-73YBF52D.mjs.map} +0 -0
- /package/dist/{chunk-AIWDXM7L.mjs.map → chunk-BWYAGPEF.mjs.map} +0 -0
- /package/dist/{chunk-33ERMMNX.mjs.map → chunk-DU7PVINC.mjs.map} +0 -0
- /package/dist/{chunk-H4XENJME.mjs.map → chunk-SYJIZLOI.mjs.map} +0 -0
- /package/dist/{chunk-3K7JAFGM.mjs.map → chunk-TFSMXQYS.mjs.map} +0 -0
- /package/dist/hooks/{use-agent-state.mjs.map → use-coagent-action.mjs.map} +0 -0
- /package/dist/{hooks/use-copilot-chat-ui.mjs.map → types/coagent-action.mjs.map} +0 -0
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
CopilotApiConfig,
|
|
37
37
|
InChatRenderFunction,
|
|
38
38
|
ChatComponentsCache,
|
|
39
|
+
AgentSession,
|
|
39
40
|
} from "../../context/copilot-context";
|
|
40
41
|
import useTree from "../../hooks/use-tree";
|
|
41
42
|
import { CopilotChatSuggestionConfiguration, DocumentPointer } from "../../types";
|
|
@@ -50,7 +51,8 @@ import { AgentStateMessage, Message } from "@copilotkit/runtime-client-gql";
|
|
|
50
51
|
import { FrontendAction } from "../../types/frontend-action";
|
|
51
52
|
import useFlatCategoryStore from "../../hooks/use-flat-category-store";
|
|
52
53
|
import { CopilotKitProps } from "./copilotkit-props";
|
|
53
|
-
import {
|
|
54
|
+
import { CoagentAction } from "../../types/coagent-action";
|
|
55
|
+
import { CoagentState } from "../../types/coagent-state";
|
|
54
56
|
|
|
55
57
|
export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
56
58
|
// Compute all the functions and properties that we need to pass
|
|
@@ -65,7 +67,11 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
65
67
|
const chatApiEndpoint = props.runtimeUrl || COPILOT_CLOUD_CHAT_URL;
|
|
66
68
|
|
|
67
69
|
const [actions, setActions] = useState<Record<string, FrontendAction<any>>>({});
|
|
68
|
-
const
|
|
70
|
+
const [coagentActions, setCoagentActions] = useState<Record<string, CoagentAction<any>>>({});
|
|
71
|
+
const chatComponentsCache = useRef<ChatComponentsCache>({
|
|
72
|
+
actions: {},
|
|
73
|
+
coagentActions: {},
|
|
74
|
+
});
|
|
69
75
|
const { addElement, removeElement, printTree } = useTree();
|
|
70
76
|
const [messages, setMessages] = useState<Message[]>([]);
|
|
71
77
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -94,6 +100,23 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
94
100
|
});
|
|
95
101
|
}, []);
|
|
96
102
|
|
|
103
|
+
const setCoagentAction = useCallback((id: string, action: CoagentAction<any>) => {
|
|
104
|
+
setCoagentActions((prevPoints) => {
|
|
105
|
+
return {
|
|
106
|
+
...prevPoints,
|
|
107
|
+
[id]: action,
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
const removeCoagentAction = useCallback((id: string) => {
|
|
113
|
+
setCoagentActions((prevPoints) => {
|
|
114
|
+
const newPoints = { ...prevPoints };
|
|
115
|
+
delete newPoints[id];
|
|
116
|
+
return newPoints;
|
|
117
|
+
});
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
97
120
|
const getContextString = useCallback(
|
|
98
121
|
(documents: DocumentPointer[], categories: string[]) => {
|
|
99
122
|
const documentsString = documents
|
|
@@ -208,9 +231,15 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
208
231
|
});
|
|
209
232
|
};
|
|
210
233
|
|
|
211
|
-
const [
|
|
234
|
+
const [coagentStates, setCoagentStates] = useState<Record<string, CoagentState>>({});
|
|
235
|
+
let initialAgentSession: AgentSession | null = null;
|
|
236
|
+
if (props.agent) {
|
|
237
|
+
initialAgentSession = {
|
|
238
|
+
agentName: props.agent,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
212
241
|
|
|
213
|
-
const [
|
|
242
|
+
const [agentSession, setAgentSession] = useState<AgentSession | null>(initialAgentSession);
|
|
214
243
|
|
|
215
244
|
return (
|
|
216
245
|
<CopilotContext.Provider
|
|
@@ -220,6 +249,9 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
220
249
|
getFunctionCallHandler,
|
|
221
250
|
setAction,
|
|
222
251
|
removeAction,
|
|
252
|
+
coagentActions,
|
|
253
|
+
setCoagentAction,
|
|
254
|
+
removeCoagentAction,
|
|
223
255
|
getContextString,
|
|
224
256
|
addContext,
|
|
225
257
|
removeContext,
|
|
@@ -237,10 +269,10 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
237
269
|
chatInstructions,
|
|
238
270
|
setChatInstructions,
|
|
239
271
|
showDevConsole: props.showDevConsole === undefined ? "auto" : props.showDevConsole,
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
272
|
+
coagentStates,
|
|
273
|
+
setCoagentStates,
|
|
274
|
+
agentSession,
|
|
275
|
+
setAgentSession,
|
|
244
276
|
}}
|
|
245
277
|
>
|
|
246
278
|
{children}
|
|
@@ -263,7 +295,7 @@ function entryPointsToFunctionCallHandler(actions: FrontendAction<any>[]): Funct
|
|
|
263
295
|
await new Promise<void>((resolve, reject) => {
|
|
264
296
|
flushSync(async () => {
|
|
265
297
|
try {
|
|
266
|
-
result = await action.handler(args);
|
|
298
|
+
result = await action.handler?.(args);
|
|
267
299
|
resolve();
|
|
268
300
|
} catch (error) {
|
|
269
301
|
reject(error);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { CopilotCloudConfig, FunctionCallHandler } from "@copilotkit/shared";
|
|
2
|
-
import {
|
|
2
|
+
import { Message } from "@copilotkit/runtime-client-gql";
|
|
3
3
|
import { ActionRenderProps, FrontendAction } from "../types/frontend-action";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { TreeNodeId } from "../hooks/use-tree";
|
|
6
6
|
import { DocumentPointer } from "../types";
|
|
7
7
|
import { CopilotChatSuggestionConfiguration } from "../types/chat-suggestion-configuration";
|
|
8
|
-
import {
|
|
8
|
+
import { CoagentAction, CoagentActionRenderProps } from "../types/coagent-action";
|
|
9
|
+
import { CoagentState } from "../types/coagent-state";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Interface for the configuration of the Copilot API.
|
|
@@ -68,10 +69,19 @@ export interface CopilotApiConfig {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
export type InChatRenderFunction = (props: ActionRenderProps<any>) => string | JSX.Element;
|
|
72
|
+
export type CoagentInChatRenderFunction = (
|
|
73
|
+
props: CoagentActionRenderProps<any>,
|
|
74
|
+
) => string | JSX.Element;
|
|
71
75
|
|
|
72
76
|
export interface ChatComponentsCache {
|
|
73
77
|
actions: Record<string, InChatRenderFunction | string>;
|
|
74
|
-
|
|
78
|
+
coagentActions: Record<string, CoagentInChatRenderFunction | string>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface AgentSession {
|
|
82
|
+
agentName: string;
|
|
83
|
+
threadId?: string;
|
|
84
|
+
nodeName?: string;
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
export interface CopilotContextParams {
|
|
@@ -79,6 +89,12 @@ export interface CopilotContextParams {
|
|
|
79
89
|
actions: Record<string, FrontendAction<any>>;
|
|
80
90
|
setAction: (id: string, action: FrontendAction<any>) => void;
|
|
81
91
|
removeAction: (id: string) => void;
|
|
92
|
+
|
|
93
|
+
// coagent actions
|
|
94
|
+
coagentActions: Record<string, CoagentAction<any>>;
|
|
95
|
+
setCoagentAction: (id: string, action: CoagentAction<any>) => void;
|
|
96
|
+
removeCoagentAction: (id: string) => void;
|
|
97
|
+
|
|
82
98
|
chatComponentsCache: React.RefObject<ChatComponentsCache>;
|
|
83
99
|
|
|
84
100
|
getFunctionCallHandler: (
|
|
@@ -117,13 +133,11 @@ export interface CopilotContextParams {
|
|
|
117
133
|
|
|
118
134
|
showDevConsole: boolean | "auto";
|
|
119
135
|
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
chatUI: CopilotChatUI[];
|
|
126
|
-
setChatUI: React.Dispatch<React.SetStateAction<CopilotChatUI[]>>;
|
|
136
|
+
// agents
|
|
137
|
+
coagentStates: Record<string, CoagentState>;
|
|
138
|
+
setCoagentStates: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;
|
|
139
|
+
agentSession: AgentSession | null;
|
|
140
|
+
setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;
|
|
127
141
|
}
|
|
128
142
|
|
|
129
143
|
const emptyCopilotContext: CopilotContextParams = {
|
|
@@ -131,7 +145,11 @@ const emptyCopilotContext: CopilotContextParams = {
|
|
|
131
145
|
setAction: () => {},
|
|
132
146
|
removeAction: () => {},
|
|
133
147
|
|
|
134
|
-
|
|
148
|
+
coagentActions: {},
|
|
149
|
+
setCoagentAction: () => {},
|
|
150
|
+
removeCoagentAction: () => {},
|
|
151
|
+
|
|
152
|
+
chatComponentsCache: { current: { actions: {}, coagentActions: {} } },
|
|
135
153
|
getContextString: (documents: DocumentPointer[], categories: string[]) =>
|
|
136
154
|
returnAndThrowInDebug(""),
|
|
137
155
|
addContext: () => "",
|
|
@@ -169,10 +187,11 @@ const emptyCopilotContext: CopilotContextParams = {
|
|
|
169
187
|
addChatSuggestionConfiguration: () => {},
|
|
170
188
|
removeChatSuggestionConfiguration: () => {},
|
|
171
189
|
showDevConsole: "auto",
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
190
|
+
coagentStates: {},
|
|
191
|
+
setCoagentStates: () => {},
|
|
192
|
+
|
|
193
|
+
agentSession: null,
|
|
194
|
+
setAgentSession: () => {},
|
|
176
195
|
};
|
|
177
196
|
|
|
178
197
|
export const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);
|
package/src/hooks/index.ts
CHANGED
|
@@ -3,8 +3,8 @@ export type { UseCopilotChatOptions } from "./use-copilot-chat";
|
|
|
3
3
|
export type { UseCopilotChatReturn } from "./use-copilot-chat";
|
|
4
4
|
|
|
5
5
|
export { useCopilotAction } from "./use-copilot-action";
|
|
6
|
+
export { useCoagentAction } from "./use-coagent-action";
|
|
6
7
|
export { useMakeCopilotDocumentReadable } from "./use-make-copilot-document-readable";
|
|
7
8
|
export { type UseChatHelpers } from "./use-chat";
|
|
8
9
|
export { useCopilotReadable } from "./use-copilot-readable";
|
|
9
|
-
export {
|
|
10
|
-
export { useCopilotChatUI } from "./use-copilot-chat-ui";
|
|
10
|
+
export { useCoagent } from "./use-coagent";
|
package/src/hooks/use-chat.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { useRef } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
FunctionCallHandler,
|
|
4
4
|
COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,
|
|
5
|
-
Action,
|
|
6
5
|
actionParametersToJsonSchema,
|
|
6
|
+
CoagentActionHandler,
|
|
7
7
|
} from "@copilotkit/shared";
|
|
8
8
|
import {
|
|
9
9
|
Message,
|
|
@@ -21,6 +21,9 @@ import {
|
|
|
21
21
|
} from "@copilotkit/runtime-client-gql";
|
|
22
22
|
|
|
23
23
|
import { CopilotApiConfig } from "../context";
|
|
24
|
+
import { FrontendAction } from "../types/frontend-action";
|
|
25
|
+
import { CoagentState } from "../types/coagent-state";
|
|
26
|
+
import { AgentSession } from "../context/copilot-context";
|
|
24
27
|
|
|
25
28
|
export type UseChatOptions = {
|
|
26
29
|
/**
|
|
@@ -33,10 +36,16 @@ export type UseChatOptions = {
|
|
|
33
36
|
* automatically to the API and will be used to update the chat.
|
|
34
37
|
*/
|
|
35
38
|
onFunctionCall?: FunctionCallHandler;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Callback function to be called when a coagent action is received.
|
|
42
|
+
*/
|
|
43
|
+
onCoagentAction?: CoagentActionHandler;
|
|
44
|
+
|
|
36
45
|
/**
|
|
37
46
|
* Function definitions to be sent to the API.
|
|
38
47
|
*/
|
|
39
|
-
actions:
|
|
48
|
+
actions: FrontendAction<any>[];
|
|
40
49
|
|
|
41
50
|
/**
|
|
42
51
|
* The CopilotKit API configuration.
|
|
@@ -67,10 +76,25 @@ export type UseChatOptions = {
|
|
|
67
76
|
*/
|
|
68
77
|
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
|
69
78
|
|
|
79
|
+
/**
|
|
80
|
+
* The current list of coagent states.
|
|
81
|
+
*/
|
|
82
|
+
coagentStates: Record<string, CoagentState>;
|
|
83
|
+
|
|
70
84
|
/**
|
|
71
85
|
* setState-powered method to update the agent states
|
|
72
86
|
*/
|
|
73
|
-
|
|
87
|
+
setCoagentStates: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The current agent session.
|
|
91
|
+
*/
|
|
92
|
+
agentSession: AgentSession | null;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* setState-powered method to update the agent session
|
|
96
|
+
*/
|
|
97
|
+
setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;
|
|
74
98
|
};
|
|
75
99
|
|
|
76
100
|
export type UseChatHelpers = {
|
|
@@ -92,12 +116,6 @@ export type UseChatHelpers = {
|
|
|
92
116
|
stop: () => void;
|
|
93
117
|
};
|
|
94
118
|
|
|
95
|
-
interface AgentSession {
|
|
96
|
-
threadId: string;
|
|
97
|
-
agentName: string;
|
|
98
|
-
nodeName: string;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
119
|
export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
102
120
|
const {
|
|
103
121
|
messages,
|
|
@@ -109,13 +127,16 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
109
127
|
isLoading,
|
|
110
128
|
actions,
|
|
111
129
|
onFunctionCall,
|
|
112
|
-
|
|
130
|
+
onCoagentAction,
|
|
131
|
+
setCoagentStates,
|
|
132
|
+
coagentStates,
|
|
133
|
+
agentSession,
|
|
134
|
+
setAgentSession,
|
|
113
135
|
} = options;
|
|
114
136
|
|
|
115
137
|
const abortControllerRef = useRef<AbortController>();
|
|
116
138
|
const threadIdRef = useRef<string | null>(null);
|
|
117
139
|
const runIdRef = useRef<string | null>(null);
|
|
118
|
-
const agentSessionRef = useRef<AgentSession | null>(null);
|
|
119
140
|
|
|
120
141
|
const publicApiKey = copilotConfig.publicApiKey;
|
|
121
142
|
|
|
@@ -185,15 +206,15 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
185
206
|
metadata: {
|
|
186
207
|
requestType: CopilotRequestType.Chat,
|
|
187
208
|
},
|
|
188
|
-
...(
|
|
209
|
+
...(agentSession
|
|
189
210
|
? {
|
|
190
|
-
agentSession
|
|
191
|
-
threadId: agentSessionRef.current.threadId,
|
|
192
|
-
agentName: agentSessionRef.current.agentName,
|
|
193
|
-
nodeName: agentSessionRef.current.nodeName,
|
|
194
|
-
},
|
|
211
|
+
agentSession,
|
|
195
212
|
}
|
|
196
213
|
: {}),
|
|
214
|
+
agentStates: Object.values(coagentStates).map((state) => ({
|
|
215
|
+
agentName: state.name,
|
|
216
|
+
state: JSON.stringify(state.state),
|
|
217
|
+
})),
|
|
197
218
|
},
|
|
198
219
|
properties: copilotConfig.properties,
|
|
199
220
|
signal: abortControllerRef.current?.signal,
|
|
@@ -205,7 +226,8 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
205
226
|
|
|
206
227
|
const reader = stream.getReader();
|
|
207
228
|
|
|
208
|
-
let
|
|
229
|
+
let actionResults: { [id: string]: string } = {};
|
|
230
|
+
let executedCoagentActions: string[] = [];
|
|
209
231
|
|
|
210
232
|
try {
|
|
211
233
|
while (true) {
|
|
@@ -250,22 +272,25 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
250
272
|
|
|
251
273
|
if (message instanceof AgentStateMessage) {
|
|
252
274
|
if (message.running) {
|
|
253
|
-
|
|
275
|
+
setCoagentStates((prevAgentStates) => ({
|
|
254
276
|
...prevAgentStates,
|
|
255
|
-
[message.agentName]:
|
|
277
|
+
[message.agentName]: {
|
|
278
|
+
name: message.agentName,
|
|
279
|
+
state: message.state,
|
|
280
|
+
running: message.running,
|
|
281
|
+
active: message.active,
|
|
282
|
+
threadId: message.threadId,
|
|
283
|
+
nodeName: message.nodeName,
|
|
284
|
+
runId: message.runId,
|
|
285
|
+
},
|
|
256
286
|
}));
|
|
257
|
-
|
|
287
|
+
setAgentSession({
|
|
258
288
|
threadId: message.threadId,
|
|
259
289
|
agentName: message.agentName,
|
|
260
290
|
nodeName: message.nodeName,
|
|
261
|
-
};
|
|
262
|
-
} else {
|
|
263
|
-
setAgentStates((prevAgentStates) => {
|
|
264
|
-
const newAgentStates = { ...prevAgentStates };
|
|
265
|
-
delete newAgentStates[message.agentName];
|
|
266
|
-
return newAgentStates;
|
|
267
291
|
});
|
|
268
|
-
|
|
292
|
+
} else {
|
|
293
|
+
setAgentSession(null);
|
|
269
294
|
}
|
|
270
295
|
}
|
|
271
296
|
|
|
@@ -276,7 +301,7 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
276
301
|
message.scope === "client" &&
|
|
277
302
|
onFunctionCall
|
|
278
303
|
) {
|
|
279
|
-
if (!(message.id in
|
|
304
|
+
if (!(message.id in actionResults)) {
|
|
280
305
|
// Do not execute a function call if guardrails are enabled but the status is not known
|
|
281
306
|
if (guardrailsEnabled && value.generateCopilotResponse.status === undefined) {
|
|
282
307
|
break;
|
|
@@ -287,18 +312,38 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
287
312
|
name: message.name,
|
|
288
313
|
args: message.arguments,
|
|
289
314
|
});
|
|
290
|
-
|
|
315
|
+
actionResults[message.id] = result;
|
|
291
316
|
}
|
|
292
317
|
|
|
293
318
|
// add the result message
|
|
294
319
|
newMessages.push(
|
|
295
320
|
new ResultMessage({
|
|
296
|
-
result: ResultMessage.encodeResult(
|
|
321
|
+
result: ResultMessage.encodeResult(actionResults[message.id]),
|
|
297
322
|
actionExecutionId: message.id,
|
|
298
323
|
actionName: message.name,
|
|
299
324
|
}),
|
|
300
325
|
);
|
|
301
326
|
}
|
|
327
|
+
|
|
328
|
+
// execute coagent actions
|
|
329
|
+
if (
|
|
330
|
+
message instanceof AgentStateMessage &&
|
|
331
|
+
!message.active &&
|
|
332
|
+
!executedCoagentActions.includes(message.id) &&
|
|
333
|
+
onCoagentAction
|
|
334
|
+
) {
|
|
335
|
+
// Do not execute a coagent action if guardrails are enabled but the status is not known
|
|
336
|
+
if (guardrailsEnabled && value.generateCopilotResponse.status === undefined) {
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
// execute coagent action
|
|
340
|
+
await onCoagentAction({
|
|
341
|
+
name: message.agentName,
|
|
342
|
+
nodeName: message.nodeName,
|
|
343
|
+
state: message.state,
|
|
344
|
+
});
|
|
345
|
+
executedCoagentActions.push(message.id);
|
|
346
|
+
}
|
|
302
347
|
}
|
|
303
348
|
}
|
|
304
349
|
|
|
@@ -308,11 +353,16 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
308
353
|
const filteredMessages = [...previousMessages, ...newMessages].reduce(
|
|
309
354
|
(acc: Message[], message: Message) => {
|
|
310
355
|
if (
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
356
|
+
// If the current message is an AgentStateMessage
|
|
357
|
+
message instanceof AgentStateMessage &&
|
|
358
|
+
// And there is at least one message in the accumulator
|
|
359
|
+
acc.length > 0 &&
|
|
360
|
+
// And the last message in the accumulator is also an AgentStateMessage
|
|
361
|
+
acc[acc.length - 1] instanceof AgentStateMessage &&
|
|
362
|
+
// And the agentName, nodeName, and runId are the same
|
|
363
|
+
(acc[acc.length - 1] as AgentStateMessage).agentName === message.agentName &&
|
|
364
|
+
(acc[acc.length - 1] as AgentStateMessage).nodeName === message.nodeName &&
|
|
365
|
+
(acc[acc.length - 1] as AgentStateMessage).runId === message.runId
|
|
316
366
|
) {
|
|
317
367
|
// If the conditions are met, replace the last message in the accumulator with the current message
|
|
318
368
|
acc[acc.length - 1] = message;
|
|
@@ -320,7 +370,7 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
320
370
|
// Otherwise, add the current message to the accumulator
|
|
321
371
|
acc.push(message);
|
|
322
372
|
}
|
|
323
|
-
return acc;
|
|
373
|
+
return acc;
|
|
324
374
|
},
|
|
325
375
|
[],
|
|
326
376
|
);
|
|
@@ -332,7 +382,7 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
|
|
|
332
382
|
|
|
333
383
|
if (
|
|
334
384
|
// if we have client side results
|
|
335
|
-
Object.values(
|
|
385
|
+
Object.values(actionResults).length ||
|
|
336
386
|
// or the last message we received is a result
|
|
337
387
|
(newMessages.length && newMessages[newMessages.length - 1] instanceof ResultMessage)
|
|
338
388
|
) {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useRef, useContext, useEffect } from "react";
|
|
2
|
+
import { CopilotContext } from "../context/copilot-context";
|
|
3
|
+
import { randomId } from "@copilotkit/shared";
|
|
4
|
+
import { CoagentAction } from "../types/coagent-action";
|
|
5
|
+
|
|
6
|
+
// We implement useCoagentAction dependency handling so that
|
|
7
|
+
// the developer has the option to not provide any dependencies.
|
|
8
|
+
// see useCopilotAction for more details about this approach.
|
|
9
|
+
export function useCoagentAction<T = any>(action: CoagentAction<T>, dependencies?: any[]): void {
|
|
10
|
+
const { setCoagentAction, removeCoagentAction, coagentActions, chatComponentsCache } =
|
|
11
|
+
useContext(CopilotContext);
|
|
12
|
+
const idRef = useRef<string>(randomId());
|
|
13
|
+
|
|
14
|
+
const key = `${action.name}-${action.nodeName || "global"}`;
|
|
15
|
+
|
|
16
|
+
if (dependencies === undefined) {
|
|
17
|
+
if (coagentActions[idRef.current]) {
|
|
18
|
+
coagentActions[idRef.current].handler = action.handler as any;
|
|
19
|
+
if (typeof action.render === "function") {
|
|
20
|
+
if (chatComponentsCache.current !== null) {
|
|
21
|
+
chatComponentsCache.current.coagentActions[key] = action.render;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setCoagentAction(idRef.current, action as any);
|
|
29
|
+
if (chatComponentsCache.current !== null && action.render !== undefined) {
|
|
30
|
+
chatComponentsCache.current.coagentActions[key] = action.render;
|
|
31
|
+
}
|
|
32
|
+
return () => {
|
|
33
|
+
removeCoagentAction(idRef.current);
|
|
34
|
+
};
|
|
35
|
+
}, [
|
|
36
|
+
setCoagentAction,
|
|
37
|
+
removeCoagentAction,
|
|
38
|
+
action.name,
|
|
39
|
+
// include render only if it's a string
|
|
40
|
+
typeof action.render === "string" ? action.render : undefined,
|
|
41
|
+
// dependencies set by the developer
|
|
42
|
+
...(dependencies || []),
|
|
43
|
+
]);
|
|
44
|
+
}
|
package/src/hooks/use-coagent.ts
CHANGED
|
@@ -1,40 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useCopilotContext } from "../context";
|
|
3
|
+
import { CoagentState } from "../types/coagent-state";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
interface WithInternalStateManagementAndInitial<T> {
|
|
6
|
+
name: string;
|
|
7
|
+
initialState: T;
|
|
5
8
|
}
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const [story, setStory] = useState({
|
|
12
|
-
story: "dasfsdf",
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const { nodeName } = useCoagent({
|
|
16
|
-
name: "myAgent",
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
// what do we need from useCoagent?
|
|
20
|
-
// - nodeName
|
|
21
|
-
// - threadId
|
|
22
|
-
// - running
|
|
23
|
-
// - state
|
|
24
|
-
|
|
25
|
-
export function useCopilotAction<T = any>(coagentAction: CoagentAction<T>) {
|
|
26
|
-
throw new Error("Not implemented");
|
|
10
|
+
interface WithInternalStateManagement {
|
|
11
|
+
name: string;
|
|
12
|
+
initialState?: any; // Optional initialState with default type any
|
|
27
13
|
}
|
|
28
14
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export interface UseCoagentOptions<T> {
|
|
15
|
+
interface WithExternalStateManagement<T> {
|
|
32
16
|
name: string;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
setState?: (newState: T | ((prevState: T | undefined) => T)) => void;
|
|
17
|
+
state: T;
|
|
18
|
+
setState: (newState: T | ((prevState: T | undefined) => T)) => void;
|
|
36
19
|
}
|
|
37
20
|
|
|
21
|
+
type UseCoagentOptions<T> =
|
|
22
|
+
| WithInternalStateManagementAndInitial<T>
|
|
23
|
+
| WithInternalStateManagement
|
|
24
|
+
| WithExternalStateManagement<T>;
|
|
25
|
+
|
|
38
26
|
export interface UseCoagentReturnType<T> {
|
|
39
27
|
name: string;
|
|
40
28
|
nodeName?: string;
|
|
@@ -46,15 +34,100 @@ export interface UseCoagentReturnType<T> {
|
|
|
46
34
|
stop: () => void;
|
|
47
35
|
}
|
|
48
36
|
|
|
49
|
-
export
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
export function useCoagent<T = any>(options: UseCoagentOptions<T>): UseCoagentReturnType<T> {
|
|
38
|
+
const isExternalStateManagement = (
|
|
39
|
+
options: UseCoagentOptions<T>,
|
|
40
|
+
): options is WithExternalStateManagement<T> => {
|
|
41
|
+
return "state" in options && "setState" in options;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const { name } = options;
|
|
45
|
+
|
|
46
|
+
const isInternalStateManagementWithInitial = (
|
|
47
|
+
options: UseCoagentOptions<T>,
|
|
48
|
+
): options is WithInternalStateManagementAndInitial<T> => {
|
|
49
|
+
return "initialState" in options;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const { coagentStates, setCoagentStates } = useCopilotContext();
|
|
53
|
+
|
|
54
|
+
const getCoagentState = (coagentStates: Record<string, CoagentState>, name: string) => {
|
|
55
|
+
if (coagentStates[name]) {
|
|
56
|
+
return coagentStates[name];
|
|
57
|
+
} else {
|
|
58
|
+
return {
|
|
59
|
+
name,
|
|
60
|
+
state: isInternalStateManagementWithInitial(options) ? options.initialState : {},
|
|
61
|
+
running: false,
|
|
62
|
+
active: false,
|
|
63
|
+
threadId: undefined,
|
|
64
|
+
nodeName: undefined,
|
|
65
|
+
runId: undefined,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// if we manage state internally, we need to provide a function to set the state
|
|
71
|
+
const setState = (newState: T | ((prevState: T | undefined) => T)) => {
|
|
72
|
+
setCoagentStates((prevAgentStates) => {
|
|
73
|
+
let coagentState: CoagentState = getCoagentState(prevAgentStates, name);
|
|
74
|
+
|
|
75
|
+
const updatedState =
|
|
76
|
+
typeof newState === "function" ? (newState as Function)(coagentState.state) : newState;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
...prevAgentStates,
|
|
80
|
+
[name]: {
|
|
81
|
+
...coagentState,
|
|
82
|
+
state: updatedState,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const coagentState = getCoagentState(coagentStates, name);
|
|
89
|
+
|
|
90
|
+
const state = isExternalStateManagement(options) ? options.state : coagentState.state;
|
|
91
|
+
|
|
92
|
+
// Sync internal state with external state if state management is external
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (isExternalStateManagement(options)) {
|
|
95
|
+
setState(options.state);
|
|
96
|
+
} else if (coagentStates[name] === undefined) {
|
|
97
|
+
setState(options.initialState === undefined ? {} : options.initialState);
|
|
98
|
+
}
|
|
99
|
+
}, [isExternalStateManagement(options) ? JSON.stringify(options.state) : undefined]);
|
|
100
|
+
|
|
101
|
+
// Return the state and setState function
|
|
102
|
+
return {
|
|
103
|
+
name,
|
|
104
|
+
nodeName: coagentState.nodeName,
|
|
105
|
+
state,
|
|
106
|
+
setState,
|
|
107
|
+
running: coagentState.running,
|
|
108
|
+
start: () => {
|
|
109
|
+
startAgent(name);
|
|
110
|
+
},
|
|
111
|
+
stop: () => {
|
|
112
|
+
stopAgent(name);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function startAgent(name: string) {
|
|
118
|
+
const { setAgentSession } = useCopilotContext();
|
|
119
|
+
setAgentSession({
|
|
120
|
+
agentName: name,
|
|
121
|
+
});
|
|
53
122
|
}
|
|
54
123
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
124
|
+
function stopAgent(name: string) {
|
|
125
|
+
const { agentSession, setAgentSession } = useCopilotContext();
|
|
126
|
+
if (agentSession && agentSession.agentName === name) {
|
|
127
|
+
setAgentSession(null);
|
|
128
|
+
} else {
|
|
129
|
+
console.warn(`No agent session found for ${name}`);
|
|
130
|
+
}
|
|
60
131
|
}
|
|
132
|
+
|
|
133
|
+
// <CopilotKit agent="lockedInAgentName" />
|