@epam/ai-dial-chat-hooks 1.2.0-dev.2 → 1.2.0-dev.201

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 (92) hide show
  1. package/api-error/api-error.js +5 -4
  2. package/attachment/useAttachmentValidation/useAttachmentValidation.js +26 -19
  3. package/attachments.d.ts +10 -4
  4. package/catalog/catalog-derivations.js +1 -1
  5. package/catalog/deployment-id.js +8 -2
  6. package/catalog/map-deployment-limits-to-input.js +81 -9
  7. package/catalog/map-deployment-to-catalog-item.js +34 -34
  8. package/catalog/map-entity-details-to-catalog.js +7 -0
  9. package/catalog/map-skill-to-catalog-item.js +30 -27
  10. package/catalog/publish.js +6 -5
  11. package/catalog/useApplicationCredentials/useApplicationCredentials.js +39 -0
  12. package/catalog/useSkillDetailsPanelData/useSkillDetailsPanelData.js +39 -39
  13. package/catalog/useSkillItemDetails.js +19 -17
  14. package/catalog.d.ts +134 -20
  15. package/catalog.js +23 -22
  16. package/conversation/announcement-message.js +16 -5
  17. package/conversation/conversation-transfer/export-conversation.js +24 -16
  18. package/conversation/conversation-transfer/import-conversation.js +80 -31
  19. package/conversation/conversation-transfer/queue.js +8 -5
  20. package/conversation/create-chat-stream-api.js +85 -49
  21. package/conversation/message-utils.js +44 -2
  22. package/conversation/stage.js +23 -0
  23. package/conversation/useAttachmentUpload/useAttachmentUpload.js +12 -5
  24. package/conversation/useConversationExport/useConversationExport.js +9 -9
  25. package/conversation/useConversationHandlers/useConversationHandlers.js +13 -17
  26. package/conversation/useConversationImport/useConversationImport.js +123 -121
  27. package/conversation/useConversationPanelItems/useConversationPanelItems.js +2 -3
  28. package/conversation/useConversationScroll/useConversationScroll.js +68 -64
  29. package/conversation/useConversationStream/apply-chunk.js +1 -1
  30. package/conversation/useConversationStream/generation-resume.js +104 -63
  31. package/conversation/useConversationStream/useConversationStream.js +183 -108
  32. package/conversation/useMessageSelectionReply/useMessageSelectionReply.js +189 -0
  33. package/conversation/useTranscribeAudio/transcription-retry.js +5 -4
  34. package/conversation-overlay.d.ts +7 -0
  35. package/conversation-overlay.js +2 -0
  36. package/conversation-sources/useConversationSources/useConversationSources.js +31 -24
  37. package/conversation-sources.d.ts +1 -1
  38. package/conversation-transfer.d.ts +2 -1
  39. package/conversation.d.ts +274 -17
  40. package/conversation.js +32 -30
  41. package/file-manager-canvas.d.ts +398 -0
  42. package/file-manager-canvas.js +2 -0
  43. package/file-manager.d.ts +153 -348
  44. package/file-manager.js +25 -24
  45. package/files/attachment-canvas.js +51 -13
  46. package/files/attachment-types.js +14 -13
  47. package/files/dial-file-manager-mapping.util.js +2 -1
  48. package/files/dial-file-manager-path.util.js +23 -1
  49. package/files/dial-file-manager.model.js +23 -19
  50. package/files/dial-file-manager.types.js +3 -3
  51. package/files/useDialFileListing/useDialFileListing.js +157 -145
  52. package/files/useDialFileManager/useDialFileManager.js +132 -128
  53. package/files/useDialFileManagerSections/useDialFileManagerSections.js +155 -0
  54. package/files/useDialFileManagerTabConfig/useDialFileManagerTabConfig.js +20 -19
  55. package/files/useDialFileMutations/useDialFileMutations.js +33 -32
  56. package/files/useDialFileUploadBatch/useDialFileUploadBatch.js +117 -110
  57. package/files/useFileAttachmentPicker/useFileAttachmentPicker.js +43 -0
  58. package/index.d.ts +1124 -90
  59. package/index.js +136 -122
  60. package/mcp-apps/useMcpAppHostAdapter/useMcpAppHostAdapter.js +7 -5
  61. package/mcp-apps/useMcpAppHostContext/useMcpAppHostContext.js +1 -1
  62. package/mcp-apps/useMcpAppTools/useMcpAppTools.js +1 -1
  63. package/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.js +25 -23
  64. package/mcp-apps.d.ts +8 -6
  65. package/oauth/toolset-id.js +5 -3
  66. package/oauth/useToolsetLogin/useToolsetLogin.js +8 -8
  67. package/oauth.d.ts +32 -0
  68. package/oauth.js +9 -9
  69. package/package.json +36 -21
  70. package/scheduled-task/scheduled-task-description.js +77 -0
  71. package/scheduled-task/scheduled-task-preparation.js +24 -0
  72. package/scheduled-task/scheduled-task-trigger.js +7 -2
  73. package/scheduled-task/scheduled-tasks-api-client.js +19 -0
  74. package/scheduled-task/use-scheduled-task-runs.js +194 -0
  75. package/scheduled-task/use-scheduled-tasks.js +93 -0
  76. package/scheduled-tasks.d.ts +195 -3
  77. package/scheduled-tasks.js +7 -2
  78. package/skill/skill-archive.js +19 -0
  79. package/skill/skill-types.js +8 -7
  80. package/skill/skill.js +42 -27
  81. package/skill/useSkillArchiveImport/useSkillArchiveImport.js +75 -0
  82. package/skill/useSkillEditorLoad.js +29 -28
  83. package/skill/useSkillEditorSubmit.js +108 -84
  84. package/skill/useSkillFileActions.js +70 -58
  85. package/skill-editor.d.ts +131 -3
  86. package/skill-editor.js +9 -8
  87. package/usage/map-usage-data-to-dashboard.js +66 -0
  88. package/usage/map-user-usage-to-model-limits.js +202 -0
  89. package/usage.d.ts +125 -0
  90. package/usage.js +3 -0
  91. package/usePageFileDrag/usePageFileDrag.js +3 -3
  92. package/utils.d.ts +8 -6
