@copilotkit/react-core 0.16.0-alpha.3 → 0.17.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.
Files changed (144) hide show
  1. package/.turbo/turbo-build.log +159 -125
  2. package/CHANGELOG.md +4 -36
  3. package/dist/components/copilot-provider/copilot-provider-props.d.ts +3 -3
  4. package/dist/components/copilot-provider/copilot-provider-props.mjs +1 -2
  5. package/dist/components/copilot-provider/copilot-provider-props.mjs.map +1 -1
  6. package/dist/components/copilot-provider/copilot-provider.d.ts +11 -6
  7. package/dist/components/copilot-provider/copilot-provider.mjs +468 -7
  8. package/dist/components/copilot-provider/copilot-provider.mjs.map +1 -1
  9. package/dist/components/copilot-provider/index.d.ts +3 -3
  10. package/dist/components/copilot-provider/index.mjs +467 -8
  11. package/dist/components/copilot-provider/index.mjs.map +1 -1
  12. package/dist/components/copilot-provider/{standard-cpilot-api-config.d.ts → standard-copilot-api-config.d.ts} +3 -3
  13. package/dist/{chunk-6N6X7K7T.mjs → components/copilot-provider/standard-copilot-api-config.mjs} +5 -5
  14. package/dist/components/copilot-provider/standard-copilot-api-config.mjs.map +1 -0
  15. package/dist/components/index.d.ts +3 -3
  16. package/dist/components/index.mjs +467 -9
  17. package/dist/components/index.mjs.map +1 -1
  18. package/dist/context/copilot-context.d.ts +6 -10
  19. package/dist/context/copilot-context.mjs +70 -3
  20. package/dist/context/copilot-context.mjs.map +1 -1
  21. package/dist/context/index.d.ts +4 -4
  22. package/dist/context/index.mjs +69 -4
  23. package/dist/context/index.mjs.map +1 -1
  24. package/dist/hooks/index.d.ts +6 -1
  25. package/dist/hooks/index.mjs +654 -14
  26. package/dist/hooks/index.mjs.map +1 -1
  27. package/dist/hooks/use-chat.d.ts +84 -0
  28. package/dist/hooks/use-chat.mjs +461 -0
  29. package/dist/hooks/use-chat.mjs.map +1 -0
  30. package/dist/hooks/use-copilot-chat.d.ts +10 -3
  31. package/dist/hooks/use-copilot-chat.mjs +599 -10
  32. package/dist/hooks/use-copilot-chat.mjs.map +1 -1
  33. package/dist/hooks/use-flat-category-store.mjs +68 -3
  34. package/dist/hooks/use-flat-category-store.mjs.map +1 -1
  35. package/dist/hooks/use-make-copilot-actionable.mjs +95 -4
  36. package/dist/hooks/use-make-copilot-actionable.mjs.map +1 -1
  37. package/dist/hooks/use-make-copilot-document-readable.mjs +87 -4
  38. package/dist/hooks/use-make-copilot-document-readable.mjs.map +1 -1
  39. package/dist/hooks/use-make-copilot-readable.mjs +87 -4
  40. package/dist/hooks/use-make-copilot-readable.mjs.map +1 -1
  41. package/dist/hooks/use-tree.mjs +153 -3
  42. package/dist/hooks/use-tree.mjs.map +1 -1
  43. package/dist/index.d.ts +6 -2
  44. package/dist/index.mjs +1204 -21
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/openai/chat-completion-client.d.ts +56 -0
  47. package/dist/openai/chat-completion-client.mjs +360 -0
  48. package/dist/openai/chat-completion-client.mjs.map +1 -0
  49. package/dist/openai/chat-completion-stream.d.ts +21 -0
  50. package/dist/openai/chat-completion-stream.mjs +221 -0
  51. package/dist/openai/chat-completion-stream.mjs.map +1 -0
  52. package/dist/openai/chat-completion-transport.d.ts +40 -0
  53. package/dist/openai/chat-completion-transport.mjs +181 -0
  54. package/dist/openai/chat-completion-transport.mjs.map +1 -0
  55. package/dist/openai/index.d.ts +10 -0
  56. package/dist/openai/index.mjs +221 -0
  57. package/dist/openai/index.mjs.map +1 -0
  58. package/dist/openai-assistants/hooks/index.mjs +235 -14
  59. package/dist/openai-assistants/hooks/index.mjs.map +1 -1
  60. package/dist/openai-assistants/hooks/use-assistants.mjs +52 -8
  61. package/dist/openai-assistants/hooks/use-assistants.mjs.map +1 -1
  62. package/dist/openai-assistants/hooks/use-copilot-chat-v2.mjs +236 -13
  63. package/dist/openai-assistants/hooks/use-copilot-chat-v2.mjs.map +1 -1
  64. package/dist/openai-assistants/index.mjs +236 -15
  65. package/dist/openai-assistants/index.mjs.map +1 -1
  66. package/dist/openai-assistants/utils/index.mjs +46 -4
  67. package/dist/openai-assistants/utils/index.mjs.map +1 -1
  68. package/dist/openai-assistants/utils/process-message-stream.mjs +46 -3
  69. package/dist/openai-assistants/utils/process-message-stream.mjs.map +1 -1
  70. package/dist/types/annotated-function.mjs +0 -2
  71. package/dist/types/annotated-function.mjs.map +1 -1
  72. package/dist/types/base.d.ts +56 -0
  73. package/dist/types/base.mjs +1 -0
  74. package/dist/types/base.mjs.map +1 -0
  75. package/dist/types/document-pointer.mjs +0 -2
  76. package/dist/types/document-pointer.mjs.map +1 -1
  77. package/dist/types/index.d.ts +1 -0
  78. package/dist/types/index.mjs +0 -2
  79. package/dist/types/index.mjs.map +1 -1
  80. package/dist/types/message.d.ts +2 -0
  81. package/dist/types/message.mjs +1 -0
  82. package/dist/types/message.mjs.map +1 -0
  83. package/dist/utils/utils.mjs +0 -2
  84. package/dist/utils/utils.mjs.map +1 -1
  85. package/dist/utils/utils.test.mjs +0 -1
  86. package/dist/utils/utils.test.mjs.map +1 -1
  87. package/package.json +3 -3
  88. package/src/components/copilot-provider/copilot-provider.tsx +14 -9
  89. package/src/context/copilot-context.tsx +3 -14
  90. package/src/context/index.ts +0 -1
  91. package/src/hooks/index.ts +1 -0
  92. package/src/hooks/use-chat.ts +197 -0
  93. package/src/hooks/use-copilot-chat.ts +10 -22
  94. package/src/index.tsx +1 -0
  95. package/src/openai/chat-completion-client.ts +240 -0
  96. package/src/openai/chat-completion-stream.ts +56 -0
  97. package/src/openai/chat-completion-transport.ts +190 -0
  98. package/src/openai/index.tsx +5 -0
  99. package/src/openai-assistants/hooks/use-copilot-chat-v2.ts +2 -2
  100. package/src/types/base.ts +61 -0
  101. package/src/types/index.ts +1 -0
  102. package/src/types/message.ts +0 -0
  103. package/dist/chunk-3MAIWZNZ.mjs +0 -58
  104. package/dist/chunk-3MAIWZNZ.mjs.map +0 -1
  105. package/dist/chunk-45PUEKTG.mjs +0 -19
  106. package/dist/chunk-45PUEKTG.mjs.map +0 -1
  107. package/dist/chunk-6LKBKYRJ.mjs +0 -165
  108. package/dist/chunk-6LKBKYRJ.mjs.map +0 -1
  109. package/dist/chunk-6LNDDH6K.mjs +0 -19
  110. package/dist/chunk-6LNDDH6K.mjs.map +0 -1
  111. package/dist/chunk-6N6X7K7T.mjs.map +0 -1
  112. package/dist/chunk-7GFKOIO7.mjs +0 -3
  113. package/dist/chunk-7GFKOIO7.mjs.map +0 -1
  114. package/dist/chunk-BABVSMJR.mjs +0 -3
  115. package/dist/chunk-BABVSMJR.mjs.map +0 -1
  116. package/dist/chunk-E3P5YZO2.mjs +0 -27
  117. package/dist/chunk-E3P5YZO2.mjs.map +0 -1
  118. package/dist/chunk-EFZPSZWO.mjs +0 -3
  119. package/dist/chunk-EFZPSZWO.mjs.map +0 -1
  120. package/dist/chunk-FRAKUJWH.mjs +0 -3
  121. package/dist/chunk-FRAKUJWH.mjs.map +0 -1
  122. package/dist/chunk-JD7BAH7U.mjs +0 -3
  123. package/dist/chunk-JD7BAH7U.mjs.map +0 -1
  124. package/dist/chunk-JHJ7LUTD.mjs +0 -125
  125. package/dist/chunk-JHJ7LUTD.mjs.map +0 -1
  126. package/dist/chunk-MRXNTQOX.mjs +0 -55
  127. package/dist/chunk-MRXNTQOX.mjs.map +0 -1
  128. package/dist/chunk-MZ5UN3BY.mjs +0 -28
  129. package/dist/chunk-MZ5UN3BY.mjs.map +0 -1
  130. package/dist/chunk-OFRZZ5OF.mjs +0 -79
  131. package/dist/chunk-OFRZZ5OF.mjs.map +0 -1
  132. package/dist/chunk-QACD2U6P.mjs +0 -3
  133. package/dist/chunk-QACD2U6P.mjs.map +0 -1
  134. package/dist/chunk-SPCZTZCY.mjs +0 -3
  135. package/dist/chunk-SPCZTZCY.mjs.map +0 -1
  136. package/dist/chunk-VUY2K2DI.mjs +0 -135
  137. package/dist/chunk-VUY2K2DI.mjs.map +0 -1
  138. package/dist/chunk-YPSGKPDA.mjs +0 -3
  139. package/dist/chunk-YPSGKPDA.mjs.map +0 -1
  140. package/dist/chunk-YULKJPY3.mjs +0 -70
  141. package/dist/chunk-YULKJPY3.mjs.map +0 -1
  142. package/dist/components/copilot-provider/standard-cpilot-api-config.mjs +0 -4
  143. package/dist/components/copilot-provider/standard-cpilot-api-config.mjs.map +0 -1
  144. /package/src/components/copilot-provider/{standard-cpilot-api-config.tsx → standard-copilot-api-config.tsx} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":["../../../src/openai-assistants/utils/process-message-stream.ts"],"sourcesContent":["export async function processMessageStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n processMessage: (message: string) => void | Promise<void>,\n) {\n const decoder = new TextDecoder();\n let buffer = \"\";\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n if (buffer.length > 0) {\n processMessage(buffer);\n }\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n let endIndex: number;\n while ((endIndex = buffer.indexOf(\"\\n\")) !== -1) {\n processMessage(buffer.substring(0, endIndex).trim());\n buffer = buffer.substring(endIndex + 1); // Remove the processed instruction + delimiter\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAsB,qBACpB,QACA,gBACA;AAAA;AACA,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AACb,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,UAAI,MAAM;AACR,YAAI,OAAO,SAAS,GAAG;AACrB,yBAAe,MAAM;AAAA,QACvB;AACA;AAAA,MACF;AAEA,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAEhD,UAAI;AACJ,cAAQ,WAAW,OAAO,QAAQ,IAAI,OAAO,IAAI;AAC/C,uBAAe,OAAO,UAAU,GAAG,QAAQ,EAAE,KAAK,CAAC;AACnD,iBAAS,OAAO,UAAU,WAAW,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA;","names":[]}
