@apia/ai 3.0.16 → 3.0.17

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.
package/dist/index.js CHANGED
@@ -1,12 +1,15 @@
1
1
  import { jsx, jsxs, Fragment } from '@apia/theme/jsx-runtime';
2
- import { Box, getVariant, Textarea, Paragraph } from '@apia/theme';
2
+ import { Box, getVariant, useBreakpointIndex, Textarea, Paragraph } from '@apia/theme';
3
3
  import { useRef, useCallback, useState } from 'react';
4
- import { IconButton, SimpleButton, ApiaUtil } from '@apia/components';
4
+ import { IconButton, SimpleButton, ApiaUtil, SortableList, SortableListItem } from '@apia/components';
5
5
  import { getLabel, noNaN, AudioRecorder, EventEmitter } from '@apia/util';
6
- import { makeObservable, observable } from 'mobx';
7
- import { FileIcon } from '@apia/icons';
6
+ import { makeObservable, observable, action, toJS, makeAutoObservable } from 'mobx';
7
+ import { CollectorField, Collector } from '@apia/validations';
8
8
  import { uniqueId } from '@apia/notifications';
9
+ import { FileIcon } from '@apia/icons';
9
10
  import { observer } from 'mobx-react-lite';
11
+ import axios from 'axios';
12
+ import { makeApiaUrl, parseSuccessfulResponse, ApiaApi } from '@apia/api';
10
13
 
