@forbespro/lead-agent
Version:
Lead Chat Agent React Component
298 lines (297 loc) • 7.41 kB
JavaScript
import { generateId as Dt } from "./index15.js";
import { fillMessageParts as H, extractMaxToolInvocationStep as Ct, callChatApi as St, shouldResubmitMessages as xt, prepareAttachmentsForRequest as rt, getMessageParts as At, updateToolCallResult as wt, isAssistantMessageWithCompletedToolCalls as Rt, isDeepEqualData as _t } from "./index16.js";
import { useState as J, useMemo as It, useRef as T, useEffect as P, useCallback as d } from "react";
import F from "./index17.js";
import Tt from "./index18.js";
function nt(r, o) {
return o != null ? Tt(r, o) : r;
}
function Ft(r) {
const [o, A] = J(r);
return P(() => {
_t(r, o) || A(r);
}, [r, o]), o;
}
function Ut({
api: r = "/api/chat",
id: o,
initialMessages: A,
initialInput: ot = "",
sendExtraMessageFields: L,
onToolCall: N,
experimental_prepareRequestBody: k,
maxSteps: O = 1,
streamProtocol: Q = "data",
onResponse: X,
onFinish: Y,
onError: E,
credentials: q,
headers: K,
body: U,
generateId: m = Dt,
fetch: Z,
keepLastMessageOnError: $ = !0,
experimental_throttle: W
} = {}) {
const [lt] = J(m), h = o != null ? o : lt, w = typeof r == "string" ? [r, h] : h, B = Ft(A != null ? A : []), ct = It(
() => H(B),
[B]
), { data: p, mutate: b } = F(
[w, "messages"],
null,
{ fallbackData: ct }
), n = T(p || []);
P(() => {
n.current = p || [];
}, [p]);
const { data: R, mutate: _ } = F([w, "streamData"], null), M = T(R);
P(() => {
M.current = R;
}, [R]);
const { data: y = "ready", mutate: v } = F([w, "status"], null), { data: ut = void 0, mutate: j } = F([w, "error"], null), u = T(null), g = T({
credentials: q,
headers: K,
body: U
});
P(() => {
g.current = {
credentials: q,
headers: K,
body: U
};
}, [q, K, U]);
const l = d(
async (t) => {
var a, s;
v("submitted"), j(void 0);
const e = H(t.messages), i = e.length, C = Ct(
(a = e[e.length - 1]) == null ? void 0 : a.toolInvocations
);
try {
const c = new AbortController();
u.current = c;
const S = nt(b, W), vt = nt(
_,
W
), pt = n.current;
S(e, !1);
const Mt = L ? e : e.map(
({
role: G,
content: x,
experimental_attachments: I,
data: tt,
annotations: et,
toolInvocations: st,
parts: at
}) => ({
role: G,
content: x,
...I !== void 0 && {
experimental_attachments: I
},
...tt !== void 0 && { data: tt },
...et !== void 0 && { annotations: et },
...st !== void 0 && { toolInvocations: st },
...at !== void 0 && { parts: at }
})
), V = M.current;
await St({
api: r,
body: (s = k == null ? void 0 : k({
id: h,
messages: e,
requestData: t.data,
requestBody: t.body
})) != null ? s : {
id: h,
messages: Mt,
data: t.data,
...g.current.body,
...t.body
},
streamProtocol: Q,
credentials: g.current.credentials,
headers: {
...g.current.headers,
...t.headers
},
abortController: () => u.current,
restoreMessagesOnFailure() {
$ || S(pt, !1);
},
onResponse: X,
onUpdate({ message: G, data: x, replaceLastMessage: I }) {
v("streaming"), S(
[
...I ? e.slice(0, e.length - 1) : e,
G
],
!1
), x != null && x.length && vt(
[...V != null ? V : [], ...x],
!1
);
},
onToolCall: N,
onFinish: Y,
generateId: m,
fetch: Z,
lastMessage: e[e.length - 1]
}), u.current = null, v("ready");
} catch (c) {
if (c.name === "AbortError")
return u.current = null, v("ready"), null;
E && c instanceof Error && E(c), j(c), v("error");
}
const f = n.current;
xt({
originalMaxToolInvocationStep: C,
originalMessageCount: i,
maxSteps: O,
messages: f
}) && await l({ messages: f });
},
[
b,
v,
r,
g,
X,
Y,
E,
j,
_,
M,
Q,
L,
k,
N,
O,
n,
u,
m,
Z,
$,
W,
h
]
), it = d(
async (t, {
data: a,
headers: s,
body: e,
experimental_attachments: i
} = {}) => {
var C, f;
const c = await rt(
i
), S = n.current.concat({
...t,
id: (C = t.id) != null ? C : m(),
createdAt: (f = t.createdAt) != null ? f : /* @__PURE__ */ new Date(),
experimental_attachments: c.length > 0 ? c : void 0,
parts: At(t)
});
return l({ messages: S, headers: s, body: e, data: a });
},
[l, m]
), dt = d(
async ({ data: t, headers: a, body: s } = {}) => {
const e = n.current;
if (e.length === 0)
return null;
const i = e[e.length - 1];
return l({
messages: i.role === "assistant" ? e.slice(0, -1) : e,
headers: a,
body: s,
data: t
});
},
[l]
), mt = d(() => {
u.current && (u.current.abort(), u.current = null);
}, []), gt = d(
(t) => {
typeof t == "function" && (t = t(n.current));
const a = H(t);
b(a, !1), n.current = a;
},
[b]
), ft = d(
(t) => {
typeof t == "function" && (t = t(M.current)), _(t, !1), M.current = t;
},
[_]
), [D, z] = J(ot), ht = d(
async (t, a = {}, s) => {
var e;
if ((e = t == null ? void 0 : t.preventDefault) == null || e.call(t), !D && !a.allowEmptySubmit)
return;
s && (g.current = {
...g.current,
...s
});
const i = await rt(
a.experimental_attachments
), f = {
messages: n.current.concat({
id: m(),
createdAt: /* @__PURE__ */ new Date(),
role: "user",
content: D,
experimental_attachments: i.length > 0 ? i : void 0,
parts: [{ type: "text", text: D }]
}),
headers: a.headers,
body: a.body,
data: a.data
};
l(f), z("");
},
[D, m, l]
), bt = (t) => {
z(t.target.value);
}, yt = d(
({ toolCallId: t, result: a }) => {
const s = n.current;
if (wt({
messages: s,
toolCallId: t,
toolResult: a
}), b(
[
...s.slice(0, s.length - 1),
{ ...s[s.length - 1] }
],
!1
), y === "submitted" || y === "streaming")
return;
const e = s[s.length - 1];
Rt(e) && l({ messages: s });
},
[b, y, l]
);
return {
messages: p != null ? p : [],
id: h,
setMessages: gt,
data: R,
setData: ft,
error: ut,
append: it,
reload: dt,
stop: mt,
input: D,
setInput: z,
handleInputChange: bt,
handleSubmit: ht,
isLoading: y === "submitted" || y === "streaming",
status: y,
addToolResult: yt
};
}
export {
Ut as useChat
};