@@ -1,4 +1,47 @@
1
- export { processMessageStream } from '../../chunk-MZ5UN3BY.mjs';
2
- import '../../chunk-MRXNTQOX.mjs';
3
- //# sourceMappingURL=out.js.map
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+
22
+ // src/openai-assistants/utils/process-message-stream.ts
23
+ function processMessageStream(reader, processMessage) {
24
+ return __async(this, null, function* () {
25
+ const decoder = new TextDecoder();
26
+ let buffer = "";
27
+ while (true) {
28
+ const { done, value } = yield reader.read();
29
+ if (done) {
30
+ if (buffer.length > 0) {
31
+ processMessage(buffer);
32
+ }
33
+ break;
34
+ }
35
+ buffer += decoder.decode(value, { stream: true });
36
+ let endIndex;
37
+ while ((endIndex = buffer.indexOf("\n")) !== -1) {
38
+ processMessage(buffer.substring(0, endIndex).trim());
39
+ buffer = buffer.substring(endIndex + 1);
40
+ }
41
+ }
42
+ });
43
+ }
44
+ export {
45
+ processMessageStream
46
+ };
4
47
  //# sourceMappingURL=process-message-stream.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":["../../../src/openai-assistants/utils/process-message-stream.ts"],"sourcesContent":["export async function processMessageStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n processMessage: (message: string) => void | Promise<void>,\n) {\n const decoder = new TextDecoder();\n let buffer = \"\";\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n if (buffer.length > 0) {\n processMessage(buffer);\n }\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n let endIndex: number;\n while ((endIndex = buffer.indexOf(\"\\n\")) !== -1) {\n processMessage(buffer.substring(0, endIndex).trim());\n buffer = buffer.substring(endIndex + 1); // Remove the processed instruction + delimiter\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAsB,qBACpB,QACA,gBACA;AAAA;AACA,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AACb,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,UAAI,MAAM;AACR,YAAI,OAAO,SAAS,GAAG;AACrB,yBAAe,MAAM;AAAA,QACvB;AACA;AAAA,MACF;AAEA,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAEhD,UAAI;AACJ,cAAQ,WAAW,OAAO,QAAQ,IAAI,OAAO,IAAI;AAC/C,uBAAe,OAAO,UAAU,GAAG,QAAQ,EAAE,KAAK,CAAC;AACnD,iBAAS,OAAO,UAAU,WAAW,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA;","names":[]}
