@chatbotkit/react 0.8.0 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,304 +1,126 @@
1
1
  "use strict";
2
- /* eslint-disable @typescript-eslint/ban-ts-comment */
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useConversationManager = void 0;
4
4
  const react_1 = require("react");
5
- const index_js_1 = require("@chatbotkit/sdk/conversation/index.cjs");
6
- const string_js_1 = require("../utils/string.cjs");
7
- /**
8
- * @typedef {{
9
- * id: string,
10
- * type: string,
11
- * text: string,
12
- * createdAt: number,
13
- * meta?: Record<string,any>
14
- * }} Message
15
- *
16
- * @typedef {(error: any) => any} onErrorFn
17
- * @typedef {(conversationId: string, messages: Message[], data: Record<string,any>) => any} onSendFn
18
- * @typedef {(conversationId: string, messages: Message[], data: Record<string,any>) => any} onReceiveFn
19
- *
20
- * @param {{
21
- * conversationId?: string,
22
- * token?: string,
23
- * messages?: Message[],
24
- * stream?: boolean,
25
- * verbose?: boolean,
26
- * onError?: onErrorFn?,
27
- * onSend?: onSendFn?,
28
- * onReceive?: onReceiveFn?,
29
- * }}[options]
30
- */
31
- // @ts-ignore
32
- function useConversationManager({ conversationId: _conversationId = '', token: _token = '', messages: _messages = [], stream = false, verbose = false, onError = null, onSend = null, onReceive = null, } = {}) {
33
- // general states
34
- const [conversationId, setConversationId] = (0, react_1.useState)(_conversationId);
5
+ const sdk_1 = require("@chatbotkit/sdk");
6
+ const object_js_1 = require("../utils/object...cjs");
7
+ function useConversationManager(options) {
8
+ const { client: _client, endpoint, token: _token, conversationId: _conversationId, backstory: _backstory, model: _model, datasetId: _datasetId, skillsetId: _skillsetId, ...rest } = options;
35
9
  const [token, setToken] = (0, react_1.useState)(_token);
36
- const [messages, setMessages] = (0, react_1.useState)(_messages);
37
- const [text, setText] = (0, react_1.useState)('');
38
- const [entities, setEntities] = (0, react_1.useState)({});
39
- const [outgoingMessage, setOutgoingMessage] = (0, react_1.useState)('');
40
- // loading & thinking state
41
- const [loading, setLoading] = (0, react_1.useState)(false);
42
- const [thinking, setThinking] = (0, react_1.useState)(false);
43
- (0, react_1.useEffect)(() => {
44
- // NOTE: if we are loading we must be thinking
45
- if (loading) {
46
- setThinking(true);
10
+ const [conversationId, setConversationId] = (0, react_1.useState)(_conversationId);
11
+ const [backstory, setBackstory] = (0, react_1.useState)(_backstory);
12
+ const [model, setModel] = (0, react_1.useState)(_model);
13
+ const [datasetId, setDatasetId] = (0, react_1.useState)(_datasetId);
14
+ const [skillsetId, setSkillsetId] = (0, react_1.useState)(_skillsetId);
15
+ const client = (0, react_1.useMemo)(() => {
16
+ var _a, _b;
17
+ const options = { ...rest, secret: token || '' };
18
+ let thisClient = _client || new sdk_1.ConversationClient(options);
19
+ const extension = {};
20
+ if (endpoint) {
21
+ extension.url = new URL(((_b = (_a = globalThis.window) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.origin) || 'about:blank');
22
+ extension.endpoints = {
23
+ '/api/v1/conversation/complete': endpoint,
24
+ };
47
25
  }
48
- }, [loading]);
49
- // entity methods
50
- /**
51
- * @param {string} text
52
- * @param {Record<string,string>} en
53
- */
54
- function redactEnitities(text, en = entities) {
55
- const steps = (0, string_js_1.replaceWithCoordinates)(text, Object.entries(en));
56
- const output = steps.pop();
57
- steps.forEach((step) => {
58
- // @ts-ignore
59
- delete step.input;
60
- // @ts-ignore
61
- delete step.output;
62
- });
63
- return [output, ...steps];
64
- }
65
- /**
66
- * @param {string} text
67
- * @param {Record<string,string>} en
68
- */
69
- function unredactEnitities(text, en = entities) {
70
- Object.entries(en).forEach(([real, redacted]) => {
71
- text = text.split(redacted).join(real);
72
- });
73
- return text;
74
- }
75
- // state utility methods
76
- /**
77
- * @returns {Promise<void>}
78
- */
79
- async function flushUserMessage() {
26
+ if (token) {
27
+ extension.secret = token;
28
+ }
29
+ if (Object.keys(extension).length === 0) {
30
+ return thisClient;
31
+ }
32
+ return (0, object_js_1.cloneAndExtend)(thisClient, extension);
33
+ }, [_client, endpoint, token]);
34
+ const [text, setText] = (0, react_1.useState)((''));
35
+ const [messages, setMessages] = (0, react_1.useState)(([]));
36
+ const [thinking, setThinking] = (0, react_1.useState)(false);
37
+ const [writing, setWriting] = (0, react_1.useState)(false);
38
+ const [error, setError] = (0, react_1.useState)((null));
39
+ async function submit() {
80
40
  if (!text) {
81
41
  return;
82
42
  }
83
43
  setText('');
84
- setOutgoingMessage(text);
85
- let newMessages = messages.slice(0);
86
- newMessages = newMessages.concat({
87
- id: (0, string_js_1.getRandomId)('message-'),
44
+ const userMessage = {
88
45
  type: 'user',
89
- text,
90
- createdAt: Date.now(),
91
- });
92
- setMessages(newMessages);
93
- }
94
- // utility states
95
- const [nextStep, setNextStep] = (0, react_1.useState)(null);
96
- (0, react_1.useEffect)(() => {
97
- if (!nextStep) {
98
- return;
99
- }
100
- setNextStep(null);
101
- // @ts-ignore
102
- switch (nextStep.fn) {
103
- case 'continueConversation':
104
- // @ts-ignore
105
- continueConversation(nextStep.options);
106
- break;
107
- default:
108
- // @ts-ignore
109
- throw new Error(`Unrecognised fn: ${nextStep.fn}`);
110
- }
111
- }, [nextStep]);
112
- // base methods
113
- /**
114
- * @param {{
115
- * token?: string,
116
- * }} [options]
117
- * @returns {Promise<void>}
118
- */
119
- async function continueConversation(options) {
46
+ text: text,
47
+ };
120
48
  let newMessages = messages.slice(0);
121
- let thisText;
122
- if (text) {
123
- thisText = text;
124
- const message = {
125
- id: (0, string_js_1.getRandomId)('message-'),
126
- text: text,
127
- type: 'user',
128
- createdAt: Date.now(),
129
- };
130
- newMessages = newMessages.concat([message]);
131
- setText('');
132
- }
133
- else if (outgoingMessage) {
134
- thisText = outgoingMessage;
135
- setOutgoingMessage('');
49
+ newMessages = [...newMessages, userMessage];
50
+ setMessages([...newMessages]);
51
+ setThinking(true);
52
+ let it;
53
+ try {
54
+ if (conversationId) {
55
+ it = client.complete(conversationId, { text });
56
+ }
57
+ else {
58
+ it = client.complete(null, {
59
+ backstory: backstory,
60
+ model: model,
61
+ datasetId: datasetId,
62
+ skillsetId: skillsetId,
63
+ messages: newMessages.slice(-100),
64
+ });
65
+ }
136
66
  }
137
- else {
67
+ catch (e) {
68
+ setThinking(false);
69
+ setError(e);
138
70
  return;
139
71
  }
140
- setMessages(newMessages);
141
- setLoading(true);
142
- const [redactedText, ...redactedEntities] = redactEnitities(thisText, entities);
143
- const secret = options?.token || token;
144
- const client = new index_js_1.ConversationClient({ secret });
145
- // @ts-ignore
146
- const completion = client.complete(conversationId, {
147
- text: redactedText,
148
- entities: redactedEntities,
149
- });
150
- let iter;
151
- if (stream) {
152
- iter = completion.stream();
153
- }
154
- else {
155
- iter = (async function* () {
156
- yield { type: 'receiveResult', data: await completion };
157
- })();
158
- }
72
+ const botMessage = {
73
+ type: 'bot',
74
+ text: '',
75
+ };
76
+ let alreadyStreaming = false;
159
77
  try {
160
- if (onSend) {
161
- await onSend(conversationId, newMessages, {});
162
- }
163
- const tempId = (0, string_js_1.getRandomId)('tmp-');
164
- let tempText = '';
165
- for await (let { type, data } of iter) {
166
- switch (type) {
167
- case 'intentDetectionEnd': {
168
- if (!verbose) {
169
- break;
170
- }
171
- const { action } = data;
172
- if (!action) {
173
- break;
174
- }
175
- const { name, input } = action;
176
- switch (name) {
177
- case 'search': {
178
- const id = (0, string_js_1.getRandomId)('tmp-');
179
- newMessages = newMessages.concat([
180
- {
181
- id: id,
182
- text: '',
183
- type: 'context',
184
- createdAt: Date.now(),
185
- meta: {
186
- search: input,
187
- },
188
- },
189
- ]);
190
- setMessages(newMessages);
191
- break;
192
- }
193
- }
194
- break;
195
- }
196
- case 'token': {
197
- if (!stream) {
198
- break;
199
- }
200
- const { token } = data;
201
- tempText += token;
202
- setMessages([
203
- ...newMessages,
204
- {
205
- id: tempId,
206
- text: tempText,
207
- type: 'bot',
208
- createdAt: Date.now(),
209
- meta: {},
210
- },
211
- ]);
212
- if (tempText.length) {
213
- setThinking(false);
214
- }
215
- break;
216
- }
217
- case 'sendResult': {
218
- const { entities: newEntities } = data;
219
- setEntities({ ...entities, ...newEntities });
220
- break;
221
- }
222
- case 'receiveResult': {
223
- const { id, text, parse } = data;
224
- setMessages([
225
- ...newMessages,
226
- {
227
- id: id,
228
- text: unredactEnitities((parse ? parse.stripped : text).trim(), entities),
229
- type: 'bot',
230
- createdAt: Date.now(),
231
- },
232
- ]);
78
+ for await (const event of it.stream()) {
79
+ if (event.type === 'token') {
80
+ if (!alreadyStreaming) {
81
+ alreadyStreaming = true;
82
+ newMessages = [...newMessages, botMessage];
83
+ setMessages(newMessages);
233
84
  setThinking(false);
234
- if (onReceive) {
235
- await onReceive(conversationId, newMessages, data);
236
- }
237
- break;
85
+ setWriting(true);
238
86
  }
87
+ botMessage.text += event.data.token;
88
+ setMessages([...newMessages]);
239
89
  }
240
90
  }
241
91
  }
242
92
  catch (e) {
243
- if (onError) {
244
- onError(e);
245
- }
246
- }
247
- setLoading(false);
248
- }
249
- // helper methods
250
- /**
251
- * @param {{
252
- * token?: string,
253
- * conversationId?: string
254
- * messages?: Message[]
255
- * }} [options]
256
- * @returns {void}
257
- */
258
- function interact(options) {
259
- if (options?.token) {
260
- setToken(options.token);
261
- }
262
- if (options?.conversationId) {
263
- setConversationId(options.conversationId);
264
- }
265
- if (options?.messages) {
266
- setMessages(options.messages);
93
+ setError(e);
267
94
  }
268
- if (options?.conversationId || conversationId) {
269
- setNextStep({
270
- // @ts-ignore
271
- fn: 'continueConversation',
272
- options,
273
- });
95
+ finally {
96
+ setWriting(false);
274
97
  }
275
- else {
276
- throw new Error(`No conversation id specified`);
277
- }
278
- }
279
- /**
280
- * @returns {void}
281
- */
282
- function reset() {
283
- setMessages([]);
284
- setConversationId('');
285
98
  }
286
- // final
287
99
  return {
288
- text,
289
- setText,
290
100
  token,
291
101
  setToken,
292
102
  conversationId,
293
103
  setConversationId,
104
+ backstory,
105
+ setBackstory,
106
+ model,
107
+ setModel,
108
+ datasetId,
109
+ setDatasetId,
110
+ skillsetId,
111
+ setSkillsetId,
112
+ text,
113
+ setText,
294
114
  messages,
295
115
  setMessages,
296
- flushUserMessage,
297
- continueConversation,
298
- interact,
299
- reset,
300
- loading,
301
116
  thinking,
117
+ setThinking,
118
+ writing,
119
+ setWriting,
120
+ error,
121
+ setError,
122
+ submit,
302
123
  };
303
124
  }
125
+ exports.useConversationManager = useConversationManager;
304
126
  exports.default = useConversationManager;
@@ -1,65 +1,41 @@
1
- /**
2
- * @typedef {{
3
- * id: string,
4
- * type: string,
5
- * text: string,
6
- * createdAt: number,
7
- * meta?: Record<string,any>
8
- * }} Message
9
- *
10
- * @typedef {(error: any) => any} onErrorFn
11
- * @typedef {(conversationId: string, messages: Message[], data: Record<string,any>) => any} onSendFn
12
- * @typedef {(conversationId: string, messages: Message[], data: Record<string,any>) => any} onReceiveFn
13
- *
14
- * @param {{
15
- * conversationId?: string,
16
- * token?: string,
17
- * messages?: Message[],
18
- * stream?: boolean,
19
- * verbose?: boolean,
20
- * onError?: onErrorFn?,
21
- * onSend?: onSendFn?,
22
- * onReceive?: onReceiveFn?,
23
- * }}[options]
24
- */
25
- export default function useConversationManager({ conversationId: _conversationId, token: _token, messages: _messages, stream, verbose, onError, onSend, onReceive, }?: {
26
- conversationId?: string | undefined;
1
+ export function useConversationManager(options: {
2
+ [key: string]: any;
3
+ client?: ConversationClient | undefined;
4
+ endpoint?: string | undefined;
27
5
  token?: string | undefined;
28
- messages?: Message[] | undefined;
29
- stream?: boolean | undefined;
30
- verbose?: boolean | undefined;
31
- onError?: onErrorFn | null | undefined;
32
- onSend?: onSendFn | null | undefined;
33
- onReceive?: onReceiveFn | null | undefined;
34
- } | undefined): {
6
+ conversationId?: string | undefined;
7
+ backstory?: string | undefined;
8
+ model?: string | undefined;
9
+ datasetId?: string | undefined;
10
+ skillsetId?: string | undefined;
11
+ }): {
12
+ token: string | undefined;
13
+ setToken: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
14
+ conversationId: string | undefined;
15
+ setConversationId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
16
+ backstory: string | undefined;
17
+ setBackstory: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
18
+ model: string | undefined;
19
+ setModel: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
20
+ datasetId: string | undefined;
21
+ setDatasetId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
22
+ skillsetId: string | undefined;
23
+ setSkillsetId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
35
24
  text: string;
36
25
  setText: import("react").Dispatch<import("react").SetStateAction<string>>;
37
- token: string;
38
- setToken: import("react").Dispatch<import("react").SetStateAction<string>>;
39
- conversationId: string;
40
- setConversationId: import("react").Dispatch<import("react").SetStateAction<string>>;
41
26
  messages: Message[];
42
27
  setMessages: import("react").Dispatch<import("react").SetStateAction<Message[]>>;
43
- flushUserMessage: () => Promise<void>;
44
- continueConversation: (options?: {
45
- token?: string | undefined;
46
- } | undefined) => Promise<void>;
47
- interact: (options?: {
48
- token?: string | undefined;
49
- conversationId?: string | undefined;
50
- messages?: Message[] | undefined;
51
- } | undefined) => void;
52
- reset: () => void;
53
- loading: boolean;
54
28
  thinking: boolean;
29
+ setThinking: import("react").Dispatch<import("react").SetStateAction<boolean>>;
30
+ writing: boolean;
31
+ setWriting: import("react").Dispatch<import("react").SetStateAction<boolean>>;
32
+ error: any;
33
+ setError: import("react").Dispatch<any>;
34
+ submit: () => Promise<void>;
55
35
  };
36
+ export default useConversationManager;
56
37
  export type Message = {
57
- id: string;
58
- type: string;
38
+ type: 'bot' | 'user';
59
39
  text: string;
60
- createdAt: number;
61
- meta?: Record<string, any>;
62
40
  };
63
- export type onErrorFn = (error: any) => any;
64
- export type onSendFn = (conversationId: string, messages: Message[], data: Record<string, any>) => any;
65
- export type onReceiveFn = (conversationId: string, messages: Message[], data: Record<string, any>) => any;
41
+ import { ConversationClient } from '@chatbotkit/sdk';
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.useConversationManager = exports.AutoTextarea = void 0;
7
- var AutoTextarea_js_1 = require("./components/AutoTextarea.cjs");
8
- Object.defineProperty(exports, "AutoTextarea", { enumerable: true, get: function () { return __importDefault(AutoTextarea_js_1).default; } });
9
- var useConversationManager_js_1 = require("./hooks/useConversationManager.cjs");
10
- Object.defineProperty(exports, "useConversationManager", { enumerable: true, get: function () { return __importDefault(useConversationManager_js_1).default; } });
4
+ var AutoTextarea_js_1 = require("./components/AutoTextarea...cjs");
5
+ Object.defineProperty(exports, "AutoTextarea", { enumerable: true, get: function () { return AutoTextarea_js_1.AutoTextarea; } });
6
+ var useConversationManager_js_1 = require("./hooks/useConversationManager...cjs");
7
+ Object.defineProperty(exports, "useConversationManager", { enumerable: true, get: function () { return useConversationManager_js_1.useConversationManager; } });
@@ -1,2 +1,2 @@
1
- export { default as AutoTextarea } from "./components/AutoTextarea.js";
2
- export { default as useConversationManager } from "./hooks/useConversationManager.js";
1
+ export { AutoTextarea } from "./components/AutoTextarea.js";
2
+ export { useConversationManager } from "./hooks/useConversationManager.js";
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cloneAndExtend = void 0;
4
+ function cloneAndExtend(object, extension) {
5
+ return Object.assign(Object.assign(Object.create(Object.getPrototypeOf(object)), object), extension);
6
+ }
7
+ exports.cloneAndExtend = cloneAndExtend;
@@ -0,0 +1 @@
1
+ export function cloneAndExtend<T>(object: T, extension: object): T;
@@ -1,30 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.replaceWithCoordinates = exports.replaceBetween = exports.getRandomId = void 0;
4
- /**
5
- * @param {string} [prefix]
6
- * @returns {string}
7
- */
8
4
  function getRandomId(prefix) {
9
5
  return `${prefix || ''}${Math.random().toString(32).slice(2)}`;
10
6
  }
11
7
  exports.getRandomId = getRandomId;
12
- /**
13
- * @param {string} input
14
- * @param {number} begin
15
- * @param {number} end
16
- * @param {string} replacement
17
- * @returns {string}
18
- */
19
8
  function replaceBetween(input, begin, end, replacement) {
20
9
  return input.substring(0, begin) + replacement + input.substring(end);
21
10
  }
22
11
  exports.replaceBetween = replaceBetween;
23
- /**
24
- * @param {string} input
25
- * @param {[string, string][]} replacements
26
- * @returns {({begin: number, end: number, input: string, output: string}|string)[]}
27
- */
28
12
  function replaceWithCoordinates(input, replacements) {
29
13
  const output = [];
30
14
  let currentIndex = 0;
@@ -1,21 +1,5 @@
1
- /**
2
- * @param {string} [prefix]
3
- * @returns {string}
4
- */
5
1
  export function getRandomId(prefix?: string | undefined): string;
6
- /**
7
- * @param {string} input
8
- * @param {number} begin
9
- * @param {number} end
10
- * @param {string} replacement
11
- * @returns {string}
12
- */
13
2
  export function replaceBetween(input: string, begin: number, end: number, replacement: string): string;
14
- /**
15
- * @param {string} input
16
- * @param {[string, string][]} replacements
17
- * @returns {({begin: number, end: number, input: string, output: string}|string)[]}
18
- */
19
3
  export function replaceWithCoordinates(input: string, replacements: [string, string][]): (string | {
20
4
  begin: number;
21
5
  end: number;
@@ -1,20 +1,9 @@
1
- export function AutoScrollAnchor(): React.JSX.Element;
2
- /**
3
- * @param {{
4
- * anchor?: 'top'|'bottom',
5
- * childList?: boolean,
6
- * subtree?: boolean,
7
- * block?: 'start'|'end',
8
- * delay?: number,
9
- * [name: string]: any
10
- * }} props
11
- */
12
- export default function AutoScroller({ anchor, childList, subtree, block, delay, disabled, children, ...props }: {
1
+ export function AutoScroller(props?: {
13
2
  [name: string]: any;
14
3
  anchor?: "top" | "bottom" | undefined;
15
4
  childList?: boolean | undefined;
16
5
  subtree?: boolean | undefined;
17
- block?: "end" | "start" | undefined;
6
+ block?: "start" | "end" | undefined;
18
7
  delay?: number | undefined;
19
- }): React.JSX.Element;
20
- import React from 'react';
8
+ } | undefined): import("react/jsx-runtime").JSX.Element;
9
+ export default AutoScroller;