@copilotkit/react-core 0.13.0 → 0.15.0-alpha.0
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 +141 -88
- package/CHANGELOG.md +17 -0
- package/dist/components/copilot-provider/copilot-provider-props.d.ts +50 -0
- package/dist/components/copilot-provider/copilot-provider-props.mjs +2 -0
- package/dist/components/copilot-provider/copilot-provider-props.mjs.map +1 -0
- package/dist/components/copilot-provider/copilot-provider.d.ts +45 -0
- package/dist/components/copilot-provider/copilot-provider.mjs +469 -0
- package/dist/components/copilot-provider/copilot-provider.mjs.map +1 -0
- package/dist/components/copilot-provider/index.d.ts +9 -0
- package/dist/components/copilot-provider/index.mjs +468 -0
- package/dist/components/copilot-provider/index.mjs.map +1 -0
- package/dist/components/copilot-provider/standard-cpilot-api-config.d.ts +24 -0
- package/dist/components/copilot-provider/standard-cpilot-api-config.mjs +13 -0
- package/dist/components/copilot-provider/standard-cpilot-api-config.mjs.map +1 -0
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.mjs +467 -7
- package/dist/components/index.mjs.map +1 -1
- package/dist/context/copilot-context.d.ts +5 -0
- package/dist/context/copilot-context.mjs +81 -3
- package/dist/context/copilot-context.mjs.map +1 -1
- package/dist/context/index.mjs +80 -4
- package/dist/context/index.mjs.map +1 -1
- package/dist/hooks/index.mjs +249 -12
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +194 -8
- package/dist/hooks/use-copilot-chat.mjs.map +1 -1
- package/dist/hooks/use-flat-category-store.mjs +68 -3
- package/dist/hooks/use-flat-category-store.mjs.map +1 -1
- package/dist/hooks/use-make-copilot-actionable.mjs +95 -4
- package/dist/hooks/use-make-copilot-actionable.mjs.map +1 -1
- package/dist/hooks/use-make-copilot-document-readable.mjs +87 -4
- package/dist/hooks/use-make-copilot-document-readable.mjs.map +1 -1
- package/dist/hooks/use-make-copilot-readable.mjs +87 -4
- package/dist/hooks/use-make-copilot-readable.mjs.map +1 -1
- package/dist/hooks/use-tree.mjs +153 -3
- package/dist/hooks/use-tree.mjs.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +755 -14
- package/dist/index.mjs.map +1 -1
- package/dist/openai-assistants/hooks/index.d.ts +2 -0
- package/dist/openai-assistants/hooks/index.mjs +246 -0
- package/dist/openai-assistants/hooks/index.mjs.map +1 -0
- package/dist/openai-assistants/hooks/use-assistants.d.ts +17 -0
- package/dist/openai-assistants/hooks/use-assistants.mjs +131 -0
- package/dist/openai-assistants/hooks/use-assistants.mjs.map +1 -0
- package/dist/openai-assistants/hooks/use-copilot-chat-v2.d.ts +44 -0
- package/dist/openai-assistants/hooks/use-copilot-chat-v2.mjs +247 -0
- package/dist/openai-assistants/hooks/use-copilot-chat-v2.mjs.map +1 -0
- package/dist/openai-assistants/index.d.ts +3 -0
- package/dist/openai-assistants/index.mjs +247 -0
- package/dist/openai-assistants/index.mjs.map +1 -0
- package/dist/openai-assistants/utils/index.d.ts +1 -0
- package/dist/openai-assistants/utils/index.mjs +47 -0
- package/dist/openai-assistants/utils/index.mjs.map +1 -0
- package/dist/openai-assistants/utils/process-message-stream.d.ts +3 -0
- package/dist/openai-assistants/utils/process-message-stream.mjs +47 -0
- package/dist/openai-assistants/utils/process-message-stream.mjs.map +1 -0
- package/dist/types/annotated-function.mjs +0 -2
- package/dist/types/annotated-function.mjs.map +1 -1
- package/dist/types/document-pointer.mjs +0 -2
- package/dist/types/document-pointer.mjs.map +1 -1
- package/dist/types/index.mjs +0 -2
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.mjs +0 -2
- package/dist/utils/utils.mjs.map +1 -1
- package/dist/utils/utils.test.d.ts +1 -0
- package/dist/utils/utils.test.mjs +0 -1
- package/dist/utils/utils.test.mjs.map +1 -1
- package/package.json +7 -6
- package/src/components/copilot-provider/copilot-provider-props.tsx +50 -0
- package/src/components/{copilot-provider.tsx → copilot-provider/copilot-provider.tsx} +84 -63
- package/src/components/copilot-provider/index.ts +7 -0
- package/src/components/copilot-provider/standard-cpilot-api-config.tsx +28 -0
- package/src/components/index.ts +1 -4
- package/src/context/copilot-context.tsx +19 -17
- package/src/hooks/use-copilot-chat.ts +17 -22
- package/src/hooks/use-flat-category-store.ts +15 -25
- package/src/hooks/use-make-copilot-actionable.ts +3 -6
- package/src/hooks/use-make-copilot-document-readable.ts +2 -3
- package/src/hooks/use-make-copilot-readable.ts +1 -1
- package/src/hooks/use-tree.ts +10 -28
- package/src/index.tsx +1 -0
- package/src/openai-assistants/hooks/index.ts +9 -0
- package/src/openai-assistants/hooks/use-assistants.ts +114 -0
- package/src/openai-assistants/hooks/use-copilot-chat-v2.ts +186 -0
- package/src/openai-assistants/index.ts +2 -0
- package/src/openai-assistants/utils/index.ts +1 -0
- package/src/openai-assistants/utils/process-message-stream.ts +25 -0
- package/dist/chunk-3BOHSSKR.mjs +0 -141
- package/dist/chunk-3BOHSSKR.mjs.map +0 -1
- package/dist/chunk-63ILXW5V.mjs +0 -76
- package/dist/chunk-63ILXW5V.mjs.map +0 -1
- package/dist/chunk-AMFRKVFT.mjs +0 -19
- package/dist/chunk-AMFRKVFT.mjs.map +0 -1
- package/dist/chunk-EFZPSZWO.mjs +0 -3
- package/dist/chunk-EFZPSZWO.mjs.map +0 -1
- package/dist/chunk-FIYUJVWU.mjs +0 -161
- package/dist/chunk-FIYUJVWU.mjs.map +0 -1
- package/dist/chunk-G5LZS72K.mjs +0 -19
- package/dist/chunk-G5LZS72K.mjs.map +0 -1
- package/dist/chunk-JD7BAH7U.mjs +0 -3
- package/dist/chunk-JD7BAH7U.mjs.map +0 -1
- package/dist/chunk-MRXNTQOX.mjs +0 -55
- package/dist/chunk-MRXNTQOX.mjs.map +0 -1
- package/dist/chunk-P3QUZTN7.mjs +0 -30
- package/dist/chunk-P3QUZTN7.mjs.map +0 -1
- package/dist/chunk-PRPQRCVY.mjs +0 -82
- package/dist/chunk-PRPQRCVY.mjs.map +0 -1
- package/dist/chunk-QACD2U6P.mjs +0 -3
- package/dist/chunk-QACD2U6P.mjs.map +0 -1
- package/dist/chunk-X24EEZGG.mjs +0 -50
- package/dist/chunk-X24EEZGG.mjs.map +0 -1
- package/dist/chunk-YPSGKPDA.mjs +0 -3
- package/dist/chunk-YPSGKPDA.mjs.map +0 -1
- package/dist/components/copilot-provider.d.ts +0 -11
- package/dist/components/copilot-provider.mjs +0 -7
- package/dist/components/copilot-provider.mjs.map +0 -1
|
@@ -17,28 +17,19 @@ interface FlatCategoryStoreElement<T> {
|
|
|
17
17
|
|
|
18
18
|
const useFlatCategoryStore = <T>(): UseFlatCategoryStoreReturn<T> => {
|
|
19
19
|
const [elements, dispatch] = useReducer<
|
|
20
|
-
React.Reducer<
|
|
21
|
-
|
|
22
|
-
Action<T>
|
|
23
|
-
>
|
|
24
|
-
>(
|
|
25
|
-
flatCategoryStoreReducer,
|
|
26
|
-
new Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>>()
|
|
27
|
-
);
|
|
20
|
+
React.Reducer<Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>>, Action<T>>
|
|
21
|
+
>(flatCategoryStoreReducer, new Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>>());
|
|
28
22
|
|
|
29
|
-
const addElement = useCallback(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
},
|
|
40
|
-
[]
|
|
41
|
-
);
|
|
23
|
+
const addElement = useCallback((value: T, categories: string[]): FlatCategoryStoreId => {
|
|
24
|
+
const newId = nanoid();
|
|
25
|
+
dispatch({
|
|
26
|
+
type: "ADD_ELEMENT",
|
|
27
|
+
value,
|
|
28
|
+
id: newId,
|
|
29
|
+
categories,
|
|
30
|
+
});
|
|
31
|
+
return newId;
|
|
32
|
+
}, []);
|
|
42
33
|
|
|
43
34
|
const removeElement = useCallback((id: FlatCategoryStoreId): void => {
|
|
44
35
|
dispatch({ type: "REMOVE_ELEMENT", id });
|
|
@@ -55,7 +46,7 @@ const useFlatCategoryStore = <T>(): UseFlatCategoryStoreReturn<T> => {
|
|
|
55
46
|
});
|
|
56
47
|
return result;
|
|
57
48
|
},
|
|
58
|
-
[elements]
|
|
49
|
+
[elements],
|
|
59
50
|
);
|
|
60
51
|
|
|
61
52
|
return { addElement, removeElement, allElements };
|
|
@@ -76,7 +67,7 @@ type Action<T> =
|
|
|
76
67
|
// Reducer
|
|
77
68
|
function flatCategoryStoreReducer<T>(
|
|
78
69
|
state: Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>>,
|
|
79
|
-
action: Action<T
|
|
70
|
+
action: Action<T>,
|
|
80
71
|
): Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>> {
|
|
81
72
|
switch (action.type) {
|
|
82
73
|
case "ADD_ELEMENT": {
|
|
@@ -101,8 +92,7 @@ function flatCategoryStoreReducer<T>(
|
|
|
101
92
|
}
|
|
102
93
|
|
|
103
94
|
function setsHaveIntersection<T>(setA: Set<T>, setB: Set<T>): boolean {
|
|
104
|
-
const [smallerSet, largerSet] =
|
|
105
|
-
setA.size <= setB.size ? [setA, setB] : [setB, setA];
|
|
95
|
+
const [smallerSet, largerSet] = setA.size <= setB.size ? [setA, setB] : [setB, setA];
|
|
106
96
|
|
|
107
97
|
for (let item of smallerSet) {
|
|
108
98
|
if (largerSet.has(item)) {
|
|
@@ -7,7 +7,7 @@ import { nanoid } from "nanoid";
|
|
|
7
7
|
|
|
8
8
|
export function useMakeCopilotActionable<ActionInput extends any[]>(
|
|
9
9
|
annotatedFunction: AnnotatedFunction<ActionInput>,
|
|
10
|
-
dependencies: any[]
|
|
10
|
+
dependencies: any[],
|
|
11
11
|
) {
|
|
12
12
|
const idRef = useRef(nanoid()); // generate a unique id
|
|
13
13
|
const { setEntryPoint, removeEntryPoint } = useContext(CopilotContext);
|
|
@@ -19,14 +19,11 @@ export function useMakeCopilotActionable<ActionInput extends any[]>(
|
|
|
19
19
|
argumentAnnotations: annotatedFunction.argumentAnnotations,
|
|
20
20
|
implementation: annotatedFunction.implementation,
|
|
21
21
|
}),
|
|
22
|
-
dependencies
|
|
22
|
+
dependencies,
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
useEffect(() => {
|
|
26
|
-
setEntryPoint(
|
|
27
|
-
idRef.current,
|
|
28
|
-
memoizedAnnotatedFunction as AnnotatedFunction<any[]>
|
|
29
|
-
);
|
|
26
|
+
setEntryPoint(idRef.current, memoizedAnnotatedFunction as AnnotatedFunction<any[]>);
|
|
30
27
|
|
|
31
28
|
return () => {
|
|
32
29
|
removeEntryPoint(idRef.current);
|
|
@@ -14,10 +14,9 @@ import { DocumentPointer } from "../types";
|
|
|
14
14
|
export function useMakeCopilotDocumentReadable(
|
|
15
15
|
document: DocumentPointer,
|
|
16
16
|
categories?: string[],
|
|
17
|
-
dependencies: any[] = []
|
|
17
|
+
dependencies: any[] = [],
|
|
18
18
|
): string | undefined {
|
|
19
|
-
const { addDocumentContext, removeDocumentContext } =
|
|
20
|
-
useContext(CopilotContext);
|
|
19
|
+
const { addDocumentContext, removeDocumentContext } = useContext(CopilotContext);
|
|
21
20
|
const idRef = useRef<string>();
|
|
22
21
|
|
|
23
22
|
useEffect(() => {
|
|
@@ -13,7 +13,7 @@ import { CopilotContext } from "../context/copilot-context";
|
|
|
13
13
|
export function useMakeCopilotReadable(
|
|
14
14
|
information: string,
|
|
15
15
|
parentId?: string,
|
|
16
|
-
categories?: string[]
|
|
16
|
+
categories?: string[],
|
|
17
17
|
): string | undefined {
|
|
18
18
|
const { addContext, removeContext } = useContext(CopilotContext);
|
|
19
19
|
const idRef = useRef<string>();
|
package/src/hooks/use-tree.ts
CHANGED
|
@@ -15,11 +15,7 @@ export type Tree = TreeNode[];
|
|
|
15
15
|
|
|
16
16
|
export interface UseTreeReturn {
|
|
17
17
|
tree: Tree;
|
|
18
|
-
addElement: (
|
|
19
|
-
value: string,
|
|
20
|
-
categories: string[],
|
|
21
|
-
parentId?: TreeNodeId
|
|
22
|
-
) => TreeNodeId;
|
|
18
|
+
addElement: (value: string, categories: string[], parentId?: TreeNodeId) => TreeNodeId;
|
|
23
19
|
printTree: (categories: string[]) => string;
|
|
24
20
|
removeElement: (id: TreeNodeId) => void;
|
|
25
21
|
}
|
|
@@ -47,11 +43,7 @@ const removeNode = (nodes: Tree, id: TreeNodeId): Tree => {
|
|
|
47
43
|
}, []);
|
|
48
44
|
};
|
|
49
45
|
|
|
50
|
-
const addNode = (
|
|
51
|
-
nodes: Tree,
|
|
52
|
-
newNode: TreeNode,
|
|
53
|
-
parentId?: TreeNodeId
|
|
54
|
-
): Tree => {
|
|
46
|
+
const addNode = (nodes: Tree, newNode: TreeNode, parentId?: TreeNodeId): Tree => {
|
|
55
47
|
if (!parentId) {
|
|
56
48
|
return [...nodes, newNode];
|
|
57
49
|
}
|
|
@@ -65,10 +57,7 @@ const addNode = (
|
|
|
65
57
|
});
|
|
66
58
|
};
|
|
67
59
|
|
|
68
|
-
const treeIndentationRepresentation = (
|
|
69
|
-
index: number,
|
|
70
|
-
indentLevel: number
|
|
71
|
-
): string => {
|
|
60
|
+
const treeIndentationRepresentation = (index: number, indentLevel: number): string => {
|
|
72
61
|
if (indentLevel === 0) {
|
|
73
62
|
return (index + 1).toString();
|
|
74
63
|
} else if (indentLevel === 1) {
|
|
@@ -105,12 +94,9 @@ const printNode = (node: TreeNode, prefix = "", indentLevel = 0): string => {
|
|
|
105
94
|
(child, index) =>
|
|
106
95
|
(output += printNode(
|
|
107
96
|
child,
|
|
108
|
-
`${childPrePrefix}${treeIndentationRepresentation(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)}. `,
|
|
112
|
-
indentLevel + 1
|
|
113
|
-
))
|
|
97
|
+
`${childPrePrefix}${treeIndentationRepresentation(index, indentLevel + 1)}. `,
|
|
98
|
+
indentLevel + 1,
|
|
99
|
+
)),
|
|
114
100
|
);
|
|
115
101
|
return output;
|
|
116
102
|
};
|
|
@@ -168,7 +154,7 @@ const useTree = (): UseTreeReturn => {
|
|
|
168
154
|
});
|
|
169
155
|
return newNodeId; // Return the new ID
|
|
170
156
|
},
|
|
171
|
-
[]
|
|
157
|
+
[],
|
|
172
158
|
);
|
|
173
159
|
|
|
174
160
|
const removeElement = useCallback((id: TreeNodeId): void => {
|
|
@@ -191,14 +177,11 @@ const useTree = (): UseTreeReturn => {
|
|
|
191
177
|
output += "\n";
|
|
192
178
|
}
|
|
193
179
|
|
|
194
|
-
output += printNode(
|
|
195
|
-
node,
|
|
196
|
-
`${treeIndentationRepresentation(index, 0)}. `
|
|
197
|
-
);
|
|
180
|
+
output += printNode(node, `${treeIndentationRepresentation(index, 0)}. `);
|
|
198
181
|
});
|
|
199
182
|
return output;
|
|
200
183
|
},
|
|
201
|
-
[tree]
|
|
184
|
+
[tree],
|
|
202
185
|
);
|
|
203
186
|
|
|
204
187
|
return { tree, addElement, printTree, removeElement };
|
|
@@ -207,8 +190,7 @@ const useTree = (): UseTreeReturn => {
|
|
|
207
190
|
export default useTree;
|
|
208
191
|
|
|
209
192
|
function setsHaveIntersection<T>(setA: Set<T>, setB: Set<T>): boolean {
|
|
210
|
-
const [smallerSet, largerSet] =
|
|
211
|
-
setA.size <= setB.size ? [setA, setB] : [setB, setA];
|
|
193
|
+
const [smallerSet, largerSet] = setA.size <= setB.size ? [setA, setB] : [setB, setA];
|
|
212
194
|
|
|
213
195
|
for (let item of smallerSet) {
|
|
214
196
|
if (largerSet.has(item)) {
|
package/src/index.tsx
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// export type { AssistantStatus } from "./use-assistants";
|
|
2
|
+
// export { experimental_useAssistant } from "./use-assistants";
|
|
3
|
+
export type {
|
|
4
|
+
AssistantStatus,
|
|
5
|
+
RequestForwardingOptions,
|
|
6
|
+
UseCopilotChatOptionsV2,
|
|
7
|
+
UseCopilotChatV2Result,
|
|
8
|
+
} from "./use-copilot-chat-v2";
|
|
9
|
+
export { useCopilotChatV2 } from "./use-copilot-chat-v2";
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { processMessageStream } from "../utils";
|
|
5
|
+
import { Message, parseStreamPart } from "@copilotkit/shared";
|
|
6
|
+
|
|
7
|
+
export type AssistantStatus = "in_progress" | "awaiting_message";
|
|
8
|
+
|
|
9
|
+
export interface UseAssistantResult {
|
|
10
|
+
messages: Message[];
|
|
11
|
+
input: string;
|
|
12
|
+
handleInputChange: (e: any) => void;
|
|
13
|
+
submitMessage: (e: any) => Promise<void>;
|
|
14
|
+
status: AssistantStatus;
|
|
15
|
+
error: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function experimental_useAssistant({
|
|
19
|
+
api,
|
|
20
|
+
threadId: threadIdParam,
|
|
21
|
+
}: {
|
|
22
|
+
api: string;
|
|
23
|
+
threadId?: string | undefined;
|
|
24
|
+
}): UseAssistantResult {
|
|
25
|
+
const [messages, setMessages] = useState<Message[]>([]);
|
|
26
|
+
const [input, setInput] = useState("");
|
|
27
|
+
const [threadId, setThreadId] = useState<string | undefined>(undefined);
|
|
28
|
+
const [status, setStatus] = useState<AssistantStatus>("awaiting_message");
|
|
29
|
+
const [error, setError] = useState<unknown | undefined>(undefined);
|
|
30
|
+
|
|
31
|
+
const handleInputChange = (e: any) => {
|
|
32
|
+
setInput(e.target.value);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const submitMessage = async (e: any) => {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
|
|
38
|
+
if (input === "") {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setStatus("in_progress");
|
|
43
|
+
|
|
44
|
+
setMessages((messages) => [...messages, { id: "", role: "user", content: input }]);
|
|
45
|
+
|
|
46
|
+
setInput("");
|
|
47
|
+
|
|
48
|
+
const result = await fetch(api, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/json" },
|
|
51
|
+
body: JSON.stringify({
|
|
52
|
+
// always use user-provided threadId when available:
|
|
53
|
+
threadId: threadIdParam ?? threadId ?? null,
|
|
54
|
+
message: input,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (result.body == null) {
|
|
59
|
+
throw new Error("The response body is empty.");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
await processMessageStream(result.body.getReader(), (message: string) => {
|
|
63
|
+
try {
|
|
64
|
+
const { type, value } = parseStreamPart(message);
|
|
65
|
+
|
|
66
|
+
switch (type) {
|
|
67
|
+
case "assistant_message": {
|
|
68
|
+
// append message:
|
|
69
|
+
setMessages((messages) => [
|
|
70
|
+
...messages,
|
|
71
|
+
{
|
|
72
|
+
id: value.id,
|
|
73
|
+
role: value.role,
|
|
74
|
+
content: value.content[0].text.value,
|
|
75
|
+
},
|
|
76
|
+
]);
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
case "assistant_control_data": {
|
|
81
|
+
setThreadId(value.threadId);
|
|
82
|
+
|
|
83
|
+
// set id of last message:
|
|
84
|
+
setMessages((messages) => {
|
|
85
|
+
const lastMessage = messages[messages.length - 1];
|
|
86
|
+
lastMessage.id = value.messageId;
|
|
87
|
+
return [...messages.slice(0, messages.length - 1), lastMessage];
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case "error": {
|
|
94
|
+
setError(value);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
setError(error);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
setStatus("awaiting_message");
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
messages,
|
|
108
|
+
input,
|
|
109
|
+
handleInputChange,
|
|
110
|
+
submitMessage,
|
|
111
|
+
status,
|
|
112
|
+
error,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { useContext, useMemo, useState } from "react";
|
|
2
|
+
import { processMessageStream } from "../utils";
|
|
3
|
+
import { Message, parseStreamPart } from "@copilotkit/shared";
|
|
4
|
+
import { CopilotContext, copilotApiConfigExtrapolator } from "../../context";
|
|
5
|
+
import { defaultCopilotContextCategories } from "../../components";
|
|
6
|
+
|
|
7
|
+
export type AssistantStatus = "in_progress" | "awaiting_message";
|
|
8
|
+
|
|
9
|
+
export interface RequestForwardingOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The credentials mode to be used for the fetch request.
|
|
12
|
+
* Possible values are: 'omit', 'same-origin', 'include'.
|
|
13
|
+
* Defaults to 'same-origin'.
|
|
14
|
+
*/
|
|
15
|
+
credentials?: RequestCredentials;
|
|
16
|
+
/**
|
|
17
|
+
* HTTP headers to be sent with the API request.
|
|
18
|
+
*/
|
|
19
|
+
headers?: Record<string, string> | Headers;
|
|
20
|
+
/**
|
|
21
|
+
* Extra body object to be sent with the API request.
|
|
22
|
+
* @example
|
|
23
|
+
* Send a `sessionId` to the API along with the messages.
|
|
24
|
+
* ```js
|
|
25
|
+
* useChat({
|
|
26
|
+
* body: {
|
|
27
|
+
* sessionId: '123',
|
|
28
|
+
* }
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
body?: object;
|
|
33
|
+
}
|
|
34
|
+
export interface UseCopilotChatOptionsV2 extends RequestForwardingOptions {
|
|
35
|
+
makeSystemMessage?: (contextString: string) => string;
|
|
36
|
+
threadId?: string | undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface UseCopilotChatV2Result {
|
|
40
|
+
messages: Message[];
|
|
41
|
+
input: string;
|
|
42
|
+
handleInputChange: (e: any) => void;
|
|
43
|
+
submitMessage: (e: any) => Promise<void>;
|
|
44
|
+
status: AssistantStatus;
|
|
45
|
+
error: unknown;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function useCopilotChatV2(options: UseCopilotChatOptionsV2): UseCopilotChatV2Result {
|
|
49
|
+
const {
|
|
50
|
+
getContextString,
|
|
51
|
+
getChatCompletionFunctionDescriptions,
|
|
52
|
+
getFunctionCallHandler,
|
|
53
|
+
copilotApiConfig,
|
|
54
|
+
} = useContext(CopilotContext);
|
|
55
|
+
|
|
56
|
+
const [messages, setMessages] = useState<Message[]>([]);
|
|
57
|
+
const [input, setInput] = useState("");
|
|
58
|
+
const [threadId, setThreadId] = useState<string | undefined>(undefined);
|
|
59
|
+
const [status, setStatus] = useState<AssistantStatus>("awaiting_message");
|
|
60
|
+
const [error, setError] = useState<unknown | undefined>(undefined);
|
|
61
|
+
|
|
62
|
+
const systemMessage: Message = useMemo(() => {
|
|
63
|
+
const systemMessageMaker = options.makeSystemMessage || defaultSystemMessage;
|
|
64
|
+
const contextString = getContextString([], defaultCopilotContextCategories); // TODO: make the context categories configurable
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
id: "system",
|
|
68
|
+
content: systemMessageMaker(contextString),
|
|
69
|
+
role: "system",
|
|
70
|
+
};
|
|
71
|
+
}, [getContextString, options.makeSystemMessage]);
|
|
72
|
+
|
|
73
|
+
const handleInputChange = (e: any) => {
|
|
74
|
+
setInput(e.target.value);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const submitMessage = async (e: any) => {
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
|
|
80
|
+
if (input === "") {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
setStatus("in_progress");
|
|
85
|
+
|
|
86
|
+
setMessages((messages) => [...messages, { id: "", role: "user", content: input }]);
|
|
87
|
+
|
|
88
|
+
setInput("");
|
|
89
|
+
|
|
90
|
+
const apiUrl = copilotApiConfigExtrapolator(copilotApiConfig).chatApiEndpointV2;
|
|
91
|
+
const result = await fetch(apiUrl, {
|
|
92
|
+
method: "POST",
|
|
93
|
+
headers: {
|
|
94
|
+
"Content-Type": "application/json",
|
|
95
|
+
...copilotApiConfig.headers,
|
|
96
|
+
...options.headers,
|
|
97
|
+
},
|
|
98
|
+
body: JSON.stringify({
|
|
99
|
+
// always use user-provided threadId when available:
|
|
100
|
+
threadId: options.threadId ?? threadId ?? null,
|
|
101
|
+
message: input,
|
|
102
|
+
functions: getChatCompletionFunctionDescriptions(),
|
|
103
|
+
...copilotApiConfig.body,
|
|
104
|
+
...options.body,
|
|
105
|
+
}),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (result.body == null) {
|
|
109
|
+
throw new Error("The response body is empty.");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
await processMessageStream(result.body.getReader(), (message: string) => {
|
|
113
|
+
try {
|
|
114
|
+
const { type, value } = parseStreamPart(message);
|
|
115
|
+
|
|
116
|
+
switch (type) {
|
|
117
|
+
case "assistant_message": {
|
|
118
|
+
// append message:
|
|
119
|
+
setMessages((messages) => [
|
|
120
|
+
...messages,
|
|
121
|
+
{
|
|
122
|
+
id: value.id,
|
|
123
|
+
role: value.role,
|
|
124
|
+
content: value.content[0].text.value,
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
case "assistant_control_data": {
|
|
131
|
+
setThreadId(value.threadId);
|
|
132
|
+
|
|
133
|
+
// set id of last message:
|
|
134
|
+
setMessages((messages) => {
|
|
135
|
+
const lastMessage = messages[messages.length - 1];
|
|
136
|
+
lastMessage.id = value.messageId;
|
|
137
|
+
return [...messages.slice(0, messages.length - 1), lastMessage];
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case "error": {
|
|
144
|
+
setError(value);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
setError(error);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
setStatus("awaiting_message");
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
messages,
|
|
158
|
+
input,
|
|
159
|
+
handleInputChange,
|
|
160
|
+
submitMessage,
|
|
161
|
+
status,
|
|
162
|
+
error,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function defaultSystemMessage(contextString: string): string {
|
|
167
|
+
return `
|
|
168
|
+
Please act as an efficient, competent, conscientious, and industrious professional assistant.
|
|
169
|
+
|
|
170
|
+
Help the user achieve their goals, and you do so in a way that is as efficient as possible, without unnecessary fluff, but also without sacrificing professionalism.
|
|
171
|
+
Always be polite and respectful, and prefer brevity over verbosity.
|
|
172
|
+
|
|
173
|
+
The user has provided you with the following context:
|
|
174
|
+
\`\`\`
|
|
175
|
+
${contextString}
|
|
176
|
+
\`\`\`
|
|
177
|
+
|
|
178
|
+
They have also provided you with functions you can call to initiate actions on their behalf, or functions you can call to receive more information.
|
|
179
|
+
|
|
180
|
+
Please assist them as best you can.
|
|
181
|
+
|
|
182
|
+
You can ask them for clarifying questions if needed, but don't be annoying about it. If you can reasonably 'fill in the blanks' yourself, do so.
|
|
183
|
+
|
|
184
|
+
If you would like to call a function, call it without saying anything else.
|
|
185
|
+
`;
|
|
186
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { processMessageStream } from "./process-message-stream";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export async function processMessageStream(
|
|
2
|
+
reader: ReadableStreamDefaultReader<Uint8Array>,
|
|
3
|
+
processMessage: (message: string) => void | Promise<void>,
|
|
4
|
+
) {
|
|
5
|
+
const decoder = new TextDecoder();
|
|
6
|
+
let buffer = "";
|
|
7
|
+
while (true) {
|
|
8
|
+
const { done, value } = await reader.read();
|
|
9
|
+
|
|
10
|
+
if (done) {
|
|
11
|
+
if (buffer.length > 0) {
|
|
12
|
+
processMessage(buffer);
|
|
13
|
+
}
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
buffer += decoder.decode(value, { stream: true });
|
|
18
|
+
|
|
19
|
+
let endIndex: number;
|
|
20
|
+
while ((endIndex = buffer.indexOf("\n")) !== -1) {
|
|
21
|
+
processMessage(buffer.substring(0, endIndex).trim());
|
|
22
|
+
buffer = buffer.substring(endIndex + 1); // Remove the processed instruction + delimiter
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
package/dist/chunk-3BOHSSKR.mjs
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { __spreadProps, __spreadValues } from './chunk-MRXNTQOX.mjs';
|
|
2
|
-
import { nanoid } from 'nanoid';
|
|
3
|
-
import { useReducer, useCallback } from 'react';
|
|
4
|
-
|
|
5
|
-
var removeNode = (nodes, id) => {
|
|
6
|
-
return nodes.reduce((result, node) => {
|
|
7
|
-
if (node.id !== id) {
|
|
8
|
-
const newNode = __spreadProps(__spreadValues({}, node), { children: removeNode(node.children, id) });
|
|
9
|
-
result.push(newNode);
|
|
10
|
-
}
|
|
11
|
-
return result;
|
|
12
|
-
}, []);
|
|
13
|
-
};
|
|
14
|
-
var addNode = (nodes, newNode, parentId) => {
|
|
15
|
-
if (!parentId) {
|
|
16
|
-
return [...nodes, newNode];
|
|
17
|
-
}
|
|
18
|
-
return nodes.map((node) => {
|
|
19
|
-
if (node.id === parentId) {
|
|
20
|
-
return __spreadProps(__spreadValues({}, node), { children: [...node.children, newNode] });
|
|
21
|
-
} else if (node.children.length) {
|
|
22
|
-
return __spreadProps(__spreadValues({}, node), { children: addNode(node.children, newNode, parentId) });
|
|
23
|
-
}
|
|
24
|
-
return node;
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
var treeIndentationRepresentation = (index, indentLevel) => {
|
|
28
|
-
if (indentLevel === 0) {
|
|
29
|
-
return (index + 1).toString();
|
|
30
|
-
} else if (indentLevel === 1) {
|
|
31
|
-
return String.fromCharCode(65 + index);
|
|
32
|
-
} else if (indentLevel === 2) {
|
|
33
|
-
return String.fromCharCode(97 + index);
|
|
34
|
-
} else {
|
|
35
|
-
return "-";
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var printNode = (node, prefix = "", indentLevel = 0) => {
|
|
39
|
-
const indent = " ".repeat(3).repeat(indentLevel);
|
|
40
|
-
const prefixPlusIndentLength = prefix.length + indent.length;
|
|
41
|
-
const subsequentLinesPrefix = " ".repeat(prefixPlusIndentLength);
|
|
42
|
-
const valueLines = node.value.split("\n");
|
|
43
|
-
const outputFirstLine = `${indent}${prefix}${valueLines[0]}`;
|
|
44
|
-
const outputSubsequentLines = valueLines.slice(1).map((line) => `${subsequentLinesPrefix}${line}`).join("\n");
|
|
45
|
-
let output = `${outputFirstLine}
|
|
46
|
-
`;
|
|
47
|
-
if (outputSubsequentLines) {
|
|
48
|
-
output += `${outputSubsequentLines}
|
|
49
|
-
`;
|
|
50
|
-
}
|
|
51
|
-
const childPrePrefix = " ".repeat(prefix.length);
|
|
52
|
-
node.children.forEach(
|
|
53
|
-
(child, index) => output += printNode(
|
|
54
|
-
child,
|
|
55
|
-
`${childPrePrefix}${treeIndentationRepresentation(
|
|
56
|
-
index,
|
|
57
|
-
indentLevel + 1
|
|
58
|
-
)}. `,
|
|
59
|
-
indentLevel + 1
|
|
60
|
-
)
|
|
61
|
-
);
|
|
62
|
-
return output;
|
|
63
|
-
};
|
|
64
|
-
function treeReducer(state, action) {
|
|
65
|
-
switch (action.type) {
|
|
66
|
-
case "ADD_NODE": {
|
|
67
|
-
const { value, parentId, id: newNodeId } = action;
|
|
68
|
-
const newNode = {
|
|
69
|
-
id: newNodeId,
|
|
70
|
-
value,
|
|
71
|
-
children: [],
|
|
72
|
-
categories: new Set(action.categories)
|
|
73
|
-
};
|
|
74
|
-
try {
|
|
75
|
-
return addNode(state, newNode, parentId);
|
|
76
|
-
} catch (error) {
|
|
77
|
-
console.error(`Error while adding node with id ${newNodeId}: ${error}`);
|
|
78
|
-
return state;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
case "REMOVE_NODE":
|
|
82
|
-
return removeNode(state, action.id);
|
|
83
|
-
default:
|
|
84
|
-
return state;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
var useTree = () => {
|
|
88
|
-
const [tree, dispatch] = useReducer(treeReducer, []);
|
|
89
|
-
const addElement = useCallback(
|
|
90
|
-
(value, categories, parentId) => {
|
|
91
|
-
const newNodeId = nanoid();
|
|
92
|
-
dispatch({
|
|
93
|
-
type: "ADD_NODE",
|
|
94
|
-
value,
|
|
95
|
-
parentId,
|
|
96
|
-
id: newNodeId,
|
|
97
|
-
categories
|
|
98
|
-
});
|
|
99
|
-
return newNodeId;
|
|
100
|
-
},
|
|
101
|
-
[]
|
|
102
|
-
);
|
|
103
|
-
const removeElement = useCallback((id) => {
|
|
104
|
-
dispatch({ type: "REMOVE_NODE", id });
|
|
105
|
-
}, []);
|
|
106
|
-
const printTree = useCallback(
|
|
107
|
-
(categories) => {
|
|
108
|
-
const categoriesSet = new Set(categories);
|
|
109
|
-
let output = "";
|
|
110
|
-
tree.forEach((node, index) => {
|
|
111
|
-
if (!setsHaveIntersection(categoriesSet, node.categories)) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (index !== 0) {
|
|
115
|
-
output += "\n";
|
|
116
|
-
}
|
|
117
|
-
output += printNode(
|
|
118
|
-
node,
|
|
119
|
-
`${treeIndentationRepresentation(index, 0)}. `
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
return output;
|
|
123
|
-
},
|
|
124
|
-
[tree]
|
|
125
|
-
);
|
|
126
|
-
return { tree, addElement, printTree, removeElement };
|
|
127
|
-
};
|
|
128
|
-
var use_tree_default = useTree;
|
|
129
|
-
function setsHaveIntersection(setA, setB) {
|
|
130
|
-
const [smallerSet, largerSet] = setA.size <= setB.size ? [setA, setB] : [setB, setA];
|
|
131
|
-
for (let item of smallerSet) {
|
|
132
|
-
if (largerSet.has(item)) {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export { use_tree_default };
|
|
140
|
-
//# sourceMappingURL=out.js.map
|
|
141
|
-
//# sourceMappingURL=chunk-3BOHSSKR.mjs.map
|