11
14
  const AutoscrollContainer = ({ children }) => {
12
15
  const observer = useRef(null);
@@ -190,10 +193,10 @@ function useHandleFileUpload({
190
193
  return { progress, handleFileUpload };
191
194
  }
192
195
 
193
- var __defProp$5 = Object.defineProperty;
194
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
195
- var __publicField$5 = (obj, key, value) => {
196
- __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
196
+ var __defProp$7 = Object.defineProperty;
197
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
198
+ var __publicField$7 = (obj, key, value) => {
199
+ __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
197
200
  return value;
198
201
  };
199
202
  let maxId = 0;
@@ -202,9 +205,9 @@ class ChatMessage {
202
205
  this.message = message;
203
206
  this.messageType = messageType;
204
207
  this.attachments = attachments;
205
- __publicField$5(this, "id");
206
- __publicField$5(this, "copy", () => new ChatMessage(this.message, this.messageType, this.attachments));
207
- __publicField$5(this, "Component", () => {
208
+ __publicField$7(this, "id");
209
+ __publicField$7(this, "copy", () => new ChatMessage(this.message, this.messageType, this.attachments));
210
+ __publicField$7(this, "Component", () => {
208
211
  return /* @__PURE__ */ jsxs(
209
212
  Box,
210
213
  {
@@ -243,16 +246,18 @@ class ChatMessage {
243
246
  }
244
247
  }
245
248
 
246
- var __defProp$4 = Object.defineProperty;
247
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
248
- var __publicField$4 = (obj, key, value) => {
249
- __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
249
+ var __defProp$6 = Object.defineProperty;
250
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
251
+ var __publicField$6 = (obj, key, value) => {
252
+ __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
250
253
  return value;
251
254
  };
252
- class AIContent {
255
+ class AIContent extends CollectorField {
253
256
  constructor(content) {
254
- __publicField$4(this, "content");
255
- __publicField$4(this, "Component", () => {
257
+ super(uniqueId(), "");
258
+ __publicField$6(this, "type", "aiContent");
259
+ __publicField$6(this, "content");
260
+ __publicField$6(this, "Component", () => {
256
261
  return /* @__PURE__ */ jsx(Box, { variant: "layout.common.components.aiMessage.textBox", children: /* @__PURE__ */ jsx(Box, { variant: "layout.common.components.aiMessage.textSnippet", children: this.content }) });
257
262
  });
258
263
  this.content = content;
@@ -287,40 +292,97 @@ var AIMessageRole = /* @__PURE__ */ ((AIMessageRole2) => {
287
292
  return AIMessageRole2;
288
293
  })(AIMessageRole || {});
289
294
 
290
- var __defProp$3 = Object.defineProperty;
291
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
292
- var __publicField$3 = (obj, key, value) => {
293
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
295
+ var __defProp$5 = Object.defineProperty;
296
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
297
+ var __publicField$5 = (obj, key, value) => {
298
+ __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
294
299
  return value;
295
300
  };
296
301
  const _AIFileContent = class _AIFileContent extends AIContent {
297
- constructor(content, fileUrl, fileName, f) {
302
+ constructor(fileUrl, fileName, f, error) {
298
303
  const extension = _AIFileContent.getExtensionFromFileName(fileName);
304
+ super();
305
+ __publicField$5(this, "type");
306
+ __publicField$5(this, "fileUrl");
307
+ __publicField$5(this, "fileName");
308
+ __publicField$5(this, "extension");
309
+ __publicField$5(this, "__file");
310
+ __publicField$5(this, "__error");
311
+ __publicField$5(this, "overrideSize");
312
+ __publicField$5(this, "inferContent", () => {
313
+ return `You must collect information contained in this ${this.type} as help to build your tool choice.`;
314
+ });
315
+ __publicField$5(this, "inferExtension", (extension) => {
316
+ switch (extension) {
317
+ case AIFileContentAllowedExtensions.jpg:
318
+ case AIFileContentAllowedExtensions.jpeg:
319
+ case AIFileContentAllowedExtensions.png:
320
+ case AIFileContentAllowedExtensions.svg:
321
+ return FileType.IMAGE;
322
+ case AIFileContentAllowedExtensions.txt:
323
+ case AIFileContentAllowedExtensions.doc:
324
+ case AIFileContentAllowedExtensions.pdf:
325
+ case AIFileContentAllowedExtensions.docx:
326
+ return FileType.DOCUMENT;
327
+ case AIFileContentAllowedExtensions.csv:
328
+ case AIFileContentAllowedExtensions.xlsx:
329
+ case AIFileContentAllowedExtensions.xls:
330
+ return FileType.SHEET;
331
+ case AIFileContentAllowedExtensions.mp3:
332
+ case AIFileContentAllowedExtensions.wav:
333
+ return FileType.AUDIO;
334
+ default:
335
+ this.__throwError(
336
+ new Error(_AIFileContent.__getExtensionErrorMessage(extension)),
337
+ this.__error?.fileExtension
338
+ );
339
+ }
340
+ });
341
+ // COMPONENT METHODS
342
+ __publicField$5(this, "Component", () => /* @__PURE__ */ jsxs(
343
+ Box,
344
+ {
345
+ sx: {
346
+ ...this.overrideSize ? {
347
+ ...this.overrideSize,
348
+ img: {
349
+ width: `${this.overrideSize.width - 20}px`,
350
+ height: `${this.overrideSize.height - 61}px`
351
+ }
352
+ } : {}
353
+ },
354
+ variant: "layout.common.components.aiMessage.fileBox",
355
+ children: [
356
+ FileType.IMAGE === this.type ? /* @__PURE__ */ jsx("img", { src: URL.createObjectURL(this.file), alt: this.fileName }) : /* @__PURE__ */ jsx(FileIcon, { iconSize: "lg", docName: this.fileName }),
357
+ /* @__PURE__ */ jsx(
358
+ Box,
359
+ {
360
+ as: "p",
361
+ variant: "layout.common.components.aiMessage.fileName",
362
+ title: this.fileName,
363
+ children: this.fileName
364
+ }
365
+ )
366
+ ]
367
+ }
368
+ ));
369
+ this.__error = error;
299
370
  if (!_AIFileContent.isValidExtension(extension))
300
- throw new Error(_AIFileContent.getExtensionErrorMessage(extension));
301
- super(content);
302
- __publicField$3(this, "type");
303
- __publicField$3(this, "fileUrl");
304
- __publicField$3(this, "fileName");
305
- __publicField$3(this, "extension");
306
- __publicField$3(this, "__file");
307
- __publicField$3(this, "Component", () => /* @__PURE__ */ jsxs(Box, { variant: "layout.common.components.aiMessage.fileBox", children: [
308
- FileType.IMAGE === this.type ? /* @__PURE__ */ jsx("img", { src: URL.createObjectURL(this.file), alt: this.fileName }) : /* @__PURE__ */ jsx(FileIcon, { iconSize: "lg", docName: this.fileName }),
309
- /* @__PURE__ */ jsx(
310
- Box,
311
- {
312
- as: "p",
313
- variant: "layout.common.components.aiMessage.fileName",
314
- title: this.fileName,
315
- children: this.fileName
316
- }
317
- )
318
- ] }));
371
+ this.__throwError(
372
+ new Error(_AIFileContent.__getExtensionErrorMessage(extension)),
373
+ this.__error?.fileExtension
374
+ );
319
375
  this.fileUrl = fileUrl;
320
376
  this.extension = extension;
321
- this.type = _AIFileContent.inferExtension(extension);
377
+ this.type = this.inferExtension(this.extension);
322
378
  this.fileName = fileName;
323
379
  this.__file = f;
380
+ this.content = this.inferContent();
381
+ }
382
+ // PUBLIC METHODS
383
+ setOverrideSize(overrideSize) {
384
+ this.overrideSize = overrideSize;
385
+ return this;
324
386
  }
325
387
  get file() {
326
388
  if (!this.__file)
@@ -330,12 +392,23 @@ const _AIFileContent = class _AIFileContent extends AIContent {
330
392
  static getExtensionFromFileName(fileName) {
331
393
  return fileName.split(".", 2).pop();
332
394
  }
333
- static getExtensionErrorMessage(extension) {
395
+ // PRIVATE METHODS
396
+ static __getExtensionErrorMessage(extension) {
334
397
  return `extension "${extension}" is not included into valid types:
335
398
  ${Object.keys(AIFileContentAllowedExtensions)}`;
336
399
  }
400
+ __throwError(e, callback) {
401
+ callback && callback();
402
+ throw e;
403
+ }
337
404
  };
338
- __publicField$3(_AIFileContent, "blobToBase64", async (blob) => {
405
+ // STATIC METHODS
406
+ __publicField$5(_AIFileContent, "isValidExtension", (extension) => {
407
+ return Object.values(
408
+ AIFileContentAllowedExtensions
409
+ ).includes(extension);
410
+ });
411
+ __publicField$5(_AIFileContent, "blobToBase64", async (blob) => {
339
412
  return await ((blob2) => new Promise((resolve, reject) => {
340
413
  const reader = new FileReader();
341
414
  reader.onloadend = () => {
@@ -346,58 +419,55 @@ __publicField$3(_AIFileContent, "blobToBase64", async (blob) => {
346
419
  reader.readAsDataURL(blob2);
347
420
  }))(blob);
348
421
  });
349
- __publicField$3(_AIFileContent, "fromFile", async (f, content) => {
422
+ __publicField$5(_AIFileContent, "fromFile", async (f, error) => {
350
423
  const fileUrl = await ((f2) => new Promise((resolve, reject) => {
351
424
  const reader = new FileReader();
352
425
  reader.readAsDataURL(f2);
353
426
  reader.onload = () => resolve(reader.result);
354
427
  reader.onerror = () => reject();
355
428
  }))(f);
356
- return new _AIFileContent(content, fileUrl, f.name, f);
357
- });
358
- __publicField$3(_AIFileContent, "inferExtension", (extension) => {
359
- switch (extension) {
360
- case AIFileContentAllowedExtensions.jpg:
361
- case AIFileContentAllowedExtensions.jpeg:
362
- case AIFileContentAllowedExtensions.png:
363
- case AIFileContentAllowedExtensions.svg:
364
- return FileType.IMAGE;
365
- case AIFileContentAllowedExtensions.txt:
366
- case AIFileContentAllowedExtensions.doc:
367
- case AIFileContentAllowedExtensions.pdf:
368
- case AIFileContentAllowedExtensions.docx:
369
- return FileType.DOCUMENT;
370
- case AIFileContentAllowedExtensions.csv:
371
- case AIFileContentAllowedExtensions.xlsx:
372
- case AIFileContentAllowedExtensions.xls:
373
- return FileType.SHEET;
374
- case AIFileContentAllowedExtensions.mp3:
375
- case AIFileContentAllowedExtensions.wav:
376
- return FileType.AUDIO;
377
- default:
378
- throw new Error(_AIFileContent.getExtensionErrorMessage(extension));
379
- }
380
- });
381
- __publicField$3(_AIFileContent, "isValidExtension", (extension) => {
382
- return Object.values(
383
- AIFileContentAllowedExtensions
384
- ).includes(extension);
429
+ return new _AIFileContent(fileUrl, f.name, f, error);
385
430
  });
386
431
  let AIFileContent = _AIFileContent;
387
432
 
388
- var __defProp$2 = Object.defineProperty;
389
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
390
- var __publicField$2 = (obj, key, value) => {
391
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
433
+ var __defProp$4 = Object.defineProperty;
434
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
435
+ var __publicField$4 = (obj, key, value) => {
436
+ __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
392
437
  return value;
393
438
  };
394
439
  class AIMessageAttachments {
395
440
  constructor(role, content, close) {
396
441
  this.close = close;
397
- __publicField$2(this, "role");
398
- __publicField$2(this, "content");
399
- __publicField$2(this, "id", uniqueId());
400
- __publicField$2(this, "Component", (props) => /* @__PURE__ */ jsxs(Box, { ...getVariant("layout.common.components.aiMessage"), children: [
442
+ __publicField$4(this, "role");
443
+ __publicField$4(this, "content");
444
+ __publicField$4(this, "id", uniqueId());
445
+ __publicField$4(this, "customDescription", false);
446
+ __publicField$4(this, "addDescription", async () => {
447
+ const collector = new Collector();
448
+ const collected = await collector.add(this.content).add(
449
+ new collector.fields.textarea(
450
+ "addCommentTextArea",
451
+ getLabel("lblAiAddImageCo").text.replace(".", ""),
452
+ {
453
+ initialValue: this.content instanceof AIFileContent && this.content.content !== this.content.inferContent() ? this.content.content : ""
454
+ }
455
+ )
456
+ ).show({
457
+ title: getLabel("btnAddComment").text
458
+ }).catch((e) => {
459
+ throw e;
460
+ });
461
+ if (collected?.addCommentTextArea) {
462
+ this.content.content = collected.addCommentTextArea;
463
+ this.customDescription = true;
464
+ } else {
465
+ if (this.content instanceof AIFileContent)
466
+ this.content.content = this.content.inferContent();
467
+ this.customDescription = false;
468
+ }
469
+ });
470
+ __publicField$4(this, "Component", (props) => /* @__PURE__ */ jsxs(Box, { ...getVariant("layout.common.components.aiMessage"), children: [
401
471
  props.closeButton ? /* @__PURE__ */ jsx(
402
472
  IconButton,
403
473
  {
@@ -408,6 +478,15 @@ class AIMessageAttachments {
408
478
  title: getLabel("lblDeleteItem").title
409
479
  }
410
480
  ) : /* @__PURE__ */ jsx(Fragment, {}),
481
+ props?.canAddDescription ? /* @__PURE__ */ jsx(
482
+ IconButton,
483
+ {
484
+ className: "descriptionButton",
485
+ size: "Md",
486
+ icon: "Magic",
487
+ onClick: this.addDescription
488
+ }
489
+ ) : /* @__PURE__ */ jsx(Fragment, {}),
411
490
  /* @__PURE__ */ jsx(this.content.Component, {})
412
491
  ] }));
413
492
  this.role = role;
@@ -420,10 +499,18 @@ const handleFileUploadAsMessage = async (fileInputElement, chatController) => {
420
499
  [...fileInputElement.files].forEach(async (f) => {
421
500
  const m = new AIMessageAttachments(
422
501
  AIMessageRole.USER,
423
- await AIFileContent.fromFile(
424
- f,
425
- "you must collect information contained in this image as help to build your tool choice"
426
- ),
502
+ await AIFileContent.fromFile(f, {
503
+ fileExtension: () => chatController.messages.add(
504
+ new ChatMessage(
505
+ getLabel("msgAiIncorrectFileExtensionError", {
506
+ text: {
507
+ TOK1: `[${Object.keys(AIFileContentAllowedExtensions).join(", ")}]`
508
+ }
509
+ }).text,
510
+ "error"
511
+ )
512
+ )
513
+ }),
427
514
  () => chatController.attachments.drop(m)
428
515
  );
429
516
  chatController.attachments.add(m);
@@ -440,6 +527,7 @@ const makeTextarea = (chatController) => {
440
527
  preventAppendUserMessages
441
528
  }) => {
442
529
  const [isLoading, setIsLoading] = useState(false);
530
+ const breakpoint = useBreakpointIndex();
443
531
  const submit = useCallback(() => {
444
532
  if (preventAppendUserMessages !== true)
445
533
  chatController.messages.add(chatController.state.current);
@@ -501,6 +589,95 @@ const makeTextarea = (chatController) => {
501
589
  ev.preventDefault();
502
590
  setDragging(true);
503
591
  };
592
+ const additionalButtons = [];
593
+ additionalButtons.push({
594
+ key: "prev",
595
+ children: /* @__PURE__ */ jsx(
596
+ SimpleButton,
597
+ {
598
+ title: getLabel("btnAiPrevious").title,
599
+ variant: "outline",
600
+ type: "button",
601
+ onClick: chatController.history.previous,
602
+ size: "sm",
603
+ children: getLabel("btnAiPrevious").text
604
+ }
605
+ )
606
+ });
607
+ additionalButtons.push({
608
+ key: "next",
609
+ children: /* @__PURE__ */ jsx(
610
+ SimpleButton,
611
+ {
612
+ title: getLabel("btnAiNext").title,
613
+ variant: "outline",
614
+ type: "button",
615
+ onClick: chatController.history.next,
616
+ size: "sm",
617
+ children: getLabel("btnAiNext").text
618
+ }
619
+ )
620
+ });
621
+ if (!hideDeleteButton) {
622
+ additionalButtons.push({
623
+ key: "delete",
624
+ children: /* @__PURE__ */ jsx(
625
+ SimpleButton,
626
+ {
627
+ title: getLabel("btnAiDelete").title,
628
+ variant: "outline",
629
+ type: "button",
630
+ onClick: () => {
631
+ chatController.state.current.message = "";
632
+ chatController.attachments.dropAll();
633
+ chatController.currentHistoryIndex = -1;
634
+ },
635
+ size: "sm",
636
+ children: getLabel("btnAiDelete").text
637
+ }
638
+ )
639
+ });
640
+ additionalButtons.push({
641
+ key: "deleteMessages",
642
+ children: /* @__PURE__ */ jsx(
643
+ SimpleButton,
644
+ {
645
+ title: getLabel("btnAiDeleteMessages").title,
646
+ variant: "outline",
647
+ type: "button",
648
+ onClick: () => chatController.messages.clear(),
649
+ size: "sm",
650
+ children: getLabel("btnAiDeleteMessages").text
651
+ }
652
+ )
653
+ });
654
+ }
655
+ const isPhone = breakpoint < 4;
656
+ let iconButton = /* @__PURE__ */ jsx(Fragment, {});
657
+ if (isPhone) {
658
+ iconButton = /* @__PURE__ */ jsx(
659
+ IconButton,
660
+ {
661
+ ...getVariant("layout.ai.execution.formsAssistant.settingsButton"),
662
+ iconSize: "Md",
663
+ size: "Lg",
664
+ icon: "Ellipsis",
665
+ isLoading: actualIsLoading,
666
+ onClick: () => {
667
+ const util = ApiaUtil.instance;
668
+ const items = [];
669
+ items.push(...additionalButtons);
670
+ if (items.length > 0)
671
+ util.menu.open({
672
+ menuProps: {
673
+ anchorPoint: { x: util.mouse.x, y: util.mouse.y }
674
+ },
675
+ items
676
+ });
677
+ }
678
+ }
679
+ );
680
+ }
504
681
  return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column", width: "100%" }, children: [
505
682
  /* @__PURE__ */ jsx(
506
683
  Box,
@@ -596,7 +773,7 @@ const makeTextarea = (chatController) => {
596
773
  icon: chatController.audioRecorder.state.recording ? "Stop" : "Microphone",
597
774
  id: "transcribeAudio",
598
775
  size: "Lg",
599
- title: "TODO: MAKE LABEL TRANSCRIBE AUDIO"
776
+ title: getLabel("lblAiRecordAudio").text
600
777
  }
601
778
  ),
602
779
  /* @__PURE__ */ jsx(
@@ -614,54 +791,9 @@ const makeTextarea = (chatController) => {
614
791
  size: "Lg"
615
792
  }
616
793
  ),
617
- /* @__PURE__ */ jsx(
618
- SimpleButton,
619
- {
620
- title: getLabel("btnAiPrevious").title,
621
- variant: "outline",
622
- type: "button",
623
- onClick: chatController.history.previous,
624
- size: "sm",
625
- children: getLabel("btnAiPrevious").text
626
- }
627
- ),
628
- /* @__PURE__ */ jsx(
629
- SimpleButton,
630
- {
631
- title: getLabel("btnAiNext").title,
632
- variant: "outline",
633
- type: "button",
634
- onClick: chatController.history.next,
635
- size: "sm",
636
- children: getLabel("btnAiNext").text
637
- }
638
- ),
639
- !hideDeleteButton && /* @__PURE__ */ jsxs(Fragment, { children: [
640
- /* @__PURE__ */ jsx(
641
- SimpleButton,
642
- {
643
- title: getLabel("btnAiDelete").title,
644
- variant: "outline",
645
- type: "button",
646
- onClick: () => {
647
- chatController.state.current.message = "";
648
- chatController.attachments.dropAll();
649
- chatController.currentHistoryIndex = -1;
650
- },
651
- size: "sm",
652
- children: getLabel("btnAiDelete").text
653
- }
654
- ),
655
- /* @__PURE__ */ jsx(
656
- SimpleButton,
657
- {
658
- title: getLabel("btnAiDeleteMessages").title,
659
- variant: "outline",
660
- type: "button",
661
- onClick: () => chatController.messages.clear(),
662
- size: "sm",
663
- children: getLabel("btnAiDeleteMessages").text
664
- }
794
+ isPhone ? iconButton : /* @__PURE__ */ jsxs(Fragment, { children: [
795
+ ...additionalButtons.map(
796
+ (x) => x.children
665
797
  )
666
798
  ] }),
667
799
  /* @__PURE__ */ jsx(
@@ -685,10 +817,10 @@ const makeTextarea = (chatController) => {
685
817
  return NewTextarea;
686
818
  };
687
819
 
688
- var __defProp$1 = Object.defineProperty;
689
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
690
- var __publicField$1 = (obj, key, value) => {
691
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
820
+ var __defProp$3 = Object.defineProperty;
821
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
822
+ var __publicField$3 = (obj, key, value) => {
823
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
692
824
  return value;
693
825
  };
694
826
  var __accessCheck = (obj, member, msg) => {
@@ -713,11 +845,11 @@ var _promptsHistory, _internalAudioRecorder;
713
845
  class ChatController {
714
846
  constructor(id, welcomeMessage) {
715
847
  this.id = id;
716
- __publicField$1(this, "state", {
848
+ __publicField$3(this, "state", {
717
849
  current: new ChatMessage(),
718
850
  messages: []
719
851
  });
720
- __publicField$1(this, "components", {
852
+ __publicField$3(this, "components", {
721
853
  MessageHistory: observer(() => {
722
854
  return /* @__PURE__ */ jsx(
723
855
  Box,
@@ -731,14 +863,13 @@ class ChatController {
731
863
  Textarea: makeTextarea(this)
732
864
  });
733
865
  __privateAdd(this, _promptsHistory, []);
734
- __publicField$1(this, "currentHistoryIndex", -1);
866
+ __publicField$3(this, "currentHistoryIndex", -1);
735
867
  __privateAdd(this, _internalAudioRecorder, new AudioRecorder());
736
- __publicField$1(this, "audioRecorder", {
868
+ __publicField$3(this, "audioRecorder", {
737
869
  start: () => __privateGet(this, _internalAudioRecorder).start().then(async (blob) => {
738
870
  const m = new AIMessageAttachments(
739
871
  AIMessageRole.USER,
740
872
  new AIFileContent(
741
- "this is a record from user's voice",
742
873
  await AIFileContent.blobToBase64(blob),
743
874
  `userRecord_${this.audioRecorder.record++}.wav`
744
875
  ),
@@ -752,7 +883,7 @@ class ChatController {
752
883
  record: 0,
753
884
  state: __privateGet(this, _internalAudioRecorder).state
754
885
  });
755
- __publicField$1(this, "history", {
886
+ __publicField$3(this, "history", {
756
887
  add: (message) => {
757
888
  this.currentHistoryIndex = -1;
758
889
  if (message === __privateGet(this, _promptsHistory)[__privateGet(this, _promptsHistory).length]) {
@@ -789,7 +920,7 @@ class ChatController {
789
920
  },
790
921
  size: () => this.state.messages.length
791
922
  });
792
- __publicField$1(this, "messages", {
923
+ __publicField$3(this, "messages", {
793
924
  add: (message, idx) => {
794
925
  if (idx !== void 0 && idx !== null) {
795
926
  this.state.messages.splice(idx, 0, message);
@@ -801,7 +932,7 @@ class ChatController {
801
932
  this.state.messages = [];
802
933
  }
803
934
  });
804
- __publicField$1(this, "attachments", {
935
+ __publicField$3(this, "attachments", {
805
936
  add: (...aiMessage) => {
806
937
  this.state.current.attachments.push(...aiMessage);
807
938
  },
@@ -813,7 +944,7 @@ class ChatController {
813
944
  if (!this.state.current.message && this.attachments.size() < 1)
814
945
  this.currentHistoryIndex = -1;
815
946
  },
816
- getComponents: () => this.state.current.attachments.map((x) => /* @__PURE__ */ jsx(x.Component, { closeButton: true }, x.id)),
947
+ getComponents: () => this.state.current.attachments.map((x) => /* @__PURE__ */ jsx(x.Component, { closeButton: true, canAddDescription: true }, x.id)),
817
948
  get: () => this.state.current.attachments,
818
949
  size: () => this.state.current.attachments.length
819
950
  });
@@ -854,21 +985,233 @@ class MultipleChoiceMessage extends ChatMessage {
854
985
  }
855
986
  }
856
987
 
857
- var __defProp = Object.defineProperty;
858
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
859
- var __publicField = (obj, key, value) => {
860
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
988
+ var __defProp$2 = Object.defineProperty;
989
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
990
+ var __publicField$2 = (obj, key, value) => {
991
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
992
+ return value;
993
+ };
994
+ function isPollProgress(payload) {
995
+ return payload?.progress !== void 0;
996
+ }
997
+ class RoutinesGeneration {
998
+ constructor() {
999
+ __publicField$2(this, "audioRecorder", new AudioRecorder());
1000
+ __publicField$2(this, "routineId", "");
1001
+ __publicField$2(this, "state", {
1002
+ isLoading: false,
1003
+ progress: 0
1004
+ });
1005
+ makeObservable(this, {
1006
+ completion: action,
1007
+ state: observable,
1008
+ stop: action,
1009
+ transcribeAudio: action
1010
+ });
1011
+ }
1012
+ checkCanGenerate() {
1013
+ if (this.state.isLoading) {
1014
+ throw new Error("Cannot queue two simultaneous generations");
1015
+ }
1016
+ this.state.isLoading = true;
1017
+ }
1018
+ async pollRoutine(stream) {
1019
+ while (this.state.isLoading) {
1020
+ const pollResult = await this.callRoutinePoll(this.routineId);
1021
+ if (isPollProgress(pollResult.payload)) {
1022
+ try {
1023
+ const res = JSON.parse(pollResult.payload.debug);
1024
+ if (res.length > 0) {
1025
+ res.forEach((c) => {
1026
+ console.log(JSON.parse(c));
1027
+ });
1028
+ }
1029
+ if (pollResult.payload.streamPart && stream) {
1030
+ stream.emit("part", pollResult.payload.streamPart);
1031
+ }
1032
+ this.state.progress = pollResult.payload.progress;
1033
+ } catch (e) {
1034
+ console.error(e);
1035
+ }
1036
+ } else if (pollResult.status === "FINISHED") {
1037
+ this.resetLoading();
1038
+ return pollResult.payload;
1039
+ } else if (pollResult.status === "ERROR") {
1040
+ this.resetLoading();
1041
+ throw new Error(pollResult.payload);
1042
+ } else {
1043
+ this.resetLoading();
1044
+ throw new Error("Wrong poll response");
1045
+ }
1046
+ }
1047
+ return null;
1048
+ }
1049
+ async callAudioTranscription(audio) {
1050
+ const url = makeApiaUrl({
1051
+ action: "routineStart",
1052
+ routine: "transcription/Transcribe"
1053
+ });
1054
+ const response = await axios.post(url, audio.arrayBuffer(), {
1055
+ headers: {
1056
+ "Content-Type": "application/octet-stream"
1057
+ }
1058
+ });
1059
+ const result = await parseSuccessfulResponse(response, "");
1060
+ if (result?.orchestrator) {
1061
+ return result;
1062
+ }
1063
+ return null;
1064
+ }
1065
+ async callRoutinePoll(routineId) {
1066
+ const result = await ApiaApi.post(
1067
+ makeApiaUrl({
1068
+ action: "routinePoll",
1069
+ routineId
1070
+ })
1071
+ );
1072
+ if (result?.data?.orchestrator) {
1073
+ return JSON.parse(result.data.orchestrator);
1074
+ } else {
1075
+ throw new Error("Poll failed");
1076
+ }
1077
+ }
1078
+ async callRoutineStart(routineName, parameters, images) {
1079
+ const result = await ApiaApi.post(
1080
+ makeApiaUrl({
1081
+ action: "routineStart",
1082
+ routine: routineName
1083
+ }),
1084
+ {
1085
+ postData: {
1086
+ images: JSON.stringify(images),
1087
+ ...parameters
1088
+ },
1089
+ stringifyOptions: {
1090
+ arrayFormat: "repeat"
1091
+ },
1092
+ postDataTreatement: "stringify"
1093
+ }
1094
+ );
1095
+ return result?.data || null;
1096
+ }
1097
+ async executeRoutine(routineName, parameters, images, stream) {
1098
+ this.checkCanGenerate();
1099
+ try {
1100
+ const result = await this.callRoutineStart(
1101
+ routineName,
1102
+ parameters,
1103
+ images
1104
+ );
1105
+ if (result?.orchestrator?.routineId !== void 0) {
1106
+ this.routineId = result?.orchestrator.routineId;
1107
+ return this.pollRoutine(stream);
1108
+ } else {
1109
+ throw new Error("Cannot get routine id");
1110
+ }
1111
+ } catch (e) {
1112
+ this.resetLoading();
1113
+ throw e;
1114
+ }
1115
+ }
1116
+ resetLoading() {
1117
+ this.state.isLoading = false;
1118
+ this.state.progress = 0;
1119
+ }
1120
+ async completion(params) {
1121
+ return this.executeRoutine(
1122
+ params.routineName,
1123
+ params.parameters ?? {},
1124
+ params.images ?? [],
1125
+ params.stream
1126
+ );
1127
+ }
1128
+ stop() {
1129
+ this.resetLoading();
1130
+ ApiaApi.get(
1131
+ makeApiaUrl({
1132
+ action: "routineStop",
1133
+ routineId: this.routineId
1134
+ })
1135
+ );
1136
+ }
1137
+ async transcribeAudio(audio) {
1138
+ const result = await this.callAudioTranscription(audio);
1139
+ if (result) {
1140
+ this.state.isLoading = true;
1141
+ if (result?.orchestrator?.routineId) {
1142
+ this.routineId = result?.orchestrator?.routineId;
1143
+ return await this.pollRoutine();
1144
+ }
1145
+ }
1146
+ throw new Error("Something went wrong while transcribing the audio");
1147
+ }
1148
+ }
1149
+
1150
+ class DashboardsRoutinesGeneration extends RoutinesGeneration {
1151
+ constructor(dispatcher) {
1152
+ super();
1153
+ this.dispatcher = dispatcher;
1154
+ }
1155
+ blobToBase64(audio) {
1156
+ return new Promise((resolve, reject) => {
1157
+ const reader = new FileReader();
1158
+ reader.onloadend = () => {
1159
+ if (reader.result && typeof reader.result === "string") {
1160
+ const base64 = reader.result.split(",")[1];
1161
+ resolve(base64);
1162
+ } else {
1163
+ reject(new Error("Could not convert Blob to base64"));
1164
+ }
1165
+ };
1166
+ reader.onerror = reject;
1167
+ reader.readAsDataURL(audio);
1168
+ });
1169
+ }
1170
+ async callAudioTranscription(audio) {
1171
+ const audioBase64 = await this.blobToBase64(audio);
1172
+ const result = await this.dispatcher({
1173
+ action: "transcription",
1174
+ audioBase64
1175
+ });
1176
+ return result?.data || null;
1177
+ }
1178
+ async callRoutinePoll(routineId) {
1179
+ const result = await this.dispatcher({
1180
+ action: "routinePoll",
1181
+ routineId
1182
+ });
1183
+ if (result?.data?.orchestrator) {
1184
+ const parsed = JSON.parse(result.data.orchestrator);
1185
+ return parsed;
1186
+ }
1187
+ throw new Error("Poll failed");
1188
+ }
1189
+ async callRoutineStart(routineName, parameters, images) {
1190
+ const result = await this.dispatcher({
1191
+ action: "routineStart",
1192
+ routine: routineName,
1193
+ ...parameters,
1194
+ images
1195
+ });
1196
+ return result?.data || null;
1197
+ }
1198
+ }
1199
+
1200
+ var __defProp$1 = Object.defineProperty;
1201
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1202
+ var __publicField$1 = (obj, key, value) => {
1203
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
861
1204
  return value;
862
1205
  };
863
1206
  class ResponseStream extends EventEmitter {
864
1207
  constructor() {
865
1208
  super(...arguments);
866
- __publicField(this, "buffer", "");
867
- __publicField(this, "isRunning", false);
868
- __publicField(this, "locked", false);
869
- __publicField(this, "partSize", 2);
870
- __publicField(this, "stopped", false);
871
- __publicField(this, "waiting", []);
1209
+ __publicField$1(this, "buffer", "");
1210
+ __publicField$1(this, "isRunning", false);
1211
+ __publicField$1(this, "locked", false);
1212
+ __publicField$1(this, "partSize", 2);
1213
+ __publicField$1(this, "stopped", false);
1214
+ __publicField$1(this, "waiting", []);
872
1215
  }
873
1216
  close() {
874
1217
  this.stopped = true;
@@ -911,5 +1254,202 @@ class ResponseStream extends EventEmitter {
911
1254
  }
912
1255
  }
913
1256
 
914
- export { AIMessageAttachments as AIMessage, AutoscrollContainer, ChatController, ChatMessage, MultipleChoiceMessage, ResponseStream };
1257
+ async function getImageFromDisk(inputProps) {
1258
+ return (await getImagesFromDisk({ ...inputProps, multiple: "false" }))[0] ?? null;
1259
+ }
1260
+ function getImagesFromDisk(inputProps) {
1261
+ return new Promise((resolve) => {
1262
+ const input = document.createElement("input");
1263
+ input.accept = "image/*";
1264
+ input.type = "file";
1265
+ input.style.display = "none";
1266
+ Object.assign(input, inputProps);
1267
+ document.body.append(input);
1268
+ input.addEventListener("change", (event) => {
1269
+ const target = event?.target;
1270
+ if (!target?.files)
1271
+ return;
1272
+ const retrievedImages = [];
1273
+ const sources = [...target.files ?? []];
1274
+ const checkResolve = () => {
1275
+ if (sources.length === retrievedImages.length) {
1276
+ resolve(retrievedImages.filter((c) => !!c));
1277
+ }
1278
+ };
1279
+ sources.forEach((file) => {
1280
+ if (file) {
1281
+ const reader = new FileReader();
1282
+ reader.onload = function(e) {
1283
+ const binary = e.target?.result?.split(",")[1];
1284
+ input.remove();
1285
+ retrievedImages.push({
1286
+ base64: binary,
1287
+ path: file.name
1288
+ });
1289
+ checkResolve();
1290
+ };
1291
+ reader.readAsDataURL(file);
1292
+ } else {
1293
+ retrievedImages.push(null);
1294
+ }
1295
+ checkResolve();
1296
+ });
1297
+ });
1298
+ input.click();
1299
+ });
1300
+ }
1301
+
1302
+ const ImageIcon = ({
1303
+ deletable,
1304
+ onClick,
1305
+ onRemove,
1306
+ src
1307
+ }) => {
1308
+ return /* @__PURE__ */ jsxs(Box, { className: "image_preview", children: [
1309
+ deletable && /* @__PURE__ */ jsx(IconButton, { icon: "Close", size: "Xs", iconSize: "Xs", onClick: onRemove }),
1310
+ /* @__PURE__ */ jsx("img", { src, onClick })
1311
+ ] });
1312
+ };
1313
+
1314
+ function getSrcFromBase64(base64) {
1315
+ return `data:image/jpg;base64,${base64}`;
1316
+ }
1317
+
1318
+ var __defProp = Object.defineProperty;
1319
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1320
+ var __publicField = (obj, key, value) => {
1321
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1322
+ return value;
1323
+ };
1324
+ class ImagesStore {
1325
+ constructor(images, multiple) {
1326
+ this.multiple = multiple;
1327
+ __publicField(this, "images", /* @__PURE__ */ new Map());
1328
+ __publicField(this, "selectedId", "");
1329
+ this.images = new Map(
1330
+ images.map((c) => {
1331
+ const id = uniqueId();
1332
+ return [id, { ...c, id }];
1333
+ })
1334
+ );
1335
+ this.selectedId = this.images.values().next().value.id;
1336
+ makeAutoObservable(this);
1337
+ }
1338
+ }
1339
+ const GetImagesDescription = observer(({ store }) => {
1340
+ return /* @__PURE__ */ jsxs(
1341
+ Box,
1342
+ {
1343
+ className: "images_description_generator",
1344
+ ...getVariant("layout.design.projectAnalysis.imagesLoader"),
1345
+ children: [
1346
+ /* @__PURE__ */ jsx(Box, { className: "images_sort_wrapper", children: /* @__PURE__ */ jsx(
1347
+ SortableList,
1348
+ {
1349
+ onSortChange: (ev) => {
1350
+ store.images = new Map(
1351
+ ev.map((c) => [
1352
+ c.props.id,
1353
+ c.props.additionalProps
1354
+ ])
1355
+ );
1356
+ },
1357
+ children: [...store.images].map(([k, c]) => /* @__PURE__ */ jsx(SortableListItem, { additionalProps: c, id: c.id, children: /* @__PURE__ */ jsx(
1358
+ ImageIcon,
1359
+ {
1360
+ deletable: store.multiple,
1361
+ onClick: () => {
1362
+ store.selectedId = c.id;
1363
+ },
1364
+ onRemove: () => {
1365
+ store.images.delete(k);
1366
+ },
1367
+ src: getSrcFromBase64(c.base64 ?? "")
1368
+ }
1369
+ ) }, c.id))
1370
+ }
1371
+ ) }),
1372
+ /* @__PURE__ */ jsxs(Box, { className: "image_editor", children: [
1373
+ /* @__PURE__ */ jsx(Box, { className: "image_preview", children: store.images.get(store.selectedId) && /* @__PURE__ */ jsx(
1374
+ "img",
1375
+ {
1376
+ src: getSrcFromBase64(
1377
+ store.images.get(store.selectedId).base64 ?? ""
1378
+ )
1379
+ }
1380
+ ) }),
1381
+ /* @__PURE__ */ jsxs(Box, { className: "image_description", children: [
1382
+ /* @__PURE__ */ jsx(
1383
+ Textarea,
1384
+ {
1385
+ autoFocus: true,
1386
+ disabled: !store.images.get(store.selectedId),
1387
+ onChange: (ev) => {
1388
+ const image = store.images.get(store.selectedId);
1389
+ if (image)
1390
+ image.description = ev.target.value;
1391
+ },
1392
+ value: store.images.get(store.selectedId)?.description
1393
+ }
1394
+ ),
1395
+ store.multiple && /* @__PURE__ */ jsx(
1396
+ IconButton,
1397
+ {
1398
+ icon: "Attach",
1399
+ onClick: () => {
1400
+ getImagesFromDisk({ multiple: "true" }).then((res) => {
1401
+ res.forEach((c) => {
1402
+ const id = uniqueId();
1403
+ store.images.set(id, {
1404
+ base64: c.base64,
1405
+ description: "",
1406
+ id
1407
+ });
1408
+ });
1409
+ });
1410
+ },
1411
+ size: "Md",
1412
+ iconSize: "Sm",
1413
+ variant: "icon-only"
1414
+ }
1415
+ )
1416
+ ] })
1417
+ ] })
1418
+ ]
1419
+ }
1420
+ );
1421
+ });
1422
+ function getImagesWithDescription({
1423
+ multiple
1424
+ }) {
1425
+ return new Promise((resolve) => {
1426
+ getImagesFromDisk({ multiple: multiple ? "true" : void 0 }).then(
1427
+ (images) => {
1428
+ const store = new ImagesStore(
1429
+ images.map((c) => ({
1430
+ base64: c.base64,
1431
+ description: ""
1432
+ })),
1433
+ multiple || false
1434
+ );
1435
+ ApiaUtil.instance.modals.open({
1436
+ children: /* @__PURE__ */ jsx(GetImagesDescription, { store }),
1437
+ initialFocusGetter(modalInnerRef) {
1438
+ return modalInnerRef.querySelector("textarea");
1439
+ },
1440
+ onConfirm: () => {
1441
+ resolve([...toJS(store.images).values()]);
1442
+ },
1443
+ onCancel() {
1444
+ resolve([]);
1445
+ },
1446
+ size: "xxxl-fixed",
1447
+ noHeader: true
1448
+ });
1449
+ }
1450
+ );
1451
+ });
1452
+ }
1453
+
1454
+ export { AIMessageAttachments, AutoscrollContainer, ChatController, ChatMessage, DashboardsRoutinesGeneration, MultipleChoiceMessage, ResponseStream, RoutinesGeneration, getImageFromDisk, getImagesFromDisk, getImagesWithDescription };
915
1455
  //# sourceMappingURL=index.js.map