@things-factory/ai-assistant 10.1.226 → 10.1.227

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.
Files changed (105) hide show
  1. package/client/components/assistant-chat.ts +50 -2
  2. package/client/components/assistant-dock.ts +1 -1
  3. package/client/components/assistant-mode.ts +1 -1
  4. package/client/components/entry-review.ts +2 -2
  5. package/client/components/workspace-view.ts +1 -1
  6. package/client/index.ts +1 -1
  7. package/client/pages/assistant-workspace-page.ts +1 -1
  8. package/client/route.ts +1 -1
  9. package/client/utils/attachment-policy.ts +15 -8
  10. package/client/utils/document-text.ts +332 -0
  11. package/client/utils/entry-hash.ts +1 -1
  12. package/client/utils/entry-proposal.ts +1 -1
  13. package/client/utils/entry-workspace.ts +1 -1
  14. package/client/utils/pdf-pages.ts +38 -0
  15. package/client/utils/workspace.ts +1 -1
  16. package/dist-client/components/assistant-chat.d.ts +3 -1
  17. package/dist-client/components/assistant-chat.js +48 -2
  18. package/dist-client/components/assistant-chat.js.map +1 -1
  19. package/dist-client/components/assistant-dock.js +1 -1
  20. package/dist-client/components/assistant-dock.js.map +1 -1
  21. package/dist-client/components/assistant-mode.d.ts +1 -1
  22. package/dist-client/components/assistant-mode.js.map +1 -1
  23. package/dist-client/components/entry-review.d.ts +1 -1
  24. package/dist-client/components/entry-review.js +2 -2
  25. package/dist-client/components/entry-review.js.map +1 -1
  26. package/dist-client/components/workspace-view.js +1 -1
  27. package/dist-client/components/workspace-view.js.map +1 -1
  28. package/dist-client/index.js +1 -1
  29. package/dist-client/index.js.map +1 -1
  30. package/dist-client/pages/assistant-workspace-page.js +1 -1
  31. package/dist-client/pages/assistant-workspace-page.js.map +1 -1
  32. package/dist-client/route.js +1 -1
  33. package/dist-client/route.js.map +1 -1
  34. package/dist-client/tsconfig.tsbuildinfo +1 -1
  35. package/dist-client/utils/attachment-policy.d.ts +2 -2
  36. package/dist-client/utils/attachment-policy.js +9 -5
  37. package/dist-client/utils/attachment-policy.js.map +1 -1
  38. package/dist-client/utils/document-text.d.ts +118 -0
  39. package/dist-client/utils/document-text.js +320 -0
  40. package/dist-client/utils/document-text.js.map +1 -0
  41. package/dist-client/utils/entry-hash.js +1 -1
  42. package/dist-client/utils/entry-hash.js.map +1 -1
  43. package/dist-client/utils/entry-proposal.js +1 -1
  44. package/dist-client/utils/entry-proposal.js.map +1 -1
  45. package/dist-client/utils/entry-workspace.js +1 -1
  46. package/dist-client/utils/entry-workspace.js.map +1 -1
  47. package/dist-client/utils/pdf-pages.d.ts +6 -0
  48. package/dist-client/utils/pdf-pages.js +34 -0
  49. package/dist-client/utils/pdf-pages.js.map +1 -0
  50. package/dist-client/utils/workspace.js +1 -1
  51. package/dist-client/utils/workspace.js.map +1 -1
  52. package/dist-server/service/assistant-mode/assistant-mode-resolver.js +1 -1
  53. package/dist-server/service/assistant-mode/assistant-mode-resolver.js.map +1 -1
  54. package/dist-server/service/assistant-mode/mode-categories.d.ts +3 -3
  55. package/dist-server/service/assistant-mode/mode-categories.js +4 -4
  56. package/dist-server/service/assistant-mode/mode-categories.js.map +1 -1
  57. package/dist-server/service/chat-session/attachment-policy.d.ts +1 -1
  58. package/dist-server/service/chat-session/attachment-policy.js +2 -2
  59. package/dist-server/service/chat-session/attachment-policy.js.map +1 -1
  60. package/dist-server/service/data-entry/entry-apply.d.ts +1 -1
  61. package/dist-server/service/data-entry/entry-apply.js +1 -1
  62. package/dist-server/service/data-entry/entry-apply.js.map +1 -1
  63. package/dist-server/service/data-entry/entry-hash.js +1 -1
  64. package/dist-server/service/data-entry/entry-hash.js.map +1 -1
  65. package/dist-server/service/data-read/read-target.d.ts +1 -1
  66. package/dist-server/service/data-read/read-target.js +2 -2
  67. package/dist-server/service/data-read/read-target.js.map +1 -1
  68. package/dist-server/service/data-read/read-tools.js +5 -5
  69. package/dist-server/service/data-read/read-tools.js.map +1 -1
  70. package/dist-server/service/index.js +1 -1
  71. package/dist-server/service/index.js.map +1 -1
  72. package/dist-server/service/people/index.js +1 -1
  73. package/dist-server/service/people/index.js.map +1 -1
  74. package/dist-server/service/workspace/workspace-blocks.js +1 -1
  75. package/dist-server/service/workspace/workspace-blocks.js.map +1 -1
  76. package/dist-server/service/workspace/workspace-tools.js +1 -1
  77. package/dist-server/service/workspace/workspace-tools.js.map +1 -1
  78. package/dist-server/tsconfig.tsbuildinfo +1 -1
  79. package/package.json +11 -9
  80. package/server/service/assistant-mode/assistant-mode-resolver.ts +1 -1
  81. package/server/service/assistant-mode/mode-categories.ts +4 -4
  82. package/server/service/assistant-mode/mode-front.test.ts +1 -1
  83. package/server/service/assistant-mode/resolve.test.ts +1 -1
  84. package/server/service/chat-session/attachment-policy.ts +7 -5
  85. package/server/service/data-entry/entry-apply.ts +2 -2
  86. package/server/service/data-entry/entry-hash.ts +1 -1
  87. package/server/service/data-read/read-target.ts +2 -2
  88. package/server/service/data-read/read-tools.ts +5 -5
  89. package/server/service/data-read/read-words.test.ts +1 -1
  90. package/server/service/index.ts +1 -1
  91. package/server/service/people/index.ts +1 -1
  92. package/server/service/unattended-run/run-unattended.test.ts +1 -1
  93. package/server/service/workspace/workspace-blocks.ts +1 -1
  94. package/server/service/workspace/workspace-tools.ts +1 -1
  95. package/server/service/workspace/workspace.test.ts +1 -1
  96. package/test/attachment-policy-agree.test.ts +4 -1
  97. package/test/document-text.test.ts +175 -0
  98. package/test/entry-workspace.test.ts +1 -1
  99. package/test/workspace.test.ts +1 -1
  100. package/translations/en.json +6 -0
  101. package/translations/es.json +6 -0
  102. package/translations/ja.json +6 -0
  103. package/translations/ko.json +16 -10
  104. package/translations/ms.json +6 -0
  105. package/translations/zh.json +6 -0