@@ -1,3 +1 @@
1
-
2
- //# sourceMappingURL=out.js.map
3
1
  //# sourceMappingURL=annotated-function.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,56 @@
1
+ type Role = "system" | "user" | "assistant" | "function";
2
+ interface Message {
3
+ id: string;
4
+ createdAt?: Date;
5
+ content: string;
6
+ role: Role;
7
+ /**
8
+ * If the message has a role of `function`, the `name` field is the name of the function.
9
+ * Otherwise, the name field should not be set.
10
+ */
11
+ name?: string;
12
+ /**
13
+ * If the assistant role makes a function call, the `function_call` field
14
+ * contains the function call name and arguments. Otherwise, the field should
15
+ * not be set.
16
+ */
17
+ function_call?: FunctionCall;
18
+ }
19
+ interface FunctionCall {
20
+ /**
21
+ * The arguments to call the function with, as generated by the model in JSON
22
+ * format. Note that the model does not always generate valid JSON, and may
23
+ * hallucinate parameters not defined by your function schema. Validate the
24
+ * arguments in your code before calling your function.
25
+ */
26
+ arguments?: string;
27
+ /**
28
+ * The name of the function to call.
29
+ */
30
+ name?: string;
31
+ }
32
+ interface Function {
33
+ /**
34
+ * The name of the function to be called. Must be a-z, A-Z, 0-9, or contain
35
+ * underscores and dashes, with a maximum length of 64.
36
+ */
37
+ name: string;
38
+ /**
39
+ * The parameters the functions accepts, described as a JSON Schema object. See the
40
+ * [guide](/docs/guides/gpt/function-calling) for examples, and the
41
+ * [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for
42
+ * documentation about the format.
43
+ *
44
+ * To describe a function that accepts no parameters, provide the value
45
+ * `{"type": "object", "properties": {}}`.
46
+ */
47
+ parameters: Record<string, unknown>;
48
+ /**
49
+ * A description of what the function does, used by the model to choose when and
50
+ * how to call the function.
51
+ */
52
+ description?: string;
53
+ }
54
+ type FunctionCallHandler = (chatMessages: Message[], functionCall: FunctionCall) => Promise<void>;
55
+
56
+ export { Function, FunctionCall, FunctionCallHandler, Message, Role };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=base.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,3 +1 @@
1
-
2
- //# sourceMappingURL=out.js.map
3
1
  //# sourceMappingURL=document-pointer.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,2 +1,3 @@
