@dudousxd/nestjs-agent-react 0.21.0 → 0.22.0
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/README.md +57 -55
- package/dist/{client-ePlgRwP-.d.cts → client-CYlhK7XD.d.cts} +2 -7
- package/dist/{client-ePlgRwP-.d.ts → client-CYlhK7XD.d.ts} +2 -7
- package/dist/index.cjs +405 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +172 -111
- package/dist/index.d.ts +172 -111
- package/dist/index.js +405 -152
- package/dist/index.js.map +1 -1
- package/dist/media.cjs.map +1 -1
- package/dist/media.d.cts +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/media.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -115,11 +115,6 @@ var AgentClient = class {
|
|
|
115
115
|
forkFromMessage(threadId, messageId) {
|
|
116
116
|
return this.request("POST", `/threads/${encodeURIComponent(threadId)}/fork-from/${encodeURIComponent(messageId)}`);
|
|
117
117
|
}
|
|
118
|
-
renameThread(id, title) {
|
|
119
|
-
return this.updateThread(id, {
|
|
120
|
-
title
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
118
|
/** General `PATCH <path>/threads/:threadId` — title and/or the thread's pinned default agent. */
|
|
124
119
|
updateThread(id, patch) {
|
|
125
120
|
return this.request("PATCH", `/threads/${encodeURIComponent(id)}`, patch);
|
|
@@ -212,9 +207,6 @@ var AgentClient = class {
|
|
|
212
207
|
getQuota() {
|
|
213
208
|
return this.request("GET", "/quota");
|
|
214
209
|
}
|
|
215
|
-
getQuotaToday() {
|
|
216
|
-
return this.request("GET", "/quota/today");
|
|
217
|
-
}
|
|
218
210
|
cancelStream(runId) {
|
|
219
211
|
return this.request("POST", `/chat/${encodeURIComponent(runId)}/cancel`);
|
|
220
212
|
}
|
|
@@ -626,13 +618,14 @@ var AgentChatTransport = class {
|
|
|
626
618
|
function ensureStarted() {
|
|
627
619
|
if (started) return;
|
|
628
620
|
started = true;
|
|
629
|
-
controller.enqueue(
|
|
621
|
+
controller.enqueue({
|
|
630
622
|
type: "start",
|
|
631
623
|
messageMetadata: {
|
|
632
|
-
|
|
624
|
+
...streamRunId !== void 0 ? {
|
|
625
|
+
runId: streamRunId
|
|
626
|
+
} : {},
|
|
627
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
633
628
|
}
|
|
634
|
-
} : {
|
|
635
|
-
type: "start"
|
|
636
629
|
});
|
|
637
630
|
}
|
|
638
631
|
__name(ensureStarted, "ensureStarted");
|
|
@@ -3662,14 +3655,18 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3662
3655
|
const [picks, setPicks] = useState10(() => /* @__PURE__ */ new Map());
|
|
3663
3656
|
const [settling, setSettling] = useState10(() => /* @__PURE__ */ new Map());
|
|
3664
3657
|
const [settleErrors, setSettleErrors] = useState10(() => /* @__PURE__ */ new Map());
|
|
3658
|
+
const backend = useAgentBackend();
|
|
3659
|
+
const handlers = settleHandlers(options, backend);
|
|
3665
3660
|
const latest = useRef9({
|
|
3666
3661
|
options,
|
|
3662
|
+
handlers,
|
|
3667
3663
|
drafts,
|
|
3668
3664
|
picks,
|
|
3669
3665
|
messages
|
|
3670
3666
|
});
|
|
3671
3667
|
latest.current = {
|
|
3672
3668
|
options,
|
|
3669
|
+
handlers,
|
|
3673
3670
|
drafts,
|
|
3674
3671
|
picks,
|
|
3675
3672
|
messages
|
|
@@ -3729,34 +3726,46 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3729
3726
|
}, []);
|
|
3730
3727
|
const answer = useCallback8((toolCallId) => {
|
|
3731
3728
|
const current = latest.current;
|
|
3732
|
-
const onAnswer = current.
|
|
3729
|
+
const onAnswer = current.handlers.onAnswer;
|
|
3733
3730
|
if (!onAnswer) {
|
|
3734
3731
|
return;
|
|
3735
3732
|
}
|
|
3736
|
-
settle(toolCallId, "answer", () => onAnswer(
|
|
3733
|
+
settle(toolCallId, "answer", () => onAnswer({
|
|
3734
|
+
toolCallId,
|
|
3735
|
+
answers: answersFor(current.picks, toolCallId)
|
|
3736
|
+
}));
|
|
3737
3737
|
}, [
|
|
3738
3738
|
settle
|
|
3739
3739
|
]);
|
|
3740
3740
|
const skip = useCallback8((toolCallId) => {
|
|
3741
|
-
const onSkip = latest.current.
|
|
3741
|
+
const onSkip = latest.current.handlers.onSkip;
|
|
3742
3742
|
if (onSkip) {
|
|
3743
|
-
settle(toolCallId, "skip", () => onSkip(
|
|
3743
|
+
settle(toolCallId, "skip", () => onSkip({
|
|
3744
|
+
toolCallId
|
|
3745
|
+
}));
|
|
3744
3746
|
}
|
|
3745
3747
|
}, [
|
|
3746
3748
|
settle
|
|
3747
3749
|
]);
|
|
3748
3750
|
const approve = useCallback8((toolCallId, options2) => {
|
|
3749
|
-
const onApprove = latest.current.
|
|
3751
|
+
const onApprove = latest.current.handlers.onApprove;
|
|
3750
3752
|
if (onApprove) {
|
|
3751
|
-
settle(toolCallId, "approve", () =>
|
|
3753
|
+
settle(toolCallId, "approve", () => onApprove({
|
|
3754
|
+
toolCallId,
|
|
3755
|
+
...options2?.remember === true ? {
|
|
3756
|
+
remember: true
|
|
3757
|
+
} : {}
|
|
3758
|
+
}));
|
|
3752
3759
|
}
|
|
3753
3760
|
}, [
|
|
3754
3761
|
settle
|
|
3755
3762
|
]);
|
|
3756
3763
|
const reject = useCallback8((toolCallId) => {
|
|
3757
|
-
const onReject = latest.current.
|
|
3764
|
+
const onReject = latest.current.handlers.onReject;
|
|
3758
3765
|
if (onReject) {
|
|
3759
|
-
settle(toolCallId, "reject", () => onReject(
|
|
3766
|
+
settle(toolCallId, "reject", () => onReject({
|
|
3767
|
+
toolCallId
|
|
3768
|
+
}));
|
|
3760
3769
|
}
|
|
3761
3770
|
}, [
|
|
3762
3771
|
settle
|
|
@@ -3811,13 +3820,20 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3811
3820
|
return;
|
|
3812
3821
|
}
|
|
3813
3822
|
created.cancelEdit();
|
|
3814
|
-
void latest.current.options.onEditSubmit?.(
|
|
3823
|
+
void latest.current.options.onEditSubmit?.({
|
|
3824
|
+
messageId: id,
|
|
3825
|
+
text: next
|
|
3826
|
+
});
|
|
3815
3827
|
}, "save"),
|
|
3816
3828
|
fork: /* @__PURE__ */ __name(() => {
|
|
3817
|
-
void latest.current.options.onFork?.(
|
|
3829
|
+
void latest.current.options.onFork?.({
|
|
3830
|
+
messageId: id
|
|
3831
|
+
});
|
|
3818
3832
|
}, "fork"),
|
|
3819
3833
|
regenerate: /* @__PURE__ */ __name(() => {
|
|
3820
|
-
void latest.current.options.onRegenerate?.(
|
|
3834
|
+
void latest.current.options.onRegenerate?.({
|
|
3835
|
+
messageId: id
|
|
3836
|
+
});
|
|
3821
3837
|
}, "regenerate"),
|
|
3822
3838
|
textareaRef: /* @__PURE__ */ __name((element) => {
|
|
3823
3839
|
if (!element) {
|
|
@@ -3854,7 +3870,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3854
3870
|
const draft = drafts.get(message.id);
|
|
3855
3871
|
const isEditing = draft !== void 0;
|
|
3856
3872
|
const text = extractMessageText(message.parts);
|
|
3857
|
-
const usage = options.getUsage
|
|
3873
|
+
const usage = (options.getUsage ?? usageFromMetadata)(message);
|
|
3858
3874
|
const isUser = message.role === "user";
|
|
3859
3875
|
const isAssistant = message.role === "assistant";
|
|
3860
3876
|
const isLastAssistant = isAssistant && message.id === lastAssistantId;
|
|
@@ -3876,22 +3892,22 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3876
3892
|
...options.toolCatalog !== void 0 ? {
|
|
3877
3893
|
toolCatalog: options.toolCatalog
|
|
3878
3894
|
} : {},
|
|
3879
|
-
...
|
|
3895
|
+
...handlers.onAnswer !== void 0 ? {
|
|
3880
3896
|
elicitation: {
|
|
3881
3897
|
picked: /* @__PURE__ */ __name((toolCallId, questionId) => picks.get(pickKey(toolCallId, questionId)), "picked"),
|
|
3882
3898
|
pick,
|
|
3883
3899
|
canAnswer: true,
|
|
3884
|
-
canSkip:
|
|
3900
|
+
canSkip: handlers.onSkip !== void 0,
|
|
3885
3901
|
answer,
|
|
3886
3902
|
skip,
|
|
3887
3903
|
submitting: /* @__PURE__ */ __name((toolCallId) => settling.get(toolCallId) ?? null, "submitting"),
|
|
3888
3904
|
errorOf: /* @__PURE__ */ __name((toolCallId) => settleErrors.get(toolCallId) ?? null, "errorOf")
|
|
3889
3905
|
}
|
|
3890
3906
|
} : {},
|
|
3891
|
-
...
|
|
3907
|
+
...handlers.onApprove !== void 0 || handlers.onReject !== void 0 ? {
|
|
3892
3908
|
approval: {
|
|
3893
|
-
canApprove:
|
|
3894
|
-
canReject:
|
|
3909
|
+
canApprove: handlers.onApprove !== void 0,
|
|
3910
|
+
canReject: handlers.onReject !== void 0,
|
|
3895
3911
|
approve,
|
|
3896
3912
|
reject,
|
|
3897
3913
|
submitting: /* @__PURE__ */ __name((toolCallId) => settling.get(toolCallId) ?? null, "submitting"),
|
|
@@ -3901,7 +3917,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3901
3917
|
}),
|
|
3902
3918
|
text,
|
|
3903
3919
|
usage: usage ? describeUsage(usage) : null,
|
|
3904
|
-
timestamp: describeTimestamp(options.getCreatedAt
|
|
3920
|
+
timestamp: describeTimestamp((options.getCreatedAt ?? createdAtFromMetadata)(message)),
|
|
3905
3921
|
copy: {
|
|
3906
3922
|
available: text.length > 0,
|
|
3907
3923
|
copied: copied.has(message.id),
|
|
@@ -3936,6 +3952,43 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3936
3952
|
return items;
|
|
3937
3953
|
}
|
|
3938
3954
|
__name(useTranscriptItems, "useTranscriptItems");
|
|
3955
|
+
function settleHandlers(options, backend) {
|
|
3956
|
+
const pick = /* @__PURE__ */ __name((own, fallback2) => own === null ? void 0 : own ?? fallback2, "pick");
|
|
3957
|
+
return {
|
|
3958
|
+
onAnswer: pick(options.onAnswer, backend.answerToolCall ? async (input) => {
|
|
3959
|
+
await backend.answerToolCall?.(input);
|
|
3960
|
+
} : void 0),
|
|
3961
|
+
onSkip: pick(options.onSkip, backend.skipToolCall ? async (input) => {
|
|
3962
|
+
await backend.skipToolCall?.(input);
|
|
3963
|
+
} : void 0),
|
|
3964
|
+
onApprove: pick(options.onApprove, backend.approveToolCall ? async (input) => {
|
|
3965
|
+
await backend.approveToolCall?.(input);
|
|
3966
|
+
} : void 0),
|
|
3967
|
+
onReject: pick(options.onReject, backend.rejectToolCall ? async (input) => {
|
|
3968
|
+
await backend.rejectToolCall?.(input);
|
|
3969
|
+
} : void 0)
|
|
3970
|
+
};
|
|
3971
|
+
}
|
|
3972
|
+
__name(settleHandlers, "settleHandlers");
|
|
3973
|
+
function metadataOf2(message) {
|
|
3974
|
+
const metadata = message.metadata;
|
|
3975
|
+
return metadata !== null && typeof metadata === "object" ? metadata : {};
|
|
3976
|
+
}
|
|
3977
|
+
__name(metadataOf2, "metadataOf");
|
|
3978
|
+
function usageFromMetadata(message) {
|
|
3979
|
+
const usage = metadataOf2(message).usage;
|
|
3980
|
+
if (usage === void 0) return null;
|
|
3981
|
+
return {
|
|
3982
|
+
inputTokens: usage.inputTokens,
|
|
3983
|
+
outputTokens: usage.outputTokens,
|
|
3984
|
+
costUsd: usage.costUsd ?? null
|
|
3985
|
+
};
|
|
3986
|
+
}
|
|
3987
|
+
__name(usageFromMetadata, "usageFromMetadata");
|
|
3988
|
+
function createdAtFromMetadata(message) {
|
|
3989
|
+
return metadataOf2(message).createdAt ?? null;
|
|
3990
|
+
}
|
|
3991
|
+
__name(createdAtFromMetadata, "createdAtFromMetadata");
|
|
3939
3992
|
function pickKey(toolCallId, questionId) {
|
|
3940
3993
|
return `${toolCallId}|${questionId}`;
|
|
3941
3994
|
}
|
|
@@ -3985,7 +4038,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3985
4038
|
editable
|
|
3986
4039
|
} : {},
|
|
3987
4040
|
...onEditSubmit ? {
|
|
3988
|
-
onEditSubmit
|
|
4041
|
+
onEditSubmit
|
|
3989
4042
|
} : {},
|
|
3990
4043
|
...onFork ? {
|
|
3991
4044
|
onFork
|
|
@@ -3994,7 +4047,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3994
4047
|
regeneratable
|
|
3995
4048
|
} : {},
|
|
3996
4049
|
...onRegenerate ? {
|
|
3997
|
-
onRegenerate
|
|
4050
|
+
onRegenerate
|
|
3998
4051
|
} : {},
|
|
3999
4052
|
...usage != null ? {
|
|
4000
4053
|
getUsage: /* @__PURE__ */ __name(() => usage, "getUsage")
|
|
@@ -4699,7 +4752,7 @@ function useToolCatalog(options = {}) {
|
|
|
4699
4752
|
setLoading(true);
|
|
4700
4753
|
load(client, agent).then((loaded) => {
|
|
4701
4754
|
if (cancelled) return;
|
|
4702
|
-
setEntries(loaded);
|
|
4755
|
+
setEntries(Array.isArray(loaded) ? loaded : []);
|
|
4703
4756
|
setError(null);
|
|
4704
4757
|
setLoading(false);
|
|
4705
4758
|
}, (failure) => {
|
|
@@ -4927,14 +4980,27 @@ function storedMessageToUiMessage(message) {
|
|
|
4927
4980
|
});
|
|
4928
4981
|
parts.push(...pushedByCall.get(call.id) ?? []);
|
|
4929
4982
|
}
|
|
4983
|
+
const metadata = {
|
|
4984
|
+
...message.feedback !== void 0 ? {
|
|
4985
|
+
feedback: message.feedback
|
|
4986
|
+
} : {},
|
|
4987
|
+
...message.createdAt ? {
|
|
4988
|
+
createdAt: message.createdAt
|
|
4989
|
+
} : {},
|
|
4990
|
+
...message.usage !== void 0 ? {
|
|
4991
|
+
usage: {
|
|
4992
|
+
inputTokens: message.usage.inputTokens,
|
|
4993
|
+
outputTokens: message.usage.outputTokens,
|
|
4994
|
+
costUsd: message.usage.costUsd ?? null
|
|
4995
|
+
}
|
|
4996
|
+
} : {}
|
|
4997
|
+
};
|
|
4930
4998
|
return {
|
|
4931
4999
|
id: message.id,
|
|
4932
5000
|
role: message.role,
|
|
4933
5001
|
parts,
|
|
4934
|
-
...
|
|
4935
|
-
metadata
|
|
4936
|
-
feedback: message.feedback
|
|
4937
|
-
}
|
|
5002
|
+
...Object.keys(metadata).length > 0 ? {
|
|
5003
|
+
metadata
|
|
4938
5004
|
} : {}
|
|
4939
5005
|
};
|
|
4940
5006
|
}
|
|
@@ -4972,12 +5038,16 @@ function mergeTurn(rows) {
|
|
|
4972
5038
|
const parts = rows.flatMap((row) => storedMessageToUiMessage(row).parts);
|
|
4973
5039
|
const usage = sumUsage(rows);
|
|
4974
5040
|
const feedback = lastRow.feedback;
|
|
5041
|
+
const createdAt = rows[0]?.createdAt;
|
|
4975
5042
|
const metadata = {
|
|
4976
5043
|
...usage !== void 0 ? {
|
|
4977
5044
|
usage
|
|
4978
5045
|
} : {},
|
|
4979
5046
|
...feedback !== void 0 ? {
|
|
4980
5047
|
feedback
|
|
5048
|
+
} : {},
|
|
5049
|
+
...createdAt ? {
|
|
5050
|
+
createdAt
|
|
4981
5051
|
} : {}
|
|
4982
5052
|
};
|
|
4983
5053
|
return {
|
|
@@ -5007,50 +5077,61 @@ __name(sumUsage, "sumUsage");
|
|
|
5007
5077
|
// src/use-agent-chat.ts
|
|
5008
5078
|
import { useChat } from "@ai-sdk/react";
|
|
5009
5079
|
import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo11, useRef as useRef12, useState as useState14 } from "react";
|
|
5080
|
+
var localChatSequence = 0;
|
|
5081
|
+
function localChatId() {
|
|
5082
|
+
localChatSequence += 1;
|
|
5083
|
+
return `local-chat-${localChatSequence}`;
|
|
5084
|
+
}
|
|
5085
|
+
__name(localChatId, "localChatId");
|
|
5010
5086
|
function useAgentChat(options = {}) {
|
|
5011
5087
|
const latest = useRef12(options);
|
|
5012
5088
|
latest.current = options;
|
|
5089
|
+
const resolved = useAgentBackend(options.backend);
|
|
5090
|
+
const client = useRef12(resolved).current;
|
|
5091
|
+
const createdThreadId = useRef12(void 0);
|
|
5092
|
+
const chatIdRef = useRef12(options.threadId ?? localChatId());
|
|
5093
|
+
const boundThreadRef = useRef12(options.threadId);
|
|
5094
|
+
if (options.threadId !== boundThreadRef.current) {
|
|
5095
|
+
boundThreadRef.current = options.threadId;
|
|
5096
|
+
const adopting = options.threadId !== void 0 && options.threadId === createdThreadId.current;
|
|
5097
|
+
if (!adopting) {
|
|
5098
|
+
chatIdRef.current = options.threadId ?? localChatId();
|
|
5099
|
+
createdThreadId.current = void 0;
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
const chatId = chatIdRef.current;
|
|
5013
5103
|
const [runId, setRunId] = useState14(options.resumeRunId);
|
|
5014
5104
|
const runIdRef = useRef12(runId);
|
|
5015
5105
|
runIdRef.current = runId;
|
|
5016
5106
|
const settlingRunIdRef = useRef12(void 0);
|
|
5017
5107
|
const autoResumeRunIdRef = useRef12(void 0);
|
|
5018
|
-
const [autoResume, setAutoResume] = useState14(false);
|
|
5019
5108
|
const [activeRunId, setActiveRunId] = useState14(null);
|
|
5109
|
+
const [isLoadingHistory, setIsLoadingHistory] = useState14(false);
|
|
5110
|
+
const [historyError, setHistoryError] = useState14(null);
|
|
5111
|
+
const [threadModel, setThreadModel] = useState14(null);
|
|
5112
|
+
const [pickedModel, setPickedModel] = useState14(void 0);
|
|
5113
|
+
const pickedModelRef = useRef12(pickedModel);
|
|
5114
|
+
pickedModelRef.current = pickedModel;
|
|
5115
|
+
const pendingPin = useRef12(void 0);
|
|
5020
5116
|
const regenerateNext = useRef12(false);
|
|
5021
|
-
const
|
|
5022
|
-
const resolved = useAgentBackend(options.backend);
|
|
5023
|
-
const client = useRef12(resolved).current;
|
|
5117
|
+
const currentThreadId = useCallback11(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
5024
5118
|
const [connection, setConnection] = useState14({
|
|
5025
5119
|
status: "live"
|
|
5026
5120
|
});
|
|
5027
5121
|
const resyncAfterSettle = useRef12(false);
|
|
5028
|
-
useEffect14(() => {
|
|
5029
|
-
if (!options.resume || options.threadId === void 0) return;
|
|
5030
|
-
let cancelled = false;
|
|
5031
|
-
const threadId = options.threadId;
|
|
5032
|
-
void client.getThread(threadId).then((thread) => {
|
|
5033
|
-
if (cancelled) return;
|
|
5034
|
-
setActiveRunId(thread.activeRunId ?? null);
|
|
5035
|
-
if (thread.activeRunId != null) {
|
|
5036
|
-
autoResumeRunIdRef.current = thread.activeRunId;
|
|
5037
|
-
setAutoResume(true);
|
|
5038
|
-
}
|
|
5039
|
-
});
|
|
5040
|
-
return () => {
|
|
5041
|
-
cancelled = true;
|
|
5042
|
-
};
|
|
5043
|
-
}, [
|
|
5044
|
-
client,
|
|
5045
|
-
options.resume,
|
|
5046
|
-
options.threadId
|
|
5047
|
-
]);
|
|
5048
5122
|
const transport = useMemo11(() => {
|
|
5049
5123
|
function onMeta(meta) {
|
|
5050
5124
|
settlingRunIdRef.current = meta.runId;
|
|
5051
5125
|
setRunId(meta.runId);
|
|
5052
5126
|
if (latest.current.threadId === void 0 && meta.threadId && createdThreadId.current !== meta.threadId) {
|
|
5053
5127
|
createdThreadId.current = meta.threadId;
|
|
5128
|
+
const pin = pendingPin.current;
|
|
5129
|
+
if (pin !== void 0) {
|
|
5130
|
+
pendingPin.current = void 0;
|
|
5131
|
+
void client.updateThread(meta.threadId, {
|
|
5132
|
+
model: pin.model
|
|
5133
|
+
}).catch(() => void 0);
|
|
5134
|
+
}
|
|
5054
5135
|
latest.current.onThreadCreated?.(meta.threadId);
|
|
5055
5136
|
notifyThreads(client, {
|
|
5056
5137
|
type: "changed"
|
|
@@ -5077,13 +5158,14 @@ function useAgentChat(options = {}) {
|
|
|
5077
5158
|
const pageContext = current.getPageContext?.() ?? null;
|
|
5078
5159
|
const regenerate2 = regenerateNext.current;
|
|
5079
5160
|
regenerateNext.current = false;
|
|
5080
|
-
const threadId =
|
|
5161
|
+
const threadId = currentThreadId();
|
|
5162
|
+
const model = current.model ?? pickedModelRef.current;
|
|
5081
5163
|
return {
|
|
5082
5164
|
...threadId !== void 0 ? {
|
|
5083
5165
|
threadId
|
|
5084
5166
|
} : {},
|
|
5085
|
-
...
|
|
5086
|
-
model
|
|
5167
|
+
...model !== void 0 ? {
|
|
5168
|
+
model
|
|
5087
5169
|
} : {},
|
|
5088
5170
|
...pageContext ? {
|
|
5089
5171
|
pageContext
|
|
@@ -5103,10 +5185,8 @@ function useAgentChat(options = {}) {
|
|
|
5103
5185
|
const backgroundRef = useRef12(() => Promise.resolve());
|
|
5104
5186
|
const chat = useChat({
|
|
5105
5187
|
transport,
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
id: options.threadId
|
|
5109
|
-
} : {},
|
|
5188
|
+
id: chatId,
|
|
5189
|
+
resume: options.resumeRunId !== void 0,
|
|
5110
5190
|
...options.initialMessages !== void 0 ? {
|
|
5111
5191
|
messages: options.initialMessages
|
|
5112
5192
|
} : {},
|
|
@@ -5116,7 +5196,7 @@ function useAgentChat(options = {}) {
|
|
|
5116
5196
|
const title = part.data?.title;
|
|
5117
5197
|
if (typeof title === "string") {
|
|
5118
5198
|
latest.current.onTitle?.(title);
|
|
5119
|
-
const threadId =
|
|
5199
|
+
const threadId = currentThreadId();
|
|
5120
5200
|
if (threadId !== void 0) notifyThreads(client, {
|
|
5121
5201
|
type: "title",
|
|
5122
5202
|
threadId,
|
|
@@ -5152,7 +5232,7 @@ function useAgentChat(options = {}) {
|
|
|
5152
5232
|
const chatRef = useRef12(chat);
|
|
5153
5233
|
chatRef.current = chat;
|
|
5154
5234
|
async function resyncFromThread() {
|
|
5155
|
-
const threadId =
|
|
5235
|
+
const threadId = currentThreadId();
|
|
5156
5236
|
if (threadId === void 0) return;
|
|
5157
5237
|
try {
|
|
5158
5238
|
const thread = await client.getThread(threadId);
|
|
@@ -5161,13 +5241,75 @@ function useAgentChat(options = {}) {
|
|
|
5161
5241
|
}
|
|
5162
5242
|
}
|
|
5163
5243
|
__name(resyncFromThread, "resyncFromThread");
|
|
5244
|
+
const firstChatId = useRef12(chatId);
|
|
5245
|
+
useEffect14(() => {
|
|
5246
|
+
if (chatId === firstChatId.current) return;
|
|
5247
|
+
firstChatId.current = chatId;
|
|
5248
|
+
setRunId(void 0);
|
|
5249
|
+
setActiveRunId(null);
|
|
5250
|
+
setThreadModel(null);
|
|
5251
|
+
setBackgroundRuns([]);
|
|
5252
|
+
setHistoryError(null);
|
|
5253
|
+
autoResumeRunIdRef.current = void 0;
|
|
5254
|
+
pendingPin.current = void 0;
|
|
5255
|
+
}, [
|
|
5256
|
+
chatId
|
|
5257
|
+
]);
|
|
5258
|
+
useEffect14(() => {
|
|
5259
|
+
const threadId = options.threadId;
|
|
5260
|
+
if (threadId === void 0) return;
|
|
5261
|
+
if (threadId === createdThreadId.current) return;
|
|
5262
|
+
const current = latest.current;
|
|
5263
|
+
const wantHistory = current.history !== false && current.initialMessages === void 0;
|
|
5264
|
+
const wantResume = current.resume !== false && current.resumeRunId === void 0;
|
|
5265
|
+
if (!wantHistory && !wantResume) return;
|
|
5266
|
+
let cancelled = false;
|
|
5267
|
+
if (wantHistory) setIsLoadingHistory(true);
|
|
5268
|
+
client.getThread(threadId).then((thread) => {
|
|
5269
|
+
if (cancelled || thread == null) return;
|
|
5270
|
+
const active = thread.activeRunId ?? null;
|
|
5271
|
+
const stored = Array.isArray(thread.messages) ? thread.messages : [];
|
|
5272
|
+
setActiveRunId(active);
|
|
5273
|
+
setThreadModel(thread.model ?? null);
|
|
5274
|
+
setHistoryError(null);
|
|
5275
|
+
const resuming = wantResume && active !== null;
|
|
5276
|
+
if (wantHistory && chatRef.current.messages.length === 0) {
|
|
5277
|
+
const rows = resuming ? stored.filter((message) => !(message.role === "assistant" && message.runId === active)) : stored;
|
|
5278
|
+
chatRef.current.setMessages(storedThreadToUiMessages(rows));
|
|
5279
|
+
}
|
|
5280
|
+
if (resuming) {
|
|
5281
|
+
autoResumeRunIdRef.current = active;
|
|
5282
|
+
void chatRef.current.resumeStream();
|
|
5283
|
+
}
|
|
5284
|
+
}, (error) => {
|
|
5285
|
+
if (cancelled) return;
|
|
5286
|
+
setHistoryError(error instanceof Error ? error : new Error(String(error)));
|
|
5287
|
+
}).finally(() => {
|
|
5288
|
+
if (!cancelled) setIsLoadingHistory(false);
|
|
5289
|
+
});
|
|
5290
|
+
return () => {
|
|
5291
|
+
cancelled = true;
|
|
5292
|
+
setIsLoadingHistory(false);
|
|
5293
|
+
};
|
|
5294
|
+
}, [
|
|
5295
|
+
client,
|
|
5296
|
+
chatId,
|
|
5297
|
+
options.threadId
|
|
5298
|
+
]);
|
|
5164
5299
|
const turnInFlight = useRef12(false);
|
|
5165
5300
|
const isTurnInFlight = useCallback11(() => turnInFlight.current || transport.isAttemptLive, [
|
|
5166
5301
|
transport
|
|
5167
5302
|
]);
|
|
5303
|
+
const quota = useQuota({
|
|
5304
|
+
backend: client,
|
|
5305
|
+
enabled: options.quota !== false && typeof client.getQuota === "function"
|
|
5306
|
+
});
|
|
5307
|
+
const blocked = options.blocked !== void 0 ? options.blocked : quota.blocked;
|
|
5308
|
+
const blockedRef = useRef12(blocked);
|
|
5309
|
+
blockedRef.current = blocked;
|
|
5168
5310
|
const sendMessage = useCallback11(async (...args) => {
|
|
5169
|
-
const
|
|
5170
|
-
if (
|
|
5311
|
+
const block = blockedRef.current;
|
|
5312
|
+
if (block != null) throw new QuotaBlockedError(block);
|
|
5171
5313
|
if (isTurnInFlight()) return;
|
|
5172
5314
|
turnInFlight.current = true;
|
|
5173
5315
|
try {
|
|
@@ -5183,11 +5325,9 @@ function useAgentChat(options = {}) {
|
|
|
5183
5325
|
toolCallId,
|
|
5184
5326
|
output
|
|
5185
5327
|
}), []);
|
|
5186
|
-
const [threads, setThreads] = useState14([]);
|
|
5187
|
-
const [quota, setQuota] = useState14(null);
|
|
5188
5328
|
const [backgroundRuns, setBackgroundRuns] = useState14([]);
|
|
5189
5329
|
const refreshBackground = useCallback11(async () => {
|
|
5190
|
-
const threadId =
|
|
5330
|
+
const threadId = currentThreadId();
|
|
5191
5331
|
if (threadId === void 0) {
|
|
5192
5332
|
return;
|
|
5193
5333
|
}
|
|
@@ -5207,7 +5347,8 @@ function useAgentChat(options = {}) {
|
|
|
5207
5347
|
];
|
|
5208
5348
|
});
|
|
5209
5349
|
}, [
|
|
5210
|
-
client
|
|
5350
|
+
client,
|
|
5351
|
+
currentThreadId
|
|
5211
5352
|
]);
|
|
5212
5353
|
backgroundRef.current = refreshBackground;
|
|
5213
5354
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
@@ -5219,6 +5360,7 @@ function useAgentChat(options = {}) {
|
|
|
5219
5360
|
}, [
|
|
5220
5361
|
options.background,
|
|
5221
5362
|
options.threadId,
|
|
5363
|
+
chatId,
|
|
5222
5364
|
refreshBackground
|
|
5223
5365
|
]);
|
|
5224
5366
|
useEffect14(() => {
|
|
@@ -5232,59 +5374,12 @@ function useAgentChat(options = {}) {
|
|
|
5232
5374
|
isWorking,
|
|
5233
5375
|
refreshBackground
|
|
5234
5376
|
]);
|
|
5235
|
-
const loadThreads = useCallback11(async () => {
|
|
5236
|
-
const list = await client.listThreads();
|
|
5237
|
-
setThreads(list);
|
|
5238
|
-
return list;
|
|
5239
|
-
}, [
|
|
5240
|
-
client
|
|
5241
|
-
]);
|
|
5242
|
-
const loadThread = useCallback11((id) => client.getThread(id), [
|
|
5243
|
-
client
|
|
5244
|
-
]);
|
|
5245
|
-
const deleteThread = useCallback11(async (id) => {
|
|
5246
|
-
await client.deleteThread(id);
|
|
5247
|
-
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
5248
|
-
}, [
|
|
5249
|
-
client
|
|
5250
|
-
]);
|
|
5251
|
-
const forkThread = useCallback11((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
5252
|
-
client
|
|
5253
|
-
]);
|
|
5254
|
-
const renameThread = useCallback11(async (id, title) => {
|
|
5255
|
-
await client.updateThread(id, {
|
|
5256
|
-
title
|
|
5257
|
-
});
|
|
5258
|
-
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
5259
|
-
...thread,
|
|
5260
|
-
title
|
|
5261
|
-
} : thread));
|
|
5262
|
-
}, [
|
|
5263
|
-
client
|
|
5264
|
-
]);
|
|
5265
|
-
const promoteThread = useCallback11(async (id) => {
|
|
5266
|
-
await requireBackendMethod(client, "promoteThread")(id);
|
|
5267
|
-
await loadThreads();
|
|
5268
|
-
}, [
|
|
5269
|
-
client,
|
|
5270
|
-
loadThreads
|
|
5271
|
-
]);
|
|
5272
|
-
const truncateFromMessage = useCallback11((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
5273
|
-
client
|
|
5274
|
-
]);
|
|
5275
|
-
const loadQuota = useCallback11(async () => {
|
|
5276
|
-
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
5277
|
-
setQuota(today);
|
|
5278
|
-
return today;
|
|
5279
|
-
}, [
|
|
5280
|
-
client
|
|
5281
|
-
]);
|
|
5282
5377
|
const cancel = useCallback11(async () => {
|
|
5283
5378
|
chatRef.current.stop();
|
|
5284
|
-
const
|
|
5285
|
-
if (
|
|
5379
|
+
const active = runIdRef.current;
|
|
5380
|
+
if (active) {
|
|
5286
5381
|
try {
|
|
5287
|
-
await client.cancelStream(
|
|
5382
|
+
await client.cancelStream(active);
|
|
5288
5383
|
} catch {
|
|
5289
5384
|
}
|
|
5290
5385
|
}
|
|
@@ -5334,9 +5429,9 @@ function useAgentChat(options = {}) {
|
|
|
5334
5429
|
}, [
|
|
5335
5430
|
client
|
|
5336
5431
|
]);
|
|
5337
|
-
const regenerate = useCallback11(() => {
|
|
5338
|
-
const
|
|
5339
|
-
if (
|
|
5432
|
+
const regenerate = useCallback11((_input) => {
|
|
5433
|
+
const block = blockedRef.current;
|
|
5434
|
+
if (block != null) throw new QuotaBlockedError(block);
|
|
5340
5435
|
if (isTurnInFlight()) return;
|
|
5341
5436
|
regenerateNext.current = true;
|
|
5342
5437
|
turnInFlight.current = true;
|
|
@@ -5346,15 +5441,78 @@ function useAgentChat(options = {}) {
|
|
|
5346
5441
|
}, [
|
|
5347
5442
|
isTurnInFlight
|
|
5348
5443
|
]);
|
|
5349
|
-
const
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5444
|
+
const storedIdOf = useCallback11(async (messageId, threadId) => {
|
|
5445
|
+
const message = chatRef.current.messages.find((candidate) => candidate.id === messageId);
|
|
5446
|
+
const runOf = message?.metadata?.runId;
|
|
5447
|
+
if (runOf === void 0) return messageId;
|
|
5448
|
+
const thread = await client.getThread(threadId);
|
|
5449
|
+
const row = [
|
|
5450
|
+
...thread.messages
|
|
5451
|
+
].reverse().find((candidate) => candidate.role === "assistant" && candidate.runId === runOf);
|
|
5452
|
+
return row?.id ?? messageId;
|
|
5453
|
+
}, [
|
|
5454
|
+
client
|
|
5455
|
+
]);
|
|
5456
|
+
const fork = useCallback11(async ({ messageId, threadId }) => {
|
|
5457
|
+
const source = threadId ?? currentThreadId();
|
|
5458
|
+
if (source === void 0) throw new Error("fork: this chat has no thread yet");
|
|
5459
|
+
const stored = await storedIdOf(messageId, source);
|
|
5460
|
+
const forked = await requireBackendMethod(client, "forkFromMessage")(source, stored);
|
|
5461
|
+
notifyThreads(client, {
|
|
5462
|
+
type: "changed"
|
|
5463
|
+
});
|
|
5464
|
+
latest.current.onThreadCreated?.(forked.id);
|
|
5465
|
+
return forked;
|
|
5466
|
+
}, [
|
|
5467
|
+
client,
|
|
5468
|
+
currentThreadId,
|
|
5469
|
+
storedIdOf
|
|
5470
|
+
]);
|
|
5471
|
+
const truncateFrom = useCallback11(async ({ messageId, threadId }) => {
|
|
5472
|
+
const target = threadId ?? currentThreadId();
|
|
5473
|
+
if (target === void 0) throw new Error("truncateFrom: this chat has no thread yet");
|
|
5474
|
+
const stored = await storedIdOf(messageId, target);
|
|
5475
|
+
await requireBackendMethod(client, "truncateFromMessage")(target, stored);
|
|
5476
|
+
}, [
|
|
5477
|
+
client,
|
|
5478
|
+
currentThreadId,
|
|
5479
|
+
storedIdOf
|
|
5480
|
+
]);
|
|
5481
|
+
const promote = useCallback11(async ({ threadId } = {}) => {
|
|
5482
|
+
const target = threadId ?? currentThreadId();
|
|
5483
|
+
if (target === void 0) throw new Error("promote: this chat has no thread yet");
|
|
5484
|
+
await requireBackendMethod(client, "promoteThread")(target);
|
|
5485
|
+
notifyThreads(client, {
|
|
5486
|
+
type: "changed"
|
|
5487
|
+
});
|
|
5488
|
+
}, [
|
|
5489
|
+
client,
|
|
5490
|
+
currentThreadId
|
|
5491
|
+
]);
|
|
5492
|
+
const [modelsWanted, setModelsWanted] = useState14(false);
|
|
5493
|
+
const modelsWantedRef = useRef12(modelsWanted);
|
|
5494
|
+
modelsWantedRef.current = modelsWanted;
|
|
5495
|
+
const catalog = useModels({
|
|
5496
|
+
backend: client,
|
|
5497
|
+
...options.agent !== void 0 ? {
|
|
5498
|
+
agent: options.agent
|
|
5499
|
+
} : {},
|
|
5500
|
+
enabled: modelsWanted && typeof client.listModels === "function"
|
|
5501
|
+
});
|
|
5502
|
+
const wantModels = useCallback11(() => {
|
|
5503
|
+
if (modelsWantedRef.current) return;
|
|
5504
|
+
modelsWantedRef.current = true;
|
|
5505
|
+
queueMicrotask(() => setModelsWanted(true));
|
|
5506
|
+
}, []);
|
|
5507
|
+
const selectModel = useCallback11((id) => setPickedModel(id), []);
|
|
5508
|
+
const pinToThread = useCallback11(async (model) => {
|
|
5509
|
+
const threadId = currentThreadId();
|
|
5510
|
+
setThreadModel(model);
|
|
5356
5511
|
if (threadId === void 0) {
|
|
5357
|
-
|
|
5512
|
+
pendingPin.current = {
|
|
5513
|
+
model
|
|
5514
|
+
};
|
|
5515
|
+
return;
|
|
5358
5516
|
}
|
|
5359
5517
|
await client.updateThread(threadId, {
|
|
5360
5518
|
model
|
|
@@ -5363,10 +5521,99 @@ function useAgentChat(options = {}) {
|
|
|
5363
5521
|
type: "changed"
|
|
5364
5522
|
});
|
|
5365
5523
|
}, [
|
|
5366
|
-
client
|
|
5524
|
+
client,
|
|
5525
|
+
currentThreadId
|
|
5367
5526
|
]);
|
|
5368
|
-
const
|
|
5527
|
+
const models = {
|
|
5528
|
+
get list() {
|
|
5529
|
+
wantModels();
|
|
5530
|
+
return catalog.models;
|
|
5531
|
+
},
|
|
5532
|
+
get providers() {
|
|
5533
|
+
wantModels();
|
|
5534
|
+
return catalog.providers;
|
|
5535
|
+
},
|
|
5536
|
+
selected: options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5537
|
+
select: selectModel,
|
|
5538
|
+
pinToThread,
|
|
5539
|
+
isLoading: modelsWanted && catalog.isLoading,
|
|
5540
|
+
error: catalog.error
|
|
5541
|
+
};
|
|
5369
5542
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
5543
|
+
const isBusy = status === "submitted" || status === "streaming" || status === "reconnecting";
|
|
5544
|
+
const files = useAttachments({
|
|
5545
|
+
...options.composer,
|
|
5546
|
+
backend: client
|
|
5547
|
+
});
|
|
5548
|
+
const [text, setText] = useState14("");
|
|
5549
|
+
const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.attachments.length === 0 ? "empty" : null;
|
|
5550
|
+
const composerRef = useRef12({
|
|
5551
|
+
text,
|
|
5552
|
+
files,
|
|
5553
|
+
blockedBy
|
|
5554
|
+
});
|
|
5555
|
+
composerRef.current = {
|
|
5556
|
+
text,
|
|
5557
|
+
files,
|
|
5558
|
+
blockedBy
|
|
5559
|
+
};
|
|
5560
|
+
const submit = useCallback11(async () => {
|
|
5561
|
+
const current = composerRef.current;
|
|
5562
|
+
if (current.blockedBy !== null) return;
|
|
5563
|
+
const refs = current.files.refs;
|
|
5564
|
+
const draft = current.text.trim();
|
|
5565
|
+
setText("");
|
|
5566
|
+
current.files.clear();
|
|
5567
|
+
await sendMessage({
|
|
5568
|
+
text: draft
|
|
5569
|
+
}, refs.length > 0 ? {
|
|
5570
|
+
body: {
|
|
5571
|
+
attachments: refs
|
|
5572
|
+
}
|
|
5573
|
+
} : void 0);
|
|
5574
|
+
}, [
|
|
5575
|
+
sendMessage
|
|
5576
|
+
]);
|
|
5577
|
+
const composer = {
|
|
5578
|
+
text,
|
|
5579
|
+
setText,
|
|
5580
|
+
files,
|
|
5581
|
+
canSend: blockedBy === null,
|
|
5582
|
+
blockedBy,
|
|
5583
|
+
submit
|
|
5584
|
+
};
|
|
5585
|
+
const ownCatalog = options.transcript?.toolCatalog;
|
|
5586
|
+
const tools = useToolCatalog({
|
|
5587
|
+
backend: client,
|
|
5588
|
+
...options.agent !== void 0 ? {
|
|
5589
|
+
agent: options.agent
|
|
5590
|
+
} : {},
|
|
5591
|
+
enabled: ownCatalog === void 0 && typeof client.listTools === "function"
|
|
5592
|
+
});
|
|
5593
|
+
const canFork = typeof client.forkFromMessage === "function";
|
|
5594
|
+
const transcript = useChatTranscript({
|
|
5595
|
+
messages: chat.messages,
|
|
5596
|
+
status,
|
|
5597
|
+
onStop: cancel,
|
|
5598
|
+
onApprove: approve,
|
|
5599
|
+
onReject: reject,
|
|
5600
|
+
onAnswer: answer,
|
|
5601
|
+
onSkip: skip,
|
|
5602
|
+
regeneratable: true,
|
|
5603
|
+
onRegenerate: regenerate,
|
|
5604
|
+
...canFork ? {
|
|
5605
|
+
onFork: /* @__PURE__ */ __name((input) => fork(input).then(() => void 0), "onFork")
|
|
5606
|
+
} : {},
|
|
5607
|
+
...ownCatalog === void 0 ? {
|
|
5608
|
+
toolCatalog: tools.catalog
|
|
5609
|
+
} : {},
|
|
5610
|
+
...options.transcript
|
|
5611
|
+
});
|
|
5612
|
+
const background = {
|
|
5613
|
+
runs: backgroundRuns,
|
|
5614
|
+
isWorking,
|
|
5615
|
+
refresh: refreshBackground
|
|
5616
|
+
};
|
|
5370
5617
|
return {
|
|
5371
5618
|
...chat,
|
|
5372
5619
|
status,
|
|
@@ -5377,32 +5624,38 @@ function useAgentChat(options = {}) {
|
|
|
5377
5624
|
/** Sub-agents this conversation started and did not wait for. */
|
|
5378
5625
|
background,
|
|
5379
5626
|
runId,
|
|
5380
|
-
/** The
|
|
5627
|
+
/** The loaded thread's running turn, or `null` once read with none. */
|
|
5381
5628
|
activeRunId,
|
|
5629
|
+
/** The thread's history is being read. */
|
|
5630
|
+
isLoadingHistory,
|
|
5631
|
+
/** Reading the thread's history failed. */
|
|
5632
|
+
historyError,
|
|
5382
5633
|
/**
|
|
5383
5634
|
* The thread this chat is on right now: the `threadId` option, else the one the backend created
|
|
5384
5635
|
* on the first send. A getter, because the created id is learned mid-stream.
|
|
5385
5636
|
*/
|
|
5386
|
-
getThreadId,
|
|
5387
|
-
setThreadModel,
|
|
5637
|
+
getThreadId: currentThreadId,
|
|
5388
5638
|
/** The backend this chat talks to — the same one every other hook under the provider uses. */
|
|
5389
5639
|
backend: client,
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
truncateFromMessage,
|
|
5640
|
+
/** The transcript model, with every action already bound to this chat. */
|
|
5641
|
+
transcript,
|
|
5642
|
+
/** A headless composer: draft, files, send gate, `submit()`. */
|
|
5643
|
+
composer,
|
|
5644
|
+
/** The model picker: `list`, `selected`, `select(id)`, `pinToThread(id)`. */
|
|
5645
|
+
models,
|
|
5646
|
+
/** The caller's budget (`GET <base>/quota`); `quota.blocked` gates sends. */
|
|
5398
5647
|
quota,
|
|
5399
|
-
|
|
5648
|
+
/** The window blocking sends right now (the `blocked` option, else the quota report's). */
|
|
5649
|
+
blocked,
|
|
5400
5650
|
cancel,
|
|
5401
5651
|
approve,
|
|
5402
5652
|
reject,
|
|
5403
5653
|
answer,
|
|
5404
5654
|
skip,
|
|
5405
|
-
regenerate
|
|
5655
|
+
regenerate,
|
|
5656
|
+
fork,
|
|
5657
|
+
truncateFrom,
|
|
5658
|
+
promote
|
|
5406
5659
|
};
|
|
5407
5660
|
}
|
|
5408
5661
|
__name(useAgentChat, "useAgentChat");
|