@chatbotkit/react 0.8.0 → 1.1.4

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,90 +1,57 @@
1
1
  "use strict";
2
- /* eslint-disable @typescript-eslint/ban-ts-comment */
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || function (mod) {
20
- if (mod && mod.__esModule) return mod;
21
- var result = {};
22
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
- __setModuleDefault(result, mod);
24
- return result;
25
- };
26
2
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.AutoScrollAnchor = void 0;
28
- const react_1 = __importStar(require("react"));
3
+ exports.AutoScroller = exports.AutoScrollAnchor = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = tslib_1.__importStar(require("react"));
29
7
  function AutoScrollAnchor() {
30
- return react_1.default.createElement("div", { className: "auto-scroll-anchor ![height:1px]" });
8
+ return (0, jsx_runtime_1.jsx)("div", { className: "auto-scroll-anchor ![height:1px]" });
31
9
  }
32
10
  exports.AutoScrollAnchor = AutoScrollAnchor;
33
- /**
34
- * @param {{
35
- * anchor?: 'top'|'bottom',
36
- * childList?: boolean,
37
- * subtree?: boolean,
38
- * block?: 'start'|'end',
39
- * delay?: number,
40
- * [name: string]: any
41
- * }} props
42
- */
43
- function AutoScroller({ anchor = 'bottom', childList = true, subtree = false, block = 'end', delay = 3000, disabled, children, ...props }) {
44
- const rootRef = (0, react_1.useRef)();
11
+ function AutoScroller(props) {
12
+ const { anchor = 'bottom', childList = true, subtree = false, block = 'end', delay = 3000, disabled, children, ...rest } = props || {};
13
+ const rootRef = ((0, react_1.useRef)());
45
14
  (0, react_1.useEffect)(() => {
15
+ var _a;
46
16
  if (disabled) {
47
17
  return;
48
18
  }
49
19
  let visible = false;
50
20
  let pause = false;
51
- let timeout = 0;
21
+ let timeout;
52
22
  const io = new IntersectionObserver((entries) => {
53
23
  if (pause) {
54
24
  return;
55
25
  }
56
26
  visible = entries.some((entry) => entry.isIntersecting);
57
27
  });
58
- // @ts-ignore
59
- io.observe(rootRef.current?.querySelector('.auto-scroll-anchor'));
28
+ const anchor = (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('.auto-scroll-anchor');
29
+ if (anchor) {
30
+ io.observe(anchor);
31
+ }
60
32
  const mo = new MutationObserver(() => {
33
+ var _a, _b;
61
34
  if (!visible) {
62
35
  return;
63
36
  }
64
37
  pause = true;
65
- rootRef.current
66
- // @ts-ignore
67
- ?.querySelector('.auto-scroll-anchor')
68
- ?.scrollIntoView({ behavior: 'smooth', block });
38
+ (_b = (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('.auto-scroll-anchor')) === null || _b === void 0 ? void 0 : _b.scrollIntoView({ behavior: 'smooth', block });
69
39
  clearTimeout(timeout);
70
- // @ts-ignore
71
40
  timeout = setTimeout(() => {
72
41
  visible = true;
73
42
  pause = false;
74
43
  }, delay);
75
44
  });
76
- // @ts-ignore
77
- mo.observe(rootRef.current, { childList, subtree });
45
+ const root = rootRef.current;
46
+ if (root) {
47
+ mo.observe(root, { childList, subtree });
48
+ }
78
49
  return () => {
79
50
  io.disconnect();
80
51
  mo.disconnect();
81
52
  };
82
53
  }, [disabled]);
83
- return (
84
- // @ts-ignore
85
- react_1.default.createElement("div", { ref: rootRef, ...props },
86
- anchor === 'top' ? react_1.default.createElement(AutoScrollAnchor, { key: "top" }) : null,
87
- children,
88
- anchor === 'bottom' ? react_1.default.createElement(AutoScrollAnchor, { key: "bottom" }) : null));
54
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: rootRef, ...rest, children: [anchor === 'top' ? (0, jsx_runtime_1.jsx)(AutoScrollAnchor, {}, "top") : null, children, anchor === 'bottom' ? (0, jsx_runtime_1.jsx)(AutoScrollAnchor, {}, "bottom") : null] }));
89
55
  }
56
+ exports.AutoScroller = AutoScroller;
90
57
  exports.default = AutoScroller;
@@ -1,20 +1,10 @@
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 AutoScrollAnchor(): import("react/jsx-runtime").JSX.Element;
2
+ export function AutoScroller(props?: {
13
3
  [name: string]: any;
14
- anchor?: "top" | "bottom" | undefined;
4
+ anchor?: "bottom" | "top" | undefined;
15
5
  childList?: boolean | undefined;
16
6
  subtree?: boolean | undefined;
17
7
  block?: "end" | "start" | undefined;
18
8
  delay?: number | undefined;
19
- }): React.JSX.Element;
20
- import React from 'react';
9
+ } | undefined): import("react/jsx-runtime").JSX.Element;
10
+ export default AutoScroller;
@@ -1,23 +1,11 @@
1
1
  "use strict";
2
- /* eslint-disable @typescript-eslint/ban-ts-comment */
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
2
  Object.defineProperty(exports, "__esModule", { value: true });
7
- const react_1 = __importDefault(require("react"));
8
- /**
9
- * @typedef {(event: React.ChangeEvent<HTMLTextAreaElement>) => any} onInputFn
10
- *
11
- * @param {{
12
- * onInput?: onInputFn?,
13
- * [name: string]: any
14
- * }} [props]
15
- */
16
- // @ts-ignore
17
- function AutoTextarea({ onInput, ...props } = {}) {
18
- /**
19
- * @param {React.ChangeEvent<HTMLTextAreaElement>} event
20
- */
3
+ exports.AutoTextarea = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = tslib_1.__importDefault(require("react"));
7
+ function AutoTextarea(props) {
8
+ const { onInput, ...rest } = props || {};
21
9
  function handleOnInput(event) {
22
10
  const adjustment = `calc(${[event.target.style.paddingTop, event.target.style.paddingBottom]
23
11
  .filter((f) => f)
@@ -28,6 +16,7 @@ function AutoTextarea({ onInput, ...props } = {}) {
28
16
  onInput(event);
29
17
  }
30
18
  }
31
- return react_1.default.createElement("textarea", { ...props, rows: 1, onInput: handleOnInput });
19
+ return (0, jsx_runtime_1.jsx)("textarea", { ...rest, rows: 1, onInput: handleOnInput });
32
20
  }
21
+ exports.AutoTextarea = AutoTextarea;
33
22
  exports.default = AutoTextarea;
@@ -1,14 +1,7 @@
1
- /**
2
- * @typedef {(event: React.ChangeEvent<HTMLTextAreaElement>) => any} onInputFn
3
- *
4
- * @param {{
5
- * onInput?: onInputFn?,
6
- * [name: string]: any
7
- * }} [props]
8
- */
9
- export default function AutoTextarea({ onInput, ...props }?: {
1
+ export function AutoTextarea(props?: {
10
2
  [name: string]: any;
11
3
  onInput?: onInputFn | null | undefined;
12
- } | undefined): React.JSX.Element;
4
+ } | undefined): import("react/jsx-runtime").JSX.Element;
5
+ export default AutoTextarea;
13
6
  export type onInputFn = (event: React.ChangeEvent<HTMLTextAreaElement>) => any;
14
7
  import React from 'react';
@@ -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;