1
1
  export { AnnotatedFunction, AnnotatedFunctionArgument } from './annotated-function.js';
2
2
  export { DocumentPointer } from './document-pointer.js';
3
+ export { Function, FunctionCall, FunctionCallHandler, Message, Role } from './base.js';
@@ -1,3 +1 @@
1
- import '../chunk-EFZPSZWO.mjs';
2
- //# sourceMappingURL=out.js.map
3
1
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=message.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,3 +1 @@
1
-
2
- //# sourceMappingURL=out.js.map
3
1
  //# sourceMappingURL=utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -4,5 +4,4 @@ describe("emptyTest", () => {
4
4
  expect(true).toBeTruthy();
5
5
  });
6
6
  });
7
- //# sourceMappingURL=out.js.map
8
7
  //# sourceMappingURL=utils.test.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/utils.test.ts"],"names":[],"mappings":";AAEA,SAAS,aAAa,MAAM;AAC1B,KAAG,oBAAoB,MAAM;AAC3B,WAAO,IAAI,EAAE,WAAW;AAAA,EAC1B,CAAC;AACH,CAAC","sourcesContent":["import * as utils from \"./utils\";\n\ndescribe(\"emptyTest\", () => {\n it(\"should be truthy\", () => {\n expect(true).toBeTruthy();\n });\n});\n"]}
