@chatbotkit/react 0.7.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,89 +1,57 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.AutoScrollAnchor = void 0;
27
- 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"));
28
7
  function AutoScrollAnchor() {
29
- 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]" });
30
9
  }
31
10
  exports.AutoScrollAnchor = AutoScrollAnchor;
32
- /**
33
- * @param {{
34
- * anchor?: 'top'|'bottom',
35
- * childList?: boolean,
36
- * subtree?: boolean,
37
- * block?: 'start'|'end',
38
- * delay?: number,
39
- * [name: string]: any
40
- * }} props
41
- */
42
- function AutoScroller({ anchor = 'bottom', childList = true, subtree = false, block = 'end', delay = 3000, disabled, children, ...props }) {
43
- 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)());
44
14
  (0, react_1.useEffect)(() => {
15
+ var _a;
45
16
  if (disabled) {
46
17
  return;
47
18
  }
48
19
  let visible = false;
49
20
  let pause = false;
50
- let timeout = 0;
21
+ let timeout;
51
22
  const io = new IntersectionObserver((entries) => {
52
23
  if (pause) {
53
24
  return;
54
25
  }
55
26
  visible = entries.some((entry) => entry.isIntersecting);
56
27
  });
57
- // @ts-ignore
58
- 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
+ }
59
32
  const mo = new MutationObserver(() => {
33
+ var _a, _b;
60
34
  if (!visible) {
61
35
  return;
62
36
  }
63
37
  pause = true;
64
- rootRef.current
65
- // @ts-ignore
66
- ?.querySelector('.auto-scroll-anchor')
67
- ?.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 });
68
39
  clearTimeout(timeout);
69
- // @ts-ignore
70
40
  timeout = setTimeout(() => {
71
41
  visible = true;
72
42
  pause = false;
73
43
  }, delay);
74
44
  });
75
- // @ts-ignore
76
- mo.observe(rootRef.current, { childList, subtree });
45
+ const root = rootRef.current;
46
+ if (root) {
47
+ mo.observe(root, { childList, subtree });
48
+ }
77
49
  return () => {
78
50
  io.disconnect();
79
51
  mo.disconnect();
80
52
  };
81
53
  }, [disabled]);
82
- return (
83
- // @ts-ignore
84
- react_1.default.createElement("div", { ref: rootRef, ...props },
85
- anchor === 'top' ? react_1.default.createElement(AutoScrollAnchor, { key: "top" }) : null,
86
- children,
87
- 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] }));
88
55
  }
