@copilotkit/react-core 0.21.0-mme-assistant-api.0 → 0.21.0-mme-function-call-labels.2
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/.turbo/turbo-build.log +146 -127
- package/CHANGELOG.md +26 -2
- package/dist/{chunk-2EP7VLPI.mjs → chunk-4VUJYN3U.mjs} +2 -2
- package/dist/{chunk-PHK2K7UB.mjs → chunk-5TE3LHXD.mjs} +19 -25
- package/dist/chunk-5TE3LHXD.mjs.map +1 -0
- package/dist/{chunk-UHTJLRI6.mjs → chunk-5VLCJLRQ.mjs} +7 -7
- package/dist/chunk-5VLCJLRQ.mjs.map +1 -0
- package/dist/{chunk-2YF2MC22.mjs → chunk-AEUR5JBT.mjs} +42 -22
- package/dist/chunk-AEUR5JBT.mjs.map +1 -0
- package/dist/{chunk-S7ZVOTYK.mjs → chunk-DVLYNQG4.mjs} +2 -1
- package/dist/chunk-DVLYNQG4.mjs.map +1 -0
- package/dist/chunk-IOP6JX34.mjs +1 -0
- package/dist/{chunk-WH4L73VS.mjs → chunk-NNUIXO74.mjs} +7 -3
- package/dist/chunk-NNUIXO74.mjs.map +1 -0
- package/dist/{chunk-KLGA2MES.mjs → chunk-OSQO6ASW.mjs} +4 -4
- package/dist/chunk-OSQO6ASW.mjs.map +1 -0
- package/dist/chunk-UQKARKHD.mjs +95 -0
- package/dist/chunk-UQKARKHD.mjs.map +1 -0
- package/dist/chunk-WCI6UGKK.mjs +13 -0
- package/dist/chunk-WCI6UGKK.mjs.map +1 -0
- package/dist/{chunk-6WZFE6II.mjs → chunk-XDKLZEPZ.mjs} +3 -3
- package/dist/{chunk-JVCBCB2T.mjs → chunk-ZAB22RCR.mjs} +2 -2
- package/dist/components/copilot-provider/copilotkit.js +13 -16
- package/dist/components/copilot-provider/copilotkit.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.mjs +3 -3
- package/dist/components/copilot-provider/index.js +13 -16
- package/dist/components/copilot-provider/index.js.map +1 -1
- package/dist/components/copilot-provider/index.mjs +3 -3
- package/dist/components/copilot-provider/standard-copilot-api-config.d.ts +1 -0
- package/dist/components/index.js +13 -16
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +3 -3
- package/dist/context/copilot-context.d.ts +7 -5
- package/dist/context/copilot-context.js +1 -0
- package/dist/context/copilot-context.js.map +1 -1
- package/dist/context/copilot-context.mjs +1 -1
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.js +1 -0
- package/dist/context/index.js.map +1 -1
- package/dist/context/index.mjs +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +149 -34
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +16 -11
- package/dist/hooks/use-chat.d.ts +1 -0
- package/dist/hooks/use-chat.js +48 -20
- package/dist/hooks/use-chat.js.map +1 -1
- package/dist/hooks/use-chat.mjs +1 -1
- package/dist/hooks/use-copilot-action-implementation.d.ts +8 -0
- package/dist/hooks/use-copilot-action-implementation.js +190 -0
- package/dist/hooks/use-copilot-action-implementation.js.map +1 -0
- package/dist/hooks/use-copilot-action-implementation.mjs +12 -0
- package/dist/hooks/use-copilot-action-implementation.mjs.map +1 -0
- package/dist/hooks/use-copilot-action.d.ts +7 -0
- package/dist/hooks/use-copilot-action.js +148 -0
- package/dist/hooks/use-copilot-action.js.map +1 -0
- package/dist/hooks/use-copilot-action.mjs +11 -0
- package/dist/hooks/use-copilot-action.mjs.map +1 -0
- package/dist/hooks/use-copilot-chat.d.ts +1 -0
- package/dist/hooks/use-copilot-chat.js +40 -21
- package/dist/hooks/use-copilot-chat.js.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +5 -5
- package/dist/hooks/use-make-copilot-actionable.d.ts +3 -0
- package/dist/hooks/use-make-copilot-actionable.js +61 -6
- package/dist/hooks/use-make-copilot-actionable.js.map +1 -1
- package/dist/hooks/use-make-copilot-actionable.mjs +3 -2
- package/dist/hooks/use-make-copilot-document-readable.js +1 -0
- 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/hooks/use-make-copilot-readable.js +1 -0
- package/dist/hooks/use-make-copilot-readable.js.map +1 -1
- package/dist/hooks/use-make-copilot-readable.mjs +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +171 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -20
- package/dist/lib/copilot-task.d.ts +4 -3
- package/dist/lib/copilot-task.js +2 -2
- package/dist/lib/copilot-task.js.map +1 -1
- package/dist/lib/copilot-task.mjs +4 -4
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +2 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +4 -4
- package/dist/openai-assistants/hooks/index.js +1 -0
- package/dist/openai-assistants/hooks/index.js.map +1 -1
- package/dist/openai-assistants/hooks/index.mjs +4 -4
- package/dist/openai-assistants/hooks/use-copilot-chat-v2.js +1 -0
- package/dist/openai-assistants/hooks/use-copilot-chat-v2.js.map +1 -1
- package/dist/openai-assistants/hooks/use-copilot-chat-v2.mjs +4 -4
- package/dist/openai-assistants/index.js +1 -0
- package/dist/openai-assistants/index.js.map +1 -1
- package/dist/openai-assistants/index.mjs +4 -4
- package/dist/types/frontend-action.d.ts +40 -0
- package/dist/types/frontend-action.js +19 -0
- package/dist/types/frontend-action.js.map +1 -0
- package/dist/types/frontend-action.mjs +1 -0
- package/dist/types/frontend-action.mjs.map +1 -0
- package/dist/utils/fetch-chat-completion.d.ts +1 -0
- package/package.json +7 -6
- package/src/components/copilot-provider/copilotkit.tsx +20 -53
- package/src/context/copilot-context.tsx +9 -7
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-chat.ts +52 -27
- package/src/hooks/use-copilot-action-implementation.ts +114 -0
- package/src/hooks/use-copilot-action.ts +45 -0
- package/src/hooks/use-copilot-chat.ts +2 -1
- package/src/hooks/use-make-copilot-actionable.ts +6 -1
- package/src/lib/copilot-task.ts +6 -5
- package/src/types/frontend-action.ts +56 -0
- package/dist/chunk-2YF2MC22.mjs.map +0 -1
- package/dist/chunk-5UGLWBZJ.mjs +0 -1
- package/dist/chunk-KLGA2MES.mjs.map +0 -1
- package/dist/chunk-PHK2K7UB.mjs.map +0 -1
- package/dist/chunk-S7ZVOTYK.mjs.map +0 -1
- package/dist/chunk-UHTJLRI6.mjs.map +0 -1
- package/dist/chunk-WH4L73VS.mjs.map +0 -1
- /package/dist/{chunk-2EP7VLPI.mjs.map → chunk-4VUJYN3U.mjs.map} +0 -0
- /package/dist/{chunk-5UGLWBZJ.mjs.map → chunk-IOP6JX34.mjs.map} +0 -0
- /package/dist/{chunk-6WZFE6II.mjs.map → chunk-XDKLZEPZ.mjs.map} +0 -0
- /package/dist/{chunk-JVCBCB2T.mjs.map → chunk-ZAB22RCR.mjs.map} +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/types/frontend-action.ts
|
|
17
|
+
var frontend_action_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(frontend_action_exports);
|
|
19
|
+
//# sourceMappingURL=frontend-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/frontend-action.ts"],"sourcesContent":["import { Action, Parameter, MappedParameterTypes } from \"@copilotkit/shared\";\nimport React from \"react\";\n\ninterface InProgressState<T extends Parameter[] | [] = []> {\n status: \"inProgress\";\n args: Partial<MappedParameterTypes<T>>;\n result: undefined;\n}\n\ninterface ExecutingState<T extends Parameter[] | [] = []> {\n status: \"executing\";\n args: MappedParameterTypes<T>;\n result: undefined;\n}\n\ninterface CompleteState<T extends Parameter[] | [] = []> {\n status: \"complete\";\n args: MappedParameterTypes<T>;\n result: any;\n}\n\ninterface InProgressStateNoArgs<T extends Parameter[] | [] = []> {\n status: \"inProgress\";\n args: Partial<MappedParameterTypes<T>>;\n result: undefined;\n}\n\ninterface ExecutingStateNoArgs<T extends Parameter[] | [] = []> {\n status: \"executing\";\n args: MappedParameterTypes<T>;\n result: undefined;\n}\n\ninterface CompleteStateNoArgs<T extends Parameter[] | [] = []> {\n status: \"complete\";\n args: MappedParameterTypes<T>;\n result: any;\n}\n\nexport type ActionRenderProps<T extends Parameter[] | [] = []> =\n | CompleteState<T>\n | ExecutingState<T>\n | InProgressState<T>;\n\nexport type ActionRenderPropsNoArgs<T extends Parameter[] | [] = []> =\n | CompleteStateNoArgs<T>\n | ExecutingStateNoArgs<T>\n | InProgressStateNoArgs<T>;\n\nexport type FrontendAction<T extends Parameter[] | [] = []> = Action<T> & {\n render?:\n | string\n | (T extends []\n ? (props: ActionRenderPropsNoArgs<T>) => string | React.ReactElement\n : (props: ActionRenderProps<T>) => string | React.ReactElement);\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=frontend-action.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Message, ToolDefinition, ChatCompletionEvent } from '@copilotkit/shared';
|
|
2
2
|
import { CopilotApiConfig } from '../context/copilot-context.js';
|
|
3
|
+
import '../types/frontend-action.js';
|
|
3
4
|
import 'react';
|
|
4
5
|
import '../hooks/use-tree.js';
|
|
5
6
|
import '../types/document-pointer.js';
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.21.0-mme-
|
|
7
|
+
"version": "0.21.0-mme-function-call-labels.2",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"module": "./dist/index.mjs",
|
|
@@ -19,18 +19,19 @@
|
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/jest": "^29.5.4",
|
|
21
21
|
"@types/react": "^18.2.5",
|
|
22
|
-
"eslint": "^
|
|
22
|
+
"eslint": "^8.56.0",
|
|
23
23
|
"jest": "^29.6.4",
|
|
24
24
|
"react": "^18.2.0",
|
|
25
25
|
"ts-jest": "^29.1.1",
|
|
26
26
|
"tsup": "^6.7.0",
|
|
27
|
-
"typescript": "^5.
|
|
28
|
-
"eslint-config-custom": "0.6.0-mme-
|
|
29
|
-
"tsconfig": "0.10.0-mme-
|
|
27
|
+
"typescript": "^5.2.3",
|
|
28
|
+
"eslint-config-custom": "0.6.0-mme-function-call-labels.2",
|
|
29
|
+
"tsconfig": "0.10.0-mme-function-call-labels.2"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"nanoid": "^4.0.2",
|
|
33
|
-
"
|
|
33
|
+
"untruncate-json": "^0.0.1",
|
|
34
|
+
"@copilotkit/shared": "0.5.0-mme-function-call-labels.2"
|
|
34
35
|
},
|
|
35
36
|
"scripts": {
|
|
36
37
|
"build": "tsup --clean",
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { useCallback, useState } from "react";
|
|
3
|
+
import { Ref, useCallback, useRef, useState } from "react";
|
|
5
4
|
import { CopilotContext, CopilotApiConfig } from "../../context/copilot-context";
|
|
6
5
|
import useTree from "../../hooks/use-tree";
|
|
7
6
|
import { DocumentPointer } from "../../types";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
AnnotatedFunction,
|
|
11
|
-
annotatedFunctionToChatCompletionFunction,
|
|
12
|
-
} from "@copilotkit/shared";
|
|
7
|
+
import { FunctionCallHandler, actionToChatCompletionFunction } from "@copilotkit/shared";
|
|
8
|
+
import { FrontendAction } from "../../types/frontend-action";
|
|
13
9
|
import useFlatCategoryStore from "../../hooks/use-flat-category-store";
|
|
14
10
|
import { StandardCopilotApiConfig } from "./standard-copilot-api-config";
|
|
15
11
|
import { CopilotKitProps } from "./copilotkit-props";
|
|
@@ -56,8 +52,8 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
56
52
|
// Compute all the functions and properties that we need to pass
|
|
57
53
|
// to the CopilotContext.
|
|
58
54
|
|
|
59
|
-
const [entryPoints, setEntryPoints] = useState<Record<string,
|
|
60
|
-
|
|
55
|
+
const [entryPoints, setEntryPoints] = useState<Record<string, FrontendAction<any>>>({});
|
|
56
|
+
const chatComponentsCache = useRef<Record<string, Function | string>>({});
|
|
61
57
|
const { addElement, removeElement, printTree } = useTree();
|
|
62
58
|
|
|
63
59
|
const {
|
|
@@ -66,7 +62,7 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
66
62
|
allElements: allDocuments,
|
|
67
63
|
} = useFlatCategoryStore<DocumentPointer>();
|
|
68
64
|
|
|
69
|
-
const setEntryPoint = useCallback((id: string, entryPoint:
|
|
65
|
+
const setEntryPoint = useCallback((id: string, entryPoint: FrontendAction<any>) => {
|
|
70
66
|
setEntryPoints((prevPoints) => {
|
|
71
67
|
return {
|
|
72
68
|
...prevPoints,
|
|
@@ -117,14 +113,14 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
117
113
|
);
|
|
118
114
|
|
|
119
115
|
const getChatCompletionFunctionDescriptions = useCallback(
|
|
120
|
-
(customEntryPoints?: Record<string,
|
|
116
|
+
(customEntryPoints?: Record<string, FrontendAction<any>>) => {
|
|
121
117
|
return entryPointsToChatCompletionFunctions(Object.values(customEntryPoints || entryPoints));
|
|
122
118
|
},
|
|
123
119
|
[entryPoints],
|
|
124
120
|
);
|
|
125
121
|
|
|
126
122
|
const getFunctionCallHandler = useCallback(
|
|
127
|
-
(customEntryPoints?: Record<string,
|
|
123
|
+
(customEntryPoints?: Record<string, FrontendAction<any>>) => {
|
|
128
124
|
return entryPointsToFunctionCallHandler(Object.values(customEntryPoints || entryPoints));
|
|
129
125
|
},
|
|
130
126
|
[entryPoints],
|
|
@@ -166,6 +162,7 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
166
162
|
<CopilotContext.Provider
|
|
167
163
|
value={{
|
|
168
164
|
entryPoints,
|
|
165
|
+
chatComponentsCache,
|
|
169
166
|
getChatCompletionFunctionDescriptions,
|
|
170
167
|
getFunctionCallHandler,
|
|
171
168
|
setEntryPoint,
|
|
@@ -186,54 +183,24 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
186
183
|
|
|
187
184
|
export const defaultCopilotContextCategories = ["global"];
|
|
188
185
|
|
|
189
|
-
function
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
function entryPointsToChatCompletionFunctions(actions: FrontendAction<any>[]): ToolDefinition[] {
|
|
187
|
+
return actions.map(actionToChatCompletionFunction);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function entryPointsToFunctionCallHandler(actions: FrontendAction<any>[]): FunctionCallHandler {
|
|
192
191
|
return async (chatMessages, functionCall) => {
|
|
193
|
-
let
|
|
194
|
-
for (let
|
|
195
|
-
|
|
192
|
+
let actionsByFunctionName: Record<string, FrontendAction<any>> = {};
|
|
193
|
+
for (let action of actions) {
|
|
194
|
+
actionsByFunctionName[action.name] = action;
|
|
196
195
|
}
|
|
197
196
|
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
197
|
+
const action = actionsByFunctionName[functionCall.name || ""];
|
|
198
|
+
if (action) {
|
|
200
199
|
let functionCallArguments: Record<string, any>[] = [];
|
|
201
200
|
if (functionCall.arguments) {
|
|
202
201
|
functionCallArguments = JSON.parse(functionCall.arguments);
|
|
203
202
|
}
|
|
204
|
-
|
|
205
|
-
const paramsInCorrectOrder: any[] = [];
|
|
206
|
-
for (let arg of entryPointFunction.argumentAnnotations) {
|
|
207
|
-
paramsInCorrectOrder.push(
|
|
208
|
-
functionCallArguments[arg.name as keyof typeof functionCallArguments],
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
await entryPointFunction.implementation(...paramsInCorrectOrder);
|
|
213
|
-
|
|
214
|
-
// commented out becasue for now we don't want to return anything
|
|
215
|
-
// const result = await entryPointFunction.implementation(
|
|
216
|
-
// ...parsedFunctionCallArguments
|
|
217
|
-
// );
|
|
218
|
-
// const functionResponse: ChatRequest = {
|
|
219
|
-
// messages: [
|
|
220
|
-
// ...chatMessages,
|
|
221
|
-
// {
|
|
222
|
-
// id: nanoid(),
|
|
223
|
-
// name: functionCall.name,
|
|
224
|
-
// role: 'function' as const,
|
|
225
|
-
// content: JSON.stringify(result),
|
|
226
|
-
// },
|
|
227
|
-
// ],
|
|
228
|
-
// };
|
|
229
|
-
|
|
230
|
-
// return functionResponse;
|
|
203
|
+
return await action.handler(functionCallArguments);
|
|
231
204
|
}
|
|
232
205
|
};
|
|
233
206
|
}
|
|
234
|
-
|
|
235
|
-
function entryPointsToChatCompletionFunctions(
|
|
236
|
-
entryPoints: AnnotatedFunction<any[]>[],
|
|
237
|
-
): ToolDefinition[] {
|
|
238
|
-
return entryPoints.map(annotatedFunctionToChatCompletionFunction);
|
|
239
|
-
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { FunctionCallHandler,
|
|
4
|
-
import
|
|
3
|
+
import { FunctionCallHandler, ToolDefinition } from "@copilotkit/shared";
|
|
4
|
+
import { FrontendAction } from "../types/frontend-action";
|
|
5
|
+
import React, { Ref } from "react";
|
|
5
6
|
import { TreeNodeId } from "../hooks/use-tree";
|
|
6
7
|
import { DocumentPointer } from "../types";
|
|
7
8
|
|
|
@@ -58,14 +59,15 @@ export interface CopilotApiConfig {
|
|
|
58
59
|
|
|
59
60
|
export interface CopilotContextParams {
|
|
60
61
|
// function-calling
|
|
61
|
-
entryPoints: Record<string,
|
|
62
|
-
setEntryPoint: (id: string, entryPoint:
|
|
62
|
+
entryPoints: Record<string, FrontendAction<any>>;
|
|
63
|
+
setEntryPoint: (id: string, entryPoint: FrontendAction<any>) => void;
|
|
63
64
|
removeEntryPoint: (id: string) => void;
|
|
65
|
+
chatComponentsCache: React.RefObject<Record<string, Function | string>>;
|
|
64
66
|
getChatCompletionFunctionDescriptions: (
|
|
65
|
-
customEntryPoints?: Record<string,
|
|
67
|
+
customEntryPoints?: Record<string, FrontendAction<any>>,
|
|
66
68
|
) => ToolDefinition[];
|
|
67
69
|
getFunctionCallHandler: (
|
|
68
|
-
customEntryPoints?: Record<string,
|
|
70
|
+
customEntryPoints?: Record<string, FrontendAction<any>>,
|
|
69
71
|
) => FunctionCallHandler;
|
|
70
72
|
|
|
71
73
|
// text context
|
|
@@ -88,7 +90,7 @@ const emptyCopilotContext: CopilotContextParams = {
|
|
|
88
90
|
removeEntryPoint: () => {},
|
|
89
91
|
getChatCompletionFunctionDescriptions: () => returnAndThrowInDebug([]),
|
|
90
92
|
getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),
|
|
91
|
-
|
|
93
|
+
chatComponentsCache: { current: {} },
|
|
92
94
|
getContextString: (documents: DocumentPointer[], categories: string[]) =>
|
|
93
95
|
returnAndThrowInDebug(""),
|
|
94
96
|
addContext: () => "",
|
package/src/hooks/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export type { UseCopilotChatOptions } from "./use-copilot-chat";
|
|
|
3
3
|
export type { UseCopilotChatReturn } from "./use-copilot-chat";
|
|
4
4
|
|
|
5
5
|
export { useMakeCopilotActionable } from "./use-make-copilot-actionable";
|
|
6
|
+
export { useCopilotAction } from "./use-copilot-action";
|
|
6
7
|
export { useMakeCopilotReadable } from "./use-make-copilot-readable";
|
|
7
8
|
export { useMakeCopilotDocumentReadable } from "./use-make-copilot-document-readable";
|
|
8
9
|
export { type UseChatHelpers } from "./use-chat";
|
package/src/hooks/use-chat.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { useRef, useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Message,
|
|
4
|
+
ToolDefinition,
|
|
5
|
+
FunctionCallHandler,
|
|
6
|
+
encodeResult,
|
|
7
|
+
FunctionCall,
|
|
8
|
+
} from "@copilotkit/shared";
|
|
9
|
+
|
|
3
10
|
import { nanoid } from "nanoid";
|
|
4
11
|
import { fetchAndDecodeChatCompletion } from "../utils/fetch-chat-completion";
|
|
5
12
|
import { CopilotApiConfig } from "../context";
|
|
13
|
+
import untruncateJson from "untruncate-json";
|
|
6
14
|
|
|
7
15
|
export type UseChatOptions = {
|
|
8
16
|
/**
|
|
@@ -176,7 +184,7 @@ export function useChat(options: UseChatOptionsWithCopilotConfig): UseChatHelper
|
|
|
176
184
|
|
|
177
185
|
// After receiving a result, feed back the new messages to GPT
|
|
178
186
|
feedback = true;
|
|
179
|
-
} else if (value.type === "function") {
|
|
187
|
+
} else if (value.type === "function" || value.type === "partial") {
|
|
180
188
|
// Create a new message if the previous one is not empty
|
|
181
189
|
if (
|
|
182
190
|
currentMessage.content != "" ||
|
|
@@ -191,36 +199,53 @@ export function useChat(options: UseChatOptionsWithCopilotConfig): UseChatHelper
|
|
|
191
199
|
};
|
|
192
200
|
newMessages.push(currentMessage);
|
|
193
201
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
202
|
+
if (value.type === "function") {
|
|
203
|
+
currentMessage.function_call = {
|
|
204
|
+
name: value.name,
|
|
205
|
+
arguments: JSON.stringify(value.arguments),
|
|
206
|
+
scope: value.scope,
|
|
207
|
+
};
|
|
208
|
+
} else if (value.type === "partial") {
|
|
209
|
+
let partialArguments: any = {};
|
|
210
|
+
try {
|
|
211
|
+
partialArguments = JSON.parse(untruncateJson(value.arguments));
|
|
212
|
+
} catch (e) {}
|
|
213
|
+
|
|
214
|
+
currentMessage.partialFunctionCall = {
|
|
215
|
+
name: value.name,
|
|
216
|
+
arguments: partialArguments,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
199
219
|
|
|
200
220
|
newMessages[newMessages.length - 1] = currentMessage;
|
|
201
221
|
setMessages([...messages, ...newMessages]);
|
|
202
222
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
223
|
+
if (value.type === "function") {
|
|
224
|
+
// Execute the function call
|
|
225
|
+
try {
|
|
226
|
+
if (options.onFunctionCall && value.scope === "client") {
|
|
227
|
+
const result = await options.onFunctionCall(
|
|
228
|
+
messages,
|
|
229
|
+
currentMessage.function_call as FunctionCall,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
currentMessage = {
|
|
233
|
+
id: nanoid(),
|
|
234
|
+
role: "function",
|
|
235
|
+
content: encodeResult(result),
|
|
236
|
+
name: (currentMessage.function_call! as FunctionCall).name!,
|
|
237
|
+
};
|
|
238
|
+
newMessages.push(currentMessage);
|
|
239
|
+
setMessages([...messages, ...newMessages]);
|
|
240
|
+
|
|
241
|
+
// After a function call, feed back the new messages to GPT
|
|
242
|
+
feedback = true;
|
|
243
|
+
}
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error("Failed to execute function call", error);
|
|
246
|
+
// TODO: Handle error
|
|
247
|
+
// this should go to the message itself
|
|
219
248
|
}
|
|
220
|
-
} catch (error) {
|
|
221
|
-
console.error("Failed to execute function call", error);
|
|
222
|
-
// TODO: Handle error
|
|
223
|
-
// this should go to the message itself
|
|
224
249
|
}
|
|
225
250
|
}
|
|
226
251
|
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { AnnotatedFunction, Parameter } from "@copilotkit/shared";
|
|
4
|
+
import { useRef, useContext, useEffect } from "react";
|
|
5
|
+
import { FrontendAction } from "../types/frontend-action";
|
|
6
|
+
import { CopilotContext } from "../context/copilot-context";
|
|
7
|
+
import { nanoid } from "nanoid";
|
|
8
|
+
|
|
9
|
+
// We implement useCopilotActionImplementation dependency handling so that
|
|
10
|
+
// the developer has the option to not provide any dependencies.
|
|
11
|
+
// In this case, we assume they want to update the handler on each rerender.
|
|
12
|
+
// To avoid getting stuck in an infinite loop, we update the handler directly,
|
|
13
|
+
// skipping React state updates.
|
|
14
|
+
// This is ok in this case, because the handler is not part of any UI that
|
|
15
|
+
// needs to be updated.
|
|
16
|
+
// useCallback, useMemo or other memoization techniques are not suitable here,
|
|
17
|
+
// because they will cause a infinite rerender loop.
|
|
18
|
+
export function useCopilotActionImplementation<T extends Array<any> = []>(
|
|
19
|
+
action: FrontendAction<T>,
|
|
20
|
+
dependencies?: any[],
|
|
21
|
+
): void {
|
|
22
|
+
const { setEntryPoint, removeEntryPoint, entryPoints, chatComponentsCache } =
|
|
23
|
+
useContext(CopilotContext);
|
|
24
|
+
const idRef = useRef<string>(nanoid());
|
|
25
|
+
|
|
26
|
+
// If the developer doesn't provide dependencies, we assume they want to
|
|
27
|
+
// update handler and render function when the action object changes.
|
|
28
|
+
// This ensures that any captured variables in the handler are up to date.
|
|
29
|
+
if (dependencies === undefined) {
|
|
30
|
+
if (entryPoints[idRef.current]) {
|
|
31
|
+
entryPoints[idRef.current].handler = action.handler;
|
|
32
|
+
if (typeof action.render === "function") {
|
|
33
|
+
if (chatComponentsCache.current !== null) {
|
|
34
|
+
chatComponentsCache.current[action.name] = action.render;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
setEntryPoint(idRef.current, action);
|
|
42
|
+
if (chatComponentsCache.current !== null && action.render !== undefined) {
|
|
43
|
+
chatComponentsCache.current[action.name] = action.render;
|
|
44
|
+
}
|
|
45
|
+
return () => {
|
|
46
|
+
// NOTE: For now, we don't remove the chatComponentsCache entry when the action is removed.
|
|
47
|
+
// This is because we currently don't have access to the messages array in CopilotContext.
|
|
48
|
+
removeEntryPoint(idRef.current);
|
|
49
|
+
};
|
|
50
|
+
}, [
|
|
51
|
+
setEntryPoint,
|
|
52
|
+
removeEntryPoint,
|
|
53
|
+
action.description,
|
|
54
|
+
action.name,
|
|
55
|
+
// This should be faster than deep equality checking
|
|
56
|
+
// In addition, all major JS engines guarantee the order of object keys
|
|
57
|
+
JSON.stringify(action.parameters),
|
|
58
|
+
// include render only if it's a string
|
|
59
|
+
typeof action.render === "string" ? action.render : undefined,
|
|
60
|
+
// dependencies set by the developer
|
|
61
|
+
...(dependencies || []),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function annotatedFunctionToAction(
|
|
66
|
+
annotatedFunction: AnnotatedFunction<any[]>,
|
|
67
|
+
): FrontendAction<any> {
|
|
68
|
+
const parameters: Parameter[] = annotatedFunction.argumentAnnotations.map((annotation) => {
|
|
69
|
+
switch (annotation.type) {
|
|
70
|
+
case "string":
|
|
71
|
+
case "number":
|
|
72
|
+
case "boolean":
|
|
73
|
+
case "object":
|
|
74
|
+
return {
|
|
75
|
+
name: annotation.name,
|
|
76
|
+
description: annotation.description,
|
|
77
|
+
type: annotation.type,
|
|
78
|
+
required: annotation.required,
|
|
79
|
+
};
|
|
80
|
+
case "array":
|
|
81
|
+
let type;
|
|
82
|
+
if (annotation.items.type === "string") {
|
|
83
|
+
type = "string[]";
|
|
84
|
+
} else if (annotation.items.type === "number") {
|
|
85
|
+
type = "number[]";
|
|
86
|
+
} else if (annotation.items.type === "boolean") {
|
|
87
|
+
type = "boolean[]";
|
|
88
|
+
} else if (annotation.items.type === "object") {
|
|
89
|
+
type = "object[]";
|
|
90
|
+
} else {
|
|
91
|
+
type = "string[]";
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
name: annotation.name,
|
|
95
|
+
description: annotation.description,
|
|
96
|
+
type: type as any,
|
|
97
|
+
required: annotation.required,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
name: annotatedFunction.name,
|
|
104
|
+
description: annotatedFunction.description,
|
|
105
|
+
parameters: parameters,
|
|
106
|
+
handler: (args) => {
|
|
107
|
+
const paramsInCorrectOrder: any[] = [];
|
|
108
|
+
for (let arg of annotatedFunction.argumentAnnotations) {
|
|
109
|
+
paramsInCorrectOrder.push(args[arg.name]);
|
|
110
|
+
}
|
|
111
|
+
return annotatedFunction.implementation(...paramsInCorrectOrder);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Parameter } from "@copilotkit/shared";
|
|
4
|
+
import { FrontendAction } from "../types/frontend-action";
|
|
5
|
+
import { useCopilotActionImplementation } from "./use-copilot-action-implementation";
|
|
6
|
+
|
|
7
|
+
// Prettier chokes on the `const` in the function signature
|
|
8
|
+
// To have the main implementation checked by prettier, we split
|
|
9
|
+
// this into a separate file
|
|
10
|
+
// prettier-ignore
|
|
11
|
+
export function useCopilotAction<const T extends Parameter[] | [] = []>(action: FrontendAction<T>, dependencies?: any[]): void {
|
|
12
|
+
return useCopilotActionImplementation(action, dependencies);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Usage Example:
|
|
16
|
+
// useCopilotAction({
|
|
17
|
+
// name: "myAction",
|
|
18
|
+
// parameters: [
|
|
19
|
+
// { name: "arg1", type: "string", enum: ["option1", "option2", "option3"], required: false },
|
|
20
|
+
// { name: "arg2", type: "number" },
|
|
21
|
+
// {
|
|
22
|
+
// name: "arg3",
|
|
23
|
+
// type: "object",
|
|
24
|
+
// attributes: [
|
|
25
|
+
// { name: "nestedArg1", type: "boolean" },
|
|
26
|
+
// { name: "xyz", required: false },
|
|
27
|
+
// ],
|
|
28
|
+
// },
|
|
29
|
+
// { name: "arg4", type: "number[]" },
|
|
30
|
+
// ],
|
|
31
|
+
// handler: ({ arg1, arg2, arg3, arg4 }) => {
|
|
32
|
+
// const x = arg3.nestedArg1;
|
|
33
|
+
// const z = arg3.xyz;
|
|
34
|
+
// console.log(arg1, arg2, arg3);
|
|
35
|
+
// },
|
|
36
|
+
// });
|
|
37
|
+
|
|
38
|
+
// useCopilotAction({
|
|
39
|
+
// name: "myAction",
|
|
40
|
+
// handler: () => {
|
|
41
|
+
// console.log("No parameters provided.");
|
|
42
|
+
// },
|
|
43
|
+
// });
|
|
44
|
+
|
|
45
|
+
// https://community.openai.com/t/function-call-complex-arrays-as-parameters/295648/3
|
|
@@ -61,7 +61,8 @@ export function useCopilotChat({
|
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
const visibleMessages = messages.filter(
|
|
64
|
-
(message) =>
|
|
64
|
+
(message) =>
|
|
65
|
+
message.role === "user" || message.role === "assistant" || message.role === "function",
|
|
65
66
|
);
|
|
66
67
|
|
|
67
68
|
return {
|
|
@@ -4,7 +4,11 @@ import { useRef, useContext, useEffect, useMemo } from "react";
|
|
|
4
4
|
import { CopilotContext } from "../context/copilot-context";
|
|
5
5
|
import { AnnotatedFunction } from "@copilotkit/shared";
|
|
6
6
|
import { nanoid } from "nanoid";
|
|
7
|
+
import { annotatedFunctionToAction } from "./use-copilot-action-implementation";
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use the useCopilotAction function instead.
|
|
11
|
+
*/
|
|
8
12
|
export function useMakeCopilotActionable<ActionInput extends any[]>(
|
|
9
13
|
annotatedFunction: AnnotatedFunction<ActionInput>,
|
|
10
14
|
dependencies: any[],
|
|
@@ -23,7 +27,8 @@ export function useMakeCopilotActionable<ActionInput extends any[]>(
|
|
|
23
27
|
);
|
|
24
28
|
|
|
25
29
|
useEffect(() => {
|
|
26
|
-
|
|
30
|
+
const action = annotatedFunctionToAction(memoizedAnnotatedFunction as AnnotatedFunction<any[]>);
|
|
31
|
+
setEntryPoint(idRef.current, action);
|
|
27
32
|
|
|
28
33
|
return () => {
|
|
29
34
|
removeEntryPoint(idRef.current);
|
package/src/lib/copilot-task.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FunctionCall, Message } from "@copilotkit/shared";
|
|
2
|
+
import { FrontendAction } from "../types/frontend-action";
|
|
2
3
|
import { CopilotContextParams } from "../context";
|
|
3
4
|
import { defaultCopilotContextCategories } from "../components";
|
|
4
5
|
import { fetchAndDecodeChatCompletion } from "../utils/fetch-chat-completion";
|
|
@@ -11,7 +12,7 @@ export interface CopilotTaskConfig {
|
|
|
11
12
|
/**
|
|
12
13
|
* Action definitions to be sent to the API.
|
|
13
14
|
*/
|
|
14
|
-
actions?:
|
|
15
|
+
actions?: FrontendAction<any>[];
|
|
15
16
|
/**
|
|
16
17
|
* Whether to include the copilot readable context in the task.
|
|
17
18
|
*/
|
|
@@ -25,13 +26,13 @@ export interface CopilotTaskConfig {
|
|
|
25
26
|
|
|
26
27
|
export class CopilotTask<T = any> {
|
|
27
28
|
private instructions: string;
|
|
28
|
-
private
|
|
29
|
+
private actions: FrontendAction<any>[];
|
|
29
30
|
private includeCopilotReadable: boolean;
|
|
30
31
|
private includeCopilotActionable: boolean;
|
|
31
32
|
|
|
32
33
|
constructor(config: CopilotTaskConfig) {
|
|
33
34
|
this.instructions = config.instructions;
|
|
34
|
-
this.
|
|
35
|
+
this.actions = config.actions || [];
|
|
35
36
|
this.includeCopilotReadable = config.includeCopilotReadable || true;
|
|
36
37
|
this.includeCopilotActionable = config.includeCopilotActionable || true;
|
|
37
38
|
}
|
|
@@ -40,7 +41,7 @@ export class CopilotTask<T = any> {
|
|
|
40
41
|
const entryPoints = this.includeCopilotActionable ? Object.assign({}, context.entryPoints) : {};
|
|
41
42
|
|
|
42
43
|
// merge functions into entry points
|
|
43
|
-
for (const fn of this.
|
|
44
|
+
for (const fn of this.actions) {
|
|
44
45
|
entryPoints[fn.name] = fn;
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Action, Parameter, MappedParameterTypes } from "@copilotkit/shared";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
interface InProgressState<T extends Parameter[] | [] = []> {
|
|
5
|
+
status: "inProgress";
|
|
6
|
+
args: Partial<MappedParameterTypes<T>>;
|
|
7
|
+
result: undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ExecutingState<T extends Parameter[] | [] = []> {
|
|
11
|
+
status: "executing";
|
|
12
|
+
args: MappedParameterTypes<T>;
|
|
13
|
+
result: undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface CompleteState<T extends Parameter[] | [] = []> {
|
|
17
|
+
status: "complete";
|
|
18
|
+
args: MappedParameterTypes<T>;
|
|
19
|
+
result: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface InProgressStateNoArgs<T extends Parameter[] | [] = []> {
|
|
23
|
+
status: "inProgress";
|
|
24
|
+
args: Partial<MappedParameterTypes<T>>;
|
|
25
|
+
result: undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface ExecutingStateNoArgs<T extends Parameter[] | [] = []> {
|
|
29
|
+
status: "executing";
|
|
30
|
+
args: MappedParameterTypes<T>;
|
|
31
|
+
result: undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface CompleteStateNoArgs<T extends Parameter[] | [] = []> {
|
|
35
|
+
status: "complete";
|
|
36
|
+
args: MappedParameterTypes<T>;
|
|
37
|
+
result: any;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type ActionRenderProps<T extends Parameter[] | [] = []> =
|
|
41
|
+
| CompleteState<T>
|
|
42
|
+
| ExecutingState<T>
|
|
43
|
+
| InProgressState<T>;
|
|
44
|
+
|
|
45
|
+
export type ActionRenderPropsNoArgs<T extends Parameter[] | [] = []> =
|
|
46
|
+
| CompleteStateNoArgs<T>
|
|
47
|
+
| ExecutingStateNoArgs<T>
|
|
48
|
+
| InProgressStateNoArgs<T>;
|
|
49
|
+
|
|
50
|
+
export type FrontendAction<T extends Parameter[] | [] = []> = Action<T> & {
|
|
51
|
+
render?:
|
|
52
|
+
| string
|
|
53
|
+
| (T extends []
|
|
54
|
+
? (props: ActionRenderPropsNoArgs<T>) => string | React.ReactElement
|
|
55
|
+
: (props: ActionRenderProps<T>) => string | React.ReactElement);
|
|
56
|
+
};
|