@epam/ai-dial-chat-hooks 1.1.0-dev.447 → 1.1.0-dev.459

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  import { MessageRole as e } from "@epam/ai-dial-chat-shared";
2
2
  //#region src/conversation/useConversationHandlers/message-utils.ts
3
- var t = (e) => e != null && Object.keys(e).length > 0, n = (e, t, n, r) => {
4
- if (t !== e.content || r.length > 0) return !0;
5
- let i = e.custom_content?.attachments?.length ?? 0;
6
- return n.length !== i;
7
- }, r = (t) => t == null || t.role !== e.Assistant || !!t.wasStoppedByUser || t.streamErrorMessage != null, i = (e, t, i, a, o) => {
8
- let s = e[t];
9
- return s ? n(s, i, a, o) || r(e[t + 1]) : !1;
3
+ var t = (e) => e != null && Object.keys(e).length > 0, n = (e, t) => (e?.length ?? 0) === (t?.length ?? 0) ? (e ?? []).some((e, n) => e.url !== t?.[n]?.url) : !0, r = (e, t, r, i, a) => {
4
+ if (t !== e.content || i.length > 0) return !0;
5
+ let o = e.custom_content?.attachments?.length ?? 0;
6
+ return r.length === o ? a != null && n(e.custom_content?.skills, a) : !0;
7
+ }, i = (t) => t == null || t.role !== e.Assistant || !!t.wasStoppedByUser || t.streamErrorMessage != null, a = (e, t, n, a, o, s) => {
8
+ let c = e[t];
9
+ return c ? r(c, n, a, o, s) || i(e[t + 1]) : !1;
10
10
  };
11
11
  //#endregion
12
- export { t as hasActiveToolConfig, r as isAnswerIncomplete, n as isMessageChanged, i as shouldRerunGenerationOnEdit };
12
+ export { t as hasActiveToolConfig, i as isAnswerIncomplete, r as isMessageChanged, a as shouldRerunGenerationOnEdit };
@@ -13,24 +13,25 @@ var p = ({ conversation: p, conversationId: m, bucket: h, isStreaming: g, startS
13
13
  filesApi: b,
14
14
  bucket: h,
15
15
  onNetworkError: T
16
- }), P = u(async (e, i) => {
16
+ }), P = u(async (e, i, a) => {
17
17
  if (!m || !p) return;
18
- let a = t(i), o = r(E), s = a?.length || o ? {
19
- ...a?.length ? { attachments: a } : {},
20
- ...o ? { configuration_value: E } : {}
21
- } : void 0, c = C(), { userMessage: u, assistantMessage: d } = n(e, s, c);
18
+ let o = t(i), s = r(E), c = o?.length || s || a?.length ? {
19
+ ...o?.length ? { attachments: o } : {},
20
+ ...s ? { configuration_value: E } : {},
21
+ ...a?.length ? { skills: a } : {}
22
+ } : void 0, u = C(), { userMessage: d, assistantMessage: h } = n(e, c, u);
22
23
  v((e) => {
23
24
  if (!e) return e;
24
25
  let t = {
25
26
  ...e,
26
27
  messages: [
27
28
  ...e.messages,
28
- u,
29
- d
29
+ d,
30
+ h
30
31
  ]
31
32
  };
32
33
  return y.current = t, t;
33
- }), _(m, e, p.messages.length + 1, c, s, l(), f.Append);
34
+ }), _(m, e, p.messages.length + 1, u, c, l(), f.Append);
34
35
  }, [
35
36
  p,
36
37
  m,
@@ -206,43 +207,46 @@ var p = ({ conversation: p, conversationId: m, bucket: h, isStreaming: g, startS
206
207
  return n.delete(e), n;
207
208
  });
208
209
  }, []),
