@epam/ai-dial-chat-hooks 1.2.0-rc.0 → 1.3.0-dev.5

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,8 +1,9 @@
1
1
  //#region src/conversation/create-chat-stream-api.ts
2
2
  var e = { "Content-Type": "application/json" }, t = 409, n = "The response could not be saved. It is still shown here, but may be lost if you reload or leave this page. Copy it before continuing.", r = class extends Error {
3
3
  static type = "conversation_save_failed";
4
- constructor() {
5
- super(n), this.name = "GenerationPersistenceError";
4
+ status;
5
+ constructor(e) {
6
+ super(n), this.name = "GenerationPersistenceError", this.status = e;
6
7
  }
7
8
  }, i = "A response is already being generated in this conversation. Wait for it to finish or stop it before sending another message.", a = class extends Error {
8
9
  constructor(e = i) {
@@ -36,22 +37,25 @@ var e = { "Content-Type": "application/json" }, t = 409, n = "The response could
36
37
  i || (i = !0, clearTimeout(r), s && (document.removeEventListener("visibilitychange", o), window.removeEventListener("online", a), window.removeEventListener("pageshow", a)));
37
38
  }
38
39
  };
39
- }, u = (e) => typeof e == "object" && !!e && e.name === "AbortError", d = (e, t, n) => {
40
+ }, u = (e) => typeof e == "object" && !!e && e.name === "AbortError", d = (e) => {
41
+ let { status: t } = e;
42
+ return typeof t == "number" ? t : void 0;
43
+ }, f = (e, t, n) => {
40
44
  let i = e.trim();
41
45
  if (!i || i.startsWith(":") || !i.startsWith("data: ")) return;
42
46
  let a = i.slice(6);
43
47
  if (a !== "[DONE]") try {
44
48
  let e = JSON.parse(a);
45
49
  if (e.error) {
46
- n(e.error.type === r.type ? new r() : new o(e.error.message));
50
+ n(e.error.type === r.type ? new r(d(e.error)) : new o(e.error.message));
47
51
  return;
48
52
  }
49
53
  t(e);
50
54
  } catch {}
51
- }, f = (n) => {
55
+ }, p = (n) => {
52
56
  let { completionsBasePath: r } = n, i = (...e) => (n.fetchImpl ?? fetch)(...e);
53
57
  return {
54
- streamCompletion: (o, c, f, p, m, h, g, _, v) => {
58
+ streamCompletion: (o, c, d, p, m, h, g, _, v) => {
55
59
  let { onChunk: y, onComplete: b, onError: x, signal: S } = p;
56
60
  (async () => {
57
61
  let p;
@@ -69,7 +73,7 @@ var e = { "Content-Type": "application/json" }, t = 409, n = "The response could
69
73
  body: JSON.stringify({
70
74
  path: o,
71
75
  message: c ?? "",
72
- model: f,
76
+ model: d,
73
77
  custom_content: m || {},
74
78
  ...h != null && { generationId: h },
75
79
  ...g != null && { mode: g },
@@ -105,13 +109,13 @@ var e = { "Content-Type": "application/json" }, t = 409, n = "The response could
105
109
  let { done: e, value: t } = await w.read();
106
110
  if (O) break;
107
111
  if (e) {
108
- E.trim() && d(E, y, k);
112
+ E.trim() && f(E, y, k);
109
113
  break;
110
114
  }
111
115
  A.touch(), E += T.decode(t, { stream: !0 });
112
116
  let n = E.split("\n");
113
117
  E = n.pop() ?? "";
114
- for (let e of n) d(e, y, k);
118
+ for (let e of n) f(e, y, k);
115
119
  }
116
120
  D || (D = !0, b());
117
121
  } catch (e) {
@@ -137,4 +141,4 @@ var e = { "Content-Type": "application/json" }, t = 409, n = "The response could
137
141
  };
138
142
  };
139
143
  //#endregion
140
- export { i as DEFAULT_GENERATION_CONFLICT_MESSAGE, n as DEFAULT_GENERATION_PERSISTENCE_ERROR_MESSAGE, c as DEFAULT_STREAM_IDLE_TIMEOUT_MS, a as GenerationConflictError, r as GenerationPersistenceError, s as StreamInterruptedError, o as StreamUpstreamError, f as createChatStreamApi };
144
+ export { i as DEFAULT_GENERATION_CONFLICT_MESSAGE, n as DEFAULT_GENERATION_PERSISTENCE_ERROR_MESSAGE, c as DEFAULT_STREAM_IDLE_TIMEOUT_MS, a as GenerationConflictError, r as GenerationPersistenceError, s as StreamInterruptedError, o as StreamUpstreamError, p as createChatStreamApi };
@@ -1,28 +1,28 @@
1
1
  import { safeDecodeURI as e } from "../../shared/string-utils.js";
2
- import { DEFAULT_GENERATION_CONFLICT_MESSAGE as t, DEFAULT_GENERATION_PERSISTENCE_ERROR_MESSAGE as n, GenerationConflictError as r, GenerationPersistenceError as i, StreamInterruptedError as ee, StreamUpstreamError as a } from "../create-chat-stream-api.js";
3
- import { getConversationPath as o } from "./conversation-path.js";
4
- import { applyChunkToMessages as s } from "./apply-chunk.js";
5
- import { restoreBufferedMessage as c } from "./buffered-generation.js";
6
- import { createResumeIfAwaitingGeneration as te, fetchConversationForRecovery as ne, findPendingBackgroundMessageIndex as l, hasGeneratedPayload as re, isAwaitingGenerationResume as u } from "./generation-resume.js";
7
- import { createFrameScheduler as ie } from "./frame-scheduler.js";
8
- import { MessageRole as d, generateUUID as ae } from "@epam/ai-dial-chat-shared";
2
+ import { DEFAULT_GENERATION_CONFLICT_MESSAGE as t, DEFAULT_GENERATION_PERSISTENCE_ERROR_MESSAGE as n, GenerationConflictError as r, GenerationPersistenceError as i, StreamInterruptedError as a, StreamUpstreamError as o } from "../create-chat-stream-api.js";
3
+ import { getConversationPath as s } from "./conversation-path.js";
4
+ import { applyChunkToMessages as c } from "./apply-chunk.js";
5
+ import { restoreBufferedMessage as l } from "./buffered-generation.js";
6
+ import { createResumeIfAwaitingGeneration as ee, fetchConversationForRecovery as te, findPendingBackgroundMessageIndex as u, hasGeneratedPayload as ne, isAwaitingGenerationResume as d } from "./generation-resume.js";
7
+ import { createFrameScheduler as re } from "./frame-scheduler.js";
8
+ import { MessageRole as ie, generateUUID as ae } from "@epam/ai-dial-chat-shared";
9
9
  import { useCallback as f, useEffect as p, useMemo as oe, useRef as m, useState as h } from "react";
10
10
  import { SendCompletionDtoModeEnum as g } from "@epam/ai-dial-chat-api-client";
11
11
  //#region src/conversation/useConversationStream/useConversationStream.ts
12
- var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e instanceof a ? e.message : "", _ = (e) => {
12
+ var se = 2e4, ce = 401, le = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e instanceof o ? e.message : "", _ = (e) => {
13
13
  if (!e) return;
14
- let t = l(e);
14
+ let t = u(e);
15
15
  return t === -1 ? void 0 : e.messages[t].backgroundGeneration?.generationId;
16
- }, v = ({ conversationId: a, state: { setConversation: v, conversationRef: y }, transport: b, generation: { startGeneration: le, completeGeneration: x }, channel: S, overlay: C, onStopError: w, generationConflictMessage: ue = t, generationPersistenceErrorMessage: T = n, onStreamError: E, batchChunksPerFrame: D = !1 }) => {
16
+ }, v = ({ conversationId: o, state: { setConversation: v, conversationRef: y }, transport: b, generation: { startGeneration: ue, completeGeneration: x }, channel: S, overlay: C, onStopError: w, generationConflictMessage: de = t, generationPersistenceErrorMessage: T = n, onStreamError: E, batchChunksPerFrame: D = !1 }) => {
17
17
  let O = m(E);
18
18
  p(() => {
19
19
  O.current = E;
20
20
  }, [E]);
21
- let de = m(D);
21
+ let fe = m(D);
22
22
  p(() => {
23
- de.current = D;
23
+ fe.current = D;
24
24
  }, [D]);
25
- let [k] = h(ie), [A, j] = h(() => /* @__PURE__ */ new Set()), [M, N] = h(() => /* @__PURE__ */ new Set()), P = m(/* @__PURE__ */ new Map()), F = m(/* @__PURE__ */ new Set()), I = m(/* @__PURE__ */ new Map()), L = m(/* @__PURE__ */ new Set()), fe = m(/* @__PURE__ */ new Map()), R = m(!0), z = m(/* @__PURE__ */ new Map()), [B, V] = h(z.current), H = m(/* @__PURE__ */ new Set()), [pe, U] = h(H.current);
25
+ let [k] = h(re), [A, j] = h(() => /* @__PURE__ */ new Set()), [M, N] = h(() => /* @__PURE__ */ new Set()), P = m(/* @__PURE__ */ new Map()), F = m(/* @__PURE__ */ new Set()), I = m(/* @__PURE__ */ new Map()), L = m(/* @__PURE__ */ new Set()), pe = m(/* @__PURE__ */ new Map()), R = m(!0), z = m(/* @__PURE__ */ new Map()), [B, V] = h(z.current), H = m(/* @__PURE__ */ new Set()), [me, U] = h(H.current);
26
26
  p(() => (R.current = !0, () => {
27
27
  R.current = !1;
28
28
  }), []);
@@ -37,9 +37,9 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
37
37
  retry: t,
38
38
  isCurrent: n
39
39
  }), z.current = r, V(r);
40
- }, []), K = f(async () => {
41
- if (!a) return;
42
- let e = z.current.get(o(a));
40
+ }, []), he = f(async () => {
41
+ if (!o) return;
42
+ let e = z.current.get(s(o));
43
43
  if (!(!e || !e.isCurrent() || H.current.has(e))) {
44
44
  H.current.add(e), U(new Set(H.current));
45
45
  try {
@@ -48,9 +48,9 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
48
48
  H.current.delete(e), R.current && U(new Set(H.current));
49
49
  }
50
50
  }
51
- }, [a]), me = m(a);
52
- p(() => (me.current = a, () => k.cancelAll()), [a, k]);
53
- let q = f((e) => R.current && o(me.current ?? "") === e, []), J = f((e) => {
51
+ }, [o]), K = m(o);
52
+ p(() => (K.current = o, () => k.cancelAll()), [o, k]);
53
+ let q = f((e) => R.current && s(K.current ?? "") === e, []), J = f((e) => {
54
54
  W(e), j((t) => {
55
55
  if (t.has(e)) return t;
56
56
  let n = new Set(t);
@@ -68,9 +68,9 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
68
68
  let r = new Set(n);
69
69
  return t ? r.add(e) : r.delete(e), r;
70
70
  });
71
- }, []), he = f((e, t) => {
71
+ }, []), Z = f((e, t) => {
72
72
  P.current.get(e) === t && (P.current.delete(e), X(e, !1));
73
- }, [X]), Z = oe(() => te({
73
+ }, [X]), Q = oe(() => ee({
74
74
  transport: b,
75
75
  setConversation: v,
76
76
  conversationRef: y,
@@ -94,19 +94,19 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
94
94
  k,
95
95
  G,
96
96
  W
97
- ]), ge = f((t, n, a, te, ie, f, p = g.Append, oe = {}) => {
98
- let m = f ?? ae(), h = o(t);
99
- k.flush(h), F.current.delete(h), P.current.set(h, m), fe.current.set(h, m), X(h, !0);
97
+ ]), ge = f((t, n, o, ee, re, f, p = g.Append, oe = {}) => {
98
+ let m = f ?? ae(), h = s(t);
99
+ k.flush(h), F.current.delete(h), P.current.set(h, m), pe.current.set(h, m), X(h, !0);
100
100
  let _;
101
- p === g.Regenerate ? _ = a : p === g.Edit && (_ = a - 1);
102
- let w = () => fe.current.get(h) !== m, E = le(h, m), D = y.current?.messages[a];
101
+ p === g.Regenerate ? _ = o : p === g.Edit && (_ = o - 1);
102
+ let w = () => pe.current.get(h) !== m, E = ue(h, m), D = y.current?.messages[o];
103
103
  D ? I.current.set(h, {
104
104
  generationId: m,
105
- messageIndex: a,
105
+ messageIndex: o,
106
106
  message: D
107
107
  }) : I.current.delete(h), J(h), C?.notifyGenerationStart?.(), S?.ensureConnected();
108
108
  let A = () => {
109
- w() || Y(h), he(h, m), x(h, m), S?.notifyGenerationSettled?.();
109
+ w() || Y(h), Z(h, m), x(h, m), S?.notifyGenerationSettled?.();
110
110
  }, j = () => {
111
111
  if (w()) return;
112
112
  let e = I.current.get(h);
@@ -115,7 +115,7 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
115
115
  streamErrorMessage: T
116
116
  }, O.current?.(new i()), q(h) && v((t) => {
117
117
  if (!t || w() || !q(h)) return t;
118
- let n = c(t, e);
118
+ let n = l(t, e);
119
119
  return y.current = n, n;
120
120
  }));
121
121
  }, M = I.current.get(h), N = () => R.current && !w() && I.current.get(h) === M, z = async () => {
@@ -131,11 +131,11 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
131
131
  M && I.current.delete(h);
132
132
  return;
133
133
  }
134
- if (l(n) !== -1) {
135
- Z(t, n, { seedMessage: M?.message });
134
+ if (u(n) !== -1) {
135
+ Q(t, n, { seedMessage: M?.message });
136
136
  return;
137
137
  }
138
- if (M && M.messageIndex === n.messages.length - 1 && u(n) && re(M.message)) {
138
+ if (M && M.messageIndex === n.messages.length - 1 && d(n) && ne(M.message)) {
139
139
  j();
140
140
  return;
141
141
  }
@@ -150,18 +150,18 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
150
150
  if (w()) return;
151
151
  let t = I.current.get(h);
152
152
  if (t?.generationId === m) {
153
- let n = s([t.message], 0, e);
153
+ let n = c([t.message], 0, e);
154
154
  n && (t.message = n[0]);
155
155
  }
156
156
  if (q(h)) {
157
- if (de.current && t?.generationId === m) {
157
+ if (fe.current && t?.generationId === m) {
158
158
  k.schedule(h, () => {
159
159
  let e = I.current.get(h);
160
160
  if (w() || !q(h) || e?.generationId !== m) return;
161
161
  let t = { ...e };
162
162
  v((e) => {
163
163
  if (!e) return e;
164
- let n = c(e, t);
164
+ let n = l(e, t);
165
165
  return y.current = n, n;
166
166
  });
167
167
  });
@@ -170,9 +170,9 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
170
170
  v((t) => {
171
171
  if (!t) return t;
172
172
  let n = I.current.get(h), r;
173
- if (n?.generationId === m) r = c(t, n);
173
+ if (n?.generationId === m) r = l(t, n);
174
174
  else {
175
- let n = s(t.messages, a, e);
175
+ let n = c(t.messages, o, e);
176
176
  if (!n) return t;
177
177
  r = {
178
178
  ...t,
@@ -187,80 +187,101 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
187
187
  k.flush(h), A(), L.current.has(m) ? L.current.delete(m) : w() || C?.notifyGenerationEnd?.(), await z();
188
188
  },
189
189
  onError: (e) => {
190
- if (k.flush(h), O.current?.(e), e instanceof ee && !w()) {
191
- pe(e);
190
+ if (k.flush(h), O.current?.(e), e instanceof a && !w()) {
191
+ he(e);
192
192
  return;
193
193
  }
194
194
  if (e instanceof r && oe.resumeOnConflict && !w()) {
195
- U(e);
195
+ K(e);
196
196
  return;
197
197
  }
198
198
  V(e);
199
199
  }
200
200
  }, V = (e) => {
201
201
  let t = I.current.get(h), n = t?.generationId === m ? t : void 0;
202
- if (n && (e instanceof i ? n.message = {
203
- ...n.message,
202
+ if (n && !(e instanceof i) && I.current.delete(h), A(), n && b.saveConversation && e instanceof i && e.status === ce) {
203
+ me(e, n, b.saveConversation.bind(b));
204
+ return;
205
+ }
206
+ H(e, n);
207
+ }, H = (e, t) => {
208
+ if (t && e instanceof i && (t.message = {
209
+ ...t.message,
204
210
  streamErrorMessage: T
205
- } : I.current.delete(h)), A(), w() || !q(h)) return;
206
- let r = ce(e, ue, T);
211
+ }), w() || !q(h)) return;
212
+ let n = le(e, de, T);
207
213
  v((e) => {
208
214
  if (!e || w() || !q(h)) return e;
209
- let t = n?.generationId === m ? c(e, n) : e, i = {
210
- ...t,
211
- messages: t.messages.map((e, t) => t === a ? {
215
+ let r = t?.generationId === m ? l(e, t) : e, i = {
216
+ ...r,
217
+ messages: r.messages.map((e, t) => t === o ? {
212
218
  ...e,
213
- streamErrorMessage: r
219
+ streamErrorMessage: n
214
220
  } : e)
215
221
  };
216
222
  return y.current = i, i;
217
223
  });
218
- }, H = () => {
224
+ }, me = async (n, r, i) => {
225
+ let a = () => R.current && !w() && I.current.get(h) === r;
226
+ try {
227
+ let o = await b.getConversation(e(t));
228
+ if (!a()) return;
229
+ if (r.messageIndex !== o.messages.length - 1 || !d(o)) {
230
+ H(n, r);
231
+ return;
232
+ }
233
+ let s = await i(h, l(o, r));
234
+ if (!a() || (I.current.delete(h), !q(h))) return;
235
+ v(s), y.current = s;
236
+ } catch {
237
+ a() && H(n, r);
238
+ }
239
+ }, U = () => {
219
240
  A(), L.current.has(m) ? L.current.delete(m) : w() || C?.notifyGenerationEnd?.();
220
- }, pe = async (n) => {
221
- F.current.add(h), K(await ne(() => b.getConversation(e(t)), w), n, !1);
222
- }, U = async (n) => {
223
- P.current.get(h) === m && X(h, !1), F.current.add(h), K(await ne(() => b.getConversation(e(t)), w, (e) => e.messages.length === a && e.messages.at(-1)?.role === d.User), n, !0);
224
- }, K = (e, n, r) => {
241
+ }, he = async (n) => {
242
+ F.current.add(h), ge(await te(() => b.getConversation(e(t)), w), n, !1);
243
+ }, K = async (n) => {
244
+ P.current.get(h) === m && X(h, !1), F.current.add(h), ge(await te(() => b.getConversation(e(t)), w, (e) => e.messages.length === o && e.messages.at(-1)?.role === ie.User), n, !0);
245
+ }, ge = (e, n, r) => {
225
246
  if (w()) {
226
247
  A();
227
248
  return;
228
249
  }
229
- let i = e?.messages[e.messages.length - 1], ee = e != null && e.messages.length - 1 === a && i?.role === d.Assistant, o = r && e != null && l(e) !== -1;
230
- if (!e || !ee && !o) {
250
+ let i = e?.messages[e.messages.length - 1], a = e != null && e.messages.length - 1 === o && i?.role === ie.Assistant, s = r && e != null && u(e) !== -1;
251
+ if (!e || !a && !s) {
231
252
  F.current.delete(h), V(n);
232
253
  return;
233
254
  }
234
- let s = I.current.get(h), c = s?.generationId === m ? s : void 0;
235
- if (u(e)) {
236
- Z(t, e, {
237
- seedMessage: ee ? c?.message : void 0,
255
+ let c = I.current.get(h), l = c?.generationId === m ? c : void 0;
256
+ if (d(e)) {
257
+ Q(t, e, {
258
+ seedMessage: a ? l?.message : void 0,
238
259
  skipDedupe: !0,
239
- onSettled: H
260
+ onSettled: U
240
261
  });
241
262
  return;
242
263
  }
243
- F.current.delete(h), c && I.current.delete(h), q(h) && (v(e), y.current = e), H();
264
+ F.current.delete(h), l && I.current.delete(h), q(h) && (v(e), y.current = e), U();
244
265
  };
245
266
  (async () => {
246
267
  try {
247
268
  let e = S?.channelId ?? await S?.waitForChannel(se) ?? void 0, t = L.current.has(m);
248
269
  if (E.signal.aborted || w() || t) {
249
- I.current.get(h)?.generationId === m && I.current.delete(h), w() || Y(h), he(h, m), x(h, m), S?.notifyGenerationSettled?.(), t ? L.current.delete(m) : w() || C?.notifyGenerationEnd?.();
270
+ I.current.get(h)?.generationId === m && I.current.delete(h), w() || Y(h), Z(h, m), x(h, m), S?.notifyGenerationSettled?.(), t ? L.current.delete(m) : w() || C?.notifyGenerationEnd?.();
250
271
  return;
251
272
  }
252
- b.streamCompletion(h, n, te, B, ie, m, p, _, e);
273
+ b.streamCompletion(h, n, ee, B, re, m, p, _, e);
253
274
  } catch (e) {
254
275
  B.onError(e instanceof Error ? e : Error(String(e)));
255
276
  }
256
277
  })();
257
278
  }, [
258
- le,
279
+ ue,
259
280
  x,
260
281
  J,
261
282
  Y,
262
283
  X,
263
- he,
284
+ Z,
264
285
  q,
265
286
  S?.channelId,
266
287
  S?.ensureConnected,
@@ -268,18 +289,18 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
268
289
  S?.notifyGenerationSettled,
269
290
  C,
270
291
  b,
271
- Z,
272
- ue,
292
+ Q,
293
+ de,
273
294
  T,
274
295
  k,
275
296
  G,
276
297
  W
277
298
  ]), _e = f((e, t) => {
278
- let n = o(e), r = I.current.get(n);
279
- return z.current.get(n)?.isCurrent() && r && t.messages.length - 1 >= r.messageIndex && t.messages[r.messageIndex].role === d.Assistant && !u(t) ? (W(n), I.current.delete(n), t) : r ? c(t, r) : t;
299
+ let n = s(e), r = I.current.get(n);
300
+ return z.current.get(n)?.isCurrent() && r && t.messages.length - 1 >= r.messageIndex && t.messages[r.messageIndex].role === ie.Assistant && !d(t) ? (W(n), I.current.delete(n), t) : r ? l(t, r) : t;
280
301
  }, [W]), ve = f(() => {
281
- if (!a) return;
282
- let e = o(a), t = P.current.get(e) ?? _(y.current);
302
+ if (!o) return;
303
+ let e = s(o), t = P.current.get(e) ?? _(y.current);
283
304
  if (!t) return;
284
305
  L.current.add(t), k.flush(e), C?.notifyStopGenerating?.();
285
306
  let n = I.current.get(e)?.message.content;
@@ -292,17 +313,17 @@ var se = 2e4, ce = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
292
313
  w?.(t);
293
314
  });
294
315
  }, [
295
- a,
316
+ o,
296
317
  y,
297
318
  k,
298
319
  w,
299
320
  C,
300
321
  b
301
- ]), ye = f((e, t) => Z(e, t), [Z]), be = a != null && A.has(o(a)), Q = a == null ? null : o(a), xe = Q != null && (M.has(Q) || be && _(y.current) != null), $ = Q ? B.get(Q) : void 0, Se = $?.isCurrent() ?? !1;
322
+ ]), ye = f((e, t) => Q(e, t), [Q]), be = o != null && A.has(s(o)), $ = o == null ? null : s(o), xe = $ != null && (M.has($) || be && _(y.current) != null), Se = $ ? B.get($) : void 0, Ce = Se?.isCurrent() ?? !1;
302
323
  return {
303
- hasConversationReloadError: Se,
304
- isReloadingConversation: !!$ && Se && pe.has($),
305
- retryConversationReload: K,
324
+ hasConversationReloadError: Ce,
325
+ isReloadingConversation: !!Se && Ce && me.has(Se),
326
+ retryConversationReload: he,
306
327
  startStream: ge,
307
328
  handleStop: ve,
308
329
  resumeIfAwaitingGeneration: ye,
package/conversation.d.ts CHANGED
@@ -330,6 +330,13 @@ export declare interface ConversationStreamTransport {
330
330
  attachToGeneration(path: string, signal: AbortSignal): Promise<ReadableStream<Uint8Array>>;
331
331
  /** Reloads the persisted conversation by its full (bucket-qualified) id. */
332
332
  getConversation(conversationId: string, signal?: AbortSignal): Promise<Conversation>;
333
+ /**
334
+ * Saves `conversation` at the bucket-stripped `path`, resolving with the saved
335
+ * conversation. Used only for the single recovery save after the backend's
336
+ * terminal save was rejected with `401`; without it that failure shows the
337
+ * persistence warning immediately.
338
+ */
339
+ saveConversation?(path: string, conversation: Conversation): Promise<Conversation>;
333
340
  }
334
341
 
335
342
  /**
@@ -420,7 +427,13 @@ export declare class GenerationConflictError extends Error {
420
427
  /** Identifies a failed terminal save independently of the model's generation outcome. */
421
428
  export declare class GenerationPersistenceError extends Error {
422
429
  static readonly type = "conversation_save_failed";
423
- constructor();
430
+ /** HTTP status of the rejected terminal write, when the backend reported one. */
431
+ readonly status?: number;
432
+ /**
433
+ * Creates the error with the default persistence message.
434
+ * @param status - HTTP status of the rejected terminal write, if known
435
+ */
436
+ constructor(status?: number);
424
437
  }
425
438
 
426
439
  /**
package/index.d.ts CHANGED
@@ -963,6 +963,13 @@ export declare interface ConversationStreamTransport {
963
963
  attachToGeneration(path: string, signal: AbortSignal): Promise<ReadableStream<Uint8Array>>;
964
964
  /** Reloads the persisted conversation by its full (bucket-qualified) id. */
965
965
  getConversation(conversationId: string, signal?: AbortSignal): Promise<Conversation>;
966
+ /**
967
+ * Saves `conversation` at the bucket-stripped `path`, resolving with the saved
968
+ * conversation. Used only for the single recovery save after the backend's
969
+ * terminal save was rejected with `401`; without it that failure shows the
970
+ * persistence warning immediately.
971
+ */
972
+ saveConversation?(path: string, conversation: Conversation): Promise<Conversation>;
966
973
  }
967
974
 
968
975
  export { ConversationTransferErrorCode }
@@ -1875,7 +1882,13 @@ export declare class GenerationConflictError extends Error {
1875
1882
  /** Identifies a failed terminal save independently of the model's generation outcome. */
1876
1883
  export declare class GenerationPersistenceError extends Error {
1877
1884
  static readonly type = "conversation_save_failed";
1878
- constructor();
1885
+ /** HTTP status of the rejected terminal write, when the backend reported one. */
1886
+ readonly status?: number;
1887
+ /**
1888
+ * Creates the error with the default persistence message.
1889
+ * @param status - HTTP status of the rejected terminal write, if known
1890
+ */
1891
+ constructor(status?: number);
1879
1892
  }
1880
1893
 
1881
1894
  /** Normalizes any API error into a `{ status?, message, traceId?, code?, upstreamCode?, upstreamMessage? }` shape. */
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.2.0-rc.0",
4
+ "version": "1.3.0-dev.5",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "main": "./index.js",
@@ -111,7 +111,7 @@
111
111
  }
112
112
  },
113
113
  "dependencies": {
114
- "@epam/ai-dial-chat-api-client": "1.2.0-rc.0",
114
+ "@epam/ai-dial-chat-api-client": "1.3.0-dev.5",
115
115
  "dompurify": "3.4.16",
116
116
  "fflate": "^0.8.3",
117
117
  "lru-cache": "^10.4.3",
@@ -120,21 +120,21 @@
120
120
  },
121
121
  "peerDependencies": {
122
122
  "react": "^19.2.8",
123
- "@epam/ai-dial-attachment-canvas": "1.2.0-rc.0",
124
- "@epam/ai-dial-attachment-input": "1.2.0-rc.0",
125
- "@epam/ai-dial-catalog": "1.2.0-rc.0",
126
- "@epam/ai-dial-chat-overlay": "1.2.0-rc.0",
127
- "@epam/ai-dial-chat-shared": "1.2.0-rc.0",
128
- "@epam/ai-dial-mcp-apps": "1.2.0-rc.0",
129
- "@epam/ai-dial-publish-panel": "1.2.0-rc.0",
130
- "@epam/ai-dial-quotations": "1.2.0-rc.0",
123
+ "@epam/ai-dial-attachment-canvas": "1.3.0-dev.5",
124
+ "@epam/ai-dial-attachment-input": "1.3.0-dev.5",
125
+ "@epam/ai-dial-catalog": "1.3.0-dev.5",
126
+ "@epam/ai-dial-chat-overlay": "1.3.0-dev.5",
127
+ "@epam/ai-dial-chat-shared": "1.3.0-dev.5",
128
+ "@epam/ai-dial-mcp-apps": "1.3.0-dev.5",
129
+ "@epam/ai-dial-publish-panel": "1.3.0-dev.5",
130
+ "@epam/ai-dial-quotations": "1.3.0-dev.5",
131
131
  "@epam/ai-dial-react-file-manager": "^0.3.0",
132
- "@epam/ai-dial-scheduled-tasks": "1.2.0-rc.0",
133
- "@epam/ai-dial-share": "1.2.0-rc.0",
134
- "@epam/ai-dial-skill-editor": "1.2.0-rc.0",
135
- "@epam/ai-dial-source-panel": "1.2.0-rc.0",
132
+ "@epam/ai-dial-scheduled-tasks": "1.3.0-dev.5",
133
+ "@epam/ai-dial-share": "1.3.0-dev.5",
134
+ "@epam/ai-dial-skill-editor": "1.3.0-dev.5",
135
+ "@epam/ai-dial-source-panel": "1.3.0-dev.5",
136
136
  "@epam/ai-dial-ui-kit": "^0.15.0",
137
- "@epam/ai-dial-usage-dashboard": "1.2.0-rc.0",
137
+ "@epam/ai-dial-usage-dashboard": "1.3.0-dev.5",
138
138
  "@modelcontextprotocol/sdk": "^1.32.1",
139
139
  "@epam/pdf-highlighter-kit": "^0.0.19",
140
140
  "@mcp-ui/client": "^7.1.1"