kooby 1.0.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.
@@ -0,0 +1,881 @@
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { TextArea, ActionButton, InlineAlert, Heading, Text, ProgressCircle, DialogTrigger, Popover } from '@react-spectrum/s2';
3
+ import Copy from '@react-spectrum/s2/icons/Copy';
4
+ import OpenIn from '@react-spectrum/s2/icons/OpenIn';
5
+ import Refresh from '@react-spectrum/s2/icons/Refresh';
6
+ import ThumbDown from '@react-spectrum/s2/icons/ThumbDown';
7
+ import ThumbUp from '@react-spectrum/s2/icons/ThumbUp';
8
+ import Markdown from 'markdown-to-jsx';
9
+
10
+ function _arrayLikeToArray(r, a) {
11
+ (null == a || a > r.length) && (a = r.length);
12
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
13
+ return n;
14
+ }
15
+ function _arrayWithHoles(r) {
16
+ if (Array.isArray(r)) return r;
17
+ }
18
+ function _arrayWithoutHoles(r) {
19
+ if (Array.isArray(r)) return _arrayLikeToArray(r);
20
+ }
21
+ function _assertThisInitialized(e) {
22
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
23
+ return e;
24
+ }
25
+ function _callSuper(t, o, e) {
26
+ return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
27
+ }
28
+ function _classCallCheck(a, n) {
29
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
30
+ }
31
+ function _defineProperties(e, r) {
32
+ for (var t = 0; t < r.length; t++) {
33
+ var o = r[t];
34
+ o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);
35
+ }
36
+ }
37
+ function _createClass(e, r, t) {
38
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
39
+ writable: false
40
+ }), e;
41
+ }
42
+ function _defineProperty(e, r, t) {
43
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
44
+ value: t,
45
+ enumerable: true,
46
+ configurable: true,
47
+ writable: true
48
+ }) : e[r] = t, e;
49
+ }
50
+ function _getPrototypeOf(t) {
51
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
52
+ return t.__proto__ || Object.getPrototypeOf(t);
53
+ }, _getPrototypeOf(t);
54
+ }
55
+ function _inherits(t, e) {
56
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
57
+ t.prototype = Object.create(e && e.prototype, {
58
+ constructor: {
59
+ value: t,
60
+ writable: true,
61
+ configurable: true
62
+ }
63
+ }), Object.defineProperty(t, "prototype", {
64
+ writable: false
65
+ }), e && _setPrototypeOf(t, e);
66
+ }
67
+ function _isNativeReflectConstruct() {
68
+ try {
69
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
70
+ } catch (t) {}
71
+ return (_isNativeReflectConstruct = function () {
72
+ return !!t;
73
+ })();
74
+ }
75
+ function _iterableToArray(r) {
76
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
77
+ }
78
+ function _iterableToArrayLimit(r, l) {
79
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
80
+ if (null != t) {
81
+ var e,
82
+ n,
83
+ i,
84
+ u,
85
+ a = [],
86
+ f = true,
87
+ o = false;
88
+ try {
89
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
90
+ } catch (r) {
91
+ o = true, n = r;
92
+ } finally {
93
+ try {
94
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
95
+ } finally {
96
+ if (o) throw n;
97
+ }
98
+ }
99
+ return a;
100
+ }
101
+ }
102
+ function _nonIterableRest() {
103
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
104
+ }
105
+ function _nonIterableSpread() {
106
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
107
+ }
108
+ function ownKeys(e, r) {
109
+ var t = Object.keys(e);
110
+ if (Object.getOwnPropertySymbols) {
111
+ var o = Object.getOwnPropertySymbols(e);
112
+ r && (o = o.filter(function (r) {
113
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
114
+ })), t.push.apply(t, o);
115
+ }
116
+ return t;
117
+ }
118
+ function _objectSpread2(e) {
119
+ for (var r = 1; r < arguments.length; r++) {
120
+ var t = null != arguments[r] ? arguments[r] : {};
121
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
122
+ _defineProperty(e, r, t[r]);
123
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
124
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
125
+ });
126
+ }
127
+ return e;
128
+ }
129
+ function _objectWithoutProperties(e, t) {
130
+ if (null == e) return {};
131
+ var o,
132
+ r,
133
+ i = _objectWithoutPropertiesLoose(e, t);
134
+ if (Object.getOwnPropertySymbols) {
135
+ var n = Object.getOwnPropertySymbols(e);
136
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
137
+ }
138
+ return i;
139
+ }
140
+ function _objectWithoutPropertiesLoose(r, e) {
141
+ if (null == r) return {};
142
+ var t = {};
143
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
144
+ if (-1 !== e.indexOf(n)) continue;
145
+ t[n] = r[n];
146
+ }
147
+ return t;
148
+ }
149
+ function _possibleConstructorReturn(t, e) {
150
+ if (e && ("object" == typeof e || "function" == typeof e)) return e;
151
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
152
+ return _assertThisInitialized(t);
153
+ }
154
+ function _setPrototypeOf(t, e) {
155
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
156
+ return t.__proto__ = e, t;
157
+ }, _setPrototypeOf(t, e);
158
+ }
159
+ function _slicedToArray(r, e) {
160
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
161
+ }
162
+ function _toConsumableArray(r) {
163
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
164
+ }
165
+ function _toPrimitive(t, r) {
166
+ if ("object" != typeof t || !t) return t;
167
+ var e = t[Symbol.toPrimitive];
168
+ if (void 0 !== e) {
169
+ var i = e.call(t, r);
170
+ if ("object" != typeof i) return i;
171
+ throw new TypeError("@@toPrimitive must return a primitive value.");
172
+ }
173
+ return ("string" === r ? String : Number)(t);
174
+ }
175
+ function _toPropertyKey(t) {
176
+ var i = _toPrimitive(t, "string");
177
+ return "symbol" == typeof i ? i : i + "";
178
+ }
179
+ function _unsupportedIterableToArray(r, a) {
180
+ if (r) {
181
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
182
+ var t = {}.toString.call(r).slice(8, -1);
183
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
184
+ }
185
+ }
186
+
187
+ var ChatManagerBase = /*#__PURE__*/function () {
188
+ function ChatManagerBase(_ref) {
189
+ var url = _ref.url,
190
+ onMessage = _ref.onMessage,
191
+ onOpen = _ref.onOpen,
192
+ onClose = _ref.onClose,
193
+ onError = _ref.onError,
194
+ authToken = _ref.authToken;
195
+ _classCallCheck(this, ChatManagerBase);
196
+ if ((this instanceof ChatManagerBase ? this.constructor : void 0) === ChatManagerBase) {
197
+ throw new TypeError("Cannot construct ChatManagerBase instances directly");
198
+ }
199
+ this.url = url;
200
+ this.onMessage = onMessage;
201
+ this.onOpen = onOpen;
202
+ this.onClose = onClose;
203
+ this.onError = onError;
204
+ this.authToken = authToken;
205
+ }
206
+
207
+ // Abstract methods that must be implemented by subclasses
208
+ return _createClass(ChatManagerBase, [{
209
+ key: "connect",
210
+ value: function connect(callback) {
211
+ throw new Error("connect method must be implemented by subclass");
212
+ }
213
+ }, {
214
+ key: "sendMessage",
215
+ value: function sendMessage(message) {
216
+ throw new Error("sendMessage method must be implemented by subclass");
217
+ }
218
+ }, {
219
+ key: "disconnect",
220
+ value: function disconnect() {
221
+ throw new Error("disconnect method must be implemented by subclass");
222
+ }
223
+ }]);
224
+ }();
225
+
226
+ var WSChatManager = /*#__PURE__*/function (_ChatManagerBase) {
227
+ function WSChatManager(_ref) {
228
+ var _this;
229
+ var url = _ref.url,
230
+ onMessage = _ref.onMessage,
231
+ onOpen = _ref.onOpen,
232
+ onClose = _ref.onClose,
233
+ onError = _ref.onError,
234
+ authToken = _ref.authToken;
235
+ _ref.agent;
236
+ _classCallCheck(this, WSChatManager);
237
+ // Format WebSocket URL with optional token
238
+ var wsUrl = url;
239
+ if (authToken) {
240
+ wsUrl += "?token=".concat(authToken);
241
+ }
242
+ _this = _callSuper(this, WSChatManager, [{
243
+ url: wsUrl,
244
+ onMessage: onMessage,
245
+ onOpen: onOpen,
246
+ onClose: onClose,
247
+ onError: onError,
248
+ authToken: authToken
249
+ }]);
250
+ _this.socket = null;
251
+ return _this;
252
+ }
253
+ _inherits(WSChatManager, _ChatManagerBase);
254
+ return _createClass(WSChatManager, [{
255
+ key: "connect",
256
+ value: function connect(cb) {
257
+ var _this2 = this;
258
+ this.socket = new WebSocket(this.url);
259
+
260
+ // Call the on Open and optional callback
261
+ this.socket.onopen = function () {
262
+ _this2.onOpen();
263
+ // Optional callback after connection is established
264
+ if (cb) cb();
265
+ };
266
+ this.socket.onmessage = function (event) {
267
+ var data = JSON.parse(event.data);
268
+ _this2.onMessage(data);
269
+ };
270
+ this.socket.onclose = this.onClose;
271
+ this.socket.onerror = this.onError;
272
+ }
273
+ }, {
274
+ key: "sendMessage",
275
+ value: function sendMessage(message) {
276
+ if (this.socket && this.socket.readyState === WebSocket.OPEN) {
277
+ this.socket.send(JSON.stringify(message));
278
+ } else {
279
+ console.error("WebSocket is not open");
280
+ }
281
+ }
282
+ }, {
283
+ key: "disconnect",
284
+ value: function disconnect() {
285
+ if (this.socket) {
286
+ this.socket.close();
287
+ }
288
+ }
289
+ }]);
290
+ }(ChatManagerBase);
291
+
292
+ var ChatManager = /*#__PURE__*/function () {
293
+ function ChatManager() {
294
+ _classCallCheck(this, ChatManager);
295
+ }
296
+ return _createClass(ChatManager, null, [{
297
+ key: "create",
298
+ value: function create(_ref) {
299
+ var url = _ref.url,
300
+ onMessage = _ref.onMessage,
301
+ onOpen = _ref.onOpen,
302
+ onClose = _ref.onClose,
303
+ onError = _ref.onError,
304
+ authToken = _ref.authToken,
305
+ agent = _ref.agent;
306
+ if (url.startsWith("ws://") || url.startsWith("wss://")) {
307
+ return new WSChatManager({
308
+ url: url,
309
+ onMessage: onMessage,
310
+ onOpen: onOpen,
311
+ onClose: onClose,
312
+ onError: onError,
313
+ authToken: authToken,
314
+ agent: agent
315
+ });
316
+ }
317
+ throw new Error("Kooby expects a WebSocket URL (ws:// or wss://). Got: ".concat(url));
318
+ }
319
+ }]);
320
+ }();
321
+
322
+ function styleInject(css, ref) {
323
+ if (ref === void 0) ref = {};
324
+ var insertAt = ref.insertAt;
325
+ if (typeof document === 'undefined') {
326
+ return;
327
+ }
328
+ var head = document.head || document.getElementsByTagName('head')[0];
329
+ var style = document.createElement('style');
330
+ style.type = 'text/css';
331
+ if (insertAt === 'top') {
332
+ if (head.firstChild) {
333
+ head.insertBefore(style, head.firstChild);
334
+ } else {
335
+ head.appendChild(style);
336
+ }
337
+ } else {
338
+ head.appendChild(style);
339
+ }
340
+ if (style.styleSheet) {
341
+ style.styleSheet.cssText = css;
342
+ } else {
343
+ style.appendChild(document.createTextNode(css));
344
+ }
345
+ }
346
+
347
+ var css_248z = ".kooby {\n width: 100%;\n max-width: 1000px;\n height: 100%;\n max-height: 90vh;\n padding: 30px;\n padding-top: 50px;\n border: 1px solid var(--kooby-border, rgba(0, 0, 0, 0.15));\n border-radius: 10px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.08);\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n position: relative;\n color: #000;\n}\n\n.site--app[data-theme=\"dark\"] .kooby,\n[data-color-scheme=\"dark\"] .kooby {\n border: none;\n box-shadow: 0 0 2px rgba(255, 255, 255, 0.12);\n background-color: var(--kooby-panel-bg, rgba(30, 30, 30, 0.95));\n color: #fff;\n}\n\n.kooby-focus {\n width: 100%;\n max-width: 100%;\n}\n\n.kooby-toolbar {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 4px;\n position: absolute;\n top: 0;\n right: 0;\n padding: 5px;\n box-sizing: border-box;\n}\n\n.kooby-conversation {\n display: flex;\n flex-direction: column;\n gap: 30px;\n flex: 2;\n overflow: scroll;\n\n scrollbar-width: none;\n}\n\n.kooby-conversation::-webkit-scrollbar {\n display: none;\n}\n\n.kooby-text-box {\n flex: 0 0 auto;\n}\n\n.kooby-message {\n display: flex;\n align-items: flex-start;\n width: 100%;\n}\n\n.kooby-message-role {\n min-width: 100px;\n height: 40px;\n padding: 10px;\n border-radius: 5px 0 0 5px;\n display: flex;\n align-items: center;\n /* justify-content: center; */\n}\n\n.kooby-message-role strong {\n color: #000;\n}\n\n[data-color-scheme=\"dark\"] .kooby-message-role strong {\n color: #fff;\n}\n\n.kooby-system {\n background-color: #d3d3d3;\n}\n\n.kooby-assistant {\n background-color: #d3d3d3;\n}\n\n[data-color-scheme=\"dark\"] .kooby-system,\n[data-color-scheme=\"dark\"] .kooby-assistant {\n background-color: #3a3a3a;\n}\n\n.kooby-user {\n background-color: rgb(59, 99, 251);\n}\n\n.kooby-user strong {\n color: white;\n}\n\n[data-color-scheme=\"dark\"] .kooby-user strong {\n color: white;\n}\n\n.kooby-content {\n padding: 10px;\n width: 100%;\n text-align: left;\n color: #000;\n margin-top: 10px;\n}\n\n[data-color-scheme=\"dark\"] .kooby-content {\n color: #fff;\n}\n\n.kooby-content :where(p, li, td, th, span, strong, em, h1, h2, h3, h4, h5, h6) {\n color: inherit;\n}\n\n.kooby .mermaid {\n background-color: white;\n border-radius: 5px;\n padding: 10px;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.kooby-debug {\n position: fixed;\n right: 0;\n top: 0;\n width: 30vw;\n height: 100vh;\n color: #111;\n overflow-y: auto;\n z-index: 1000;\n padding: 30px;\n background-color: white;\n}\n\n[data-color-scheme=\"dark\"] .kooby-debug {\n color: #f5f5f5;\n background-color: var(--kooby-panel-bg, rgba(30, 30, 30));\n}\n\n.kooby-debug pre {\n white-space: pre-wrap;\n}\n\n.kooby-debug-actions {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 10px;\n}\n\n.kooby-debug-actions button {\n font-size: 1rem;\n padding: 4px 8px;\n height: auto;\n min-height: unset;\n}\n\n.kooby-feedback {\n display: flex;\n margin-top: 10px;\n align-items: center;\n gap: 6px;\n}\n\n.qr-code {\n width: 200px;\n}\n\n.qr {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding-top: 20px;\n padding-bottom: 20px;\n}\n\n.qr code {\n font-size: 12px;\n}\n\n.qr-download {\n width: 200px;\n}\n\n.site--app {\n min-height: 100vh;\n color: #000;\n}\n\n[data-color-scheme=\"dark\"] .site--app {\n color: #fff;\n}\n\n.site--app h1 {\n color: inherit;\n}\n\n.site--app-main {\n max-width: 1200px;\n margin: 0 auto;\n padding: 16px;\n}\n";
348
+ styleInject(css_248z);
349
+
350
+ var _excluded = ["debug", "url", "agent", "token", "children", "metadata", "context", "readOnly", "sendHistory", "apiRef", "expanded"];
351
+ var format = function format(value) {
352
+ if (value) {
353
+ return value.split("_").map(function (word) {
354
+ return word.charAt(0).toUpperCase() + word.slice(1);
355
+ }).join(" ");
356
+ } else {
357
+ return "Kooby";
358
+ }
359
+ };
360
+
361
+ /* Helper: interactive feedback popover (replaces non-interactive tooltip + form) */
362
+
363
+ var FeedbackField = function FeedbackField(_ref) {
364
+ var Icon = _ref.icon,
365
+ title = _ref.title,
366
+ value = _ref.value,
367
+ onValueChange = _ref.onValueChange,
368
+ onCommit = _ref.onCommit;
369
+ var _useState = useState(false),
370
+ _useState2 = _slicedToArray(_useState, 2),
371
+ open = _useState2[0],
372
+ setOpen = _useState2[1];
373
+ return /*#__PURE__*/React.createElement(DialogTrigger, {
374
+ isOpen: open,
375
+ onOpenChange: setOpen
376
+ }, /*#__PURE__*/React.createElement(ActionButton, {
377
+ isQuiet: true,
378
+ "aria-label": title
379
+ }, /*#__PURE__*/React.createElement(Icon, null)), /*#__PURE__*/React.createElement(Popover, {
380
+ size: "S"
381
+ }, /*#__PURE__*/React.createElement("div", {
382
+ style: {
383
+ padding: 12
384
+ }
385
+ }, /*#__PURE__*/React.createElement(Heading, null, title), /*#__PURE__*/React.createElement(TextArea, {
386
+ value: value,
387
+ onChange: onValueChange,
388
+ onKeyDown: function onKeyDown(e) {
389
+ if (e.key === "Enter" && !e.shiftKey) {
390
+ e.preventDefault();
391
+ onCommit();
392
+ setOpen(false);
393
+ }
394
+ }
395
+ }))));
396
+ };
397
+
398
+ /* -------------------- Kooby Context -------------------- */
399
+
400
+ var KoobyContext = /*#__PURE__*/React.createContext();
401
+ var useKooby = function useKooby() {
402
+ var context = React.useContext(KoobyContext);
403
+ if (!context) {
404
+ throw new Error("useKooby must be used within a KoobyProvider");
405
+ }
406
+ return context;
407
+ };
408
+
409
+ /* -------------------- Kooby Components -------------------- */
410
+
411
+ var Feedback = function Feedback(_ref2) {
412
+ var responding = _ref2.responding,
413
+ message = _ref2.message,
414
+ index = _ref2.index,
415
+ conversation = _ref2.conversation,
416
+ negative = _ref2.negative,
417
+ positive = _ref2.positive,
418
+ showFeedbackOnAllMessages = _ref2.showFeedbackOnAllMessages,
419
+ loading = _ref2.loading;
420
+ var currentMessage = index === conversation.length - 1;
421
+ var show = false;
422
+ if (currentMessage && !responding && message.role === "assistant") {
423
+ show = true;
424
+ }
425
+ if (!currentMessage && showFeedbackOnAllMessages && message.role === "assistant") {
426
+ show = true;
427
+ }
428
+ var copyMessage = function copyMessage() {
429
+ var messageJson = JSON.stringify(message.content, null, 2);
430
+ navigator.clipboard.writeText(messageJson);
431
+ };
432
+ var _useState3 = useState(""),
433
+ _useState4 = _slicedToArray(_useState3, 2),
434
+ positiveFeedback = _useState4[0],
435
+ setPositiveFeedback = _useState4[1];
436
+ var _useState5 = useState(""),
437
+ _useState6 = _slicedToArray(_useState5, 2),
438
+ negativeFeedback = _useState6[0],
439
+ setNegativeFeedback = _useState6[1];
440
+ if (loading && currentMessage) {
441
+ return /*#__PURE__*/React.createElement("div", {
442
+ className: "kooby-feedback",
443
+ style: {
444
+ marginTop: "-35px",
445
+ marginLeft: "-40px"
446
+ }
447
+ }, /*#__PURE__*/React.createElement(ProgressCircle, {
448
+ size: "M",
449
+ isIndeterminate: true,
450
+ "aria-label": "Loading",
451
+ staticColor: "white"
452
+ }));
453
+ }
454
+ if (show) {
455
+ return /*#__PURE__*/React.createElement("div", {
456
+ className: "kooby-feedback"
457
+ }, /*#__PURE__*/React.createElement(ActionButton, {
458
+ isQuiet: true,
459
+ "aria-label": "Copy message",
460
+ onPress: copyMessage
461
+ }, /*#__PURE__*/React.createElement(Copy, null)), positive && /*#__PURE__*/React.createElement(FeedbackField, {
462
+ icon: ThumbUp,
463
+ title: positive.label || "Positive Feedback",
464
+ value: positiveFeedback,
465
+ onValueChange: setPositiveFeedback,
466
+ onCommit: function onCommit() {
467
+ return positive.onSubmit({
468
+ feedback: positiveFeedback,
469
+ conversation: conversation,
470
+ message: message.content
471
+ });
472
+ }
473
+ }), negative && /*#__PURE__*/React.createElement(FeedbackField, {
474
+ icon: ThumbDown,
475
+ title: negative.label || "Negative Feedback",
476
+ value: negativeFeedback,
477
+ onValueChange: setNegativeFeedback,
478
+ onCommit: function onCommit() {
479
+ return negative.onSubmit({
480
+ feedback: negativeFeedback,
481
+ conversation: conversation
482
+ });
483
+ }
484
+ }));
485
+ }
486
+ };
487
+ var Content = function Content(_ref3) {
488
+ var mdjsx = _ref3.mdjsx,
489
+ feedback = _ref3.feedback,
490
+ responding = _ref3.responding,
491
+ loading = _ref3.loading,
492
+ index = _ref3.index,
493
+ message = _ref3.message,
494
+ conversation = _ref3.conversation,
495
+ positive = _ref3.positive,
496
+ negative = _ref3.negative,
497
+ showFeedbackOnAllMessages = _ref3.showFeedbackOnAllMessages;
498
+ return /*#__PURE__*/React.createElement("div", {
499
+ style: {
500
+ width: "100%"
501
+ }
502
+ }, /*#__PURE__*/React.createElement("div", {
503
+ className: "kooby-content"
504
+ }, /*#__PURE__*/React.createElement(Markdown, {
505
+ options: mdjsx
506
+ }, message.content)), feedback && /*#__PURE__*/React.createElement(Feedback, {
507
+ responding: responding,
508
+ loading: loading,
509
+ index: index,
510
+ message: message,
511
+ conversation: conversation,
512
+ positive: positive,
513
+ negative: negative,
514
+ showFeedbackOnAllMessages: showFeedbackOnAllMessages
515
+ }));
516
+ };
517
+ var Conversation = function Conversation(_ref4) {
518
+ var mdjsx = _ref4.mdjsx,
519
+ _ref4$feedback = _ref4.feedback,
520
+ feedback = _ref4$feedback === void 0 ? true : _ref4$feedback,
521
+ positive = _ref4.positive,
522
+ negative = _ref4.negative,
523
+ showFeedbackOnAllMessages = _ref4.showFeedbackOnAllMessages;
524
+ var _useKooby = useKooby(),
525
+ conversation = _useKooby.conversation,
526
+ responding = _useKooby.responding,
527
+ loading = _useKooby.loading;
528
+ var conversationEndRef = useRef(null);
529
+ useEffect(function () {
530
+ if (conversation.length > 0 && conversation[conversation.length - 1].role != "system") {
531
+ var _conversationEndRef$c;
532
+ (_conversationEndRef$c = conversationEndRef.current) === null || _conversationEndRef$c === void 0 || _conversationEndRef$c.scrollIntoView({
533
+ behavior: "smooth"
534
+ });
535
+ }
536
+ }, [conversation]);
537
+ var filteredConvo = conversation.filter(function (message) {
538
+ return message.role !== "system";
539
+ });
540
+ return /*#__PURE__*/React.createElement("div", {
541
+ className: "kooby-conversation"
542
+ }, filteredConvo.map(function (message, index) {
543
+ return /*#__PURE__*/React.createElement("div", {
544
+ key: index,
545
+ className: "kooby-message"
546
+ }, /*#__PURE__*/React.createElement("div", {
547
+ className: "kooby-message-role kooby-".concat(message.role)
548
+ }, /*#__PURE__*/React.createElement("strong", null, message.role === "assistant" || message.role === "system" ? "Kooby" : message.role.charAt(0).toUpperCase() + message.role.slice(1))), /*#__PURE__*/React.createElement(Content, {
549
+ mdjsx: mdjsx,
550
+ feedback: feedback,
551
+ responding: responding,
552
+ loading: loading,
553
+ index: index,
554
+ message: message,
555
+ conversation: filteredConvo,
556
+ positive: positive,
557
+ negative: negative,
558
+ showFeedbackOnAllMessages: showFeedbackOnAllMessages
559
+ }));
560
+ }), /*#__PURE__*/React.createElement("div", {
561
+ ref: conversationEndRef
562
+ }));
563
+ };
564
+ var TextBox = function TextBox() {
565
+ var _useKooby2 = useKooby(),
566
+ isConnected = _useKooby2.isConnected,
567
+ socketManagerRef = _useKooby2.socketManagerRef,
568
+ setConversation = _useKooby2.setConversation,
569
+ context = _useKooby2.context,
570
+ setLoading = _useKooby2.setLoading;
571
+ var _useState7 = useState(""),
572
+ _useState8 = _slicedToArray(_useState7, 2),
573
+ input = _useState8[0],
574
+ setInput = _useState8[1];
575
+ var handleSend = React.useCallback(function () {
576
+ if (input.trim()) {
577
+ if (!isConnected && !socketManagerRef.current) {
578
+ console.error("WebSocket is not connected");
579
+ return;
580
+ }
581
+ var send = function send() {
582
+ setConversation(function (prev) {
583
+ return [].concat(_toConsumableArray(prev), [{
584
+ role: "user",
585
+ content: input
586
+ }]);
587
+ });
588
+ try {
589
+ socketManagerRef.current.sendMessage({
590
+ input: input
591
+ });
592
+ socketManagerRef.current.sendMessage({
593
+ complete: true
594
+ });
595
+ setLoading(true);
596
+ } catch (error) {
597
+ console.error("Error sending message:", error);
598
+ }
599
+ setInput("");
600
+ };
601
+ if (!isConnected) {
602
+ socketManagerRef.current.connect(function () {
603
+ send();
604
+ });
605
+ return;
606
+ }
607
+ send();
608
+ }
609
+ }, [input, isConnected, socketManagerRef, setConversation, context]);
610
+ return /*#__PURE__*/React.createElement("div", {
611
+ className: "kooby-text-box"
612
+ }, /*#__PURE__*/React.createElement(TextArea, {
613
+ id: "prompt",
614
+ placeholder: "Ask Me Anything!",
615
+ "aria-label": "Prompt",
616
+ value: input,
617
+ onChange: setInput,
618
+ width: "100%",
619
+ onKeyDown: function onKeyDown(e) {
620
+ if (e.key === "Enter" && !e.shiftKey) {
621
+ e.preventDefault();
622
+ handleSend();
623
+ }
624
+ }
625
+ }));
626
+ };
627
+ var Toolbar = function Toolbar(_ref5) {
628
+ var children = _ref5.children,
629
+ _ref5$expandable = _ref5.expandable,
630
+ expandable = _ref5$expandable === void 0 ? true : _ref5$expandable,
631
+ _ref5$reset = _ref5.reset,
632
+ reset = _ref5$reset === void 0 ? true : _ref5$reset;
633
+ var _useKooby3 = useKooby(),
634
+ agent = _useKooby3.agent,
635
+ conversation = _useKooby3.conversation,
636
+ toggleFocus = _useKooby3.toggleFocus,
637
+ resetConversation = _useKooby3.resetConversation;
638
+ return /*#__PURE__*/React.createElement("div", {
639
+ className: "kooby-toolbar"
640
+ }, children ? children({
641
+ agent: agent,
642
+ conversation: conversation
643
+ }) : null, reset && /*#__PURE__*/React.createElement(ActionButton, {
644
+ "aria-label": "Reset",
645
+ onPress: resetConversation
646
+ }, /*#__PURE__*/React.createElement(Refresh, null)), expandable && /*#__PURE__*/React.createElement(ActionButton, {
647
+ "aria-label": "Expand",
648
+ onPress: toggleFocus
649
+ }, /*#__PURE__*/React.createElement(OpenIn, null)));
650
+ };
651
+ var ConnectionStatus = function ConnectionStatus() {
652
+ var _useKooby4 = useKooby(),
653
+ isConnected = _useKooby4.isConnected;
654
+ if (!isConnected) {
655
+ return (
656
+ /*#__PURE__*/
657
+ // <div >
658
+ React.createElement(InlineAlert, {
659
+ variant: "notice",
660
+ UNSAFE_style: {
661
+ marginBottom: "10px"
662
+ }
663
+ }, /*#__PURE__*/React.createElement(Heading, null, "Disconnected"), /*#__PURE__*/React.createElement(Text, null, "Please continue talking to reconnect."))
664
+ // </div>
665
+ );
666
+ }
667
+ };
668
+
669
+ /* -------------------- Kooby Component -------------------- */
670
+
671
+ var defaultGreetingMessage = function defaultGreetingMessage(agent) {
672
+ return {
673
+ role: "assistant",
674
+ content: "Hello, I'm ".concat(format(agent), "! I'm here to help you with any questions you may have.")
675
+ };
676
+ };
677
+ var initializeConversation = function initializeConversation(_ref6) {
678
+ var agent = _ref6.agent,
679
+ initialConversation = _ref6.initialConversation;
680
+ if (initialConversation && initialConversation.length > 0) {
681
+ return initialConversation;
682
+ }
683
+ return [defaultGreetingMessage(agent)];
684
+ };
685
+ var Kooby = function Kooby(_ref7) {
686
+ var debug = _ref7.debug,
687
+ url = _ref7.url,
688
+ agent = _ref7.agent,
689
+ token = _ref7.token,
690
+ children = _ref7.children,
691
+ _ref7$metadata = _ref7.metadata,
692
+ metadata = _ref7$metadata === void 0 ? {} : _ref7$metadata,
693
+ context = _ref7.context,
694
+ _ref7$readOnly = _ref7.readOnly,
695
+ readOnly = _ref7$readOnly === void 0 ? false : _ref7$readOnly;
696
+ _ref7.sendHistory;
697
+ var apiRef = _ref7.apiRef,
698
+ expanded = _ref7.expanded,
699
+ rest = _objectWithoutProperties(_ref7, _excluded);
700
+ var _useState9 = useState(false),
701
+ _useState0 = _slicedToArray(_useState9, 2),
702
+ focus = _useState0[0],
703
+ setFocus = _useState0[1];
704
+ var toggleFocus = function toggleFocus() {
705
+ return setFocus(function (prev) {
706
+ return !prev;
707
+ });
708
+ };
709
+ var initialConversation = rest.conversation;
710
+ var _useState1 = useState(function () {
711
+ return initializeConversation({
712
+ agent: agent,
713
+ initialConversation: initialConversation
714
+ });
715
+ }),
716
+ _useState10 = _slicedToArray(_useState1, 2),
717
+ conversation = _useState10[0],
718
+ setConversation = _useState10[1];
719
+ var conversationRef = useRef();
720
+ conversationRef.current = conversation;
721
+ useEffect(function () {
722
+ setConversation(initializeConversation({
723
+ agent: agent,
724
+ initialConversation: initialConversation
725
+ }));
726
+ }, [agent, initialConversation]);
727
+ var _useState11 = useState(false),
728
+ _useState12 = _slicedToArray(_useState11, 2),
729
+ isConnected = _useState12[0],
730
+ setIsConnected = _useState12[1];
731
+ var _useState13 = useState(false),
732
+ _useState14 = _slicedToArray(_useState13, 2),
733
+ responding = _useState14[0],
734
+ setResponding = _useState14[1];
735
+ var _useState15 = useState(false),
736
+ _useState16 = _slicedToArray(_useState15, 2),
737
+ loading = _useState16[0],
738
+ setLoading = _useState16[1];
739
+ var socketManagerRef = useRef(null);
740
+ var metadataRef = useRef();
741
+ metadataRef.current = metadata;
742
+ useEffect(function () {
743
+ if (url && !readOnly) {
744
+ socketManagerRef.current = ChatManager.create({
745
+ url: url,
746
+ authToken: token,
747
+ agent: agent,
748
+ onMessage: function onMessage(data) {
749
+ // Example SSE message
750
+ // {"output":" I","trace_id":"94008937-f598-4be3-8714-5c6a4b4c9a32","span_id":"07b85d19-fb89-4a57-9566-6a9d9fdb0dc7"}
751
+ // {"type":"complete","trace_id":"94008937-f598-4be3-8714-5c6a4b4c9a32","span_id":"07b85d19-fb89-4a57-9566-6a9d9fdb0dc7"}
752
+
753
+ // Check if the incoming data contains an 'output' property
754
+ if (data.output) {
755
+ // We are starting to respond
756
+ setResponding(true);
757
+ // We are done loading the response
758
+ setLoading(false);
759
+ // Update the conversation state using the setConversation function
760
+ setConversation(function (prev) {
761
+ // Get the last message in the current conversation
762
+ var lastMessage = prev[prev.length - 1];
763
+
764
+ // Clean the output by removing any prefix like "user_id-<number>: "
765
+ var cleanOutput = data.output.replace(/^user_id-\d+:\s*/, "");
766
+
767
+ // Check if the last message in the conversation is from the assistant
768
+ if (lastMessage.role === "assistant") {
769
+ // If the last message is from the assistant, update its content
770
+ // by appending the cleaned output and replace the last message
771
+ return [].concat(_toConsumableArray(prev.slice(0, -1)), [// Keep all messages except the last one
772
+ _objectSpread2(_objectSpread2({}, lastMessage), {}, {
773
+ // Copy the last message
774
+ content: lastMessage.content + cleanOutput // Append the new content
775
+ })]);
776
+ } else {
777
+ // If the last message is not from the assistant, add a new message
778
+ // from the assistant with the cleaned output
779
+ return [].concat(_toConsumableArray(prev), [{
780
+ role: "assistant",
781
+ content: cleanOutput
782
+ }]);
783
+ }
784
+ });
785
+ }
786
+ if (data.complete) {
787
+ console.log("complete");
788
+ setResponding(false);
789
+ setIsConnected(true);
790
+ }
791
+ },
792
+ onOpen: function onOpen() {
793
+ console.log("Chat Manager Connected", metadataRef.current);
794
+ setIsConnected(true);
795
+
796
+ // Take the current conversation and format it for the chat manager history
797
+ var history = initialConversation;
798
+ socketManagerRef.current.sendMessage({
799
+ handshake: true,
800
+ history: history,
801
+ metadata: _objectSpread2({
802
+ user_agent: navigator.userAgent
803
+ }, metadataRef.current)
804
+ });
805
+ },
806
+ onClose: function onClose() {
807
+ console.log("Chat Manager Disconnecting");
808
+ setIsConnected(false);
809
+ },
810
+ onError: function onError() {
811
+ setIsConnected(false);
812
+ }
813
+ });
814
+ socketManagerRef.current.connect();
815
+ }
816
+ return function () {
817
+ if (url) {
818
+ console.log("Cleaing up Socket");
819
+ socketManagerRef.current.disconnect();
820
+ setIsConnected(false);
821
+ }
822
+ };
823
+ }, [url, agent, token]);
824
+ useEffect(function () {
825
+ if (socketManagerRef.current && context) {
826
+ console.log("Setting context", context);
827
+ setConversation(function (prev) {
828
+ return [].concat(_toConsumableArray(prev), [{
829
+ role: "system",
830
+ content: context
831
+ }]);
832
+ });
833
+ socketManagerRef.current.sendMessage({
834
+ context: context
835
+ });
836
+ }
837
+ }, [context]);
838
+ var resetConversation = function resetConversation() {
839
+ if (url && !readOnly && socketManagerRef.current) {
840
+ socketManagerRef.current.sendMessage({
841
+ reset: true
842
+ });
843
+ }
844
+ setConversation([defaultGreetingMessage(agent)]);
845
+ };
846
+ var contextValue = React.useMemo(function () {
847
+ return {
848
+ conversation: conversation,
849
+ setConversation: setConversation,
850
+ resetConversation: resetConversation,
851
+ isConnected: isConnected,
852
+ setIsConnected: setIsConnected,
853
+ socketManagerRef: socketManagerRef,
854
+ agent: agent,
855
+ toggleFocus: toggleFocus,
856
+ responding: responding,
857
+ context: context,
858
+ setLoading: setLoading,
859
+ loading: loading
860
+ };
861
+ }, [conversation, isConnected, agent, responding, context]);
862
+ if (apiRef) {
863
+ apiRef.current = {
864
+ resetConversation: resetConversation
865
+ };
866
+ }
867
+ return /*#__PURE__*/React.createElement(KoobyContext.Provider, {
868
+ value: contextValue
869
+ }, /*#__PURE__*/React.createElement("div", {
870
+ className: "kooby ".concat(focus || expanded ? "kooby-focus" : "")
871
+ }, children), debug && /*#__PURE__*/React.createElement("code", {
872
+ className: "kooby-debug"
873
+ }, /*#__PURE__*/React.createElement("pre", null, JSON.stringify(conversation, null, 2))));
874
+ };
875
+ Kooby.Content = Content;
876
+ Kooby.Conversation = Conversation;
877
+ Kooby.TextBox = TextBox;
878
+ Kooby.Toolbar = Toolbar;
879
+ Kooby.ConnectionStatus = ConnectionStatus;
880
+
881
+ export { Kooby };