209
- handleEditMessage: u(async (e, n, r, a) => {
210
+ handleEditMessage: u(async (e, n, r, a, o) => {
210
211
  if (g || !m || !p) return;
211
- let o = e;
212
- if (o === -1 || p.messages[o].role !== c.User) return;
213
- let s = p.messages[o];
214
- if (!i(p.messages, o, n, r, a)) {
212
+ let s = e;
213
+ if (s === -1 || p.messages[s].role !== c.User) return;
214
+ let u = p.messages[s];
215
+ if (!i(p.messages, s, n, r, a, o)) {
215
216
  A((e) => {
216
217
  let t = new Set(e);
217
- return t.delete(o), t;
218
+ return t.delete(s), t;
218
219
  });
219
220
  return;
220
221
  }
221
- let u = t(a), d = new Set(r.map((e) => e.id)), h = [...(s.custom_content?.attachments ?? []).filter((e) => {
222
+ let d = t(a), h = new Set(r.map((e) => e.id)), b = [...(u.custom_content?.attachments ?? []).filter((e) => {
222
223
  let t = e.url ?? e.data ?? e.title;
223
- return d.has(t);
224
- }), ...u ?? []], { attachments: b, ...x } = s.custom_content ?? {}, S = h.length > 0 ? {
225
- ...x,
226
- attachments: h
227
- } : Object.keys(x).length > 0 ? x : void 0, w = {
228
- ...s,
224
+ return h.has(t);
225
+ }), ...d ?? []], { attachments: x, skills: S, ...w } = u.custom_content ?? {}, T = o ?? S, E;
226
+ E = b.length > 0 || T?.length ? {
227
+ ...w,
228
+ ...b.length > 0 ? { attachments: b } : {},
229
+ ...T?.length ? { skills: T } : {}
230
+ } : Object.keys(w).length > 0 ? w : void 0;
231
+ let D = {
232
+ ...u,
229
233
  content: n,
230
- custom_content: S
231
- }, T = Date.now(), E = {
234
+ custom_content: E
235
+ }, O = Date.now(), k = {
232
236
  role: c.Assistant,
233
237
  content: "",
234
- timestamp: new Date(T).toISOString()
235
- }, D = [
236
- ...p.messages.slice(0, o),
237
- w,
238
- E
239
- ], O = {
238
+ timestamp: new Date(O).toISOString()
239
+ }, j = [
240
+ ...p.messages.slice(0, s),
241
+ D,
242
+ k
243
+ ], M = {
240
244
  ...p,
241
- messages: D
245
+ messages: j
242
246
  };
243
- y.current = O, v(O);
244
- let k = C();
245
- _(m, n, D.length - 1, k, S, l(), f.Edit), A(/* @__PURE__ */ new Set());
247
+ y.current = M, v(M);
248
+ let N = C();
249
+ _(m, n, j.length - 1, N, E, l(), f.Edit), A(/* @__PURE__ */ new Set());
246
250
  }, [
247
251
  p,
248
252
  m,
package/conversation.d.ts CHANGED
@@ -20,6 +20,7 @@ import { PublishHistoryEntry } from '@epam/ai-dial-publish-panel';
20
20
  import { RateApi } from '@epam/ai-dial-chat-api-client';
21
21
  import { ReactNode } from 'react';
22
22
  import { RefObject } from 'react';
23
+ import { RequestSkill } from '@epam/ai-dial-chat-shared';
23
24
  import { ResponseFormat } from '@epam/ai-dial-chat-shared';
24
25
  import { SendCompletionDtoModeEnum } from '@epam/ai-dial-chat-api-client';
25
26
  import { SetStateAction } from 'react';
@@ -506,15 +507,20 @@ export declare const isAnswerIncomplete: (answer: Message | undefined) => boolea
506
507
  export declare const isAwaitingGenerationResume: (conversation: Conversation) => boolean;
507
508
 
508
509
  /**
509
- * Returns `true` when the edited text or attachment list differs from the
510
- * original message, meaning a regeneration is needed.
510
+ * Returns `true` when the edited text, attachment list, or skills list differs
511
+ * from the original message, meaning a regeneration is needed.
512
+ *
513
+ * `skills` is the skills state the edit will write: `undefined` leaves the
514
+ * original skills out of the comparison (nothing about them changes), while an
515
+ * array — including an empty one — is compared against the original.
511
516
  *
512
517
  * @param originalMessage - The unmodified message stored in the conversation.
513
518
  * @param newText - The text the user submitted from the edit area.
514
519
  * @param keptDisplayAttachments - Attachments the user kept (not removed).
515
520
  * @param newAttachments - Brand-new attachments the user added during editing.
521
+ * @param skills - The skills the edited message will carry, or `undefined` to leave them unchanged.
516
522
  */
517
- export declare const isMessageChanged: (originalMessage: Message, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[]) => boolean;
523
+ export declare const isMessageChanged: (originalMessage: Message, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[], skills?: RequestSkill[]) => boolean;
518
524
 
519
525
  /**
520
526
  * Returns `true` when `message` is the actively-streaming assistant response.
@@ -611,8 +617,10 @@ export declare const sanitizeFooterHtml: (html: string) => string;
611
617
  * its answer never completed — after stopping a generation the user submits
612
618
  * the same message precisely to get a full answer, so treating that as "no
613
619
  * change" would leave the conversation stuck with the partial one.
620
+ *
621
+ * @param skills - The skills the edited message will carry, or `undefined` to leave them unchanged — see {@link isMessageChanged}.
614
622
  */
615
- export declare const shouldRerunGenerationOnEdit: (messages: Message[], messageIndex: number, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[]) => boolean;
623
+ export declare const shouldRerunGenerationOnEdit: (messages: Message[], messageIndex: number, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[], skills?: RequestSkill[]) => boolean;
616
624
 
617
625
  /** True when the first user/assistant exchange is complete and LLM naming may still run. */
618
626
  export declare const shouldWatchForDisplayNameUpdate: (conversation: Conversation) => boolean;
@@ -795,7 +803,7 @@ export declare interface UseConversationHandlersParams {
795
803
 
796
804
  /** Return value of {@link useConversationHandlers}. */
797
805
  export declare interface UseConversationHandlersResult {
798
- handleSend: (message: string, attachments: Attachment[]) => Promise<void>;
806
+ handleSend: (message: string, attachments: Attachment[], skills?: RequestSkill[]) => Promise<void>;
799
807
  handleUploadAttachment: (attachment: Attachment) => Promise<UploadedAttachmentResult>;
800
808
  handleRegenerateMessage: (messageIndex: number) => void;
801
809
  handleDeleteMessage: (messageIndex: number) => void;
@@ -805,7 +813,7 @@ export declare interface UseConversationHandlersResult {
805
813
  handleConfirmStarter: () => void;
806
814
  handleStartEdit: (messageIndex: number) => void;
807
815
  handleCancelEdit: (messageIndex: number) => void;
808
- handleEditMessage: (messageIndex: number, text: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[]) => Promise<void>;
816
+ handleEditMessage: (messageIndex: number, text: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[], skills?: RequestSkill[]) => Promise<void>;
809
817
  editingMessageIndexes: Set<number>;
810
818
  pendingDeleteIndex: number | null;
811
819
  setPendingDeleteIndex: (index: number | null) => void;
package/file-manager.d.ts CHANGED
@@ -85,6 +85,8 @@ export declare interface AttachmentCanvasUrlResolvers {
85
85
  resolveDialFileDownloadUrl: (fileId: string) => string | undefined;
86
86
  /** Resolves the best downloadable DIAL-file URL from an attachment's `url` or `referenceUrl`. */
87
87
  resolveDialUrl: (attachment: DisplayAttachment) => string | undefined;
88
+ /** Resolves a DIAL Core file id to a fetchable metadata URL (used for cache-freshness validation). */
89
+ resolveDialFileMetadataUrl: (fileId: string) => string | undefined;
88
90
  }
89
91
 
90
92
  /** The type of content the canvas can display. */
@@ -17,45 +17,80 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
17
17
  url: e
18
18
  }), b = new h({ max: 10 }), x = new h({ max: 50 }), S = () => {
19
19
  b.clear(), x.clear();
20
- }, C = (e) => {
21
- let t = b.get(e);
22
- return t ?? (t = fetch(e).then((e) => {
20
+ }, C = async (e, t) => {
21
+ let n = t.resolveDialFileMetadataUrl(e);
22
+ if (n != null) try {
23
+ let e = await fetch(n);
24
+ if (!e.ok) return;
25
+ let t = (await e.json())?.etag;
26
+ return typeof t == "string" ? t : void 0;
27
+ } catch {
28
+ return;
29
+ }
30
+ }, w = async (e, t, n) => {
31
+ let r = await C(t, n);
32
+ if (r == null) return fetch(e).then((e) => {
33
+ if (!e.ok) throw Object.assign(/* @__PURE__ */ Error(`HTTP ${e.status}`), { status: e.status });
34
+ return e.blob();
35
+ });
36
+ let i = b.get(e);
37
+ if (i != null && i.etag === r) return i.promise;
38
+ b.delete(e);
39
+ let a = fetch(e).then((e) => {
23
40
  if (!e.ok) throw Object.assign(/* @__PURE__ */ Error(`HTTP ${e.status}`), { status: e.status });
24
41
  return e.blob();
25
42
  }).catch((t) => {
26
43
  throw b.delete(e), t;
27
- }), b.set(e, t)), t;
28
- }, w = (e) => {
29
- let t = x.get(e);
30
- return t ?? (t = fetch(e).then((e) => {
44
+ });
45
+ return b.set(e, {
46
+ etag: r,
47
+ promise: a
48
+ }), a;
49
+ }, T = async (e, t, n) => {
50
+ let r = await C(t, n);
51
+ if (r == null) return fetch(e).then((e) => {
52
+ if (!e.ok) throw Object.assign(/* @__PURE__ */ Error(`HTTP ${e.status}`), { status: e.status });
53
+ return e.text();
54
+ });
55
+ let i = x.get(e);
56
+ if (i != null && i.etag === r) return i.promise;
57
+ x.delete(e);
58
+ let a = fetch(e).then((e) => {
31
59
  if (!e.ok) throw Object.assign(/* @__PURE__ */ Error(`HTTP ${e.status}`), { status: e.status });
32
60
  return e.text();
33
61
  }).catch((t) => {
34
62
  throw x.delete(e), t;
35
- }), x.set(e, t)), t;
36
- }, T = async (e, t) => {
63
+ });
64
+ return x.set(e, {
65
+ etag: r,
66
+ promise: a
67
+ }), a;
68
+ }, E = (e) => e.split("#")[0], D = (t) => {
69
+ if (t.url != null && e(t.url)) return E(t.url);
70
+ if (t.referenceUrl != null && e(t.referenceUrl)) return E(t.referenceUrl);
71
+ }, O = async (e, t) => {
37
72
  if ("file" in e) return URL.createObjectURL(e.file);
38
73
  let n = t.resolveDialUrl(e);
39
74
  if (n != null) try {
40
- let e = await C(n);
41
- return URL.createObjectURL(e);
75
+ let r = await w(n, D(e) ?? "", t);
76
+ return URL.createObjectURL(r);
42
77
  } catch (e) {
43
78
  let t = e.status;
44
79
  return t == null ? y(n) : v(t, n);
45
80
  }
46
81
  if (e.previewUrl != null) return e.previewUrl;
47
82
  if (e.data != null) return g(e.data, e.contentType);
48
- }, E = async (e, t) => {
83
+ }, k = async (e, t) => {
49
84
  if (e.data != null) return _(e.data);
50
85
  let n = t.resolveDialUrl(e);
51
86
  if (n != null) try {
52
- return await w(n);
87
+ return await T(n, D(e) ?? "", t);
53
88
  } catch (e) {
54
89
  let t = e.status;
55
90
  return t == null ? y(n) : v(t, n);
56
91
  }
57
92
  if ("file" in e) return e.file.text();
58
- }, D = (e, t) => e.data != null || t.resolveDialUrl(e) != null || "file" in e, O = (e, n) => {
93
+ }, A = (e, t) => e.data != null || t.resolveDialUrl(e) != null || "file" in e, j = (e, n) => {
59
94
  if ("file" in e) return {
60
95
  type: t.Image,
61
96
  url: URL.createObjectURL(e.file)
@@ -71,37 +106,37 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
71
106
  type: t.Image,
72
107
  url: r
73
108
  };
74
- }, k = async (e, n) => {
75
- let r = await E(e, n);
109
+ }, M = async (e, n) => {
110
+ let r = await k(e, n);
76
111
  return r == null ? null : typeof r == "string" ? {
77
112
  type: t.PlainText,
78
113
  text: r
79
114
  } : r;
80
- }, A = async (e, n) => {
81
- let r = await E(e, n);
115
+ }, N = async (e, n) => {
116
+ let r = await k(e, n);
82
117
  return r == null ? null : typeof r == "string" ? {
83
118
  type: t.Markdown,
84
119
  text: r
85
120
  } : r;
86
- }, j = 1048576, M = async (e, n, r) => {
87
- let i = await E(e, n);
121
+ }, P = 1048576, F = async (e, n, r) => {
122
+ let i = await k(e, n);
88
123
  return i == null ? null : typeof i == "string" ? {
89
124
  type: t.Code,
90
125
  text: i,
91
126
  language: r
92
127
  } : i;
93
- }, N = async (e, n) => {
94
- let r = await E(e, n);
128
+ }, I = async (e, n) => {
129
+ let r = await k(e, n);
95
130
  if (r == null) return null;
96
131
  if (typeof r != "string") return r;
97
- if (r.length > j) return null;
132
+ if (r.length > P) return null;
98
133
  let i = n.resolveDialUrl(e) ?? void 0;
99
134
  return {
100
135
  type: t.Html,
101
136
  srcdoc: r,
102
137
  url: i
103
138
  };
104
- }, P = (n, r, i) => {
139
+ }, L = (n, r, i) => {
105
140
  let a = n.body?.source?.attachment;
106
141
  if (a?.type !== o.PDF) return null;
107
142
  let s = e(a.url) ? i.resolveDialFileDownloadUrl(a.url) : a.url;
@@ -114,7 +149,7 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
114
149
  selectedHighlightId: f.some((e) => e.id === m) ? m : void 0,
115
150
  page: p(n)
116
151
  };
117
- }, F = (e) => {
152
+ }, R = (e) => {
118
153
  switch (e.type) {
119
154
  case "docx_text_range": return {
120
155
  kind: i.DocxTextRange,
@@ -139,7 +174,7 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
139
174
  end: e.end
140
175
  };
141
176
  }
142
- }, I = (n, i, o) => {
177
+ }, z = (n, i, o) => {
143
178
  let s = n.body?.source?.attachment;
144
179
  if (s?.url == null) return null;
145
180
  let c = a(s.title ?? s.url, s.type);
@@ -153,7 +188,7 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
153
188
  let i = l(e, t);
154
189
  m.push({
155
190
  id: i,
156
- locations: r.map(F)
191
+ locations: r.map(R)
157
192
  }), e === n && (h = i);
158
193
  }), {
159
194
  type: t.Ooxml,
@@ -164,7 +199,7 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
164
199
  selectedHighlightId: h
165
200
  } : {}
166
201
  };
167
- }, L = (n, r) => {
202
+ }, B = (n, r) => {
168
203
  let i = m(n.url);
169
204
  if (i == null) return null;
170
205
  let a = e(i.baseUrl) ? r.resolveDialFileDownloadUrl(i.baseUrl) : i.baseUrl;
@@ -194,39 +229,39 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
194
229
  selectedHighlightId: o,
195
230
  page: i.page
196
231
  };
197
- }, R = (e) => {
232
+ }, V = (e) => {
198
233
  try {
199
234
  let t = new URL(e).protocol;
200
235
  return t === "http:" || t === "https:" || t === "blob:";
201
236
  } catch {
202
237
  return !1;
203
238
  }
204
- }, z = (t) => t.url != null && !e(t.url) && R(t.url) ? t.url : void 0, B = async (e, n) => {
205
- let r = await T(e, n);
239
+ }, H = (t) => t.url != null && !e(t.url) && V(t.url) ? t.url : void 0, U = async (e, n) => {
240
+ let r = await O(e, n);
206
241
  if (r != null) return typeof r == "string" ? {
207
242
  type: t.Pdf,
208
243
  url: r
209
244
  } : r;
210
- let i = z(e);
245
+ let i = H(e);
211
246
  return i == null ? null : {
212
247
  type: t.Pdf,
213
248
  url: i
214
249
  };
215
- }, V = async (e, n, r) => {
216
- let i = await T(e, n);
250
+ }, W = async (e, n, r) => {
251
+ let i = await O(e, n);
217
252
  if (i != null) return typeof i == "string" ? {
218
253
  type: t.Ooxml,
219
254
  url: i,
220
255
  format: r
221
256
  } : i;
222
- let a = z(e);
257
+ let a = H(e);
223
258
  return a == null ? null : {
224
259
  type: t.Ooxml,
225
260
  url: a,
226
261
  format: r
227
262
  };
228
- }, H = async (e, n) => {
229
- let r = await E(e, n);
263
+ }, G = async (e, n) => {
264
+ let r = await k(e, n);
230
265
  if (r == null) return null;
231
266
  if (typeof r != "string") return r;
232
267
  try {
@@ -241,8 +276,8 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
241
276
  text: r
242
277
  };
243
278
  }
244
- }, U = async (e, n, r, i) => {
245
- let a = await E(e, n);
279
+ }, K = async (e, n, r, i) => {
280
+ let a = await k(e, n);
246
281
  if (a == null || typeof a != "string") return null;
247
282
  let o = {};
248
283
  try {
@@ -265,4 +300,4 @@ var g = (e, t) => URL.createObjectURL(s(e, t)), _ = (e) => {
265
300
  };
266
301
  };
267
302
  //#endregion
268
- export { I as annotationToOoxmlCanvasContent, P as annotationToPdfCanvasContent, S as clearAttachmentCache, D as hasAttachmentTextSource, L as referenceAttachmentToPdfCanvasContent, M as resolveCodeCanvasContent, N as resolveHtmlCanvasContent, O as resolveImageCanvasContent, H as resolveJsonCanvasContent, A as resolveMarkdownCanvasContent, V as resolveOoxmlCanvasContent, B as resolvePdfCanvasContent, k as resolveTextCanvasContent, U as resolveVisualizerCanvasContent };
303
+ export { z as annotationToOoxmlCanvasContent, L as annotationToPdfCanvasContent, S as clearAttachmentCache, A as hasAttachmentTextSource, B as referenceAttachmentToPdfCanvasContent, F as resolveCodeCanvasContent, I as resolveHtmlCanvasContent, j as resolveImageCanvasContent, G as resolveJsonCanvasContent, N as resolveMarkdownCanvasContent, W as resolveOoxmlCanvasContent, U as resolvePdfCanvasContent, M as resolveTextCanvasContent, K as resolveVisualizerCanvasContent };
package/index.d.ts CHANGED
@@ -105,6 +105,7 @@ import { ReactNode } from 'react';
105
105
  import { RefObject } from 'react';
106
106
  import { RenameFilesResponseDto } from '@epam/ai-dial-chat-api-client';
107
107
  import { RenameItemDto } from '@epam/ai-dial-chat-api-client';
108
+ import { RequestSkill } from '@epam/ai-dial-chat-shared';
108
109
  import { ResponseFormat } from '@epam/ai-dial-chat-shared';
109
110
  import { RevokeAccessItemDto } from '@epam/ai-dial-chat-api-client';
110
111
  import { RevokeAccessResponseDto } from '@epam/ai-dial-chat-api-client';
@@ -276,6 +277,8 @@ export declare interface AttachmentCanvasUrlResolvers {
276
277
  resolveDialFileDownloadUrl: (fileId: string) => string | undefined;
277
278
  /** Resolves the best downloadable DIAL-file URL from an attachment's `url` or `referenceUrl`. */
278
279
  resolveDialUrl: (attachment: DisplayAttachment) => string | undefined;
280
+ /** Resolves a DIAL Core file id to a fetchable metadata URL (used for cache-freshness validation). */
281
+ resolveDialFileMetadataUrl: (fileId: string) => string | undefined;
279
282
  }
280
283
 
281
284
  /** The type of content the canvas can display. */
@@ -1911,15 +1914,20 @@ export declare const isDownloadableAttachment: (attachment: DisplayAttachment) =
1911
1914
  export declare const isExternalSourcePreviewable: (contentType: string, url: string) => boolean;
1912
1915
 
1913
1916
  /**
1914
- * Returns `true` when the edited text or attachment list differs from the
1915
- * original message, meaning a regeneration is needed.
1917
+ * Returns `true` when the edited text, attachment list, or skills list differs
1918
+ * from the original message, meaning a regeneration is needed.
1919
+ *
1920
+ * `skills` is the skills state the edit will write: `undefined` leaves the
1921
+ * original skills out of the comparison (nothing about them changes), while an
1922
+ * array — including an empty one — is compared against the original.
1916
1923
  *
1917
1924
  * @param originalMessage - The unmodified message stored in the conversation.
1918
1925
  * @param newText - The text the user submitted from the edit area.
1919
1926
  * @param keptDisplayAttachments - Attachments the user kept (not removed).
1920
1927
  * @param newAttachments - Brand-new attachments the user added during editing.
1928
+ * @param skills - The skills the edited message will carry, or `undefined` to leave them unchanged.
1921
1929
  */
1922
- export declare const isMessageChanged: (originalMessage: Message, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[]) => boolean;
1930
+ export declare const isMessageChanged: (originalMessage: Message, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[], skills?: RequestSkill[]) => boolean;
1923
1931
 
1924
1932
  /**
1925
1933
  * Returns `true` when `message` is the actively-streaming assistant response.
@@ -3067,8 +3075,10 @@ export declare interface SharedRootMeta {
3067
3075
  * its answer never completed — after stopping a generation the user submits
3068
3076
  * the same message precisely to get a full answer, so treating that as "no
3069
3077
  * change" would leave the conversation stuck with the partial one.
3078
+ *
3079
+ * @param skills - The skills the edited message will carry, or `undefined` to leave them unchanged — see {@link isMessageChanged}.
3070
3080
  */
3071
- export declare const shouldRerunGenerationOnEdit: (messages: Message[], messageIndex: number, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[]) => boolean;
3081
+ export declare const shouldRerunGenerationOnEdit: (messages: Message[], messageIndex: number, newText: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[], skills?: RequestSkill[]) => boolean;
3072
3082
 
3073
3083
  /** True when the first user/assistant exchange is complete and LLM naming may still run. */
3074
3084
  export declare const shouldWatchForDisplayNameUpdate: (conversation: Conversation) => boolean;
@@ -4176,7 +4186,7 @@ export declare interface UseConversationHandlersParams {
4176
4186
 
4177
4187
  /** Return value of {@link useConversationHandlers}. */
4178
4188
  export declare interface UseConversationHandlersResult {
4179
- handleSend: (message: string, attachments: Attachment[]) => Promise<void>;
4189
+ handleSend: (message: string, attachments: Attachment[], skills?: RequestSkill[]) => Promise<void>;
4180
4190
  handleUploadAttachment: (attachment: Attachment) => Promise<UploadedAttachmentResult>;
4181
4191
  handleRegenerateMessage: (messageIndex: number) => void;
4182
4192
  handleDeleteMessage: (messageIndex: number) => void;
@@ -4186,7 +4196,7 @@ export declare interface UseConversationHandlersResult {
4186
4196
  handleConfirmStarter: () => void;
4187
4197
  handleStartEdit: (messageIndex: number) => void;
4188
4198
  handleCancelEdit: (messageIndex: number) => void;
4189
- handleEditMessage: (messageIndex: number, text: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[]) => Promise<void>;
4199
+ handleEditMessage: (messageIndex: number, text: string, keptDisplayAttachments: DisplayAttachment[], newAttachments: Attachment[], skills?: RequestSkill[]) => Promise<void>;
4190
4200
  editingMessageIndexes: Set<number>;
4191
4201
  pendingDeleteIndex: number | null;
4192
4202
  setPendingDeleteIndex: (index: number | null) => void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@epam/ai-dial-chat-hooks",
3
3
  "description": "Framework-level React hooks extracted from AI DIAL Chat for building custom chat interfaces",
4
- "version": "1.1.0-dev.447",
4
+ "version": "1.1.0-dev.459",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "main": "./index.js",
@@ -104,21 +104,21 @@
104
104
  },
105
105
  "peerDependencies": {
106
106
  "react": "^19.2.6",
107
- "@epam/ai-dial-attachment-canvas": "1.1.0-dev.447",
108
- "@epam/ai-dial-attachment-input": "1.1.0-dev.447",
109
- "@epam/ai-dial-catalog": "1.1.0-dev.447",
110
- "@epam/ai-dial-chat-api-client": "1.1.0-dev.447",
111
- "@epam/ai-dial-chat-overlay": "1.1.0-dev.447",
112
- "@epam/ai-dial-chat-shared": "1.1.0-dev.447",
113
- "@epam/ai-dial-deployment-creation-form": "1.1.0-dev.447",
114
- "@epam/ai-dial-mcp-apps": "1.1.0-dev.447",
115
- "@epam/ai-dial-publish-panel": "1.1.0-dev.447",
116
- "@epam/ai-dial-quotations": "1.1.0-dev.447",
107
+ "@epam/ai-dial-attachment-canvas": "1.1.0-dev.459",
108
+ "@epam/ai-dial-attachment-input": "1.1.0-dev.459",
109
+ "@epam/ai-dial-catalog": "1.1.0-dev.459",
110
+ "@epam/ai-dial-chat-api-client": "1.1.0-dev.459",
111
+ "@epam/ai-dial-chat-overlay": "1.1.0-dev.459",
112
+ "@epam/ai-dial-chat-shared": "1.1.0-dev.459",
113
+ "@epam/ai-dial-deployment-creation-form": "1.1.0-dev.459",
114
+ "@epam/ai-dial-mcp-apps": "1.1.0-dev.459",
115
+ "@epam/ai-dial-publish-panel": "1.1.0-dev.459",
116
+ "@epam/ai-dial-quotations": "1.1.0-dev.459",
117
117
  "@epam/ai-dial-react-file-manager": "*",
118
- "@epam/ai-dial-scheduled-tasks": "1.1.0-dev.447",
119
- "@epam/ai-dial-share": "1.1.0-dev.447",
120
- "@epam/ai-dial-skill-editor": "1.1.0-dev.447",
121
- "@epam/ai-dial-source-panel": "1.1.0-dev.447",
118
+ "@epam/ai-dial-scheduled-tasks": "1.1.0-dev.459",
119
+ "@epam/ai-dial-share": "1.1.0-dev.459",
120
+ "@epam/ai-dial-skill-editor": "1.1.0-dev.459",
121
+ "@epam/ai-dial-source-panel": "1.1.0-dev.459",
122
122
  "@epam/ai-dial-ui-kit": "*",
123
123
  "@modelcontextprotocol/sdk": "^1.27.1",
124
124
  "@epam/pdf-highlighter-kit": ">=0.0.14",