@@ -34,12 +34,14 @@ import { i18next } from '@operato/i18n';
34
34
  import { ScrollbarStyles } from '@operato/styles';
35
35
  import gql from 'graphql-tag';
36
36
  import { renderMarkdown, injectMentionRefids, injectMentionUserIds, stripMentionRefids } from './markdown.js';
37
- import { acceptOf, chatAttachmentUrl, refuseAttachments, textCharsOf } from '../utils/attachment-policy.js';
37
+ import { acceptOf, chatAttachmentUrl, limitsOf, refuseAttachments, textCharsOf } from '../utils/attachment-policy.js';
38
38
  import { fileUploadLimits } from '@operato/utils/file-acceptance.js';
39
39
  import '@operato/input/ox-input-file.js';
40
40
  import { pastedTableFile } from '../utils/pasted-table.js';
41
41
  import { appendWords, composerHeight, composerKeyAction, composerSuggestion, sendShortcut, tableAsWords } from '../utils/composer-frame.js';
42
42
  import { readSpreadsheet, spreadsheetKindOf } from '../utils/spreadsheet-text.js';
43
+ import { documentKindOf, readDocx, readPdf, readPptx } from '../utils/document-text.js';
44
+ import { drawPdfPage, loadPdfjs } from '../utils/pdf-pages.js';
43
45
  import { entryReviewAddress, offersWorkspaceReview } from '../utils/entry-workspace.js';