1
+ {"version":3,"sources":["../../src/utils/utils.test.ts"],"sourcesContent":["import * as utils from \"./utils\";\n\ndescribe(\"emptyTest\", () => {\n it(\"should be truthy\", () => {\n expect(true).toBeTruthy();\n });\n});\n"],"mappings":";AAEA,SAAS,aAAa,MAAM;AAC1B,KAAG,oBAAoB,MAAM;AAC3B,WAAO,IAAI,EAAE,WAAW;AAAA,EAC1B,CAAC;AACH,CAAC;","names":[]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.16.0-alpha.3",
7
+ "version": "0.17.0-alpha.0",
8
8
  "sideEffects": false,
9
9
  "main": "./dist/index.js",
10
10
  "module": "./dist/index.mjs",
@@ -27,10 +27,10 @@
27
27
  "eslint-config-custom": "0.2.0"
28
28
  },
29
29
  "dependencies": {
30
- "ai": "^2.2.23",
30
+ "eventemitter3": "^5.0.1",
31
31
  "nanoid": "^4.0.2",
32
32
  "openai": "^4.6.0",
33
- "@copilotkit/shared": "0.2.0-alpha.3"
33
+ "@copilotkit/shared": "0.1.0"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsup --treeshake",
@@ -1,14 +1,13 @@
1
1
  "use client";
2
2
 
3
- import { FunctionCallHandler } from "ai";
4
3
  import { useCallback, useState } from "react";
5
4
  import { CopilotContext, CopilotApiConfig } from "../../context/copilot-context";
6
5
  import useTree from "../../hooks/use-tree";
7
6
  import { AnnotatedFunction } from "../../types/annotated-function";
8
7
  import { ChatCompletionCreateParams } from "openai/resources/chat";
9
- import { DocumentPointer } from "../../types";
8
+ import { DocumentPointer, FunctionCallHandler } from "../../types";
10
9
  import useFlatCategoryStore from "../../hooks/use-flat-category-store";
11
- import { StandardCopilotApiConfig } from "./standard-cpilot-api-config";
10
+ import { StandardCopilotApiConfig } from "./standard-copilot-api-config";
12
11
  import { CopilotProviderProps } from "./copilot-provider-props";
13
12
 
14
13
  /**
@@ -16,9 +15,14 @@ import { CopilotProviderProps } from "./copilot-provider-props";
16
15
  * This component provides the Copilot context to its children.
17
16
  * It can be configured either with a chat API endpoint or a CopilotApiConfig.
18
17
  *
18
+ * NOTE: The backend can use OpenAI, or you can bring your own LLM.
19
+ * For examples of the backend api implementation, see `examples/next-openai` usage (under `src/api/copilotkit`),
20
+ * or read the documentation at https://docs.copilotkit.ai
21
+ * In particular, Getting-Started > Quickstart-Backend: https://docs.copilotkit.ai/getting-started/quickstart-backend
22
+ *
19
23
  * Example usage:
20
24
  * ```
21
- * <CopilotProvider chatApiEndpoint="https://api.copilot.chat">
25
+ * <CopilotProvider chatApiEndpoint="https://your.copilotkit.api">
22
26
  * <App />
23
27
  * </CopilotProvider>
24
28
  * ```
@@ -27,8 +31,8 @@ import { CopilotProviderProps } from "./copilot-provider-props";
27
31
  *
28
32
  * ```
29
33
  * const copilotApiConfig = new StandardCopilotApiConfig(
30
- * "https://api.copilot.chat",
31
- * "https://api.copilot.chat/v2",
34
+ * "https://your.copilotkit.api/v1",
35
+ * "https://your.copilotkit.api/v2",
32
36
  * {},
33
37
  * {}
34
38
  * );
@@ -50,6 +54,7 @@ export function CopilotProvider({ children, ...props }: CopilotProviderProps): J
50
54
  const [entryPoints, setEntryPoints] = useState<Record<string, AnnotatedFunction<any[]>>>({});
51
55
 
52
56
  const { addElement, removeElement, printTree } = useTree();
57
+
53
58
  const {
54
59
  addElement: addDocument,
55
60
  removeElement: removeDocument,
@@ -183,15 +188,15 @@ function entryPointsToFunctionCallHandler(
183
188
 
184
189
  const entryPointFunction = entrypointsByFunctionName[functionCall.name || ""];
185
190
  if (entryPointFunction) {
186
- let parsedFunctionCallArguments: Record<string, any>[] = [];
191
+ let functionCallArguments: Record<string, any>[] = [];
187
192
  if (functionCall.arguments) {
188
- parsedFunctionCallArguments = JSON.parse(functionCall.arguments);
193
+ functionCallArguments = JSON.parse(functionCall.arguments);
189
194
  }
190
195
 
191
196
  const paramsInCorrectOrder: any[] = [];
192
197
  for (let arg of entryPointFunction.argumentAnnotations) {
193
198
  paramsInCorrectOrder.push(
194
- parsedFunctionCallArguments[arg.name as keyof typeof parsedFunctionCallArguments],
199
+ functionCallArguments[arg.name as keyof typeof functionCallArguments],
195
200
  );
196
201
  }
197
202
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { FunctionCallHandler } from "ai";
3
+ import { FunctionCallHandler } from "../types";
4
4
  import React from "react";
5
5
  import { TreeNodeId } from "../hooks/use-tree";
6
6
  import { AnnotatedFunction } from "../types/annotated-function";
@@ -46,17 +46,6 @@ export interface CopilotApiConfig {
46
46
  body: Record<string, any>;
47
47
  }
48
48
 
49
- export function copilotApiConfigExtrapolator(config: CopilotApiConfig) {
50
- return {
51
- get chatApiEndpoint(): string {
52
- return `${config.chatApiEndpoint}`;
53
- },
54
- get chatApiEndpointV2(): string {
55
- return `${config.chatApiEndpointV2}`;
56
- },
57
- };
58
- }
59
-
60
49
  export interface CopilotContextParams {
61
50
  // function-calling
62
51
  entryPoints: Record<string, AnnotatedFunction<any[]>>;
@@ -66,14 +55,14 @@ export interface CopilotContextParams {
66
55
  getFunctionCallHandler: () => FunctionCallHandler;
67
56
 
68
57
  // text context
69
- getContextString: (documents: DocumentPointer[], categories: string[]) => string;
70
58
  addContext: (context: string, parentId?: string, categories?: string[]) => TreeNodeId;
71
59
  removeContext: (id: TreeNodeId) => void;
60
+ getContextString: (documents: DocumentPointer[], categories: string[]) => string;
72
61
 
73
62
  // document context
74
- getDocumentsContext: (categories: string[]) => DocumentPointer[];
75
63
  addDocumentContext: (documentPointer: DocumentPointer, categories?: string[]) => TreeNodeId;
76
64
  removeDocumentContext: (documentId: string) => void;
65
+ getDocumentsContext: (categories: string[]) => DocumentPointer[];
77
66
 
78
67
  // api endpoints
79
68
  copilotApiConfig: CopilotApiConfig;
@@ -1,4 +1,3 @@
1
1
  export { CopilotContext } from "./copilot-context";
2
2
  export type { CopilotContextParams } from "./copilot-context";
3
3
  export type { CopilotApiConfig } from "./copilot-context";
4
- export { copilotApiConfigExtrapolator } from "./copilot-context";
@@ -5,3 +5,4 @@ export type { UseCopilotChatReturn } from "./use-copilot-chat";
5
5
  export { useMakeCopilotActionable } from "./use-make-copilot-actionable";
6
6
  export { useMakeCopilotReadable } from "./use-make-copilot-readable";
7
7
  export { useMakeCopilotDocumentReadable } from "./use-make-copilot-document-readable";
8
+ export { type UseChatHelpers } from "./use-chat";
@@ -0,0 +1,197 @@
1
+ import { useState } from "react";
2
+ import { Message, Function, FunctionCallHandler } from "../types";
3
+ import { nanoid } from "nanoid";
4
+ import { ChatCompletionClient } from "../openai/chat-completion-client";
5
+ import { CopilotApiConfig } from "../context";
6
+
7
+ export type UseChatOptions = {
8
+ /**
9
+ * The API endpoint that accepts a `{ messages: Message[] }` object and returns
10
+ * a stream of tokens of the AI chat response. Defaults to `/api/chat`.
11
+ */
12
+ api?: string;
13
+ /**
14
+ * A unique identifier for the chat. If not provided, a random one will be
15
+ * generated. When provided, the `useChat` hook with the same `id` will
16
+ * have shared states across components.
17
+ */
18
+ id?: string;
19
+ /**
20
+ * System messages of the chat. Defaults to an empty array.
21
+ */
22
+ initialMessages?: Message[];
23
+ /**
24
+ * Callback function to be called when a function call is received.
25
+ * If the function returns a `ChatRequest` object, the request will be sent
26
+ * automatically to the API and will be used to update the chat.
27
+ */
28
+ onFunctionCall?: FunctionCallHandler;
29
+ /**
30
+ * HTTP headers to be sent with the API request.
31
+ */
32
+ headers?: Record<string, string> | Headers;
33
+ /**
34
+ * Extra body object to be sent with the API request.
35
+ * @example
36
+ * Send a `sessionId` to the API along with the messages.
37
+ * ```js
38
+ * useChat({
39
+ * body: {
40
+ * sessionId: '123',
41
+ * }
42
+ * })
43
+ * ```
44
+ */
45
+ body?: object;
46
+ /**
47
+ * Function definitions to be sent to the API.
48
+ */
49
+ functions?: Function[];
50
+ };
51
+
52
+ export type UseChatHelpers = {
53
+ /** Current messages in the chat */
54
+ messages: Message[];
55
+ /**
56
+ * Append a user message to the chat list. This triggers the API call to fetch
57
+ * the assistant's response.
58
+ * @param message The message to append
59
+ */
60
+ append: (message: Message) => Promise<void>;
61
+ /**
62
+ * Reload the last AI chat response for the given chat history. If the last
63
+ * message isn't from the assistant, it will request the API to generate a
64
+ * new response.
65
+ */
66
+ reload: () => Promise<void>;
67
+ /**
68
+ * Abort the current request immediately, keep the generated tokens if any.
69
+ */
70
+ stop: () => void;
71
+ /** The current value of the input */
72
+ input: string;
73
+ /** setState-powered method to update the input value */
74
+ setInput: React.Dispatch<React.SetStateAction<string>>;
75
+ /** Whether the API request is in progress */
76
+ isLoading: boolean;
77
+ };
78
+
79
+ export type UseChatOptionsWithCopilotConfig = UseChatOptions & {
80
+ copilotConfig: CopilotApiConfig;
81
+ };
82
+
83
+ export function useChat(options: UseChatOptionsWithCopilotConfig): UseChatHelpers {
84
+ const [messages, setMessages] = useState<Message[]>([]);
85
+ const [input, setInput] = useState("");
86
+ const [isLoading, setIsLoading] = useState(false);
87
+
88
+ const runChatCompletion = async (messages: Message[]): Promise<Message> => {
89
+ return new Promise<Message>((resolve, reject) => {
90
+ setIsLoading(true);
91
+
92
+ const assistantMessage: Message = {
93
+ id: nanoid(),
94
+ createdAt: new Date(),
95
+ content: "",
96
+ role: "assistant",
97
+ };
98
+
99
+ // Assistant messages are always copied when using setState
100
+ setMessages([...messages, { ...assistantMessage }]);
101
+
102
+ const messagesWithContext = [...(options.initialMessages || []), ...messages];
103
+
104
+ const client = new ChatCompletionClient({
105
+ url: options.api || "/api/copilotkit/openai",
106
+ });
107
+
108
+ const cleanup = () => {
109
+ client.off("content");
110
+ client.off("end");
111
+ client.off("error");
112
+ client.off("function");
113
+ };
114
+
115
+ client.on("content", (content) => {
116
+ assistantMessage.content += content;
117
+ setMessages([...messages, { ...assistantMessage }]);
118
+ });
119
+
120
+ client.on("end", () => {
121
+ setIsLoading(false);
122
+ cleanup();
123
+ resolve({ ...assistantMessage });
124
+ });
125
+
126
+ client.on("error", (error) => {
127
+ setIsLoading(false);
128
+ cleanup();
129
+ reject(error);
130
+ });
131
+
132
+ client.on("function", async (functionCall) => {
133
+ assistantMessage.function_call = {
134
+ name: functionCall.name,
135
+ arguments: JSON.stringify(functionCall.arguments),
136
+ };
137
+ setMessages([...messages, { ...assistantMessage }]);
138
+ // quit early if we get a function call
139
+ setIsLoading(false);
140
+ cleanup();
141
+ resolve({ ...assistantMessage });
142
+ });
143
+
144
+ client.fetch({
145
+ messages: messagesWithContext,
146
+ functions: options.functions,
147
+ headers: options.headers,
148
+ copilotConfig: options.copilotConfig,
149
+ });
150
+ });
151
+ };
152
+
153
+ const runChatCompletionAndHandleFunctionCall = async (messages: Message[]): Promise<void> => {
154
+ const message = await runChatCompletion(messages);
155
+ if (message.function_call && options.onFunctionCall) {
156
+ await options.onFunctionCall(messages, message.function_call);
157
+ }
158
+ };
159
+
160
+ const append = async (message: Message): Promise<void> => {
161
+ if (isLoading) {
162
+ return;
163
+ }
164
+ const newMessages = [...messages, message];
165
+ setMessages(newMessages);
166
+ return runChatCompletionAndHandleFunctionCall(newMessages);
167
+ };
168
+
169
+ const reload = async (): Promise<void> => {
170
+ if (isLoading || messages.length === 0) {
171
+ return;
172
+ }
173
+ let newMessages = [...messages];
174
+ const lastMessage = messages[messages.length - 1];
175
+
176
+ if (lastMessage.role === "assistant") {
177
+ newMessages = newMessages.slice(0, -1);
178
+ }
179
+ setMessages(newMessages);
180
+
181
+ return runChatCompletionAndHandleFunctionCall(newMessages);
182
+ };
183
+
184
+ const stop = (): void => {
185
+ throw new Error("Not implemented");
186
+ };
187
+
188
+ return {
189
+ messages,
190
+ append,
191
+ reload,
192
+ stop,
193
+ isLoading,
194
+ input,
195
+ setInput,
196
+ };
197
+ }
@@ -1,12 +1,7 @@
1
1
  import { useMemo, useContext } from "react";