@@ -0,0 +1,189 @@
1
+ import { useCallback as e, useEffect as t, useLayoutEffect as n, useMemo as r, useRef as i, useState as a } from "react";
2
+ //#region src/conversation/useMessageSelectionReply/useMessageSelectionReply.ts
3
+ var o = "button,input,textarea,select,iframe,[role=\"button\"],[contenteditable=\"true\"],[hidden],[inert],[aria-hidden=\"true\"]", s = [], c = (e, t) => e?.startContainer === t.startContainer && e.startOffset === t.startOffset && e.endContainer === t.endContainer && e.endOffset === t.endOffset, l = (e, t) => {
4
+ let n = window.visualViewport, r = n?.offsetLeft ?? 0, i = n?.offsetTop ?? 0, a = r + (n?.width ?? document.documentElement.clientWidth), o = i + (n?.height ?? document.documentElement.clientHeight);
5
+ for (let e = t; e; e = e.parentElement) {
6
+ let t = getComputedStyle(e);
7
+ if (t.display === "none" || t.visibility === "hidden") return;
8
+ let n = e.getBoundingClientRect();
9
+ /(hidden|clip|auto|scroll)/.test(t.overflowX) && (r = Math.max(r, n.left), a = Math.min(a, n.right)), /(hidden|clip|auto|scroll)/.test(t.overflowY) && (i = Math.max(i, n.top), o = Math.min(o, n.bottom));
10
+ }
11
+ return Array.from(e.getClientRects()).find((e) => e.width > 0 && e.height > 0 && e.left < a && e.right > r && e.top < o && e.bottom > i);
12
+ }, u = ({ conversationId: u, enabled: d, droppedFiles: f, onDroppedFilesConsumed: p }) => {
13
+ let m = i(/* @__PURE__ */ new Set()), h = i(null), g = i(null), _ = i(null), [v, y] = a(null), [b, x] = a({
14
+ conversationId: u,
15
+ files: []
16
+ }), [S, C] = a(), [w, T] = a(0), E = i(/* @__PURE__ */ new WeakSet()), D = i({
17
+ conversationId: u,
18
+ enabled: d
19
+ });
20
+ n(() => {
21
+ D.current = {
22
+ conversationId: u,
23
+ enabled: d
24
+ };
25
+ }, [u, d]);
26
+ let O = e(() => {
27
+ _.current = g.current?.range.cloneRange() ?? null, g.current = null, y(null);
28
+ }, []), k = e((e) => {
29
+ if (e) return m.current.add(e), () => {
30
+ m.current.delete(e), g.current?.body === e && O();
31
+ };
32
+ }, [O]);
33
+ t(() => {
34
+ O(), _.current = null, E.current = /* @__PURE__ */ new WeakSet(), x({
35
+ conversationId: u,
36
+ files: []
37
+ }), T(0), C(void 0);
38
+ }, [u, O]), t(() => {
39
+ if (!d) {
40
+ O(), x({
41
+ conversationId: u,
42
+ files: []
43
+ });
44
+ return;
45
+ }
46
+ let e = 0, t = !1, n = !1, r = !1, i = () => {
47
+ if (e = 0, t || n || r || h.current?.contains(document.activeElement)) return;
48
+ let i = window.getSelection();
49
+ if (!i || i.rangeCount !== 1 || i.isCollapsed || !i.toString().trim()) {
50
+ O();
51
+ return;
52
+ }
53
+ let a = i.getRangeAt(0);
54
+ if (c(_.current, a)) return;
55
+ let s = [...m.current].find((e) => e.contains(a.startContainer) && e.contains(a.endContainer));
56
+ if (!s || !s.isConnected) {
57
+ O();
58
+ return;
59
+ }
60
+ let d = a.cloneContents();
61
+ d.querySelectorAll(o).forEach((e) => e.remove());
62
+ let f = a.commonAncestorContainer;
63
+ if ((f instanceof Element ? f : f.parentElement)?.closest(o) || !d.textContent?.trim()) {
64
+ O();
65
+ return;
66
+ }
67
+ let p = l(a, s);
68
+ if (!p) {
69
+ O();
70
+ return;
71
+ }
72
+ let v = {
73
+ conversationId: u,
74
+ body: s,
75
+ range: a.cloneRange(),
76
+ text: i.toString(),
77
+ rect: p
78
+ };
79
+ g.current = v, y(v);
80
+ }, a = () => {
81
+ e && cancelAnimationFrame(e), e = requestAnimationFrame(i);
82
+ }, s = () => {
83
+ e && cancelAnimationFrame(e), e = requestAnimationFrame(() => {
84
+ e = 0;
85
+ let t = g.current;
86
+ if (!t) return;
87
+ let n = l(t.range, t.body);
88
+ if (!n) O();
89
+ else {
90
+ let e = {
91
+ ...t,
92
+ rect: n
93
+ };
94
+ g.current = e, y(e);
95
+ }
96
+ });
97
+ }, f = (e) => {
98
+ t = h.current?.contains(e.target) ?? !1, n = !t, t || (O(), [...m.current].some((t) => t.contains(e.target)) && (_.current = null));
99
+ }, p = () => {
100
+ n = !1, t || a(), t = !1;
101
+ }, v = () => {
102
+ n = !1, r = !1, t = !1, O();
103
+ let e = window.getSelection();
104
+ _.current = e?.rangeCount ? e.getRangeAt(0).cloneRange() : null;
105
+ }, b = (e) => {
106
+ if (!h.current?.contains(document.activeElement) && (e.shiftKey && [
107
+ "ArrowLeft",
108
+ "ArrowRight",
109
+ "ArrowUp",
110
+ "ArrowDown",
111
+ "Home",
112
+ "End",
113
+ "PageUp",
114
+ "PageDown"
115
+ ].includes(e.key) || (e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a")) {
116
+ r = !0, O(), _.current = null;
117
+ return;
118
+ }
119
+ if (g.current) {
120
+ if (e.key === "Escape") {
121
+ O();
122
+ return;
123
+ }
124
+ if (e.key === "Tab" && !e.shiftKey && !h.current?.contains(document.activeElement)) {
125
+ let t = h.current?.querySelector("button");
126
+ t && (e.preventDefault(), t.focus());
127
+ }
128
+ }
129
+ }, S = (e) => {
130
+ r && !e.shiftKey && (r = !1), e.key !== "Escape" && e.key !== "Tab" && a();
131
+ }, C = new MutationObserver((e) => {
132
+ let t = g.current;
133
+ t && (!t.body.isConnected || e.some((e) => t.body.contains(e.target))) && O();
134
+ });
135
+ return C.observe(document.body, {
136
+ subtree: !0,
137
+ childList: !0,
138
+ characterData: !0,
139
+ attributes: !0,
140
+ attributeFilter: [
141
+ "class",
142
+ "style",
143
+ "hidden",
144
+ "inert"
145
+ ]
146
+ }), document.addEventListener("selectionchange", a), document.addEventListener("pointerdown", f, !0), document.addEventListener("pointerup", p, !0), document.addEventListener("pointercancel", v, !0), window.addEventListener("blur", v), document.addEventListener("keydown", b), document.addEventListener("keyup", S), document.addEventListener("scroll", s, !0), window.addEventListener("resize", s), window.visualViewport?.addEventListener("resize", s), window.visualViewport?.addEventListener("scroll", s), () => {
147
+ cancelAnimationFrame(e), C.disconnect(), document.removeEventListener("selectionchange", a), document.removeEventListener("pointerdown", f, !0), document.removeEventListener("pointerup", p, !0), document.removeEventListener("pointercancel", v, !0), window.removeEventListener("blur", v), document.removeEventListener("keydown", b), document.removeEventListener("keyup", S), document.removeEventListener("scroll", s, !0), window.removeEventListener("resize", s), window.visualViewport?.removeEventListener("resize", s), window.visualViewport?.removeEventListener("scroll", s);
148
+ };
149
+ }, [
150
+ u,
151
+ O,
152
+ d
153
+ ]);
154
+ let A = e(() => {
155
+ let e = g.current;
156
+ if (!D.current.enabled || !e || e.conversationId !== D.current.conversationId || !e.body.isConnected || !l(e.range, e.body)) return;
157
+ let t = new File([e.text], `reply-${crypto.randomUUID()}.txt`, { type: "text/plain" });
158
+ E.current.add(t), T(0), x((n) => ({
159
+ conversationId: e.conversationId,
160
+ files: [...n.conversationId === e.conversationId ? n.files : [], t]
161
+ })), C((e) => (e ?? 0) + 1), O(), window.getSelection()?.removeAllRanges();
162
+ }, [O]), j = d && b.conversationId === u ? b.files : s, M = r(() => [...f, ...j], [f, j]), N = e(() => {
163
+ f.length && p(), x((e) => ({
164
+ ...e,
165
+ files: e.files.filter((e) => !j.includes(e))
166
+ }));
167
+ }, [
168
+ f,
169
+ p,
170
+ j
171
+ ]), P = e((e) => {
172
+ let t = e.filter((e) => e.file && E.current.has(e.file));
173
+ t.length && (t.forEach((e) => E.current.delete(e.file)), T((e) => e + 1));
174
+ }, []);
175
+ return {
176
+ contentRef: k,
177
+ actionRef: h,
178
+ selection: d && v?.conversationId === u ? v : null,
179
+ onReply: A,
180
+ dismiss: O,
181
+ pendingFiles: M,
182
+ onFilesConsumed: N,
183
+ focusRequestId: S,
184
+ onAttachmentsChange: P,
185
+ addedRevision: w
186
+ };
187
+ };
188
+ //#endregion
189
+ export { u as useMessageSelectionReply };
@@ -1,6 +1,6 @@
1
1
  import { AudioTranscriptionError as e, AudioTranscriptionErrorReason as t } from "./audio-transcription-error.js";
2
2
  //#region src/conversation/useTranscribeAudio/transcription-retry.ts
3
- var n = 2, r = 9e4, i = (e, t) => (t.throwIfAborted(), new Promise((n, r) => {
3
+ var n = 2, r = 6e3, i = (e, t) => (t.throwIfAborted(), new Promise((n, r) => {
4
4
  let i = () => {
5
5
  clearTimeout(a), r(t.reason);
6
6
  }, a = setTimeout(() => {
@@ -28,9 +28,10 @@ var n = 2, r = 9e4, i = (e, t) => (t.throwIfAborted(), new Promise((n, r) => {
28
28
  503,
29
29
  504
30
30
  ].includes(u.status)) throw o;
31
- let d = [429, 503].includes(u.status) ? 3e4 : 2e3, f = Math.max(1e3, a(u.headers.get("retry-after")) ?? d * 2 ** l);
32
- if (l >= n || c + f > r) throw new e(t.Busy);
33
- c += f, await i(f, s);
31
+ if ([429, 503].includes(u.status)) throw new e(t.Busy);
32
+ let d = Math.max(1e3, a(u.headers.get("retry-after")) ?? 2e3 * 2 ** l);
33
+ if (l >= n || c + d > r) throw new e(t.Busy);
34
+ c += d, await i(d, s);
34
35
  }
35
36
  }
36
37
  };
@@ -0,0 +1,7 @@
1
+ import { Message } from '@epam/ai-dial-chat-shared';
2
+ import { OverlayChatMessage } from '@epam/ai-dial-chat-overlay';
3
+
4
+ /** Maps chat messages to the DIAL Chat Overlay protocol's message shape. */
5
+ export declare const toOverlayMessages: (messages: Message[]) => OverlayChatMessage[];
6
+
7
+ export { }
@@ -0,0 +1,2 @@
1
+ import { toOverlayMessages as e } from "./conversation/overlay-messages.js";
2
+ export { e as toOverlayMessages };
@@ -1,35 +1,42 @@
1
1
  import { MessageRole as e, messageAttachmentToDisplayAttachment as t } from "@epam/ai-dial-chat-shared";
2
- import { isReferenceOnlyAttachment as n, resolveMessageAnnotations as r } from "@epam/ai-dial-quotations";
3
- import { useMemo as i } from "react";
2
+ import { getAnnotationPdfPage as n, isReferenceOnlyAttachment as r, parsePdfPageReference as i, resolveMessageAnnotations as a } from "@epam/ai-dial-quotations";
3
+ import { useMemo as o } from "react";
4
4
  //#region src/conversation-sources/useConversationSources/useConversationSources.ts
5
- var a = {}, o = (o, s = a) => i(() => {
6
- let i = [], a = [], c = [], l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
7
- for (let f of o) {
8
- let o = f.custom_content?.attachments;
9
- if (f.role === e.User) for (let e of o ?? []) {
10
- let n = t(e, s);
11
- u.has(n.id) || (u.add(n.id), i.push(n));
5
+ var s = {}, c = (e, t) => {
6
+ let r = n(e);
7
+ if (r == null) return t;
8
+ let a = i(t);
9
+ return a == null || a.page != null ? t : `${t}#page=${r}`;
10
+ }, l = (n, i = s) => o(() => {
11
+ let o = [], s = [], l = [], u = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set(), f = /* @__PURE__ */ new Set();
12
+ for (let p of n) {
13
+ let n = p.custom_content?.attachments;
14
+ if (p.role === e.User) for (let e of n ?? []) {
15
+ let n = t(e, i);
16
+ d.has(n.id) || (d.add(n.id), o.push(n));
12
17
  }
13
- else if (f.role === e.Assistant) {
14
- let e = o?.filter((e) => !n(e));
18
+ else if (p.role === e.Assistant) {
19
+ let e = n?.filter((e) => !r(e));
15
20
  for (let n of e ?? []) {
16
- let e = t(n, s);
17
- d.has(e.id) || (d.add(e.id), a.push(e));
21
+ let e = t(n, i);
22
+ f.has(e.id) || (f.add(e.id), s.push(e));
18
23
  }
19
- for (let e of o ?? []) {
20
- if (!n(e)) continue;
24
+ for (let e of n ?? []) {
25
+ if (!r(e)) continue;
21
26
  let t = e.reference_url;
22
- l.has(t) || (l.add(t), c.push({
27
+ u.has(t) || (u.add(t), l.push({
23
28
  url: t,
24
29
  title: e.title ?? t,
25
30
  contentType: e.reference_type ?? e.type ?? "",
26
31
  quote: e.data
27
32
  }));
28
33
  }
29
- for (let e of r(f)) {
34
+ for (let e of a(p)) {
30
35
  let t = e?.body?.source?.attachment, n = t?.url;
31
- !n || l.has(n) || (l.add(n), c.push({
32
- url: n,
36
+ if (!n) continue;
37
+ let r = c(e, n);
38
+ u.has(r) || (u.add(r), l.push({
39
+ url: r,
33
40
  title: t?.title ?? n.split("/").pop() ?? n,
34
41
  contentType: t?.type ?? "",
35
42
  quote: e.body?.quote
@@ -38,10 +45,10 @@ var a = {}, o = (o, s = a) => i(() => {
38
45
  }
39
46
  }
40
47
  return {
41
- uploaded: i,
42
- generated: a,
43
- sources: c
48
+ uploaded: o,
49
+ generated: s,
50
+ sources: l
44
51
  };
45
- }, [o, s]);
52
+ }, [n, i]);
46
53
  //#endregion
47
- export { o as useConversationSources };
54
+ export { l as useConversationSources };
@@ -18,7 +18,7 @@ export declare interface UseConversationSourcesResult {
18
18
  uploaded: DisplayAttachment[];
19
19
  /** Deduplicated attachments the assistant generated across the conversation. */
20
20
  generated: DisplayAttachment[];
21
- /** Quotation sources referenced by assistant messages, deduplicated by URL. */
21
+ /** Quotation sources referenced by assistant messages, deduplicated by URL; PDF sources are qualified with `#page=N`. */
22
22
  sources: QuotationSource[];
23
23
  }
24
24
 
@@ -139,7 +139,8 @@ export declare interface UseConversationExportResult {
139
139
  * `.dial`/`.zip`, v5 envelope, old- or new-chat origin) once per file, then
140
140
  * re-uploads any archive attachments to `uploads/<YYYY-MM>/` —
141
141
  * disambiguating a name collision with a ` (n)` suffix instead of rejecting
142
- * it — rewrites attachment references (and renamed titles), regenerates each
142
+ * it — rewrites attachment references (and renamed titles), drops any
143
+ * reference still pointing into another user's bucket, regenerates each
143
144
  * conversation's id/path with a fresh UUID (collision-free save, no replace
144
145
  * dialog), and persists every conversation through the injected
145
146
  * `conversationsApi`. One job per imported file, not per conversation.