@epam/ai-dial-chat-hooks 1.2.0-dev.263 → 1.2.0-dev.265
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/conversation/useActiveConversationSync/useActiveConversationSync.js +7 -8
- package/conversation/useConversationStream/generation-resume.js +53 -50
- package/conversation/useConversationStream/useConversationStream.js +189 -154
- package/conversation.d.ts +8 -1
- package/index.d.ts +8 -1
- package/package.json +15 -15
|
@@ -2,17 +2,16 @@ import { useEffect as e, useMemo as t } from "react";
|
|
|
2
2
|
//#region src/conversation/useActiveConversationSync/useActiveConversationSync.ts
|
|
3
3
|
var n = ({ activeConversationId: n, items: r, refreshConversations: i, markConversationViewed: a, conversationIdsMatch: o, toPanelConversationId: s }) => {
|
|
4
4
|
let c = t(() => n ? s(n) : void 0, [n, s]);
|
|
5
|
-
|
|
5
|
+
e(() => {
|
|
6
6
|
c && (r.some((e) => o(e.id, c)) || i());
|
|
7
|
-
}, [c, o])
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
}, [c, o]);
|
|
8
|
+
let l = c ? r.find((e) => o(e.id, c))?.id : void 0;
|
|
9
|
+
return e(() => {
|
|
10
|
+
c && l && a(l);
|
|
11
11
|
}, [
|
|
12
12
|
c,
|
|
13
|
-
|
|
14
|
-
a
|
|
15
|
-
o
|
|
13
|
+
l,
|
|
14
|
+
a
|
|
16
15
|
]), c;
|
|
17
16
|
};
|
|
18
17
|
//#endregion
|
|
@@ -63,68 +63,71 @@ var c = (e) => {
|
|
|
63
63
|
} catch {} finally {
|
|
64
64
|
n.releaseLock();
|
|
65
65
|
}
|
|
66
|
-
}, _ = ({ transport: o, setConversation: s, conversationRef: p, resumingPathsRef: m, bufferedGenerationsRef: h, addStreamingPath: _, removeStreamingPath: v, isPathDisplayed: y, generationPersistenceErrorMessage: b = t, frameScheduler: x, stoppedGenerationIdsRef: S }) => (t,
|
|
67
|
-
if (!u(
|
|
68
|
-
|
|
66
|
+
}, _ = ({ transport: o, setConversation: s, conversationRef: p, resumingPathsRef: m, bufferedGenerationsRef: h, addStreamingPath: _, removeStreamingPath: v, isPathDisplayed: y, generationPersistenceErrorMessage: b = t, frameScheduler: x, stoppedGenerationIdsRef: S, onReloadError: C, onReloadSuccess: w }) => (t, T, E = {}) => {
|
|
67
|
+
if (!u(T)) {
|
|
68
|
+
E.onSettled?.();
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
-
let
|
|
72
|
-
if (!
|
|
73
|
-
m.current.add(
|
|
74
|
-
let
|
|
71
|
+
let D = r(t);
|
|
72
|
+
if (!E.skipDedupe && m.current.has(D)) return;
|
|
73
|
+
m.current.add(D), _(D);
|
|
74
|
+
let O = l(T), k = O !== -1, A = k ? O : T.messages.length - 1, j = {
|
|
75
75
|
generationId: f,
|
|
76
|
-
messageIndex:
|
|
77
|
-
message:
|
|
76
|
+
messageIndex: A,
|
|
77
|
+
message: E.seedMessage ?? T.messages[A]
|
|
78
78
|
};
|
|
79
|
-
h.current.set(
|
|
80
|
-
let
|
|
81
|
-
if (x?.flush(
|
|
82
|
-
m.current.delete(
|
|
83
|
-
let n = !
|
|
79
|
+
h.current.set(D, j);
|
|
80
|
+
let M = () => h.current.get(D) === j, N = k ? T.messages[A].backgroundGeneration?.generationId : void 0, P = () => N != null && (S?.current.has(N) ?? !1), F = (e, t = !1) => {
|
|
81
|
+
if (x?.flush(D), N != null && S?.current.delete(N), !M()) return;
|
|
82
|
+
m.current.delete(D), v(D);
|
|
83
|
+
let n = !k && e && e.messages.length - 1 === A && u(e) && c(j.message);
|
|
84
84
|
if (t || n) {
|
|
85
|
-
|
|
86
|
-
...
|
|
85
|
+
j.message = {
|
|
86
|
+
...j.message,
|
|
87
87
|
streamErrorMessage: b
|
|
88
|
-
}, y(
|
|
89
|
-
if (!e || !
|
|
90
|
-
let t = a(e,
|
|
88
|
+
}, y(D) && s((e) => {
|
|
89
|
+
if (!e || !M() || !y(D)) return e;
|
|
90
|
+
let t = a(e, j);
|
|
91
91
|
return p.current = t, t;
|
|
92
92
|
});
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
|
-
h.current.delete(
|
|
96
|
-
},
|
|
97
|
-
try {
|
|
98
|
-
|
|
95
|
+
h.current.delete(D), e && y(D) && (s(e), p.current = e);
|
|
96
|
+
}, I = async () => {
|
|
97
|
+
if (M()) try {
|
|
98
|
+
let n = await o.getConversation(e(t));
|
|
99
|
+
if (!M()) return;
|
|
100
|
+
w?.(D), F(n);
|
|
99
101
|
} catch {
|
|
100
|
-
|
|
102
|
+
if (!M()) return;
|
|
103
|
+
x?.flush(D), m.current.delete(D), v(D), N != null && S?.current.delete(N), C?.(D, I, M);
|
|
101
104
|
}
|
|
102
|
-
},
|
|
103
|
-
x?.cancel(
|
|
104
|
-
if (!e || !
|
|
105
|
-
let t = a(e,
|
|
105
|
+
}, L = (e) => {
|
|
106
|
+
x?.cancel(D), M() && (j.message = e, y(D) && s((e) => {
|
|
107
|
+
if (!e || !M() || !y(D)) return e;
|
|
108
|
+
let t = a(e, j);
|
|
106
109
|
return p.current = t, t;
|
|
107
110
|
}));
|
|
108
|
-
},
|
|
109
|
-
if (!e || !
|
|
110
|
-
let t = a(e,
|
|
111
|
+
}, R = () => s((e) => {
|
|
112
|
+
if (!e || !M() || !y(D)) return e;
|
|
113
|
+
let t = a(e, j);
|
|
111
114
|
return p.current = t, t;
|
|
112
|
-
}),
|
|
113
|
-
if (!
|
|
114
|
-
let t = i([
|
|
115
|
-
if (t && (
|
|
115
|
+
}), z = (e) => {
|
|
116
|
+
if (!M() || P()) return;
|
|
117
|
+
let t = i([j.message], 0, e);
|
|
118
|
+
if (t && (j.message = t[0]), y(D)) {
|
|
116
119
|
if (x) {
|
|
117
|
-
x.schedule(
|
|
120
|
+
x.schedule(D, R);
|
|
118
121
|
return;
|
|
119
122
|
}
|
|
120
|
-
|
|
123
|
+
R();
|
|
121
124
|
}
|
|
122
|
-
},
|
|
125
|
+
}, B = async () => {
|
|
123
126
|
let n = new AbortController(), r;
|
|
124
127
|
try {
|
|
125
|
-
r = await o.watchConversation(
|
|
128
|
+
r = await o.watchConversation(D, n.signal);
|
|
126
129
|
} catch {
|
|
127
|
-
await
|
|
130
|
+
await I();
|
|
128
131
|
return;
|
|
129
132
|
}
|
|
130
133
|
let i = !1, a = window.setTimeout(() => {
|
|
@@ -135,38 +138,38 @@ var c = (e) => {
|
|
|
135
138
|
if (n?.action !== "UPDATE") return !1;
|
|
136
139
|
try {
|
|
137
140
|
let n = await o.getConversation(e(t));
|
|
138
|
-
if (!u(n)) return
|
|
141
|
+
if (!u(n)) return F(n), i = !0, !0;
|
|
139
142
|
} catch {}
|
|
140
143
|
return !1;
|
|
141
144
|
});
|
|
142
145
|
} finally {
|
|
143
146
|
clearTimeout(a);
|
|
144
147
|
}
|
|
145
|
-
i || await
|
|
146
|
-
},
|
|
148
|
+
i || await I();
|
|
149
|
+
}, V = async () => {
|
|
147
150
|
let e = new AbortController(), t;
|
|
148
151
|
try {
|
|
149
|
-
t = await o.attachToGeneration(
|
|
152
|
+
t = await o.attachToGeneration(D, e.signal);
|
|
150
153
|
} catch {
|
|
151
154
|
return !1;
|
|
152
155
|
}
|
|
153
156
|
let r = !1, i = !1;
|
|
154
157
|
return await g(t, (e) => {
|
|
155
|
-
if (!
|
|
158
|
+
if (!M()) return !0;
|
|
156
159
|
switch (e.type) {
|
|
157
|
-
case "snapshot": return
|
|
158
|
-
case "chunk": return
|
|
160
|
+
case "snapshot": return L(e.message), !1;
|
|
161
|
+
case "chunk": return z(e.chunk), !1;
|
|
159
162
|
case "done":
|
|
160
163
|
case "error":
|
|
161
164
|
case "stopped": return i = e.type === "error" && e.errorType === n.type, r = !0, !0;
|
|
162
165
|
}
|
|
163
|
-
}), r ? (i ?
|
|
166
|
+
}), r ? (i ? F(void 0, !0) : await I(), !0) : !M();
|
|
164
167
|
};
|
|
165
168
|
(async () => {
|
|
166
169
|
try {
|
|
167
|
-
await
|
|
170
|
+
await V() || await B();
|
|
168
171
|
} finally {
|
|
169
|
-
|
|
172
|
+
E.onSettled?.();
|
|
170
173
|
}
|
|
171
174
|
})();
|
|
172
175
|
};
|
|
@@ -3,110 +3,166 @@ import { DEFAULT_GENERATION_CONFLICT_MESSAGE as t, DEFAULT_GENERATION_PERSISTENC
|
|
|
3
3
|
import { getConversationPath as s } from "./conversation-path.js";
|
|
4
4
|
import { applyChunkToMessages as c } from "./apply-chunk.js";
|
|
5
5
|
import { restoreBufferedMessage as l } from "./buffered-generation.js";
|
|
6
|
-
import { createResumeIfAwaitingGeneration as
|
|
7
|
-
import { createFrameScheduler as
|
|
8
|
-
import { MessageRole as
|
|
9
|
-
import { useCallback as
|
|
10
|
-
import { SendCompletionDtoModeEnum as
|
|
6
|
+
import { createResumeIfAwaitingGeneration as ee, fetchConversationForRecovery as te, findPendingBackgroundMessageIndex as ne, hasGeneratedPayload as re, isAwaitingGenerationResume as u } from "./generation-resume.js";
|
|
7
|
+
import { createFrameScheduler as d } from "./frame-scheduler.js";
|
|
8
|
+
import { MessageRole as ie, generateUUID as ae } from "@epam/ai-dial-chat-shared";
|
|
9
|
+
import { useCallback as f, useEffect as p, useMemo as m, useRef as h, useState as g } from "react";
|
|
10
|
+
import { SendCompletionDtoModeEnum as _ } from "@epam/ai-dial-chat-api-client";
|
|
11
11
|
//#region src/conversation/useConversationStream/useConversationStream.ts
|
|
12
|
-
var
|
|
12
|
+
var oe = 2e4, se = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e instanceof o ? e.message : "", v = (e) => {
|
|
13
13
|
if (!e) return;
|
|
14
|
-
let t =
|
|
14
|
+
let t = ne(e);
|
|
15
15
|
return t === -1 ? void 0 : e.messages[t].backgroundGeneration?.generationId;
|
|
16
|
-
},
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}, [
|
|
21
|
-
let
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}, [
|
|
25
|
-
let [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
}, y = ({ conversationId: r, state: { setConversation: o, conversationRef: y }, transport: b, generation: { startGeneration: ce, completeGeneration: x }, channel: S, overlay: C, onStopError: w, generationConflictMessage: T = t, generationPersistenceErrorMessage: E = n, onStreamError: D, batchChunksPerFrame: O = !1 }) => {
|
|
17
|
+
let k = h(D);
|
|
18
|
+
p(() => {
|
|
19
|
+
k.current = D;
|
|
20
|
+
}, [D]);
|
|
21
|
+
let le = h(O);
|
|
22
|
+
p(() => {
|
|
23
|
+
le.current = O;
|
|
24
|
+
}, [O]);
|
|
25
|
+
let [A] = g(d), [ue, j] = g(() => /* @__PURE__ */ new Set()), [M, N] = g(null), P = h(null), F = h(null), I = h(/* @__PURE__ */ new Set()), L = h(/* @__PURE__ */ new Map()), R = h(/* @__PURE__ */ new Set()), z = h(/* @__PURE__ */ new Map()), B = h(!0), V = h(/* @__PURE__ */ new Map()), [H, U] = g(V.current), W = h(/* @__PURE__ */ new Set()), [de, fe] = g(W.current);
|
|
26
|
+
p(() => (B.current = !0, () => {
|
|
27
|
+
B.current = !1;
|
|
28
|
+
}), []);
|
|
29
|
+
let G = f((e) => {
|
|
30
|
+
if (!V.current.has(e)) return;
|
|
31
|
+
let t = new Map(V.current);
|
|
32
|
+
t.delete(e), V.current = t, B.current && U(t);
|
|
33
|
+
}, []), K = f((e, t, n) => {
|
|
34
|
+
if (!B.current || !n()) return;
|
|
35
|
+
let r = new Map(V.current);
|
|
36
|
+
r.set(e, {
|
|
37
|
+
retry: t,
|
|
38
|
+
isCurrent: n
|
|
39
|
+
}), V.current = r, U(r);
|
|
40
|
+
}, []), pe = f(async () => {
|
|
41
|
+
if (!r) return;
|
|
42
|
+
let e = V.current.get(s(r));
|
|
43
|
+
if (!(!e || !e.isCurrent() || W.current.has(e))) {
|
|
44
|
+
W.current.add(e), fe(new Set(W.current));
|
|
45
|
+
try {
|
|
46
|
+
await e.retry();
|
|
47
|
+
} finally {
|
|
48
|
+
W.current.delete(e), B.current && fe(new Set(W.current));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}, [r]), me = h(r);
|
|
52
|
+
p(() => (me.current = r, () => A.cancelAll()), [r, A]);
|
|
53
|
+
let q = f((e) => B.current && s(me.current ?? "") === e, []), J = f((e) => {
|
|
54
|
+
G(e), j((t) => {
|
|
29
55
|
if (t.has(e)) return t;
|
|
30
56
|
let n = new Set(t);
|
|
31
57
|
return n.add(e), n;
|
|
32
58
|
});
|
|
33
|
-
}, []), Y =
|
|
34
|
-
|
|
59
|
+
}, [G]), Y = f((e) => {
|
|
60
|
+
j((t) => {
|
|
35
61
|
if (!t.has(e)) return t;
|
|
36
62
|
let n = new Set(t);
|
|
37
63
|
return n.delete(e), n;
|
|
38
64
|
});
|
|
39
|
-
}, []), X =
|
|
40
|
-
transport:
|
|
65
|
+
}, []), X = m(() => ee({
|
|
66
|
+
transport: b,
|
|
41
67
|
setConversation: o,
|
|
42
|
-
conversationRef:
|
|
43
|
-
resumingPathsRef:
|
|
44
|
-
bufferedGenerationsRef:
|
|
68
|
+
conversationRef: y,
|
|
69
|
+
resumingPathsRef: I,
|
|
70
|
+
bufferedGenerationsRef: L,
|
|
45
71
|
addStreamingPath: J,
|
|
46
72
|
removeStreamingPath: Y,
|
|
47
73
|
isPathDisplayed: q,
|
|
48
|
-
generationPersistenceErrorMessage:
|
|
49
|
-
frameScheduler:
|
|
50
|
-
stoppedGenerationIdsRef:
|
|
74
|
+
generationPersistenceErrorMessage: E,
|
|
75
|
+
frameScheduler: O ? A : void 0,
|
|
76
|
+
stoppedGenerationIdsRef: R,
|
|
77
|
+
onReloadError: K,
|
|
78
|
+
onReloadSuccess: G
|
|
51
79
|
}), [
|
|
52
80
|
J,
|
|
53
81
|
Y,
|
|
54
82
|
q,
|
|
55
|
-
|
|
83
|
+
b,
|
|
84
|
+
E,
|
|
85
|
+
O,
|
|
56
86
|
A,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
]),
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
let
|
|
63
|
-
|
|
64
|
-
let
|
|
65
|
-
|
|
66
|
-
generationId:
|
|
87
|
+
K,
|
|
88
|
+
G
|
|
89
|
+
]), he = f((t, n, r, ee, d, f, p = _.Append) => {
|
|
90
|
+
let m = f ?? ae(), h = s(t);
|
|
91
|
+
A.flush(h), I.current.delete(h), P.current = m, F.current = h, z.current.set(h, m), N(h);
|
|
92
|
+
let g;
|
|
93
|
+
p === _.Regenerate ? g = r : p === _.Edit && (g = r - 1);
|
|
94
|
+
let v = () => z.current.get(h) !== m, w = ce(h, m), D = y.current?.messages[r];
|
|
95
|
+
D ? L.current.set(h, {
|
|
96
|
+
generationId: m,
|
|
67
97
|
messageIndex: r,
|
|
68
|
-
message:
|
|
69
|
-
}) :
|
|
70
|
-
let
|
|
71
|
-
|
|
72
|
-
},
|
|
73
|
-
if (
|
|
74
|
-
let e =
|
|
75
|
-
!e || e.generationId !==
|
|
98
|
+
message: D
|
|
99
|
+
}) : L.current.delete(h), J(h), C?.notifyGenerationStart?.(), S?.ensureConnected();
|
|
100
|
+
let O = () => {
|
|
101
|
+
v() || Y(h), P.current === m && (P.current = null, F.current = null, N(null)), x(h, m), S?.notifyGenerationSettled?.();
|
|
102
|
+
}, ue = () => {
|
|
103
|
+
if (v()) return;
|
|
104
|
+
let e = L.current.get(h);
|
|
105
|
+
!e || e.generationId !== m || (e.message = {
|
|
76
106
|
...e.message,
|
|
77
|
-
streamErrorMessage:
|
|
78
|
-
},
|
|
79
|
-
if (!t ||
|
|
107
|
+
streamErrorMessage: E
|
|
108
|
+
}, k.current?.(new i()), q(h) && o((t) => {
|
|
109
|
+
if (!t || v() || !q(h)) return t;
|
|
80
110
|
let n = l(t, e);
|
|
81
|
-
return
|
|
111
|
+
return y.current = n, n;
|
|
82
112
|
}));
|
|
83
|
-
}, L = {
|
|
84
|
-
|
|
113
|
+
}, j = L.current.get(h), M = () => B.current && !v() && L.current.get(h) === j, V = async () => {
|
|
114
|
+
if (M()) {
|
|
115
|
+
if (!q(h)) {
|
|
116
|
+
j && L.current.delete(h);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
let n = await b.getConversation(e(t));
|
|
121
|
+
if (!M()) return;
|
|
122
|
+
if (G(h), !q(h)) {
|
|
123
|
+
j && L.current.delete(h);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (ne(n) !== -1) {
|
|
127
|
+
X(t, n, { seedMessage: j?.message });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (j && j.messageIndex === n.messages.length - 1 && u(n) && re(j.message)) {
|
|
131
|
+
ue();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
j && L.current.delete(h), o(n), y.current = n;
|
|
135
|
+
} catch {
|
|
136
|
+
M() && K(h, V, M);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}, H = {
|
|
140
|
+
signal: w.signal,
|
|
85
141
|
onChunk: (e) => {
|
|
86
|
-
if (
|
|
87
|
-
let t =
|
|
88
|
-
if (t?.generationId ===
|
|
142
|
+
if (P.current !== m) return;
|
|
143
|
+
let t = L.current.get(h);
|
|
144
|
+
if (t?.generationId === m) {
|
|
89
145
|
let n = c([t.message], 0, e);
|
|
90
146
|
n && (t.message = n[0]);
|
|
91
147
|
}
|
|
92
|
-
if (q(
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
let e =
|
|
96
|
-
if (
|
|
148
|
+
if (q(h)) {
|
|
149
|
+
if (le.current && t?.generationId === m) {
|
|
150
|
+
A.schedule(h, () => {
|
|
151
|
+
let e = L.current.get(h);
|
|
152
|
+
if (P.current !== m || !q(h) || e?.generationId !== m) return;
|
|
97
153
|
let t = { ...e };
|
|
98
154
|
o((e) => {
|
|
99
155
|
if (!e) return e;
|
|
100
156
|
let n = l(e, t);
|
|
101
|
-
return
|
|
157
|
+
return y.current = n, n;
|
|
102
158
|
});
|
|
103
159
|
});
|
|
104
160
|
return;
|
|
105
161
|
}
|
|
106
162
|
o((t) => {
|
|
107
163
|
if (!t) return t;
|
|
108
|
-
let n =
|
|
109
|
-
if (n?.generationId ===
|
|
164
|
+
let n = L.current.get(h), i;
|
|
165
|
+
if (n?.generationId === m) i = l(t, n);
|
|
110
166
|
else {
|
|
111
167
|
let n = c(t.messages, r, e);
|
|
112
168
|
if (!n) return t;
|
|
@@ -115,150 +171,129 @@ var re = 2e4, ie = (e, t, n) => e instanceof i ? n : e instanceof r ? t : e inst
|
|
|
115
171
|
messages: n
|
|
116
172
|
};
|
|
117
173
|
}
|
|
118
|
-
return
|
|
174
|
+
return y.current = i, i;
|
|
119
175
|
});
|
|
120
176
|
}
|
|
121
177
|
},
|
|
122
178
|
onComplete: async () => {
|
|
123
|
-
|
|
124
|
-
let n = U.current.get(v), r = n?.generationId === _ ? n : void 0;
|
|
125
|
-
if (M(), W.current.has(_) ? W.current.delete(_) : x() || D?.notifyGenerationEnd?.(), !x()) {
|
|
126
|
-
if (!q(v)) {
|
|
127
|
-
r && U.current.delete(v);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
try {
|
|
131
|
-
let n = await C.getConversation(e(t));
|
|
132
|
-
if (x()) return;
|
|
133
|
-
if (!q(v)) {
|
|
134
|
-
r && U.current.delete(v);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
if (d(n) !== -1) {
|
|
138
|
-
X(t, n, { seedMessage: r?.message });
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (r && r.messageIndex === n.messages.length - 1 && f(n) && te(r.message)) {
|
|
142
|
-
I();
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
r && U.current.delete(v), o(n), S.current = n;
|
|
146
|
-
} catch {
|
|
147
|
-
x() || I();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
179
|
+
A.flush(h), O(), R.current.has(m) ? R.current.delete(m) : v() || C?.notifyGenerationEnd?.(), await V();
|
|
150
180
|
},
|
|
151
181
|
onError: (e) => {
|
|
152
|
-
if (
|
|
153
|
-
|
|
182
|
+
if (A.flush(h), k.current?.(e), e instanceof a && !v()) {
|
|
183
|
+
de(e);
|
|
154
184
|
return;
|
|
155
185
|
}
|
|
156
|
-
|
|
186
|
+
U(e);
|
|
157
187
|
}
|
|
158
|
-
},
|
|
159
|
-
let t =
|
|
188
|
+
}, U = (e) => {
|
|
189
|
+
let t = L.current.get(h), n = t?.generationId === m ? t : void 0;
|
|
160
190
|
if (n && (e instanceof i ? n.message = {
|
|
161
191
|
...n.message,
|
|
162
|
-
streamErrorMessage:
|
|
163
|
-
} :
|
|
164
|
-
let a =
|
|
192
|
+
streamErrorMessage: E
|
|
193
|
+
} : L.current.delete(h)), O(), v() || !q(h)) return;
|
|
194
|
+
let a = se(e, T, E);
|
|
165
195
|
o((e) => {
|
|
166
|
-
if (!e ||
|
|
167
|
-
let t = n?.generationId ===
|
|
196
|
+
if (!e || v() || !q(h)) return e;
|
|
197
|
+
let t = n?.generationId === m ? l(e, n) : e, i = {
|
|
168
198
|
...t,
|
|
169
199
|
messages: t.messages.map((e, t) => t === r ? {
|
|
170
200
|
...e,
|
|
171
201
|
streamErrorMessage: a
|
|
172
202
|
} : e)
|
|
173
203
|
};
|
|
174
|
-
return
|
|
204
|
+
return y.current = i, i;
|
|
175
205
|
});
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
let i = await
|
|
181
|
-
if (
|
|
182
|
-
|
|
206
|
+
}, W = () => {
|
|
207
|
+
O(), R.current.has(m) ? R.current.delete(m) : v() || C?.notifyGenerationEnd?.();
|
|
208
|
+
}, de = async (n) => {
|
|
209
|
+
I.current.add(h);
|
|
210
|
+
let i = await te(() => b.getConversation(e(t)), v);
|
|
211
|
+
if (v()) {
|
|
212
|
+
O();
|
|
183
213
|
return;
|
|
184
214
|
}
|
|
185
|
-
let a = i?.messages[i.messages.length - 1], s = i != null && i.messages.length - 1 === r && a?.role ===
|
|
215
|
+
let a = i?.messages[i.messages.length - 1], s = i != null && i.messages.length - 1 === r && a?.role === ie.Assistant;
|
|
186
216
|
if (!i || !s) {
|
|
187
|
-
|
|
217
|
+
I.current.delete(h), U(n);
|
|
188
218
|
return;
|
|
189
219
|
}
|
|
190
|
-
let c =
|
|
191
|
-
if (
|
|
220
|
+
let c = L.current.get(h), l = c?.generationId === m ? c : void 0;
|
|
221
|
+
if (u(i)) {
|
|
192
222
|
X(t, i, {
|
|
193
223
|
seedMessage: l?.message,
|
|
194
224
|
skipDedupe: !0,
|
|
195
|
-
onSettled:
|
|
225
|
+
onSettled: W
|
|
196
226
|
});
|
|
197
227
|
return;
|
|
198
228
|
}
|
|
199
|
-
|
|
229
|
+
I.current.delete(h), l && L.current.delete(h), q(h) && (o(i), y.current = i), W();
|
|
200
230
|
};
|
|
201
231
|
(async () => {
|
|
202
232
|
try {
|
|
203
|
-
let e =
|
|
204
|
-
if (
|
|
205
|
-
|
|
233
|
+
let e = S?.channelId ?? await S?.waitForChannel(oe) ?? void 0, t = R.current.has(m);
|
|
234
|
+
if (w.signal.aborted || v() || t) {
|
|
235
|
+
L.current.get(h)?.generationId === m && L.current.delete(h), v() || Y(h), P.current === m && (P.current = null, F.current = null, N(null)), x(h, m), S?.notifyGenerationSettled?.(), t ? R.current.delete(m) : v() || C?.notifyGenerationEnd?.();
|
|
206
236
|
return;
|
|
207
237
|
}
|
|
208
|
-
|
|
238
|
+
b.streamCompletion(h, n, ee, H, d, m, p, g, e);
|
|
209
239
|
} catch (e) {
|
|
210
|
-
|
|
240
|
+
H.onError(e instanceof Error ? e : Error(String(e)));
|
|
211
241
|
}
|
|
212
242
|
})();
|
|
213
243
|
}, [
|
|
214
|
-
|
|
215
|
-
|
|
244
|
+
ce,
|
|
245
|
+
x,
|
|
216
246
|
J,
|
|
217
247
|
Y,
|
|
218
248
|
q,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
D,
|
|
249
|
+
S?.channelId,
|
|
250
|
+
S?.ensureConnected,
|
|
251
|
+
S?.waitForChannel,
|
|
252
|
+
S?.notifyGenerationSettled,
|
|
224
253
|
C,
|
|
254
|
+
b,
|
|
225
255
|
X,
|
|
226
|
-
|
|
256
|
+
T,
|
|
257
|
+
E,
|
|
227
258
|
A,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
259
|
+
K,
|
|
260
|
+
G
|
|
261
|
+
]), ge = f((e, t) => {
|
|
262
|
+
let n = s(e), r = L.current.get(n);
|
|
263
|
+
return V.current.get(n)?.isCurrent() && r && t.messages.length - 1 >= r.messageIndex && t.messages[r.messageIndex].role === ie.Assistant && !u(t) ? (G(n), L.current.delete(n), t) : r ? l(t, r) : t;
|
|
264
|
+
}, [G]), _e = f(() => {
|
|
233
265
|
if (!r) return;
|
|
234
|
-
let e = s(r), t = (
|
|
266
|
+
let e = s(r), t = (F.current === e ? P.current : null) ?? v(y.current);
|
|
235
267
|
if (!t) return;
|
|
236
|
-
|
|
237
|
-
let n =
|
|
238
|
-
|
|
268
|
+
R.current.add(t), A.flush(e), C?.notifyStopGenerating?.();
|
|
269
|
+
let n = L.current.get(e)?.message.content;
|
|
270
|
+
b.stopCompletion({
|
|
239
271
|
generationId: t,
|
|
240
272
|
path: e,
|
|
241
273
|
content: n
|
|
242
274
|
}).catch((e) => {
|
|
243
275
|
let t = e instanceof Error ? e : Error(String(e));
|
|
244
|
-
|
|
276
|
+
w?.(t);
|
|
245
277
|
});
|
|
246
278
|
}, [
|
|
247
279
|
r,
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
]),
|
|
280
|
+
y,
|
|
281
|
+
A,
|
|
282
|
+
w,
|
|
283
|
+
C,
|
|
284
|
+
b
|
|
285
|
+
]), ve = f((e, t) => X(e, t), [X]), ye = r != null && ue.has(s(r)), Z = r == null ? null : s(r), be = Z != null && (M === Z || ye && v(y.current) != null), Q = Z ? H.get(Z) : void 0, $ = Q?.isCurrent() ?? !1;
|
|
254
286
|
return {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
287
|
+
hasConversationReloadError: $,
|
|
288
|
+
isReloadingConversation: !!Q && $ && de.has(Q),
|
|
289
|
+
retryConversationReload: pe,
|
|
290
|
+
startStream: he,
|
|
291
|
+
handleStop: _e,
|
|
292
|
+
resumeIfAwaitingGeneration: ve,
|
|
293
|
+
restoreBufferedGeneration: ge,
|
|
294
|
+
isStreaming: ye,
|
|
295
|
+
canStopStreaming: be
|
|
261
296
|
};
|
|
262
297
|
};
|
|
263
298
|
//#endregion
|
|
264
|
-
export {
|
|
299
|
+
export { y as useConversationStream };
|
package/conversation.d.ts
CHANGED
|
@@ -886,7 +886,8 @@ export declare interface TranscribeWithDeploymentParams {
|
|
|
886
886
|
* 1. If the active conversation is not present in the list, requests a
|
|
887
887
|
* refresh. The list and refresh callback are intentionally excluded from
|
|
888
888
|
* the dependency array to avoid a refresh-loop on every list update.
|
|
889
|
-
* 2. Marks the active conversation as viewed
|
|
889
|
+
* 2. Marks the active conversation as viewed when its matching identity becomes
|
|
890
|
+
* available. List refreshes and persistence rollback do not retry the write.
|
|
890
891
|
*/
|
|
891
892
|
export declare const useActiveConversationSync: ({ activeConversationId, items, refreshConversations, markConversationViewed, conversationIdsMatch, toPanelConversationId, }: UseActiveConversationSyncParams) => string | undefined;
|
|
892
893
|
|
|
@@ -1193,6 +1194,12 @@ export declare interface UseConversationStreamResult {
|
|
|
1193
1194
|
restoreBufferedGeneration: (currentConversationId: string, conversation: Conversation) => Conversation;
|
|
1194
1195
|
isStreaming: boolean;
|
|
1195
1196
|
canStopStreaming: boolean;
|
|
1197
|
+
/** Whether the displayed conversation's terminal read failed. */
|
|
1198
|
+
hasConversationReloadError: boolean;
|
|
1199
|
+
/** Whether a retry of that read is in flight. */
|
|
1200
|
+
isReloadingConversation: boolean;
|
|
1201
|
+
/** Retries the failed read without saving or regenerating the answer. */
|
|
1202
|
+
retryConversationReload: () => Promise<void>;
|
|
1196
1203
|
}
|
|
1197
1204
|
|
|
1198
1205
|
/**
|
package/index.d.ts
CHANGED
|
@@ -4619,7 +4619,8 @@ export declare const USAGE_MODEL_LIMITS_I18N_KEYS: {
|
|
|
4619
4619
|
* 1. If the active conversation is not present in the list, requests a
|
|
4620
4620
|
* refresh. The list and refresh callback are intentionally excluded from
|
|
4621
4621
|
* the dependency array to avoid a refresh-loop on every list update.
|
|
4622
|
-
* 2. Marks the active conversation as viewed
|
|
4622
|
+
* 2. Marks the active conversation as viewed when its matching identity becomes
|
|
4623
|
+
* available. List refreshes and persistence rollback do not retry the write.
|
|
4623
4624
|
*/
|
|
4624
4625
|
export declare const useActiveConversationSync: ({ activeConversationId, items, refreshConversations, markConversationViewed, conversationIdsMatch, toPanelConversationId, }: UseActiveConversationSyncParams) => string | undefined;
|
|
4625
4626
|
|
|
@@ -5310,6 +5311,12 @@ export declare interface UseConversationStreamResult {
|
|
|
5310
5311
|
restoreBufferedGeneration: (currentConversationId: string, conversation: Conversation) => Conversation;
|
|
5311
5312
|
isStreaming: boolean;
|
|
5312
5313
|
canStopStreaming: boolean;
|
|
5314
|
+
/** Whether the displayed conversation's terminal read failed. */
|
|
5315
|
+
hasConversationReloadError: boolean;
|
|
5316
|
+
/** Whether a retry of that read is in flight. */
|
|
5317
|
+
isReloadingConversation: boolean;
|
|
5318
|
+
/** Retries the failed read without saving or regenerating the answer. */
|
|
5319
|
+
retryConversationReload: () => Promise<void>;
|
|
5313
5320
|
}
|
|
5314
5321
|
|
|
5315
5322
|
/**
|
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-dev.
|
|
4
|
+
"version": "1.2.0-dev.265",
|
|
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-dev.
|
|
114
|
+
"@epam/ai-dial-chat-api-client": "1.2.0-dev.265",
|
|
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-dev.
|
|
124
|
-
"@epam/ai-dial-attachment-input": "1.2.0-dev.
|
|
125
|
-
"@epam/ai-dial-catalog": "1.2.0-dev.
|
|
126
|
-
"@epam/ai-dial-chat-overlay": "1.2.0-dev.
|
|
127
|
-
"@epam/ai-dial-chat-shared": "1.2.0-dev.
|
|
128
|
-
"@epam/ai-dial-mcp-apps": "1.2.0-dev.
|
|
129
|
-
"@epam/ai-dial-publish-panel": "1.2.0-dev.
|
|
130
|
-
"@epam/ai-dial-quotations": "1.2.0-dev.
|
|
123
|
+
"@epam/ai-dial-attachment-canvas": "1.2.0-dev.265",
|
|
124
|
+
"@epam/ai-dial-attachment-input": "1.2.0-dev.265",
|
|
125
|
+
"@epam/ai-dial-catalog": "1.2.0-dev.265",
|
|
126
|
+
"@epam/ai-dial-chat-overlay": "1.2.0-dev.265",
|
|
127
|
+
"@epam/ai-dial-chat-shared": "1.2.0-dev.265",
|
|
128
|
+
"@epam/ai-dial-mcp-apps": "1.2.0-dev.265",
|
|
129
|
+
"@epam/ai-dial-publish-panel": "1.2.0-dev.265",
|
|
130
|
+
"@epam/ai-dial-quotations": "1.2.0-dev.265",
|
|
131
131
|
"@epam/ai-dial-react-file-manager": "^0.3.0-dev.22",
|
|
132
|
-
"@epam/ai-dial-scheduled-tasks": "1.2.0-dev.
|
|
133
|
-
"@epam/ai-dial-share": "1.2.0-dev.
|
|
134
|
-
"@epam/ai-dial-skill-editor": "1.2.0-dev.
|
|
135
|
-
"@epam/ai-dial-source-panel": "1.2.0-dev.
|
|
132
|
+
"@epam/ai-dial-scheduled-tasks": "1.2.0-dev.265",
|
|
133
|
+
"@epam/ai-dial-share": "1.2.0-dev.265",
|
|
134
|
+
"@epam/ai-dial-skill-editor": "1.2.0-dev.265",
|
|
135
|
+
"@epam/ai-dial-source-panel": "1.2.0-dev.265",
|
|
136
136
|
"@epam/ai-dial-ui-kit": "^0.15.0-dev.36",
|
|
137
|
-
"@epam/ai-dial-usage-dashboard": "1.2.0-dev.
|
|
137
|
+
"@epam/ai-dial-usage-dashboard": "1.2.0-dev.265",
|
|
138
138
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
139
139
|
"@epam/pdf-highlighter-kit": "^0.0.19",
|
|
140
140
|
"@mcp-ui/client": "^7.1.1"
|