@dudousxd/nestjs-agent-react 0.10.0 → 0.12.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 +38 -4
- package/dist/index.cjs +327 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -10
- package/dist/index.d.ts +118 -10
- package/dist/index.js +299 -37
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -444,6 +444,10 @@ var AgentChatTransport = class {
|
|
|
444
444
|
});
|
|
445
445
|
}
|
|
446
446
|
break;
|
|
447
|
+
case "approval-settled":
|
|
448
|
+
ensureStep();
|
|
449
|
+
forwardAsData(event, false);
|
|
450
|
+
break;
|
|
447
451
|
case "ui":
|
|
448
452
|
ensureStep();
|
|
449
453
|
closeRuns();
|
|
@@ -743,6 +747,10 @@ var AgentClient = class {
|
|
|
743
747
|
cancelStream(runId) {
|
|
744
748
|
return this.request("POST", `/agent/chat/${encodeURIComponent(runId)}/cancel`);
|
|
745
749
|
}
|
|
750
|
+
/**
|
|
751
|
+
* `remember` approves later calls of the same tool in the same thread; `via` names the surface
|
|
752
|
+
* the decision came through (the server records `'web'` when omitted).
|
|
753
|
+
*/
|
|
746
754
|
approveToolCall(input) {
|
|
747
755
|
return this.request("POST", "/agent/tool-call/approve", input);
|
|
748
756
|
}
|
|
@@ -970,8 +978,66 @@ import React3 from "react";
|
|
|
970
978
|
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
|
|
971
979
|
|
|
972
980
|
// src/transcript/model.ts
|
|
981
|
+
import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
|
|
973
982
|
import { getToolName as getToolName2, isDataUIPart, isFileUIPart, isReasoningUIPart, isTextUIPart, isToolUIPart } from "ai";
|
|
974
983
|
|
|
984
|
+
// src/elicitation/answers.ts
|
|
985
|
+
import { validateElicitationAnswer, validateElicitationValue } from "@dudousxd/nestjs-agent-core";
|
|
986
|
+
function pad(value) {
|
|
987
|
+
return String(value).padStart(2, "0");
|
|
988
|
+
}
|
|
989
|
+
__name(pad, "pad");
|
|
990
|
+
function toDay(date) {
|
|
991
|
+
if (Number.isNaN(date.getTime())) {
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
995
|
+
}
|
|
996
|
+
__name(toDay, "toDay");
|
|
997
|
+
function coerceOne(type, raw) {
|
|
998
|
+
if (raw === null || raw === void 0) {
|
|
999
|
+
return null;
|
|
1000
|
+
}
|
|
1001
|
+
if (Array.isArray(raw)) {
|
|
1002
|
+
return null;
|
|
1003
|
+
}
|
|
1004
|
+
if (raw instanceof Date) {
|
|
1005
|
+
return type === "date" || type === void 0 ? toDay(raw) : raw.toISOString();
|
|
1006
|
+
}
|
|
1007
|
+
if (typeof raw === "boolean") {
|
|
1008
|
+
return raw ? "true" : "false";
|
|
1009
|
+
}
|
|
1010
|
+
if (typeof raw === "number") {
|
|
1011
|
+
return Number.isFinite(raw) ? String(raw) : null;
|
|
1012
|
+
}
|
|
1013
|
+
const text = raw;
|
|
1014
|
+
switch (type) {
|
|
1015
|
+
case "number":
|
|
1016
|
+
case "email":
|
|
1017
|
+
case "url":
|
|
1018
|
+
case "date":
|
|
1019
|
+
return text.trim() === "" ? null : text.trim();
|
|
1020
|
+
case "boolean": {
|
|
1021
|
+
const lowered = text.trim().toLowerCase();
|
|
1022
|
+
if (lowered === "true" || lowered === "on" || lowered === "yes") return "true";
|
|
1023
|
+
if (lowered === "false" || lowered === "off" || lowered === "no") return "false";
|
|
1024
|
+
return lowered === "" ? null : text;
|
|
1025
|
+
}
|
|
1026
|
+
default:
|
|
1027
|
+
return text === "" ? null : text;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
__name(coerceOne, "coerceOne");
|
|
1031
|
+
function coerceAnswer(question, raw) {
|
|
1032
|
+
const type = question.input?.type;
|
|
1033
|
+
const items = Array.isArray(raw) ? raw : [
|
|
1034
|
+
raw
|
|
1035
|
+
];
|
|
1036
|
+
const values = items.map((item) => coerceOne(type, item)).filter((value) => value !== null);
|
|
1037
|
+
return question.multiple === true ? values : values.slice(0, 1);
|
|
1038
|
+
}
|
|
1039
|
+
__name(coerceAnswer, "coerceAnswer");
|
|
1040
|
+
|
|
975
1041
|
// src/presentation/tool-activity.ts
|
|
976
1042
|
import { getToolName } from "ai";
|
|
977
1043
|
|
|
@@ -1260,7 +1326,7 @@ function buildTranscriptBlocks(message, options) {
|
|
|
1260
1326
|
if (toolBuffer.length === 0) {
|
|
1261
1327
|
return;
|
|
1262
1328
|
}
|
|
1263
|
-
const calls = toolBuffer.map((part) => buildToolCall(part, options.approval, approvals.get(part.toolCallId)
|
|
1329
|
+
const calls = toolBuffer.map((part) => buildToolCall(part, options.approval, approvalOf(approvals.get(part.toolCallId), part), options.toolCatalog));
|
|
1264
1330
|
const roots = nestToolCalls(calls);
|
|
1265
1331
|
blocks.push({
|
|
1266
1332
|
kind: "tools",
|
|
@@ -1335,7 +1401,7 @@ function buildTranscriptBlocks(message, options) {
|
|
|
1335
1401
|
fileBuffer.push(part);
|
|
1336
1402
|
continue;
|
|
1337
1403
|
}
|
|
1338
|
-
if (part.type === APPROVAL_PART) {
|
|
1404
|
+
if (part.type === APPROVAL_PART || part.type === SETTLED_PART) {
|
|
1339
1405
|
continue;
|
|
1340
1406
|
}
|
|
1341
1407
|
flushAll();
|
|
@@ -1486,7 +1552,11 @@ function buildToolCall(part, options, approval, catalog) {
|
|
|
1486
1552
|
approve: {
|
|
1487
1553
|
available: awaiting && options?.canApprove === true,
|
|
1488
1554
|
isSubmitting: sending === "approve",
|
|
1489
|
-
|
|
1555
|
+
// Read by field, not passed through: `onClick={call.approve.run}` hands this a click event,
|
|
1556
|
+
// and a host's handler must not receive that as its options.
|
|
1557
|
+
run: /* @__PURE__ */ __name((approveOptions) => approveOptions?.remember === true ? options?.approve(toolCallId, {
|
|
1558
|
+
remember: true
|
|
1559
|
+
}) : options?.approve(toolCallId), "run")
|
|
1490
1560
|
},
|
|
1491
1561
|
reject: {
|
|
1492
1562
|
available: awaiting && options?.canReject === true,
|
|
@@ -1504,11 +1574,16 @@ function readElicitationRequest(part) {
|
|
|
1504
1574
|
}
|
|
1505
1575
|
const questions = [];
|
|
1506
1576
|
for (const candidate of input.questions) {
|
|
1507
|
-
if (!isRecord2(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string"
|
|
1577
|
+
if (!isRecord2(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
|
|
1578
|
+
return null;
|
|
1579
|
+
}
|
|
1580
|
+
const input2 = readElicitationInput(candidate.input) ?? null;
|
|
1581
|
+
const rawOptions = Array.isArray(candidate.options) ? candidate.options : [];
|
|
1582
|
+
if (rawOptions.length === 0 && (input2 === null || input2.type === "select")) {
|
|
1508
1583
|
return null;
|
|
1509
1584
|
}
|
|
1510
1585
|
const options = [];
|
|
1511
|
-
for (const option of
|
|
1586
|
+
for (const option of rawOptions) {
|
|
1512
1587
|
if (!isRecord2(option) || typeof option.value !== "string" || typeof option.label !== "string") {
|
|
1513
1588
|
return null;
|
|
1514
1589
|
}
|
|
@@ -1521,7 +1596,10 @@ function readElicitationRequest(part) {
|
|
|
1521
1596
|
questions.push({
|
|
1522
1597
|
id: candidate.id,
|
|
1523
1598
|
prompt: candidate.prompt,
|
|
1599
|
+
description: typeof candidate.description === "string" ? candidate.description : null,
|
|
1600
|
+
input: input2,
|
|
1524
1601
|
multiple: candidate.multiple === true,
|
|
1602
|
+
allowFreeText: candidate.allowFreeText === true,
|
|
1525
1603
|
defaults: Array.isArray(candidate.defaults) ? candidate.defaults.filter((value) => typeof value === "string") : [],
|
|
1526
1604
|
options
|
|
1527
1605
|
});
|
|
@@ -1557,12 +1635,38 @@ function buildElicitationBlock(key, part, request, options) {
|
|
|
1557
1635
|
const picked = isPending ? options.picked(toolCallId, question.id) : void 0;
|
|
1558
1636
|
const selected = picked ?? outcome?.answers[question.id] ?? question.defaults;
|
|
1559
1637
|
const pick = /* @__PURE__ */ __name((values) => options.pick(toolCallId, question.id, values), "pick");
|
|
1638
|
+
const error = isPending ? validateElicitationAnswer2({
|
|
1639
|
+
id: question.id,
|
|
1640
|
+
prompt: question.prompt,
|
|
1641
|
+
options: question.options.map(({ value, label }) => ({
|
|
1642
|
+
value,
|
|
1643
|
+
label
|
|
1644
|
+
})),
|
|
1645
|
+
...question.input !== null ? {
|
|
1646
|
+
input: question.input
|
|
1647
|
+
} : {},
|
|
1648
|
+
...question.multiple ? {
|
|
1649
|
+
multiple: true
|
|
1650
|
+
} : {},
|
|
1651
|
+
...question.allowFreeText ? {
|
|
1652
|
+
allowFreeText: true
|
|
1653
|
+
} : {}
|
|
1654
|
+
}, selected) : null;
|
|
1560
1655
|
return {
|
|
1561
1656
|
id: question.id,
|
|
1562
1657
|
prompt: question.prompt,
|
|
1658
|
+
description: question.description,
|
|
1659
|
+
input: question.input,
|
|
1563
1660
|
multiple: question.multiple,
|
|
1564
1661
|
position: index + 1,
|
|
1565
1662
|
selected,
|
|
1663
|
+
value: selected[0] ?? "",
|
|
1664
|
+
error,
|
|
1665
|
+
setValue: /* @__PURE__ */ __name((raw) => {
|
|
1666
|
+
if (isPending) {
|
|
1667
|
+
pick(coerceAnswer(question, raw));
|
|
1668
|
+
}
|
|
1669
|
+
}, "setValue"),
|
|
1566
1670
|
isPristine: isPending ? picked === void 0 : outcome?.defaulted.includes(question.id) ?? true,
|
|
1567
1671
|
options: question.options.map((option) => ({
|
|
1568
1672
|
value: option.value,
|
|
@@ -1597,6 +1701,7 @@ function buildElicitationBlock(key, part, request, options) {
|
|
|
1597
1701
|
questions,
|
|
1598
1702
|
questionCount: questions.length,
|
|
1599
1703
|
isPending,
|
|
1704
|
+
isValid: questions.every((question) => question.error === null),
|
|
1600
1705
|
outcome,
|
|
1601
1706
|
error: options.errorOf(toolCallId),
|
|
1602
1707
|
answer: {
|
|
@@ -1614,25 +1719,90 @@ function buildElicitationBlock(key, part, request, options) {
|
|
|
1614
1719
|
__name(buildElicitationBlock, "buildElicitationBlock");
|
|
1615
1720
|
var UI_PART = "data-ui";
|
|
1616
1721
|
var APPROVAL_PART = "data-approval-requested";
|
|
1722
|
+
var SETTLED_PART = "data-approval-settled";
|
|
1723
|
+
var SETTLED_STATUSES = [
|
|
1724
|
+
"approved",
|
|
1725
|
+
"rejected",
|
|
1726
|
+
"expired"
|
|
1727
|
+
];
|
|
1617
1728
|
function readApprovals(parts) {
|
|
1618
1729
|
const out = /* @__PURE__ */ new Map();
|
|
1730
|
+
const entry = /* @__PURE__ */ __name((id) => {
|
|
1731
|
+
let found = out.get(id);
|
|
1732
|
+
if (found === void 0) {
|
|
1733
|
+
found = {
|
|
1734
|
+
approver: null,
|
|
1735
|
+
expiresAt: null,
|
|
1736
|
+
reason: null,
|
|
1737
|
+
status: null,
|
|
1738
|
+
remember: false,
|
|
1739
|
+
decidedBy: null,
|
|
1740
|
+
decidedVia: null,
|
|
1741
|
+
decisionReason: null
|
|
1742
|
+
};
|
|
1743
|
+
out.set(id, found);
|
|
1744
|
+
}
|
|
1745
|
+
return found;
|
|
1746
|
+
}, "entry");
|
|
1619
1747
|
for (const part of parts) {
|
|
1620
|
-
if (part.type !== APPROVAL_PART) {
|
|
1748
|
+
if (part.type !== APPROVAL_PART && part.type !== SETTLED_PART) {
|
|
1621
1749
|
continue;
|
|
1622
1750
|
}
|
|
1623
1751
|
const data = part.data;
|
|
1624
|
-
if (!isRecord2(data) || typeof data.id !== "string"
|
|
1752
|
+
if (!isRecord2(data) || typeof data.id !== "string") {
|
|
1625
1753
|
continue;
|
|
1626
1754
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1755
|
+
const approval = entry(data.id);
|
|
1756
|
+
if (part.type === APPROVAL_PART) {
|
|
1757
|
+
if (typeof data.approver !== "string") {
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
approval.approver = data.approver;
|
|
1761
|
+
approval.expiresAt = typeof data.expiresAt === "string" ? data.expiresAt : null;
|
|
1762
|
+
approval.reason = typeof data.reason === "string" ? data.reason : null;
|
|
1763
|
+
continue;
|
|
1764
|
+
}
|
|
1765
|
+
if (typeof data.status !== "string" || !SETTLED_STATUSES.includes(data.status)) {
|
|
1766
|
+
continue;
|
|
1767
|
+
}
|
|
1768
|
+
approval.status = data.status;
|
|
1769
|
+
if (approval.approver === null && typeof data.approver === "string") {
|
|
1770
|
+
approval.approver = data.approver;
|
|
1771
|
+
}
|
|
1772
|
+
approval.remember = data.remember === true;
|
|
1773
|
+
approval.decidedBy = typeof data.decidedBy === "string" ? data.decidedBy : null;
|
|
1774
|
+
approval.decidedVia = typeof data.decidedVia === "string" ? data.decidedVia : null;
|
|
1775
|
+
approval.decisionReason = typeof data.reason === "string" ? data.reason : null;
|
|
1632
1776
|
}
|
|
1633
1777
|
return out;
|
|
1634
1778
|
}
|
|
1635
1779
|
__name(readApprovals, "readApprovals");
|
|
1780
|
+
function approvalOf(parts, call) {
|
|
1781
|
+
if (parts === void 0 || parts.approver === null) {
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
return {
|
|
1785
|
+
approver: parts.approver,
|
|
1786
|
+
expiresAt: parts.expiresAt,
|
|
1787
|
+
reason: parts.reason,
|
|
1788
|
+
status: parts.status ?? statusFromPart(call),
|
|
1789
|
+
remember: parts.remember,
|
|
1790
|
+
decidedBy: parts.decidedBy,
|
|
1791
|
+
decidedVia: parts.decidedVia,
|
|
1792
|
+
decisionReason: parts.decisionReason
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
__name(approvalOf, "approvalOf");
|
|
1796
|
+
function statusFromPart(call) {
|
|
1797
|
+
if (call.state === "output-denied") {
|
|
1798
|
+
return "rejected";
|
|
1799
|
+
}
|
|
1800
|
+
if (call.state === "output-available" || call.state === "output-error") {
|
|
1801
|
+
return "approved";
|
|
1802
|
+
}
|
|
1803
|
+
return "pending";
|
|
1804
|
+
}
|
|
1805
|
+
__name(statusFromPart, "statusFromPart");
|
|
1636
1806
|
function readUiComponent(part) {
|
|
1637
1807
|
const data = part.data;
|
|
1638
1808
|
if (!isRecord2(data) || typeof data.component !== "string") {
|
|
@@ -2018,10 +2188,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2018
2188
|
}, [
|
|
2019
2189
|
settle
|
|
2020
2190
|
]);
|
|
2021
|
-
const approve = useCallback3((toolCallId) => {
|
|
2191
|
+
const approve = useCallback3((toolCallId, options2) => {
|
|
2022
2192
|
const onApprove = latest.current.options.onApprove;
|
|
2023
2193
|
if (onApprove) {
|
|
2024
|
-
settle(toolCallId, "approve", () => onApprove(toolCallId));
|
|
2194
|
+
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
2025
2195
|
}
|
|
2026
2196
|
}, [
|
|
2027
2197
|
settle
|
|
@@ -2996,6 +3166,49 @@ function useToolCatalog(options) {
|
|
|
2996
3166
|
}
|
|
2997
3167
|
__name(useToolCatalog, "useToolCatalog");
|
|
2998
3168
|
|
|
3169
|
+
// src/approvals/countdown.ts
|
|
3170
|
+
import { useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
|
|
3171
|
+
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3172
|
+
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3173
|
+
if (!Number.isFinite(deadline)) {
|
|
3174
|
+
return {
|
|
3175
|
+
remainingMs: null,
|
|
3176
|
+
isExpired: false
|
|
3177
|
+
};
|
|
3178
|
+
}
|
|
3179
|
+
const remainingMs = Math.max(0, deadline - now);
|
|
3180
|
+
return {
|
|
3181
|
+
remainingMs,
|
|
3182
|
+
isExpired: remainingMs === 0
|
|
3183
|
+
};
|
|
3184
|
+
}
|
|
3185
|
+
__name(approvalCountdown, "approvalCountdown");
|
|
3186
|
+
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3187
|
+
const { intervalMs = 1e3 } = options;
|
|
3188
|
+
const nowRef = useRef6(options.now ?? Date.now);
|
|
3189
|
+
nowRef.current = options.now ?? Date.now;
|
|
3190
|
+
const [state, setState] = useState8(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
3191
|
+
useEffect8(() => {
|
|
3192
|
+
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3193
|
+
const first = read();
|
|
3194
|
+
setState(first);
|
|
3195
|
+
if (first.remainingMs === null || first.isExpired) {
|
|
3196
|
+
return;
|
|
3197
|
+
}
|
|
3198
|
+
const timer = setInterval(() => {
|
|
3199
|
+
const next = read();
|
|
3200
|
+
setState(next);
|
|
3201
|
+
if (next.isExpired) clearInterval(timer);
|
|
3202
|
+
}, intervalMs);
|
|
3203
|
+
return () => clearInterval(timer);
|
|
3204
|
+
}, [
|
|
3205
|
+
expiresAt,
|
|
3206
|
+
intervalMs
|
|
3207
|
+
]);
|
|
3208
|
+
return state;
|
|
3209
|
+
}
|
|
3210
|
+
__name(useApprovalCountdown, "useApprovalCountdown");
|
|
3211
|
+
|
|
2999
3212
|
// src/stored-message-to-ui-message.ts
|
|
3000
3213
|
import { DEFAULT_REFUSAL_REASON } from "@dudousxd/nestjs-agent-core";
|
|
3001
3214
|
function isRefusal(result) {
|
|
@@ -3055,6 +3268,41 @@ function storedMessageToUiMessage(message) {
|
|
|
3055
3268
|
}
|
|
3056
3269
|
});
|
|
3057
3270
|
}
|
|
3271
|
+
for (const approval of message.approvals ?? []) {
|
|
3272
|
+
parts.push({
|
|
3273
|
+
type: "data-approval-requested",
|
|
3274
|
+
id: approval.toolCallId,
|
|
3275
|
+
data: {
|
|
3276
|
+
id: approval.toolCallId,
|
|
3277
|
+
approver: approval.approver,
|
|
3278
|
+
...approval.expiresAt !== void 0 ? {
|
|
3279
|
+
expiresAt: approval.expiresAt
|
|
3280
|
+
} : {}
|
|
3281
|
+
}
|
|
3282
|
+
});
|
|
3283
|
+
if (approval.status !== "pending") {
|
|
3284
|
+
parts.push({
|
|
3285
|
+
type: "data-approval-settled",
|
|
3286
|
+
id: approval.toolCallId,
|
|
3287
|
+
data: {
|
|
3288
|
+
id: approval.toolCallId,
|
|
3289
|
+
status: approval.status,
|
|
3290
|
+
...approval.decidedBy !== void 0 ? {
|
|
3291
|
+
decidedBy: approval.decidedBy
|
|
3292
|
+
} : {},
|
|
3293
|
+
...approval.decidedVia !== void 0 ? {
|
|
3294
|
+
decidedVia: approval.decidedVia
|
|
3295
|
+
} : {},
|
|
3296
|
+
...approval.remember === true ? {
|
|
3297
|
+
remember: true
|
|
3298
|
+
} : {},
|
|
3299
|
+
...approval.reason !== void 0 ? {
|
|
3300
|
+
reason: approval.reason
|
|
3301
|
+
} : {}
|
|
3302
|
+
}
|
|
3303
|
+
});
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3058
3306
|
for (const call of message.toolCalls ?? []) {
|
|
3059
3307
|
const result = message.toolResults?.find((candidate) => candidate.id === call.id);
|
|
3060
3308
|
const toolKind2 = call.kind;
|
|
@@ -3157,19 +3405,19 @@ __name(sumUsage, "sumUsage");
|
|
|
3157
3405
|
|
|
3158
3406
|
// src/use-agent-chat.ts
|
|
3159
3407
|
import { useChat } from "@ai-sdk/react";
|
|
3160
|
-
import { useCallback as useCallback6, useEffect as
|
|
3408
|
+
import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo4, useRef as useRef7, useState as useState9 } from "react";
|
|
3161
3409
|
function useAgentChat(options) {
|
|
3162
|
-
const latest =
|
|
3410
|
+
const latest = useRef7(options);
|
|
3163
3411
|
latest.current = options;
|
|
3164
|
-
const [runId, setRunId] =
|
|
3165
|
-
const runIdRef =
|
|
3412
|
+
const [runId, setRunId] = useState9(options.resumeRunId);
|
|
3413
|
+
const runIdRef = useRef7(runId);
|
|
3166
3414
|
runIdRef.current = runId;
|
|
3167
|
-
const settlingRunIdRef =
|
|
3168
|
-
const autoResumeRunIdRef =
|
|
3169
|
-
const [autoResume, setAutoResume] =
|
|
3170
|
-
const [activeRunId, setActiveRunId] =
|
|
3171
|
-
const regenerateNext =
|
|
3172
|
-
const createdThreadId =
|
|
3415
|
+
const settlingRunIdRef = useRef7(void 0);
|
|
3416
|
+
const autoResumeRunIdRef = useRef7(void 0);
|
|
3417
|
+
const [autoResume, setAutoResume] = useState9(false);
|
|
3418
|
+
const [activeRunId, setActiveRunId] = useState9(null);
|
|
3419
|
+
const regenerateNext = useRef7(false);
|
|
3420
|
+
const createdThreadId = useRef7(void 0);
|
|
3173
3421
|
const client = useMemo4(() => {
|
|
3174
3422
|
if (options.client) return options.client;
|
|
3175
3423
|
return new AgentClient({
|
|
@@ -3185,7 +3433,7 @@ function useAgentChat(options) {
|
|
|
3185
3433
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
3186
3434
|
});
|
|
3187
3435
|
}, []);
|
|
3188
|
-
|
|
3436
|
+
useEffect9(() => {
|
|
3189
3437
|
if (!options.resume || options.threadId === void 0) return;
|
|
3190
3438
|
let cancelled = false;
|
|
3191
3439
|
const threadId = options.threadId;
|
|
@@ -3254,7 +3502,7 @@ function useAgentChat(options) {
|
|
|
3254
3502
|
}, "onAttemptStart")
|
|
3255
3503
|
});
|
|
3256
3504
|
}, []);
|
|
3257
|
-
const backgroundRef =
|
|
3505
|
+
const backgroundRef = useRef7(() => Promise.resolve());
|
|
3258
3506
|
const chat = useChat({
|
|
3259
3507
|
transport,
|
|
3260
3508
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
@@ -3285,9 +3533,9 @@ function useAgentChat(options) {
|
|
|
3285
3533
|
}
|
|
3286
3534
|
}, "onFinish")
|
|
3287
3535
|
});
|
|
3288
|
-
const chatRef =
|
|
3536
|
+
const chatRef = useRef7(chat);
|
|
3289
3537
|
chatRef.current = chat;
|
|
3290
|
-
const turnInFlight =
|
|
3538
|
+
const turnInFlight = useRef7(false);
|
|
3291
3539
|
const isTurnInFlight = useCallback6(() => turnInFlight.current || transport.isAttemptLive, [
|
|
3292
3540
|
transport
|
|
3293
3541
|
]);
|
|
@@ -3307,9 +3555,9 @@ function useAgentChat(options) {
|
|
|
3307
3555
|
toolCallId,
|
|
3308
3556
|
output
|
|
3309
3557
|
}), []);
|
|
3310
|
-
const [threads, setThreads] =
|
|
3311
|
-
const [quota, setQuota] =
|
|
3312
|
-
const [backgroundRuns, setBackgroundRuns] =
|
|
3558
|
+
const [threads, setThreads] = useState9([]);
|
|
3559
|
+
const [quota, setQuota] = useState9(null);
|
|
3560
|
+
const [backgroundRuns, setBackgroundRuns] = useState9([]);
|
|
3313
3561
|
const refreshBackground = useCallback6(async () => {
|
|
3314
3562
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
3315
3563
|
if (threadId === void 0) {
|
|
@@ -3335,7 +3583,7 @@ function useAgentChat(options) {
|
|
|
3335
3583
|
]);
|
|
3336
3584
|
backgroundRef.current = refreshBackground;
|
|
3337
3585
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
3338
|
-
|
|
3586
|
+
useEffect9(() => {
|
|
3339
3587
|
if (options.background !== true || options.threadId === void 0) {
|
|
3340
3588
|
return;
|
|
3341
3589
|
}
|
|
@@ -3345,7 +3593,7 @@ function useAgentChat(options) {
|
|
|
3345
3593
|
options.threadId,
|
|
3346
3594
|
refreshBackground
|
|
3347
3595
|
]);
|
|
3348
|
-
|
|
3596
|
+
useEffect9(() => {
|
|
3349
3597
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
3350
3598
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
3351
3599
|
return;
|
|
@@ -3413,18 +3661,27 @@ function useAgentChat(options) {
|
|
|
3413
3661
|
}, [
|
|
3414
3662
|
client
|
|
3415
3663
|
]);
|
|
3416
|
-
const approve = useCallback6(async ({ toolCallId }) => {
|
|
3664
|
+
const approve = useCallback6(async ({ toolCallId, remember, via }) => {
|
|
3417
3665
|
await client.approveToolCall({
|
|
3418
|
-
toolCallId
|
|
3666
|
+
toolCallId,
|
|
3667
|
+
...remember === true ? {
|
|
3668
|
+
remember: true
|
|
3669
|
+
} : {},
|
|
3670
|
+
...via !== void 0 ? {
|
|
3671
|
+
via
|
|
3672
|
+
} : {}
|
|
3419
3673
|
});
|
|
3420
3674
|
}, [
|
|
3421
3675
|
client
|
|
3422
3676
|
]);
|
|
3423
|
-
const reject = useCallback6(async ({ toolCallId, reason }) => {
|
|
3677
|
+
const reject = useCallback6(async ({ toolCallId, reason, via }) => {
|
|
3424
3678
|
await client.rejectToolCall({
|
|
3425
3679
|
toolCallId,
|
|
3426
3680
|
...reason !== void 0 ? {
|
|
3427
3681
|
reason
|
|
3682
|
+
} : {},
|
|
3683
|
+
...via !== void 0 ? {
|
|
3684
|
+
via
|
|
3428
3685
|
} : {}
|
|
3429
3686
|
});
|
|
3430
3687
|
}, [
|
|
@@ -3510,8 +3767,10 @@ export {
|
|
|
3510
3767
|
MessageList,
|
|
3511
3768
|
SPEECH_LANGUAGES,
|
|
3512
3769
|
applyCompletion,
|
|
3770
|
+
approvalCountdown,
|
|
3513
3771
|
backgroundRunsFromThread,
|
|
3514
3772
|
buildTranscriptBlocks,
|
|
3773
|
+
coerceAnswer,
|
|
3515
3774
|
correctedCallIds,
|
|
3516
3775
|
createSkillsSource,
|
|
3517
3776
|
describeTimestamp,
|
|
@@ -3537,12 +3796,15 @@ export {
|
|
|
3537
3796
|
toolCallState,
|
|
3538
3797
|
toolCatalogFrom,
|
|
3539
3798
|
useAgentChat,
|
|
3799
|
+
useApprovalCountdown,
|
|
3540
3800
|
useChatTranscript,
|
|
3541
3801
|
useComposerAutocomplete,
|
|
3542
3802
|
useElapsed,
|
|
3543
3803
|
useSpeechRecognition,
|
|
3544
3804
|
useStickToBottom,
|
|
3545
3805
|
useToolCatalog,
|
|
3546
|
-
useTranscriptItem
|
|
3806
|
+
useTranscriptItem,
|
|
3807
|
+
validateElicitationAnswer as validateAnswer,
|
|
3808
|
+
validateElicitationValue as validateAnswerValue
|
|
3547
3809
|
};
|
|
3548
3810
|
//# sourceMappingURL=index.js.map
|