56
+ exports.AutoScroller = AutoScroller;
89
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,22 +1,11 @@
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
- const react_1 = __importDefault(require("react"));
7
- /**
8
- * @typedef {(event: React.ChangeEvent<HTMLTextAreaElement>) => any} onInputFn
9
- *
10
- * @param {{
11
- * onInput?: onInputFn?,
12
- * [name: string]: any
13
- * }} [props]
14
- */
15
- // @ts-ignore
16
- function AutoTextarea({ onInput, ...props } = {}) {
17
- /**
18
- * @param {React.ChangeEvent<HTMLTextAreaElement>} event
19
- */
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 || {};
20
9
  function handleOnInput(event) {
21
10
  const adjustment = `calc(${[event.target.style.paddingTop, event.target.style.paddingBottom]
22
11
  .filter((f) => f)
@@ -27,6 +16,7 @@ function AutoTextarea({ onInput, ...props } = {}) {
27
16
  onInput(event);
28
17
  }
29
18
  }
30
- return react_1.default.createElement("textarea", { ...props, rows: 1, onInput: handleOnInput });
19
+ return (0, jsx_runtime_1.jsx)("textarea", { ...rest, rows: 1, onInput: handleOnInput });
31
20
  }
21
+ exports.AutoTextarea = AutoTextarea;
32
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,306 +1,126 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useConversationManager = void 0;
3
4
  const react_1 = require("react");
4
- const index_js_1 = require("@chatbotkit/sdk/conversation/index.cjs");
5
- const string_js_1 = require("../utils/string.cjs");
6
- /**
7
- * @typedef {{
8
- * id: string,
9
- * type: string,
10
- * text: string,
11
- * createdAt: number,
12
- * meta?: Record<string,any>
13
- * }} Message
14
- *
15
- * @typedef {(error: any) => any} onErrorFn
16
- * @typedef {(conversationId: string, messages: Message[], data: Record<string,any>) => any} onSendFn
17
- * @typedef {(conversationId: string, messages: Message[], data: Record<string,any>) => any} onReceiveFn
18
- *
19
- * @param {{
20
- * conversationId?: string,
21
- * token?: string,
22
- * messages?: Message[],
23
- * parse?: boolean,
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 = [], parse = false, 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
- const completion = client.complete(conversationId, {
146
- // @ts-ignore
147
- text: redactedText,
148
- // @ts-ignore
149
- entities: redactedEntities,
150
- parse: parse,
151
- });
152
- let iter;
153
- if (stream) {
154
- iter = completion.stream();
155
- }
156
- else {
157
- iter = (async function* () {
158
- yield { type: 'receiveResult', data: await completion };
159
- })();
160
- }
72
+ const botMessage = {
73
+ type: 'bot',
74
+ text: '',
75
+ };
76
+ let alreadyStreaming = false;
161
77
  try {
162
- if (onSend) {
163
- await onSend(conversationId, newMessages, {});
164
- }
165
- const tempId = (0, string_js_1.getRandomId)('tmp-');
166
- let tempText = '';
167
- for await (let { type, data } of iter) {
168
- switch (type) {
169
- case 'intentDetectionEnd': {
170
- if (!verbose) {
171
- break;
172
- }
173
- const { action } = data;
174
- if (!action) {
175
- break;
176
- }
177
- const { name, input } = action;
178
- switch (name) {
179
- case 'search': {
180
- const id = (0, string_js_1.getRandomId)('tmp-');
181
- newMessages = newMessages.concat([
182
- {
183
- id: id,
184
- text: '',
185
- type: 'context',
186
- createdAt: Date.now(),
187
- meta: {
188
- search: input,
189
- },
190
- },
191
- ]);
192
- setMessages(newMessages);
193
- break;
194
- }
195
- }
196
- break;
197
- }
198
- case 'token': {
199
- if (!stream) {
200
- break;
201
- }
202
- const { token } = data;
203
- tempText += token;
204
- setMessages([
205
- ...newMessages,
206
- {
207
- id: tempId,
208
- text: tempText,
209
- type: 'bot',
210
- createdAt: Date.now(),
211
- meta: {},
212
- },
213
- ]);
214
- if (tempText.length) {
215
- setThinking(false);
216
- }
217
- break;
218
- }
219
- case 'sendResult': {
220
- const { entities: newEntities } = data;
221
- setEntities({ ...entities, ...newEntities });
222
- break;
223
- }
224
- case 'receiveResult': {
225
- const { id, text, parse } = data;
226
- setMessages([
227
- ...newMessages,
228
- {
229
- id: id,
230
- text: unredactEnitities((parse ? parse.stripped : text).trim(), entities),
231
- type: 'bot',
232
- createdAt: Date.now(),
233
- },
234
- ]);
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);
235
84
  setThinking(false);
236
- if (onReceive) {
237
- await onReceive(conversationId, newMessages, data);
238
- }
239
- break;
85
+ setWriting(true);
240
86
  }
87
+ botMessage.text += event.data.token;
88
+ setMessages([...newMessages]);
241
89
  }
242
90
  }
243
91
  }
244
92
  catch (e) {
245
- if (onError) {
246
- onError(e);
247
- }
248
- }
249
- setLoading(false);
250
- }
251
- // helper methods
252
- /**
253
- * @param {{
254
- * token?: string,
255
- * conversationId?: string
256
- * messages?: Message[]
257
- * }} [options]
258
- * @returns {void}
259
- */
260
- function interact(options) {
261
- if (options?.token) {
262
- setToken(options.token);
263
- }
264
- if (options?.conversationId) {
265
- setConversationId(options.conversationId);
266
- }
267
- if (options?.messages) {
268
- setMessages(options.messages);
93
+ setError(e);
269
94
  }
270
- if (options?.conversationId || conversationId) {
271
- setNextStep({
272
- // @ts-ignore
273
- fn: 'continueConversation',
274
- options,
275
- });
95
+ finally {
96
+ setWriting(false);
276
97
  }
277
- else {
278
- throw new Error(`No conversation id specified`);
279
- }
280
- }
281
- /**
282
- * @returns {void}
283
- */
284
- function reset() {
285
- setMessages([]);
286
- setConversationId('');
287
98
  }
288
- // final
289
99
  return {
290
- text,
291
- setText,
292
100
  token,
293
101
  setToken,
294
102
  conversationId,
295
103
  setConversationId,
104
+ backstory,
105
+ setBackstory,
106
+ model,
107
+ setModel,
108
+ datasetId,
109
+ setDatasetId,
110
+ skillsetId,
111
+ setSkillsetId,
112
+ text,
113
+ setText,
296
114
  messages,
297
115
  setMessages,
298
- flushUserMessage,
299
- continueConversation,
300
- interact,
301
- reset,
302
- loading,
303
116
  thinking,
117
+ setThinking,
118
+ writing,
119
+ setWriting,
120
+ error,
121
+ setError,
122
+ submit,
304
123
  };
305
124
  }
125
+ exports.useConversationManager = useConversationManager;
306
126
  exports.default = useConversationManager;