44
46
  import { buildAssistantChatInput, buildChatMutationInput } from './chat-input-builder.js';
45
47
  import { agentDetail, offersAgentPicker, pickAgentId, rememberAgent, rememberedAgent } from '../utils/agent-choice.js';
@@ -514,6 +516,15 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
514
516
  }
515
517
  list = read.files;
516
518
  }
519
+ if (this.usesAttachmentPolicy && this.modeView?.attachments?.kinds?.includes('document')) {
520
+ /* A PDF, .docx or .pptx travels as its text with its page and slide numbers, a scanned page as an image (§9-6). */
521
+ const read = await this.readDocuments(list);
522
+ if ('refusal' in read) {
523
+ this.errorMessage = String(i18next.t(`ai-assistant.text.${read.refusal.code}`, { ...read.refusal, defaultValue: read.refusal.code }));
524
+ return;
525
+ }
526
+ list = read.files;
527
+ }
517
528
  if (this.usesAttachmentPolicy) {
518
529
  /* Said before anything is sent - never cut silently (§9-1). The one picking rule, the server's upload limit included. */
519
530
  const refusal = refuseAttachments(this.modeView?.attachments, [...this.attachments, ...list].map(f => ({ name: f.name, type: f.type, size: f.size })), await fileUploadLimits());
@@ -570,6 +581,41 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
570
581
  }
571
582
  return { files: out };
572
583
  }
584
+ /** Each document replaced by its text, and a PDF's scanned pages by their images; any other file passes as it is. */
585
+ async readDocuments(list) {
586
+ const policy = this.modeView?.attachments;
587
+ const maxChars = textCharsOf(policy);
588
+ const out = [];
589
+ for (const file of list) {
590
+ const kind = documentKindOf(file);
591
+ if (!kind) {
592
+ out.push(file);
593
+ continue;
594
+ }
595
+ if (kind === 'doc' || kind === 'ppt')
596
+ return { refusal: { code: 'attachment-old-office-not-read', name: file.name } };
597
+ const data = await file.arrayBuffer();
598
+ let read;
599
+ if (kind === 'pdf') {
600
+ const pdfjs = await loadPdfjs();
601
+ let pdf;
602
+ read = await readPdf(async () => (pdf = await pdfjs.getDocument({ data }).promise), file.name, maxChars,
603
+ /* The text travels as one file; the scans may take the rest of what one message carries. */
604
+ { allowed: !!policy?.kinds?.includes('image'), max: Math.max(0, limitsOf(policy).maxFiles - 1) }, number => drawPdfPage(pdf, number));
605
+ }
606
+ else {
607
+ const mod = await import('jszip');
608
+ const zip = mod.default ?? mod;
609
+ read = kind === 'docx' ? await readDocx(data, file.name, maxChars, zip) : await readPptx(data, file.name, maxChars, zip);
610
+ }
611
+ if ('refusal' in read)
612
+ return { refusal: read.refusal };
613
+ out.push(new File([read.files.text.text], read.files.text.name, { type: 'text/plain' }));
614
+ for (const image of read.files.images)
615
+ out.push(new File([image.blob], image.name, { type: 'image/jpeg' }));
616
+ }
617
+ return { files: out };
618
+ }
573
619
  readFileAsBase64(file) {
574
620
  return new Promise((resolve, reject) => {
575
621
  const reader = new FileReader();
@@ -4242,7 +4288,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
4242
4288
  </div>
4243
4289
  `;
4244
4290
  }
4245
- /** The AI 작업판 card - what it holds, which version, and the way to open it. The person opens it; the model does not. */
4291
+ /** The AI 작업 패널 card - what it holds, which version, and the way to open it. The person opens it; the model does not. */
4246
4292
  renderWorkspaceCard(p, key) {
4247
4293
  const { version, of } = versionOfCard(this.lines.map(one => one.proposals ?? []), p.workspace.name, key);
4248
4294
  const contents = Object.entries(p.contents ?? {})