2
- import {
3
- CopilotContext,
4
- CopilotContextParams,
5
- copilotApiConfigExtrapolator,
6
- } from "../context/copilot-context";
7
- import { useChat } from "ai/react";
8
- import { ChatRequestOptions, CreateMessage, Message } from "ai";
9
- import { UseChatOptions } from "ai";
2
+ import { CopilotContext, CopilotContextParams } from "../context/copilot-context";
3
+ import { Message } from "../types";
4
+ import { UseChatOptions, useChat } from "./use-chat";
10
5
  import { defaultCopilotContextCategories } from "../components";
11
6
  import { ChatCompletionCreateParams } from "openai/resources/chat";
12
7
 
@@ -16,11 +11,8 @@ export interface UseCopilotChatOptions extends UseChatOptions {
16
11
 
17
12
  export interface UseCopilotChatReturn {
18
13
  visibleMessages: Message[];
19
- append: (
20
- message: Message | CreateMessage,
21
- chatRequestOptions?: ChatRequestOptions,
22
- ) => Promise<string | null | undefined>;
23
- reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
14
+ append: (message: Message) => Promise<void>;
15
+ reload: () => Promise<void>;
24
16
  stop: () => void;
25
17
  isLoading: boolean;
26
18
  input: string;
@@ -49,23 +41,19 @@ export function useCopilotChat({
49
41
  };
50
42
  }, [getContextString, makeSystemMessage]);
51
43
 
52
- const initialMessagesWithContext = [systemMessage].concat(options.initialMessages || []);
53
-
54
44
  const functionDescriptions: ChatCompletionCreateParams.Function[] = useMemo(() => {
55
45
  return getChatCompletionFunctionDescriptions();
56
46
  }, [getChatCompletionFunctionDescriptions]);
57
47
 
58
48
  const { messages, append, reload, stop, isLoading, input, setInput } = useChat({
59
49
  ...options,
60
- api: copilotApiConfigExtrapolator(copilotApiConfig).chatApiEndpoint,
50
+ copilotConfig: copilotApiConfig,
61
51
  id: options.id,
62
- initialMessages: initialMessagesWithContext,
63
- experimental_onFunctionCall: getFunctionCallHandler(),
64
- headers: { ...copilotApiConfig.headers, ...options.headers },
52
+ initialMessages: [systemMessage].concat(options.initialMessages || []),
53
+ functions: functionDescriptions,
54
+ onFunctionCall: getFunctionCallHandler(),
55
+ headers: { ...options.headers },
65
56
  body: {
66
- id: options.id,
67
- ...(functionDescriptions.length > 0 && { functions: functionDescriptions }),
68
- ...copilotApiConfig.body,
69
57
  ...options.body,
70
58
  },
71
59
  });
package/src/index.tsx CHANGED
@@ -3,3 +3,4 @@ export * from "./context";
3
3
  export * from "./hooks";
4
4
  export * from "./types";
5
5
  export * from "./openai-assistants";
6
+ export * from "./openai";